Python packages
Monolith is a primarily Python codebase and uses uv
as its Python package manager. The Mono CLI provides a convenient wrapper around uv
.
Monorepository structure
Monolith is a monorepository containing multiple Python projects. Each project has its own set of dependencies and the ones in apps/
tend to be deployed as services (application, server...). This isolation allows us to only deploy what is needed for each service.
For this, Monolith leverages uv
workspaces. We'll explain the basics in this guide, but refer to the official documentation for anything that is not covered here.
Everything is configured through pyproject.toml
files and the single uv.lock
at the root.
monolith
├── apps
│ └── database
│ ├── src/database
│ └── pyproject.toml
├── libs
│ ├── stoneware
│ │ ├── src/stoneware
│ │ └── pyproject.toml
│ └── shared
│ ├── src/shared
│ └── pyproject.toml
├── pyproject.toml
└── uv.lock
We're going to dig into those files in the sections below.
Lockfile
uv.lock
is a file automatically created by uv
, which contains the exact package versions to use in development and deployments. One requirement of uv
workspaces is that you can't have a package with different versions in different projects. This can be annoying but has the following benefits:
- Single virtual environment in dev, which plays much better with code editors or Jupyter notebooks
- Avoids problems like "package B uses Pandas 2.0 and package A, but package A uses Pandas 1.0, so they are incompatible"
At some point we will likely outgrow this constraint, but we should strive to preserve it as long as possible.
Root pyproject.toml
Here is the current root pyproject.toml
:
[project]
name = "monolith"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
[dependency-groups]
dev = [
"dagit>=1.10.11",
"dagster-webserver>=1.10.11",
"ipykernel>=6.29.5",
"mono",
"nbstripout>=0.8.1",
"pytest>=8.3.5",
"ruff>=0.11.6",
]
process-eng = ["aspen[aspen]"]
[tool.uv.sources]
shared = { workspace = true }
spatial = { workspace = true }
stoneware = { workspace = true }
data-infrastructure = { workspace = true }
dagster-tools = { workspace = true }
data-tools = { workspace = true }
datasmart = { workspace = true }
database = { workspace = true }
mono = { workspace = true }
aspen = { workspace = true }
[tool.uv.workspace]
members = ["libs/*", "apps/*"]
exclude = ["apps/docs", "apps/stoneware-app"]
Here's what it means:
project
section: metadata and Python version
Project pyproject.toml
Dependency isolation
- Dependencies are not isolated in the venv, so may get errors in production