All You Need to Know to Get Started With Python Poetry
Time to read: 8 minutes
Over the years, Python packaging has undergone many changes and improvements. Today, we have different tools that can be used to solve problems, such as dependency management, packaging, and publishing. In this post, you will see how to implement a Python package using Poetry , a tool that covers all three steps when developing a Python package. You will walk through the process of creating a new project, converting it into a package, installing dependencies, and publishing it to PyPI . By the end of this post, you will have a good understanding of how to use the Poetry tools to simplify the Python packaging process.
Prerequisites
For this you’ll need:
- Python 3.8+ (all OS are welcome)
- Poetry 1.4.2
- GitHub account (for the GitHub Actions steps)
Yes, that is it. If you’re using pip, you only need to run pip install poetry==1.4.2
. Other options for installation are available here .
Create a new project with Poetry
In the command line, create a directory named " random-poems", and navigate inside it. Then, run the command poetry init
to initialize a new Poetry project. This command will guide you through the process of creating your project's configuration file (pyproject.toml).
During the initialization process, Poetry will ask you questions related to your project, such as the name of your package, its version, and its author. You can answer or skip these questions by pressing Enter to use the default values.
After you have provided the necessary information, Poetry will prompt you to add dependencies to your project. First, it will ask you about production dependencies, which are packages that your project requires to function correctly. You can add these dependencies by specifying their names and versions or skip this step by typing No. Poetry will then ask you about test dependencies, which are packages that your project requires to run tests.
Once you have finished adding dependencies, Poetry will show you the entire configuration file before generating it. This allows you to review and confirm that everything is correct. If you are satisfied with the configuration file, type Yes to proceed, and Poetry will generate it for you.
Here's an example of what the configuration file might look like:
This is an excellent description of your new Python project! However, you'll need to activate your virtual environment to maintain dependency isolation. Simply run poetry shell.
Create a Python package
In line 8 of your code, you will see that the package random_poems
is included in Poetry. This means that when you install this package using Poetry, the expected Python module will also be automatically installed.
Create a new Python module called "random_poems". Create a folder called random_poems and add a file called __init__.py inside it.
Once you have created this module, you can run the poetry install
command to install the package. This will ensure that both the package and its associated Python module are installed correctly and ready to use in your project. You should see something like this:
After installation, a new file called poetry.lock is created that contains a list of all installed packages and their respective versions.
Add some code in the package
Now you have a package! Yay! But you still need to add some code to it.
In the random_poemsmodule, create a package called poems.py. Add the method declaim
there:
It will just print a poem whenever you pass one. Now you only need to pass a poem… Wait, I know a nice place to get random poems from public-domain sources! The website Poetrydb can provide the poems to you via API. How cool is that? You only need to make a request for it using the requests library. To add it to your project, you just need to run poetry add requests
.
Below, you can see the method that your app will execute to call a random poem:
The get_random_poem
method will make a request to https://poetrydb.org/random and get its first result. The payload returns the poem’s text in lines, so when returning a dictionary, these lines are put together, separated by a break line \n
.
You can play around with your Python REPL to see whether both methods work. Hit python
in your package’s terminal and import both methods from poems.py file:
You should see a lovely poem in your terminal. Once you are done, you can leave the terminal hitting Control + D. Coming back to the code above, can you add this to a CLI? That’s what you will do in the next step.
Add a CLI to your package
This CLI (Command Line Interface) receives an argument and then gets a poem and declaims it. Create a cli.py inside random_poemswith the following content:
Using Python’s CLI argparse you will receive the argument declaim
when the user wants to see a poem on the screen. If the argument exists, you will call the methods developed before to get a random poem and declaim it.
The if __name__ == "__main__":
construct in Python is a common idiom used in scripts and modules to determine whether the Python script is being run as the main program or if it is being imported as a module into another script.
You can run it using python random_poems/cli.py declaim
. But the idea is to get Poetry to give you an excellent interface. Go to pyproject.toml and add the following section to the end of the file:
In this section, you are giving a name to your CLI executable and showing its path: the Python modules and the method that will be called. After that, install your package poetry install
and run:
Simple and sweet!
Add new dependencies and tests
To explore the structure of a project with Poetry more, you will add a testsdirectory in the root of your project repository. It should look like this:
Before you start writing tests, you should add pytest
as a dependency. Remember that it is a good practice to separate development dependencies from production dependencies. Poetry helps you with that by offering the flag --group
as an option. Install pytest
using the command poetry add --group dev pytest
to see it in action. This command will add pytest
as a dependency in the group dev
. Later on, if you want to configure a CI to run tests or deploy the application, installing it altogether or specific to the group is possible.
Pytest is set. It's time to write some tests! In the tests directory, create the file test_poems.py. There, you will add the following test as an example:
Pytest will recognize all classes that start with "Test" as test class and methods/functions that start with test_
test methods and execute them. In the test class TestDeclaim
, there is only one test method test_declaim
, that will check if the poem was declaimed correctly - that means if it was shown correctly in the stdout. Pytest offers a fixture called capsys
to capture the output. You only need to receive it as an argument in the test declaration. After that, you create all the necessary things to declaim a poem (having a title, a poem, and an author). You should also create a variable with the expected output to compare with the output brought by the method declaim
. After calling declaim
, you use capsys
to read the output. Then, it is time to compare the captured and expected output.
Run pytest
to execute all tests. Another alternative to run a command (in this case, pytest) is poetry run pytest
. The tests should pass! Feel free to play around with testing other methods.
Publish your Poetry package
At this point, you have your CLI up and running. This is exciting! Poetry also does the heavy lifting for you to publish it. You can configure your credentials directly from the CLI and run poetry publish
.
Run poetry build
and see the magic happening. ✨This is the expected output:
In order to publish a project, you will need to have an account in PyPI . You can register there; I’ll wait. Don’t forget to enable the two-factor authentication for more security as well.
After registering, go to Publishing and fill in the name of your package (if you feel like publishing a package; if not, you can skip this step) and access all projects. Once you’re done, PyPI will give you a token. Be sure to copy and store it in a safe place.
Return to your project’s terminal and run the command below with the token you just received. You only need to do this once for each new project added.
After that, you can run poetry publish
and the magic will happen. In the background, poetry will upload the wheel to PyPI and make your package available. That’s it!
A few notes about this process: when running the command poetry publish
, Poetry assumes that you want to publish to PyPI by default. If you want to publish to another repository, you must inform which repository using the flag --repository
. You can also pass a username and password as arguments.
You can see the package of this project available here .
Understand the Poetry Package and GitHub Actions
You just published to PyPI, so let’s move to CI/CD tools and use GitHub Actions for it. In this section, two essential recipes to have your library up and running on GitHub Actions: testing and releasing.
Test the application
Create a new file .github/workflows/tests.yml and place the content below there. This job will run on every push. It installs Poetry 1.4.2 and Python 3.10 with Poetry’s cache for more speed. Then, it installs the dependencies and runs the tests. Exactly the same commands you used during this tutorial!
Publish to GitHub Releases
You learned to publish a Python wheel from your local environment to PyPI. Another alternative is publishing your package to GitHub releases. This is quite useful, especially for cases where you have a private package and need it to be available only internally.
Before you jump into the yml file, you need to know how to bump a new version of your Poetry package. This is one of the parts I like the most :) You need to run the command poetry version
. Poetry follows the SemVer convention so that you will have major to prerelease options. See poetry version --help
for more details. Once you run this command, it will change the file pyproject.toml with the latest version. You still need to commit to this change, but that’s it.
Now that you know how to bump your package’s version, you can follow the release recipe. First, create the file .github/workflows/release.yml and place the following content there. The job below will be triggered on two occasions
- 1. when the workflow is triggered in the GitHub Actions Interface (there, you can choose the bump type in a small form)
- 2. when a new tag is created.
Once Python and Poetry are configured, you will bump the version and store it in the variableCURRENT_VERSION
because you will use it later in the commit message. You will also need to commit to the new version from the CI. Once done, the Actionncipollo/release-action
will generate a new release with the artifacts from dist/.
What's next for the Poetry Python package?
You are not a Poetry beginner anymore! But I thought you might have a few questions, so here is a short Q&A for you:
- Can I use it in an existing project? Yes, you can!
poetry init
will do the job. Then you can gradually migrate the steps you might have in your workflow. - Can I generate a requirements.txt out of it? Yes! Just run
poetry export > requirements.txt
, and there you go! Seepoetry export --help
for more options. - How can I use Poetry with different Python versions? Yes! You can point to the path where the version is installed like
poetry env use python3.7
and also with popular tools likepyenv
. See more info about it here.
I use Poetry in all my projects because the API works beautifully. It is as simple and practical as Python is meant to be. I hope you got excited about it, too, and can try it at least! If you want to keep playing around with this project, I have a few suggestions. You can install the test library responses and test the method get_random_poem
. Also, try to publish your own library to PyPI (or to Test PyPI !). If you want to go one step further, replace the step of releasing GitHub Releases to publishing to PyPI. What do you think?
Explore more of it in Poetry’s docs . The code for this tutorial is working and available for you in this repository . Have fun!
Ana Paula Gomes is a senior software engineer who has worked with Python for a decade, transitioning to the academic world and different companies. She’s currently doing a Ph.D. in Artificial Intelligence for Public Health. You can follow her work here https://github.com/anapaulagomes and here www.anapaulagomes.me .
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.