A small example package for creating an executable CLI.
Project description
Sample Python CLI
Sample repository for creating a CLI in Python.
Motivation
This repository is for educational purposes. I want to show how to create an executable CLI tool written in Python. With this I wanna cover:
- Creating a Python Package using traditional
setup.py. - Creating a Python Package using
poetry. - Publishing to PyPI.
- Creating a simple CLI tool that installs on to your system and is executable.
- Creating plugins for the CLI tool that are pipinstalable.
Package
We are going to create a package called pier-mob. Why? Just because! I don't wanna use
traditional example, foo, or bar because I think those names lack semantics
and the use of such names becomes difficult for less experienced devs to understand. If
you are wondering, I let roke choose the name for the
example tool that we are going to build.
Add files and directories:
pier_mob
|-- LICENSE # License file
|-- README.md # **This** file
|-- pier_mob # Main directory: all source code inside
| |-- __init__.py # needed for converting directory into a package
| |-- __main__.py # Defines what is executed when package is called
| `-- cli.py # Sample source code module
|-- setup.py # Python Packaging config file
`-- tests # Test cases directory
|-- __init__.py # needed for converting directory into a package
`-- test_version.py # Test source code sample
With this minimal structure we can run our program as module and as a simple script.
Using pip strategy to be
able of running in both ways. Look deeper on pier_mob/__main__.py.
As simple script:
$ python3 pier_mob
Pier Mob v0.0.1
And running as module:
$ python3 -m pier_mob
Pier Mob v0.0.1
Also with this minimal structure we have tests.
Tests can be run as:
$ python3 setup.py test
Let's publish our package
You will need setuptools, wheel, and twine for creating and uploading to PyPI.
Install this packages with pip in new virtualenv or in your user level packages.
Create a new virualenv, activate it and install needed packages:
$ python3 -m venv pier_build
$ source pier_build/bin/activate
(pier_build) $ pip install setuptools wheel twine
Now we need to build source distribution files. Run the following command:
(pier_build) $ python3 setup.py sdist bdist_wheel
This command will output a lot of text and once completed will generate two files in the
dist directory: a .tar.gz which is a Source Distribution, and a .whl which is a
Built Distribution.
Now we are ready to upload our package. Use your PyPI account and create a new API Token.
When twine prompts your username write __token__ then use your API Token as password.
(pier_build) $ python3 -m twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: __token__
Enter your password:
✨ 🍰 ✨ Congrats! Your package is now published on PyPI: https://pypi.org/project/pier-mob-lecovi/
Create a new virtualenv and install your package from PyPI
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install pier-mob-lecovi
...
$ python
Inside REPL run:
>>> import pier_mob
>>> pier_mob.version()
'0.0.1'
✨ 🍰 ✨ It works!!
Test PyPI
It's a complete separate instance. If you have a user on PyPI you need to create another one for Test PyPI (and vivecersa). The same goes for Tokens.
- Upload URL: https://test.pypi.org/legacy/
- Pip download URL: https://test.pypi.org/simple/ (remember to add
--index-url)
Executable
Let's change pier_mob/__main__.py for creating a console
script instalable. Wrap the print function inside main() and modify setup.py
entry_points={
'console_scripts': [
'pier=pier_mob.__main__:main',
],
},
This will create a pier executable that will call the main() function inside
__main__.py.
Create a new virtualenv and test installation:
$ python3 -m venv executable
$ source executable/bin/activate
(executable) $ python3 setup.py install
(executable) $ pier
Pier Mob v0.0.2
Adding commands
Let's improve our interface using Typer.
Add info() and version() functions to cli.py.
DON'T FORGET TO UPDATE __version__.
You also will need to update __main__ and __init__ and import the new app instead
of version().
We need to change our unittest for the better pytest suite.
(install) $ pip install typer pytest
Now test must be run with:
(install) $ pytest
Now you can update your package on PyPI.
(build) $ python3 setup.py build
(build) $ python3 -m twine upload --repository pypi dist/*
Resources
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pier-mob-lecovi-0.0.3.2.tar.gz.
File metadata
- Download URL: pier-mob-lecovi-0.0.3.2.tar.gz
- Upload date:
- Size: 4.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.51.0 CPython/3.7.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f03601711551fd58c8270e25ddbe5dfc0850baa9ecfb25eaefcb00581e8f857
|
|
| MD5 |
f97d76759c6f0840c4323dfd444172b8
|
|
| BLAKE2b-256 |
e3568df29b575ef61ffd778e735b1691eb814c76a4319e24776da25919693c68
|
File details
Details for the file pier_mob_lecovi-0.0.3.2-py3-none-any.whl.
File metadata
- Download URL: pier_mob_lecovi-0.0.3.2-py3-none-any.whl
- Upload date:
- Size: 17.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.51.0 CPython/3.7.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17a69a31652d9af326ac394d37080b3a0f3a74e0a25d4eb842b8d4730c0c1112
|
|
| MD5 |
b6340d4cfc11d9117a7fce754651a41a
|
|
| BLAKE2b-256 |
20a4827b02cbc936d24544d9299165921fae7f332d980c6ce7d9625105785e96
|