Manage Python dependencies with Poetry and Github Actions
Learn how to clean up your Python code
General
As I'm digging deeper into the python stack I came across some awesome tools like PyRight for static type checking, Ruff for Linting and Formating, Poetry for Dependency Management and Github Actions as CI/CD Pipeline to validate my Github Repository. So in this blog article I build a very simply Python Game with the Ursina Engine and use Poetry and Github Actions to clean up my Code.
Ursina Engine
First I will create a virtual environment and install Ursina Engine. Then I create my game and run it. It's just a FirstPersonController that walks on a plane.
virtualenv -p python3 .venv #I prefer virtualenv over python3 -m venv .
source .venv/bin/activate
pip install ursina
code main.py
python main.py
Notice how I purposely put a wrong indentation behind ground that pyright will recognise.
main.py
from ursina import *
from ursina.prefabs.first_person_controller import FirstPersonController
app = Ursina()
player = FirstPersonController()
ground = Entity(model="plane", collider="box", scale=64, texture="grass", texture_scale=(4, 4))
app.run()
Poetry
Now we install Poetry, Ruff and Pyright to manage our Python project. Poetry is very useful cause you can use the config file not only to validate that the project uses the right packet version but also to create linting rules and so on.
We will create a Poetry config file called pyproject.toml and add our packages to the file. You can also ignore some warnings. We also create a file called poetry.toml to tell Poetry that we are using a venv. Here are the commands that I used:
pip install ruff
pip install pyright #pylint but opensource
pip install poetry
code pyproject.toml
code poetry.toml
python --version #to manually add the version to your pyproject.toml
poetry add ursina #automatically adds the current version to your pyproject.toml
poetry add pyright --group dev #developer tool dependancy
poetry run pyright #check syntax errors
poetry add ruff --group dev #formatter and linter
poetry run ruff format #formatter
poetry run ruff check --fix #linter
The name main comes from our main.py file.
pyproject.toml
[tool.poetry]
name = "main"
version = "0.1.0"
description = "My first game"
authors = [
"arvednet",
"someone",
]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10.12"
ursina = "^7.0.0"
[tool.poetry.group.dev.dependencies]
pyright = "^1.1.388"
ruff = "^0.7.3"
[tool.pyright]
venvPath = "."
venv = ".venv"
reportWildcardImportFromLibrary = false
ignore = ["assets/test.py"]
[tool.ruff]
line-length = 120
[tool.ruff.format]
indent-style = "tab"
line-ending = "lf"
[tool.ruff.lint]
ignore = ["E402", "F405", "F403"]
poetry.toml
[virtualenvs]
in-project = true
If everything worked poetry run ruff check --fix should show All checks passed! after you fixed the indentation error.
Github Actions
Github Actions is a CI/CD Pipeline to continously test your code. We will create a Ruff and Poetry pipeline.
We have to create a .github/workflows directory in our github repository and create two files called ruff.yml and poetry.yml.
Here we will declare which official github actions repositories we want to use to test our code.
.github/workflows/ruff.yml
name: Check formatting and linting
on: push
jobs:
check_formatting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v1
with:
args: 'format --check'
check_linting:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v1
.github/workflows/poetry.yml
name: main
on: push
jobs:
ci:
runs-on: ubuntu-20.04
env:
POETRY_VIRTUALENVS_IN_PROJECT: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: abatilo/actions-poetry@v2
- name: Install dependencies and build Cython extension
run: poetry install --no-root
- name: Rebuild the project
run: poetry build
- name: Cache venv created by poetry (configured to be in '.venv')
uses: actions/cache@v3
with:
path: ./.venv
key: venv-${{ runner.os }}-${{ hashFiles('poetry.lock') }}
- name: Run pyright
run: poetry run pyright
Last we create a nice README.md and push our repository to github. Put the third ' behind console in this README.md if you copy/paste it.
README.md
# My first game
A preview of the game:
[<img alt = "My first game" src = "https://i.imgur.com/rZpWJV9.png" width = 25% />](https://i.imgur.com/rZpWJV9.png)
This is my first game:
- Its main purpose is to show how we configure Poetry and the `pyproject.toml` file for better dependency management, and add a formatter and a linter as well as a CI setup to check all this.
- But of course the game is playable. You can walk around in a 3D world :).
## Installing dependencies
Using [Poetry](https://python-poetry.org/):
``console
poetry install
``
If you ever need to rebuild them, you can do:
``console
poetry build
``
## Running
Using Poetry:
``console
poetry run python main.py
``
Great if everything worked you will have a green mark now with successful tests!
Here is the Repository. You can clone it and use poetry install to install the dependencies of the game. Check out this video which basically sums up this blog article.