<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>pip on
A Scripter's Notes</title><link>https://scripter.co/tags/pip/</link><description>Recent content in pip
on A Scripter's Notes</description><language>en-us</language><managingEditor>kaushal.modi@gmail.com (Kaushal Modi)</managingEditor><webMaster>kaushal.modi@gmail.com (Kaushal Modi)</webMaster><lastBuildDate>Wed, 22 Apr 2026 08:24:58 -0400</lastBuildDate><generator>Hugo -- gohugo.io</generator><docs>https://validator.w3.org/feed/docs/rss2.html</docs><atom:link href="https://scripter.co/tags/pip/index.xml" rel="self" type="application/rss+xml"/><item><title>Saving Python pip dependencies</title><link>https://scripter.co/saving-python-pip-dependencies/</link><description>&lt;blockquote>How I generated the Python dependencies file &lt;code>requirements.txt&lt;/code> so
that Netlify can install and run the HTML5 Validator before deploying
this site.&lt;/blockquote>&lt;div class="ox-hugo-toc toc">
&lt;div class="heading">Table of Contents&lt;/div>
&lt;ul>
&lt;li>&lt;a href="#create-a-virtual-environment">&lt;span class="section-num">1&lt;/span> Create a &lt;em>virtual environment&lt;/em>&lt;/a>&lt;/li>
&lt;li>&lt;a href="#activate-the-virtual-environment">&lt;span class="section-num">2&lt;/span> Activate the &lt;em>virtual environment&lt;/em>&lt;/a>&lt;/li>
&lt;li>&lt;a href="#install-the-packages-using-pip">&lt;span class="section-num">3&lt;/span> Install the packages using &lt;code>pip&lt;/code>&lt;/a>&lt;/li>
&lt;li>&lt;a href="#generate-requirements-dot-txt">&lt;span class="section-num">4&lt;/span> Generate &lt;code>requirements.txt&lt;/code>&lt;/a>&lt;/li>
&lt;li>&lt;a href="#netlify-deployment">Netlify deployment&lt;/a>&lt;/li>
&lt;li>&lt;a href="#summary">Summary&lt;/a>&lt;/li>
&lt;/ul>
&lt;/div>
&lt;!--endtoc-->
&lt;p>Recently I learned about the Python tool &lt;code>html5validator&lt;/code> tool and
used it to run HTML5 validation on local HTML files. You can read more
about that in the &lt;a href="https://scripter.co/offline-html5-validator/">Offline HTML5 Validator&lt;/a> post.&lt;/p>
&lt;p>But then I wondered .. &amp;ldquo;Wouldn&amp;rsquo;t it be awesome if I run this
validation step &lt;strong>each time&lt;/strong> after Hugo generates this site on &lt;a href="https://netlify.com">Netlify&lt;/a>,
but &lt;span class="underline">before&lt;/span> it gets deployed?&amp;rdquo;. That curiosity led me to &lt;a href="https://docs.netlify.com/configure-builds/manage-dependencies/#python-dependencies">Netlify&amp;rsquo;s
documentation on Python dependencies&lt;/a>, and I learned that Netlify will
run &lt;code>pip install&lt;/code> to install the dependencies in &lt;code>requirements.txt&lt;/code>
present in the repository&amp;rsquo;s base directory.&lt;/p>
&lt;p>&lt;span class="org-target" id="netlify-pip-freeze">&lt;/span> I followed the &lt;code>pip freeze &amp;gt; requirements.txt&lt;/code>
step in that documentation but that ended up listing &lt;strong>all&lt;/strong> my &lt;code>pip&lt;/code>
installed packages in that file! I needed the &lt;code>requirements.txt&lt;/code> to
include the dependencies only for &lt;code>html5validator&lt;/code>. This post was born
in my quest to achieve that.&lt;/p>
&lt;p>The solution to this problem was to first create a Python &lt;em>virtual
environment&lt;/em> in my site directory, and &lt;em>then&lt;/em> do all the &lt;code>pip&lt;/code>
operations in there. I learned about this &lt;em>virtual environment&lt;/em> step
from &lt;a href="https://medium.com/python-pandemonium/better-python-dependency-and-package-management-b5d8ea29dff1">this Python Pandemonium post&lt;/a>.&lt;/p>
&lt;p>The &lt;a href="https://docs.python.org/3/library/venv.html">&lt;strong>venv&lt;/strong> documentation&lt;/a> has a lot of details &amp;mdash; I&amp;rsquo;ll just list the
key steps in this post.&lt;/p>
&lt;h2 id="create-a-virtual-environment">&lt;span class="section-num">1&lt;/span> Create a &lt;em>virtual environment&lt;/em>&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#create-a-virtual-environment">#&lt;/a>&lt;/h2>
&lt;p>&lt;em>cd&lt;/em> to your site directory and run the below command create a
virtualenv directory named &lt;code>pyenv&lt;/code> in there.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">python3 -m venv pyenv
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="note">
&lt;p>As we are creating this &lt;em>virtual environment&lt;/em> just for the sake of
creating a &lt;code>requirements.txt&lt;/code>, we don&amp;rsquo;t need to commit this
directory to &lt;em>git&lt;/em>.&lt;/p>
&lt;/div>
&lt;h2 id="activate-the-virtual-environment">&lt;span class="section-num">2&lt;/span> Activate the &lt;em>virtual environment&lt;/em>&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#activate-the-virtual-environment">#&lt;/a>&lt;/h2>
&lt;p>The virtualenv directory &lt;code>pyenv/bin/&lt;/code> will have multiple flavors of
shell scripts to activate your virtualenv. I am using
&lt;code>activate.csh&lt;/code> here as my shell is &lt;em>tcsh&lt;/em> 🙄.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> pyenv/bin/activate.csh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Just to emphasize, it is important to use the &lt;strong>&lt;code>source&lt;/code>&lt;/strong> command here,
and not just call the shell script directly.&lt;/p>
&lt;p>Once you activate this virtualenv, you should see something like
&lt;em>[pyenv]&lt;/em> in the shell prompt.&lt;/p>
&lt;h2 id="install-the-packages-using-pip">&lt;span class="section-num">3&lt;/span> Install the packages using &lt;code>pip&lt;/code>&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#install-the-packages-using-pip">#&lt;/a>&lt;/h2>
&lt;p>Install all the project-specific packages. In this case it was just
this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">pip install html5validator
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The package (and its dependencies) will be installed in
&lt;code>pyenv/lib/python3.7/site-packages/&lt;/code>. Here, the &lt;code>python3.7/&lt;/code>
sub-directory name will match the version of Python you have
installed.&lt;/p>
&lt;h2 id="generate-requirements-dot-txt">&lt;span class="section-num">4&lt;/span> Generate &lt;code>requirements.txt&lt;/code>&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#generate-requirements-dot-txt">#&lt;/a>&lt;/h2>
&lt;p>Finally, we run the &lt;code>pip freeze&lt;/code> command &lt;a href="#netlify-pip-freeze">mentioned&lt;/a> in Netlify docs,
but with the &lt;strong>&lt;code>--local&lt;/code>&lt;/strong> switch:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">pip freeze --local &amp;gt; requirements.txt
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="note">
&lt;p>The &lt;code>--local&lt;/code> option ensures that globally-installed packages are not
listed even if the virtualenv has global access.&lt;/p>
&lt;/div>
&lt;p>Here&amp;rsquo;s the &lt;code>requirements.txt&lt;/code> created by that command:&lt;/p>
&lt;p>&lt;a id="code-snippet--netlify-requirements.txt">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">html5validator==0.4.2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PyYAML==6.0
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="src-block-caption">
&lt;span class="src-block-number">&lt;a href="#code-snippet--netlify-requirements.txt">Code Snippet 1&lt;/a>:&lt;/span>
The &lt;code>requirements.txt&lt;/code> for Netlify
&lt;/div>
&lt;p>Now, I could have just manually typed &lt;code>html5validator==0.4.2&lt;/code> in a
&lt;code>requirements.txt&lt;/code> and committed that, and that would work too. But
then, I wouldn&amp;rsquo;t have learned how to create a project-specific &lt;em>pip
dependency file&lt;/em> 😄.&lt;/p>
&lt;h2 id="netlify-deployment">Netlify deployment&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#netlify-deployment">#&lt;/a>&lt;/h2>
&lt;p>The &lt;code>html5validator&lt;/code> has a dependency on Java 8. Luckily the Netlify
environment already comes with that installed. So the only extra setup
needed to make this package work on Netlify was to set the
&lt;code>PYTHON_VERSION&lt;/code> environment variable to &lt;strong>3.8&lt;/strong>
&lt;span class="sidenote-number">&lt;small class="sidenote">
The version number should be one of the values listed in &lt;a href="https://github.com/netlify/build-image/blob/focal/included_software.md">Netlify&amp;rsquo;s
&lt;em>included software&lt;/em> list&lt;/a>.
&lt;/small>&lt;/span>
.&lt;/p>
&lt;h2 id="summary">Summary&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#summary">#&lt;/a>&lt;/h2>
&lt;p>The numbered headings in this post already summarize the steps needed
to create a project-specific &lt;code>requirements.txt&lt;/code>.&lt;/p>
&lt;p>With these in place:&lt;/p>
&lt;div class="verse">
&lt;p>✅ &lt;code>requirements.txt&lt;/code> committed in site directory root&lt;br />
✅ Netlify environment variable &lt;code>PYTHON_VERSION&lt;/code> set to 3.8&lt;br />&lt;/p>
&lt;/div>
&lt;p>my Netlify deployment script now does HTML5 Validation along with few
other checks before this site gets deployed 🎉.&lt;/p>
&lt;p>Here&amp;rsquo;s the &lt;a href="https://gitlab.com/kaushalmodi/kaushalmodi.gitlab.io/-/blob/master/build.sh">full &lt;code>build.sh&lt;/code> script&lt;/a>.&lt;/p></description><author>Kaushal.Modi@fakeEmailToMakeValidatorHappy.com (Kaushal Modi)</author><category domain="https://scripter.co/categories/web">web</category><category domain="https://scripter.co/series/html5-validator">HTML5 Validator</category><category domain="https://scripter.co/tags/html">html</category><category domain="https://scripter.co/tags/validator">validator</category><category domain="https://scripter.co/tags/python">python</category><category domain="https://scripter.co/tags/pip">pip</category><category domain="https://scripter.co/tags/100daystooffload">100DaysToOffload</category><category domain="https://scripter.co/tags/netlify">netlify</category><guid>https://scripter.co/saving-python-pip-dependencies/</guid><pubDate>Tue, 14 Jun 2022 00:38:00 -0400</pubDate></item></channel></rss>