In the First Part we:
- Started a new project.
- Created a Virtual Environment.
- Managed dependencies.
In the Second Part:
- Added our virtual Environment to VSCode.
- Integrated our dev dependencies with the editor:
- Flake8
- Black
- Pytest
And finally, in this third and last part we'll:
- Write a sample library.
- Build our project with Poetry.
- Publish it on PyPI.
Poetry Commands
Here is a table with the commands used in this series as well as their descriptions. For a full list read the Poetry Documentation.
Command | Description |
---|---|
poetry new [package-name] |
Start a new Python Project. |
poetry init |
Create a pyproject.toml file interactively. |
poetry install |
Install the packages inside the pyproject.toml file. |
poetry add [package-name] |
Add a package to a Virtual Environment. |
poetry add -D [package-name] |
Add a dev package to a Virtual Environment. |
poetry remove [package-name] |
Remove a package from a Virtual Environment. |
poetry remove -D [package-name] |
Remove a dev package from a Virtual Environment. |
poetry update |
Get the latest versions of the dependencies |
poetry shell |
Spawns a shell within the virtual environment. |
poetry build |
builds the source and wheels archives. |
poetry publish |
Publish the package to PyPi. |
poetry publish --build |
Build and publish a package. |
poetry self:update |
Update poetry to the latest stable version. |
The Project
You can download the source code from GitHub if you want, but as mentioned earlier, this will be a very simple decorator that the only thing it will do is print to the console how long it takes for a function to run:
from how_long import timer
@timer
def test_function():
[i for i in range(10000)]
test_function()
# Execution Time: 955 ms.
In the end, the project directory will look, more or less, like this:
how-long
├── how_long
│ ├── how_long.py
│ └── __init__.py
├── how_long.egg-info
│ ├── dependency_links.txt
│ ├── PKG-INFO
│ ├── requires.txt
│ ├── SOURCES.txt
│ └── top_level.txt
├── LICENSE
├── poetry.lock
├── pyproject.toml
├── README.rst
└── tests
├── __init__.py
└── test_how_long.py
Before we start, check for package updates with the poetry update
command:
Ok, now add a short description of the project in the README.rst
:
how_long
========
Simple Decorator to measure a function execution time.
Example
_______
.. code-block:: python
from how_long import timer
@timer
def some_function():
return [x for x in range(10_000_000)]
Navigate to how_long/how_long.py
:
# how_long.py
from functools import wraps
import pendulum
def timer(function):
"""
Simple Decorator to measure a function execution time.
"""
@wraps(function)
def function_wrapper():
start = pendulum.now()
function()
ellapsed_time = pendulum.now() - start
print(f"Execution Time: {ellapsed_time.microseconds} ms.")
return function_wrapper
In how_long/__init__.py
:
from .how_long import timer
__version__ = "0.1.1"
And finally, the tests/test_how_long.py
file:
from how_long import __version__
from how_long import timer
def test_version():
assert __version__ == "0.1.1"
def test_wrap():
@timer
def wrapped_function():
return
assert wrapped_function.__name__ == "wrapped_function"
You can now use poetry install
on your terminal to install and prove your package locally. Activate your virtual environment if you haven't and in the Python interactive shell:
>>> from how_long import timer
>>>
>>> @timer
... def test_function():
... [i for i in range(10000)]
...
>>> test_function()
Execution Time: 705 ms.
Run the tests and if everything is fine, move on.
Building and Publishing
Finally, the time to make this project available to the world has come! First, make sure you have an account on Pypi, and if not, register one. Remember that the package name must be unique, if unsure go and use the search to check it out.
Build
The poetry build
command builds the source and wheels archives that will letter be uploaded as the source of the project:
The how_long.egg-info directory will be created.
Publish
This command publishes the package to Pypi and automatically register it before uploading if this is the first time it is submitted:
You can also build and publish your project with
$ poetry publish --build
.
Enter your credentials and if everything is ok, browse your project and you'll see something like this:
We can now let others know that they can pip install how-long
from any machine, anywhere!
Conclusion
I remember the first time I tried to publish a package, and it was a nightmare. I was just starting in Python and I have to spend a "few hours" trying to understand what the setup.py
file was and how to use it. In the end, I ended up with several different files: a Makefile
, a MANIFEST.in
, a requirements.txt
and a test_requirements.txt
. That's why the words of Sébastien Eustace, the creator of Poetry, made a lot of sense to me:
Packaging and dependency management in Python are rather convoluted and hard to understand for newcomers. Even for seasoned developers it might be cumbersome at times to create all files needed in a Python project:
setup.py
,requirements.txt
,setup.cfg
,MANIFEST.in
and the newly addedPipfile
.So I wanted a tool that would limit everything to a single configuration file to do: dependency management, packaging and publishing.
It takes inspiration in tools that exist in other languages, like
composer
(PHP) orcargo
(Rust).And, finally, there is no reliable tool to properly resolve dependencies in Python, so I started
poetry
to bring an exhaustive dependency resolver to the Python community.
Poetry is by no means perfect but, unlike other tools, it really does what promises.
Top comments (0)