Managing FastAPI Projects with Poetry: A Step-by-Step Guide

fastapi

This guide will walk you through how to use Poetry to manage dependencies and structure your project in FastAPI. It includes detailed explanations of Poetry's core concepts and commands to help prevent issues that can arise during team collaboration and deployment.

1. What is Poetry?

Poetry is a dependency management and packaging tool for Python. It goes beyond simply installing libraries by allowing you to clearly declare the dependencies your project needs and ensuring that all developers on the project have the same library versions.

  • Clarity in Dependency Management: Explicitly manage your project's basic information and required libraries through the pyproject.toml file.
  • Reproducible Builds: By locking all dependency versions in the poetry.lock file, it fundamentally prevents "it works on my machine" problems.
  • Integrated Development Environment: It automatically creates and manages isolated virtual environments for each project and handles most project-related tasks—such as dependency installation, script execution, package building, and deployment—with a single poetry command.

With Poetry, you don't need to use venv directly. Poetry handles virtual environment management automatically by internally processing commands like python -m venv .venv, allowing you to focus solely on dependency management.

2. Poetry and Initial Project Setup

First, you need to have Python and Poetry installed on your system.

Installing Poetry:

The version of Poetry available in Ubuntu's apt repository is often not the latest official release. The official installer is recommended.

  • Latest Version Guaranteed: The official script always installs the latest stable version of Poetry.
  • Isolated Installation: The script installs Poetry in the user's home directory (~/.local/bin), isolating it from other system packages to prevent conflicts.

You should run the installer as a regular user, not root. Poetry is installed on a per-user basis, which is safer and allows you to manage environments without needing sudo privileges.

$ curl -sSL https://install.python-poetry.org | python3 -

After installation, you need to add Poetry's bin directory to your shell's PATH. For most shells on Linux and macOS, you can do this by adding the following line to your shell configuration file (e.g., ~/.bashrc, ~/.zshrc):

export PATH="$HOME/.local/bin:$PATH"

Remember to restart your shell or run source ~/.bashrc for the changes to take effect.

$ poetry --version
Poetry (version 1.8.2)

Creating a New FastAPI Project:

Use the poetry new command to create a new project. It's recommended to use the --src flag to set up the project with the standard src layout.

$ poetry new my-fastapi-project
Created package my_fastapi_project in my-fastapi-project

The resulting directory structure is as follows:

$ cd my-fastapi-project

~/my-fastapi-project$ tree
.
├── README.md
├── pyproject.toml
├── src
│   └── my_fastapi_project
│       └── __init__.py
└── tests
    └── __init__.py

4 directories, 4 files

3. Understanding Dependency Management: add, lock, and install

Poetry's dependency management revolves around two files, pyproject.toml and poetry.lock, and three core commands that handle them.

pyproject.toml vs. poetry.lock

  • pyproject.toml: This is the blueprint for your project. You, the developer, define the necessary libraries and their allowed version ranges, like fastapi = "^0.116.1".
  • poetry.lock: This is the precise specification for your project. Poetry automatically finds and records the specific versions that satisfy the ranges in pyproject.toml (e.g., version = "0.111.1"). You should never manually edit this file. It must be committed to Git and shared with your team.

Core Commands

1. poetry add [package-name] (Adding a dependency)

  • This is the most commonly used command.
  • When you add a new library, it performs the following three tasks automatically and at once:
    1. Adds the package as a dependency to pyproject.toml.
    2. Updates the poetry.lock file to lock the versions of the new and existing packages.
    3. Installs the package into the virtual environment.

2. poetry lock (Locking dependency versions)

  • Reads the pyproject.toml file to create or update the poetry.lock file.
  • It does not install any packages; it only updates the version information in the poetry.lock file.
  • Use this when you have manually edited the pyproject.toml file and want to synchronize it with poetry.lock.

3. poetry install (Installing dependencies)

  • Installs all packages with the exact versions specified in the poetry.lock file.
  • When you first clone a project from Git or pull updates to poetry.lock from a teammate, use this command to ensure everyone has an identical development environment.
  • If a poetry.lock file does not exist, it will first run the poetry lock command to create one and then proceed with the installation.

Practical Example

Installing FastAPI and Uvicorn:

Use the poetry add command to add FastAPI and the ASGI server Uvicorn as project dependencies.

$ poetry add fastapi uvicorn
Using version ^0.116.1 for fastapi
Using version ^0.35.0 for uvicorn

Updating dependencies
Resolving dependencies... (0.8s)

No dependencies to install or update

