A toolchain for testing Python application with automatic OpenTelemetry tracing
This toolchain automatically injects a pytest_otel library for test tracing visibility in Dagger TUI and Dagger Cloud. No configuration required.
Usage:
On a python project, using pytest as the test runner:
- initialize a dagger module if not already done:
dagger init . - install the
pytesttoolchain:dagger toolchain install github.com/dagger/pytest - run tests:
dagger check pytest:test. It will:- creates an Alpine based container with
uv(a uv cache volume is set) - prepares Python for the requested version via
uv, failing fast if it can't be resolved - injects the
pytest_oteldependency for automatic test tracing (before your source is added, so it stays cached) - installs your project dependencies (automatically via
uv runforpyproject.tomlprojects, or fromrequirements.txt) - export captured stdout, stderr, and Python logging records as OTel logs
- run
pytest
- creates an Alpine based container with
pytest:test runs against a self-contained Alpine + uv base, so it needs no setup. To trace pytest inside your own container instead (your Python, your dependencies, your environment), pass that container to the toolchain or use the lower-level functions directly.
The toolchain serves three levels of control:
- Plain toolchain - install it and run
dagger check. Your project is taken from the workspace automatically;pythonVersion(andsourcePath, to target a subdirectory of the workspace) are the only knobs commonly set. Everything else just works against the bundled Alpine +uvbase. - Custom image (drop-in) - set
containerto your own image (your Python, your tooling,uvor not). It replaces the default base; the module still installspytest_oteland runs pytest. If your image is notuv-based, setrunnertoPIPor leaveAUTOto auto-detect. - Embedded / custom - call the building blocks directly:
test- full pipeline (base -> source -> deps -> otel -> pytest), withskipInstallDeps: trueto skip mounting the source and installing dependencies when your image already has both.testUv/testPip- run-only: given a container that already has source + dependencies, installpytest_oteland run pytest. Use these to skip detection entirely.installPytestOtel(ctr, runner, envTarget)- install onlypytest_otelinto your container (AUTOdetects the tool;UV/PIPforce one), then run pytest yourself. UseenvTargetto control where it lands (see below) - in particularSYSTEMfor a container without a.venv.pytestOtel- get the bundledpytest_otellibrary as aDirectoryfor fully-manual integration (it is not yet published to PyPI).
runner is AUTO | UV | PIP (default AUTO: prefer uv, else pip).
envTarget is AUTO | VENV | SYSTEM (default AUTO): AUTO installs into
an existing virtual environment when present and otherwise falls back to a system
install; VENV forces a virtual environment (created when missing); SYSTEM
forces a system install (--system --break-system-packages). Containers without
a .venv work with AUTO and SYSTEM.
Example, using fastly/fastly-cli:
$ git clone https://github.com/fastly/cli
$ cd cli
$ # Initialize an empty dagger module
$ dagger init
Initialized module fastapi-cli in ~/dev/src/github.com/fastapi/fastapi-cli
$ # Add the pytest toolchain
$ dagger toolchain install github.com/dagger/pytest
toolchain installed
$ # Run tests, with tracing enabled
$ dagger check
✔ pytest:test 17.4s ⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣿⣿⣿⣿⣿⣿⣿⡆⡄⣿⣿⡄ OK