Jekyll2020-06-08T01:29:11+00:00https://development-tutorials.github.io/python-first-library/feed.xmlPython First LibraryTutorial for publishing Python libraries, and example library for use within other Python projects.S0AndS0Tag, Release, and Publish2020-06-07T23:04:56+00:002020-06-07T23:04:56+00:00https://development-tutorials.github.io/python-first-library/tag-release-publish<p>Change current working directory to your project repository…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/git/hub/development-tutorials/python-first-library
</code></pre></div></div>
<hr />
<p>Add and commit changes…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git add <span class="nb">.</span>
git commit <span class="nt">-m</span> <span class="s1">'Adds source files for Python library'</span>
</code></pre></div></div>
<p>Tag last commit for release and push to GitHub…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git tag <span class="nt">--annotate</span> v0.0.1 <span class="nt">-m</span> <span class="s1">':bookmark: Initial RFC'</span>
git push hub master
git push hub v0.0.1
</code></pre></div></div>
<p>Make a new release on GitHub (optional as of Python version 3 or greater)…</p>
<ul>
<li>
<p>Example: <code class="language-plaintext highlighter-rouge">https://github.com/development-tutorials/python-first-library/releases/new</code></p>
</li>
<li>
<p>Syntax: <em><code class="language-plaintext highlighter-rouge">https://github.com/<Account>/<Repository>/releases/new</code></em></p>
</li>
</ul>
<p>Publish to PyPi servers</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python3 setup.py sdist bdist_wheel
</code></pre></div></div>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>twine upload <span class="nt">--repository</span> testpypi dist/python-first-library-0.0.1<span class="k">*</span>
<span class="c"># twine upload dist/python-first-library-0.0.1*</span>
</code></pre></div></div>
<blockquote>
<p>Note, there will be new directories and files generated by the build process…</p>
<ul>
<li>
<p><code class="language-plaintext highlighter-rouge">build/lib</code> directory, contains directories and files that will be packaged into an archive</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">dist/</code> directory, contains archives that will be uploaded to PyPi servers</p>
</li>
</ul>
<p>. <code class="language-plaintext highlighter-rouge">python_first_library.egg-info/</code> directory, contains various metadata about the library</p>
<p>… these directories do <strong>not</strong> need to be tracked by Git, so it’s generally okay to add patterns to the <code class="language-plaintext highlighter-rouge">.gitignore</code> file to ignore tracking them by default.</p>
</blockquote>
<p><strong>Warning</strong> if at any point files are removed from the library (eg. via <code class="language-plaintext highlighter-rouge">git rm path</code>), then file(s) will also need to be removed from the <code class="language-plaintext highlighter-rouge">build/lib</code> directory structure.</p>S0AndS0Steps that will repeat for publishing and updating the libraryWrite Command Line Interface2020-06-06T23:11:56+00:002020-06-06T23:11:56+00:00https://development-tutorials.github.io/python-first-library/write-cli<p>Change current working directory to your project repository…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/git/hub/development-tutorials/python-first-library
</code></pre></div></div>
<hr />
<h2 id="python_first_librarycli__init__py"><code class="language-plaintext highlighter-rouge">python_first_library/cli/__init__.py</code></h2>
<p>[python_first_library/cli/<strong>init</strong>.py]: #python_first_librarycli__init__py “”</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span>
<span class="kn">from</span> <span class="nn">argparse</span> <span class="kn">import</span> <span class="n">ArgumentParser</span>
<span class="kn">from</span> <span class="nn">os.path</span> <span class="kn">import</span> <span class="n">basename</span>
<span class="kn">from</span> <span class="nn">sys</span> <span class="kn">import</span> <span class="n">argv</span>
<span class="kn">from</span> <span class="nn">python_first_library</span> <span class="kn">import</span> <span class="n">First_Library</span>
<span class="n">__license__</span> <span class="o">=</span> <span class="s">"""
First Python Library example usage script
Copyright (C) 2020 S0AndS0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""</span>
<span class="n">arg_parser</span> <span class="o">=</span> <span class="n">ArgumentParser</span><span class="p">(</span><span class="n">prog</span> <span class="o">=</span> <span class="n">basename</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span>
<span class="n">usage</span> <span class="o">=</span> <span class="s">'%(prog)s --string "Spam!" --float 4.2'</span><span class="p">,</span>
<span class="n">epilog</span> <span class="o">=</span> <span class="s">'https://github.com/S0AndS0'</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="p">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s">'--string'</span><span class="p">,</span>
<span class="n">help</span> <span class="o">=</span> <span class="s">'String like argument'</span><span class="p">,</span>
<span class="n">required</span> <span class="o">=</span> <span class="bp">True</span><span class="p">,</span>
<span class="nb">type</span> <span class="o">=</span> <span class="nb">str</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="p">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s">'--float'</span><span class="p">,</span>
<span class="n">help</span> <span class="o">=</span> <span class="s">'Optional, float like argument'</span><span class="p">,</span>
<span class="n">required</span> <span class="o">=</span> <span class="bp">False</span><span class="p">,</span>
<span class="n">default</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span>
<span class="nb">type</span> <span class="o">=</span> <span class="nb">float</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="p">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s">'--license'</span><span class="p">,</span>
<span class="n">help</span> <span class="o">=</span> <span class="s">'Prints license and exits'</span><span class="p">,</span>
<span class="n">required</span> <span class="o">=</span> <span class="bp">False</span><span class="p">,</span>
<span class="n">default</span> <span class="o">=</span> <span class="bp">False</span><span class="p">,</span>
<span class="n">action</span> <span class="o">=</span> <span class="s">'store_true'</span><span class="p">)</span>
<span class="n">arg_parser</span><span class="p">.</span><span class="n">add_argument</span><span class="p">(</span><span class="s">'--verbose'</span><span class="p">,</span> <span class="s">'-v'</span><span class="p">,</span>
<span class="n">help</span> <span class="o">=</span> <span class="s">'Loudness of this script'</span><span class="p">,</span>
<span class="n">action</span> <span class="o">=</span> <span class="s">'count'</span><span class="p">,</span>
<span class="n">default</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">args</span> <span class="o">=</span> <span class="nb">vars</span><span class="p">(</span><span class="n">arg_parser</span><span class="p">.</span><span class="n">parse_args</span><span class="p">())</span>
<span class="n">first_library</span> <span class="o">=</span> <span class="n">First_Library</span><span class="p">(</span><span class="o">**</span><span class="n">args</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="k">if</span> <span class="n">args</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'license'</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="n">__license__</span><span class="p">)</span>
<span class="nb">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">first_library</span><span class="p">.</span><span class="n">print_keyword_arguments</span><span class="p">()</span>
</code></pre></div></div>
<p>The <code class="language-plaintext highlighter-rouge">main</code> function is what is defined within the <code class="language-plaintext highlighter-rouge">console_scripts</code> parameter of the <code class="language-plaintext highlighter-rouge">setup.py</code> script, installation process will generally cross-link things correctly such that for MS devices a <code class="language-plaintext highlighter-rouge">.exe</code> file suffix is appended, or executable permissions are assigned for Unix devices.</p>S0AndS0Command Line Interface that shows how to utilize and test libraryWrite Library2020-06-05T23:11:56+00:002020-06-05T23:11:56+00:00https://development-tutorials.github.io/python-first-library/write-library<p>Change current working directory to your project repository…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/git/hub/development-tutorials/python-first-library
</code></pre></div></div>
<hr />
<h2 id="python_first_library__init__py"><code class="language-plaintext highlighter-rouge">python_first_library/__init__.py</code></h2>
<p>[python_first_library/<strong>init</strong>.py]: #python_first_library__init__py “”</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span>
<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
<span class="k">raise</span> <span class="nb">NotImplementedError</span><span class="p">(</span><span class="s">'Please import First_Library instead'</span><span class="p">)</span>
<span class="n">__license__</span> <span class="o">=</span> <span class="s">"""
First Python Library example usage script
Copyright (C) 2020 S0AndS0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""</span>
<span class="k">class</span> <span class="nc">First_Library</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="s">"""docstring for First_Library."""</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">keyword_arguments</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">First_Library</span><span class="p">,</span> <span class="bp">self</span><span class="p">).</span><span class="n">__init__</span><span class="p">()</span>
<span class="bp">self</span><span class="p">.</span><span class="n">keyword_arguments</span> <span class="o">=</span> <span class="n">keyword_arguments</span>
<span class="k">def</span> <span class="nf">print_keyword_arguments</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">print</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">keyword_arguments</span><span class="p">)</span>
</code></pre></div></div>
<p>When installed via pip, the class from this library will be importable via <code class="language-plaintext highlighter-rouge">from python_first_library import First_Library</code></p>S0AndS0Example `First_Library` classPackage Setup2020-06-04T23:11:56+00:002020-06-04T23:11:56+00:00https://development-tutorials.github.io/python-first-library/package-setup<p>Change current working directory to your project repository…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/git/hub/development-tutorials/python-first-library
</code></pre></div></div>
<hr />
<h2 id="-manifestin"><a href="#-manifestin" title="Defines paths that should be explicitly included or excluded">#</a> <code class="language-plaintext highlighter-rouge">MANIFEST.in</code></h2>
<p>The <code class="language-plaintext highlighter-rouge">MANIFEST.in</code> configuration file is where project files that are not automatically detected can either be included, or excluded, within build process…</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>include .github/README.md
</code></pre></div></div>
<p>… for this tutorial the ReadMe file is included, because by default <code class="language-plaintext highlighter-rouge">setuptools</code> will not include files within the <code class="language-plaintext highlighter-rouge">.github</code> directory.</p>
<hr />
<h2 id="-setupcfg"><a href="#-setupcfg" title="Defines metadata and other project properties">#</a> <code class="language-plaintext highlighter-rouge">setup.cfg</code></h2>
<p>The <code class="language-plaintext highlighter-rouge">setup.cfg</code> configuration file is able to define much more than <code class="language-plaintext highlighter-rouge">metadata</code>, and the official <a href="https://docs.python.org/3/distutils/configfile.html">Python Docs – Writing the <code class="language-plaintext highlighter-rouge">setup.cfg</code> Configuration File</a> is worthy of review…</p>
<pre><code class="language-cfg">[metadata]
description-file = .github/README.md
</code></pre>
<p>… for this tutorial the the ReadMe file is defined as the <code class="language-plaintext highlighter-rouge">description-file</code> to notify web-based documentation scripts where to pull data from.</p>
<hr />
<h2 id="-setuppy"><a href="#-setuppy" title="Script that `pip install package-name` command calls">#</a> <code class="language-plaintext highlighter-rouge">setup.py</code></h2>
<p>The <code class="language-plaintext highlighter-rouge">setup.py</code> script is called by <code class="language-plaintext highlighter-rouge">setuptools</code></p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python3
</span>
<span class="kn">from</span> <span class="nn">setuptools</span> <span class="kn">import</span> <span class="p">(</span><span class="n">find_packages</span><span class="p">,</span> <span class="n">setup</span><span class="p">)</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">".github/README.md"</span><span class="p">,</span> <span class="s">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">fh</span><span class="p">:</span>
<span class="n">long_description</span> <span class="o">=</span> <span class="n">fh</span><span class="p">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">setup</span><span class="p">(</span>
<span class="n">name</span> <span class="o">=</span> <span class="s">'python_first_library'</span><span class="p">,</span>
<span class="n">version</span> <span class="o">=</span> <span class="s">'0.0.1'</span><span class="p">,</span>
<span class="n">author</span> <span class="o">=</span> <span class="s">'<account_name>'</span><span class="p">,</span>
<span class="n">author_email</span> <span class="o">=</span> <span class="s">'<account_name>@<domain>.<tld>'</span><span class="p">,</span>
<span class="n">description</span> <span class="o">=</span> <span class="s">'An example Python library'</span><span class="p">,</span>
<span class="n">license</span> <span class="o">=</span> <span class="s">'AGPL-3.0'</span>
<span class="n">long_description</span> <span class="o">=</span> <span class="n">long_description</span><span class="p">,</span>
<span class="n">long_description_content_type</span> <span class="o">=</span> <span class="s">'text/markdown'</span><span class="p">,</span>
<span class="n">url</span> <span class="o">=</span> <span class="s">'https://github.com/development-tutorials/python-first-library'</span><span class="p">,</span>
<span class="n">packages</span> <span class="o">=</span> <span class="n">find_packages</span><span class="p">(),</span>
<span class="n">entry_points</span> <span class="o">=</span> <span class="p">{</span>
<span class="s">'console_scripts'</span><span class="p">:</span> <span class="p">[</span>
<span class="s">'watch_path = python_first_library.cli:main'</span>
<span class="p">],</span>
<span class="p">},</span>
<span class="n">install_requires</span> <span class="o">=</span> <span class="p">[],</span>
<span class="n">classifiers</span> <span class="o">=</span> <span class="p">[</span>
<span class="s">'Development Status :: 1 - Alpha'</span><span class="p">,</span>
<span class="s">'Intended Audience :: Developers'</span><span class="p">,</span>
<span class="s">'Topic :: Software Development'</span><span class="p">,</span>
<span class="s">'Programming Language :: Python :: 3'</span><span class="p">,</span>
<span class="s">'License :: OSI Approved :: GNU Affero General Public License v3'</span><span class="p">,</span>
<span class="s">'Operating System :: POSIX :: Linux'</span><span class="p">,</span>
<span class="p">],</span>
<span class="p">)</span>
</code></pre></div></div>
<h3 id="-notes-about-setuppy"><a href="#-notes-about-setuppy" title="Quick descriptions list of parameters for `setup` method">#</a> Notes about <code class="language-plaintext highlighter-rouge">setup.py</code></h3>
<ul>
<li><code class="language-plaintext highlighter-rouge">name</code>, the name of your project this value is pre-pended within project archive files under the <code class="language-plaintext highlighter-rouge">dist/</code> directory</li>
<li><code class="language-plaintext highlighter-rouge">version</code>, tag and/or release version this value is inserted within project archive files under the <code class="language-plaintext highlighter-rouge">dist/</code> directory</li>
<li><code class="language-plaintext highlighter-rouge">author</code>, your account name</li>
<li><code class="language-plaintext highlighter-rouge">author_email</code>, a valid email address used to contact you</li>
<li><code class="language-plaintext highlighter-rouge">description</code>, short (less than 80 characters) description of your project</li>
<li><code class="language-plaintext highlighter-rouge">license</code>, the code/abbreviation for chosen license, the <a href="https://opensource.org/licenses/category">OpenSource.org chart</a> lists most of the popular licenses with their abbreviations</li>
<li><code class="language-plaintext highlighter-rouge">url</code> HTTP URL to source code for your project</li>
<li><code class="language-plaintext highlighter-rouge">entry_points["console_scripts"]</code> list name of executable(s), import path, and function to call</li>
<li><code class="language-plaintext highlighter-rouge">classifiers</code>, check the <a href="https://pypi.org/classifiers/">Python Packaging – Classifiers</a> for complete listing of all valid options</li>
</ul>S0AndS0Example `setup.py` script and related configuration filesMake ReadMe2020-06-03T23:11:56+00:002020-06-03T23:11:56+00:00https://development-tutorials.github.io/python-first-library/make-readme<p>Change current working directory to your project repository…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/git/hub/development-tutorials/python-first-library
</code></pre></div></div>
<h2 id="-option-one"><a href="#-option-one" title="Make a simple ReadMe file">#</a> Option One</h2>
<p>Make a simple ReadMe file…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/git/hub/development-tutorials/python-first-library
<span class="nb">mkdir</span> .github
<span class="nb">touch</span> .github/README.md
</code></pre></div></div>
<p>Following is an example template that can be edited manually…</p>
<div class="language-markdown highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gh"># Python First Library</span>
<span class="p">[</span><span class="ss">heading__top_of_document</span><span class="p">]:</span> <span class="sx">#python-first-library</span> <span class="nn">"Top of document"</span><span class="sb">
</span><span class="p">------
-</span> <span class="p">[</span><span class="nv">Python First Library</span><span class="p">][</span><span class="ss">heading__top_of_document</span><span class="p">]</span>
<span class="p">
-</span> <span class="p">[</span><span class="nv">Installation</span><span class="p">][</span><span class="ss">heading__installation</span><span class="p">]</span>
<span class="p">
-</span> <span class="p">[</span><span class="nv">Usage</span><span class="p">][</span><span class="ss">heading__usage</span><span class="p">]</span>
<span class="p">
-</span> <span class="p">[</span><span class="nv">Notes</span><span class="p">][</span><span class="ss">heading__notes</span><span class="p">]</span>
<span class="p">
-</span> <span class="p">[</span><span class="nv">Attribution</span><span class="p">][</span><span class="ss">heading__attribution</span><span class="p">]</span>
<span class="p">
-</span> <span class="p">[</span><span class="nv">License</span><span class="p">][</span><span class="ss">heading__license</span><span class="p">]</span><span class="sb">
</span><span class="p">------
</span>
<span class="gu">## Installation</span>
<span class="p">[</span><span class="ss">heading__installation</span><span class="p">]:</span> <span class="sx">#installation</span> <span class="nn">"How to install this project"</span><span class="sb">
</span>Install to user account via...<span class="sb">
pip3 install --user python_first_library
</span><span class="gu">## Usage</span>
<span class="p">[</span><span class="ss">heading__usage</span><span class="p">]:</span> <span class="sx">#usage</span> <span class="nn">"How to utilize this project"</span><span class="sb">
</span>Import within Python shell or script via...<span class="sb">
from python_first_library import First_Library
</span><span class="gu">## Notes</span>
<span class="p">[</span><span class="ss">heading__notes</span><span class="p">]:</span> <span class="sx">#notes</span> <span class="nn">"Things to keep in mind when using the project"</span><span class="sb">
Anything else note worthy?
</span><span class="gu">## Attribution</span>
<span class="p">[</span><span class="ss">heading__attribution</span><span class="p">]:</span> <span class="sx">#attribution</span> <span class="nn">"Resources that where helpful in building this project"</span><span class="sb">
</span><span class="p">-</span> <span class="p">[</span><span class="nv">GitHub -- `development-tutorials/python-first-library`</span><span class="p">](</span><span class="sx">https://github.com/development-tutorials/python-first-library</span><span class="p">)</span><span class="sb">
</span><span class="gu">## License</span>
<span class="p">[</span><span class="ss">heading__license</span><span class="p">]:</span> <span class="sx">#license</span> <span class="nn">"Legal side of Open Source software"</span><span class="sb">
</span>This project is released under the <span class="p">[</span><span class="nv">AGPL version 3</span><span class="p">](</span><span class="sx">/LICENSE</span><span class="p">)</span> license<span class="sb">
</span></code></pre></div></div>
<hr />
<h2 id="-option-two"><a href="#-option-two" title="Initialize ReadMe file via template">#</a> Option Two</h2>
<p>The following examples make use of <a href="https://github.com/github-utilities/make-readme">GitHub – <code class="language-plaintext highlighter-rouge">github-utilities/make-readme</code></a> project which builds ReadMe files from MustacheJS templates.</p>
<p>Initialize ReadMe file via template…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-vp</span> ~/git/hub/github-utilities
<span class="nb">cd</span> ~/git/hub/github-utilities
git clone git@github.com:github-utilities/make-readme.git
<span class="nb">cd</span> ~/git/hub/github-utilities/make-readme
</code></pre></div></div>
<p>Install NPM dependencies…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install</span>
</code></pre></div></div>
<p><strong>Edit <code class="language-plaintext highlighter-rouge">github-utilities/make-readme</code> – <code class="language-plaintext highlighter-rouge">dataView.json</code></strong></p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"gfm"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nl">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"account@host.tld"</span><span class="p">,</span><span class="w">
</span><span class="nl">"author"</span><span class="p">:</span><span class="w"> </span><span class="s2">"S0AndS0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"organization"</span><span class="p">:</span><span class="w"> </span><span class="s2">"development-tutorials"</span><span class="p">,</span><span class="w">
</span><span class="nl">"repository"</span><span class="p">:</span><span class="w"> </span><span class="s2">"python-first-library"</span><span class="p">,</span><span class="w">
</span><span class="nl">"output_directory"</span><span class="p">:</span><span class="w"> </span><span class="s2">"~/git/hub/development-tutorials/python-first-library"</span><span class="p">,</span><span class="w">
</span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Example library for use within other Python projects"</span><span class="p">,</span><span class="w">
</span><span class="nl">"include_notes"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nl">"include_shields_io"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nl">"license"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AGPL-3.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"gh_pages"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nl">"verbose"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nl">"clobber"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nl">"quick_start"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"is_awk_script"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nl">"is_github_action"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nl">"is_node_package"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nl">"is_python_package"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nl">"is_submodule"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"requirements"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"utilizes_awk"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nl">"utilizes_npm"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nl">"utilizes_github_actions"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nl">"utilizes_pip"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nl">"utilizes_submodules"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"files"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"in_path"</span><span class="p">:</span><span class="w"> </span><span class="s2">".mustache/.github/README.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="nl">"out_path"</span><span class="p">:</span><span class="w"> </span><span class="s2">".github/README.md"</span><span class="p">,</span><span class="w">
</span><span class="nl">"partials"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="s2">".mustache/partials/readme/quick_start/clone.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/quick_start/is_awk_script.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/quick_start/is_node_package.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/quick_start/is_github_action.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/quick_start/is_python_package.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/quick_start/is_submodule.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/requirements/utilizes_awk.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/requirements/utilizes_github_actions.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/requirements/utilizes_npm.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/requirements/utilizes_pip.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/requirements/utilizes_submodules.md.mst"</span><span class="p">,</span><span class="w">
</span><span class="s2">".mustache/partials/readme/notes.md.mst"</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Make output directory for ReadMe file and generate new ReadMe file from template…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> ~/git/hub/development-tutorials/python-first-library/.github
npm run make-readme
</code></pre></div></div>S0AndS0A project's ReadMe file is often the first documents users will reviewInitialize Project2020-06-02T23:11:56+00:002020-06-02T23:11:56+00:00https://development-tutorials.github.io/python-first-library/initialize-project<p>Make directory path(s) to keep things organized…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-vp</span> ~/git/hub/development-tutorials
</code></pre></div></div>
<p>Initialize new Git repository…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git init ~/git/hub/development-tutorials/python-first-library
</code></pre></div></div>
<blockquote>
<p>Note, throughout this tutorial the <code class="language-plaintext highlighter-rouge">python-first-library</code> repository directory should be replaced with the directory name for your library.</p>
</blockquote>
<p>Change current working directory to your new project repository…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> ~/git/hub/development-tutorials/python-first-library
</code></pre></div></div>
<p>… add <code class="language-plaintext highlighter-rouge">hub</code> as a remote…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git remote add hub git@github.com:development-tutorials/python-first-library.git
</code></pre></div></div>
<blockquote>
<p>Note, URL syntax is <em><code class="language-plaintext highlighter-rouge">git@github.com:<account>/<repository>.git</code></em></p>
</blockquote>
<p>… touch files for <code class="language-plaintext highlighter-rouge">setuptools</code> into existence…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">touch</span> .gitignore
<span class="nb">touch </span>MANIFEST.in
<span class="nb">touch </span>requirements.txt
<span class="nb">touch </span>setup.cfg
<span class="nb">touch </span>setup.py
</code></pre></div></div>
<p>… finally make directory structure for project source code, and touch files for library and Command Line Interface example into existence…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-vp</span> python_first_library/cli
<span class="nb">touch </span>python_first_library/__init__.py
<span class="nb">touch </span>python_first_library/cli/__init__.py
</code></pre></div></div>
<h2 id="-notes-about-files"><a href="#-notes-about-files" title="Quick descriptions list of what files are used for">#</a> Notes about files</h2>
<ul>
<li>
<p><code class="language-plaintext highlighter-rouge">.gitignore</code> defines directory and file patterns that Git should ignore from version tracking</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">MANIFEST.in</code> defines files not automatically detected by <code class="language-plaintext highlighter-rouge">setuptools</code> that need to be included within package archive</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">requirements.txt</code> should define developer dependencies, note install dependencies will need to be defined within <code class="language-plaintext highlighter-rouge">setup.py</code> file</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">setup.cfg</code> defines metadata about this project and may be used by code linters (code style enforcement tools)</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">setup.py</code> is read/executed during installation process when <em><code class="language-plaintext highlighter-rouge">pip install <name></code></em> is issued by users of this project</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">python_first_library/__init__.py</code> will contain the main class(s) for this project that other projects should <code class="language-plaintext highlighter-rouge">import</code></p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">python_first_library/cli/__init__.py</code> will contain fully functional example usage of project code as a command line application</p>
</li>
</ul>S0AndS0Instructions for setting up file and directory structure for new librarySetup Environment2020-06-01T23:11:56+00:002020-06-01T23:11:56+00:00https://development-tutorials.github.io/python-first-library/setup-environment<p>Install <code class="language-plaintext highlighter-rouge">pip</code> by following <a href="https://pip.pypa.io/en/stable/installing/">PyPa documentation</a> if <code class="language-plaintext highlighter-rouge">pip3 --version</code> returns an error.</p>
<p>Install Python environment dependencies to user account…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip3 <span class="nb">install</span> <span class="nt">--user</span> setuptools twine wheel
</code></pre></div></div>
<p>Documentation links for above dependencies;</p>
<ul>
<li>
<p><a href="https://setuptools.readthedocs.io/en/latest/">Read The Docs – <code class="language-plaintext highlighter-rouge">setuptools</code></a> <em>“Setuptools is a fully-featured, actively-maintained, and stable library designed to facilitate packaging Python projects…“</em></p>
</li>
<li>
<p><a href="https://twine.readthedocs.io">Read The Docs – <code class="language-plaintext highlighter-rouge">twine</code></a> <em>“Twine is a utility for publishing Python packages on PyPI.”</em></p>
</li>
<li>
<p><a href="https://wheel.readthedocs.io">Read The Docs – <code class="language-plaintext highlighter-rouge">wheel</code></a> <em>“This library is the reference implementation of the Python wheel packaging standard, as defined in PEP 427.”</em></p>
</li>
</ul>S0AndS0List of dependencies installed via Pip and links to relevant documentationRegister PyPi Accounts2020-05-31T23:11:56+00:002020-05-31T23:11:56+00:00https://development-tutorials.github.io/python-first-library/register-pypi-accounts<h2 id="-testing-repository"><a href="#-testing-repository" title="Python testing repository links">#</a> Testing Repository</h2>
<ul>
<li>
<p><a href="https://test.pypi.org/account/register/"><code class="language-plaintext highlighter-rouge">test.pypi.org</code> – Register</a></p>
</li>
<li>
<p><a href="https://test.pypi.org/manage/account/#api-tokens"><code class="language-plaintext highlighter-rouge">test.pypi.org</code> – API Token</a></p>
</li>
<li>
<p><a href="https://pypi.org/manage/account/totp-provision"><code class="language-plaintext highlighter-rouge">test.pypi.org</code> – 2FA</a></p>
</li>
</ul>
<p>Utilizing the testing repository is a good idea, because deleting and/or editing mistakes within the official publishing repository is not generally allowed.</p>
<p>Testing Repository installation syntax adds <code class="language-plaintext highlighter-rouge">--index-url https://test.pypi.org/simple/</code> and <em><code class="language-plaintext highlighter-rouge">--no-deps <Package_Name>-<Account_Name></code></em> options, eg…</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>python3 <span class="nt">-m</span> pip <span class="nb">install</span><span class="se">\</span>
<span class="nt">--index-url</span> https://test.pypi.org/simple/<span class="se">\</span>
<span class="nt">--no-deps</span> python-first-library-S0AndS0
</code></pre></div></div>
<blockquote>
<p>Note, the <code class="language-plaintext highlighter-rouge">--no-deps</code> flag tells Pip to <strong>not</strong> install dependencies from the testing URL, this is important to avoid errors during installation, and testing.</p>
</blockquote>
<hr />
<h2 id="-publish-repository"><a href="#-publish-repository" title="Python publishing repository links">#</a> Publish Repository</h2>
<ul>
<li>
<p><a href="https://pypi.org/account/register/"><code class="language-plaintext highlighter-rouge">pypi.org</code> – Register</a></p>
</li>
<li>
<p><a href="https://pypi.org/manage/account/#api-tokens"><code class="language-plaintext highlighter-rouge">pypi.org</code> – API Token</a></p>
</li>
<li>
<p><a href="https://pypi.org/manage/account/totp-provision"><code class="language-plaintext highlighter-rouge">pypi.org</code> – 2FA</a></p>
</li>
</ul>
<p>Please do <strong>not</strong> skip setting up 2 Factor Authentication, because you’ll be publishing code for others to make use of.</p>
<hr />
<h2 id="-example-pypirc"><a href="#-example-~pypirc" title="Example pypirc configuraiton file">#</a> Example <code class="language-plaintext highlighter-rouge">~/.pypirc</code></h2>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[pypi]
username = __token__
## Test
password = pypi-API_TEST_KEY...
## Publish
# password = pypi-API_PUBLISH_KEY...
</code></pre></div></div>S0AndS0Links to testing and publishing repositories, and example `.pypirc` config. file