Writing lock file

Now, both pyproject.toml and poetry.lock are updated, and the two packages are installed in your virtual environment.

Adding Development Dependencies:

Libraries used for testing or code formatting should be managed as development dependencies using the --group dev (or -D) option.

$ poetry add pytest httpx --group dev
Using version ^8.4.1 for pytest
Using version ^0.28.1 for httpx

Updating dependencies
Resolving dependencies... (1.0s)

Package operations: 8 installs, 0 updates, 0 removals

  - Installing certifi (2025.7.14)
  - Installing httpcore (1.0.9)
  - Installing iniconfig (2.1.0)
  - Installing packaging (25.0)
  - Installing pluggy (1.6.0)
  - Installing pygments (2.19.2)
  - Installing httpx (0.28.1)
  - Installing pytest (8.4.1)

Writing lock file

pytest and httpx will be added to the [tool.poetry.group.dev.dependencies] section in pyproject.toml. These dependencies will not be installed in a production environment.

4. Writing the Application

Create a main.py file inside the my_fastapi_project directory and write a simple FastAPI application.

src/my_fastapi_project/main.py:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
    return {"item_id": item_id, "q": q}

5. Running the Development Server

The poetry run command executes a command within the virtual environment managed by Poetry. You don't need to manually activate the virtual environment with commands like source .venv/bin/activate.

$ poetry run uvicorn my_fastapi_project.main:app --reload --port 8084
INFO:     Will watch for changes in these directories: ['/home/jason/my-fastapi-project/src']
INFO:     Uvicorn running on http://127.0.0.1:8084 (Press CTRL+C to quit)
INFO:     Started reloader process [1546799] using StatReload
INFO:     Started server process [1546806]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
  • my_fastapi_project.main:app: Refers to the app instance inside the main.py file within the my_fastapi_project` package.
  • --reload: A useful development option that automatically restarts the server whenever you change the code.

Now, open your browser to http://127.0.0.1:8084 to see the "Hello": "World" message, and visit http://127.0.0.1:8084/docs to see the auto-generated API documentation.

6. Managing Commands with Scripts

Instead of typing long commands every time, you can register them as scripts in your pyproject.toml file for convenience.

Create a cli.py file inside the my_fastapi_project directory and write a script.

src/my_fastapi_project/cli.py:

import uvicorn
import pytest

def dev():
    uvicorn.run("my_fastapi_project.main:app", reload=True, port=8084)


def runtests():
    raise SystemExit(pytest.main())

Add the following section to your pyproject.toml file:

[tool.poetry.scripts]
dev  = "my_fastapi_project.cli:dev"
test = "my_fastapi_project.cli:runtests"

Now you can easily run the development server and tests with these commands:

$ poetry run dev
INFO:     Will watch for changes in these directories: ['/home/jason/my-fastapi-project']
INFO:     Uvicorn running on http://127.0.0.1:8084 (Press CTRL+C to quit)
INFO:     Started reloader process [1547940] using StatReload
INFO:     Started server process [1547948]
INFO:     Waiting for application startup.
INFO:     Application startup complete.

7. Writing and Running Tests

Write your test code in the tests directory. FastAPI provides a TestClient that makes it easy to test your application.

tests/test_main.py:

from fastapi.testclient import TestClient
from my_fastapi_project.main import app

client = TestClient(app)

def test_read_root():
    response = client.get("/")
    assert response.status_code == 200
    assert response.json() == {"Hello": "World"}

def test_read_item():
    response = client.get("/items/5?q=somequery")
    assert response.status_code == 200
    assert response.json() == {"item_id": 5, "q": "somequery"}

You can run the tests easily with the script you registered earlier:

$ poetry run test
$~/my-fastapi-project$ poetry run pytest
==================== test session starts ====================
platform linux -- Python 3.12.3, pytest-8.4.1, pluggy-1.6.0
rootdir: /home/gcp/my-fastapi-project
configfile: pyproject.toml
plugins: anyio-4.9.0
collected 2 items

tests/test_main.py ..
                                                       [100%]
==================== 2 passed in 0.45s   ====================

We hope this guide has helped you learn how to effectively build and manage your development environment in a FastAPI project using Poetry. 🎉

Comments

Popular posts from this blog

Resolving Key Exchange Failure When Connecting with SecureCRT to OpenSSH

SecureCRT] How to Back Up and Restore SecureCRT Settings on Windows

How to Set Up Vaultwarden (Bitwarden) on Synology NAS (Best Free Alternative to LastPass)