Python monorepo tooling
Project description
Una
Easy monorepos with Python
Una is a tool to make Python monorepos easier. It is a CLI tool and a build plugin that does the following things:
- Enable builds of individual apps or projects within a monorepo.
- Ensure that internal and external dependencies are correctly specified.
Una doesn't try to replicate a full build system such as Bazel or Pants. It just makes it possible to have a simple monorepo with interdependencies.
Una allows two directory structures or styles:
- Packages: The default style, where each lib or app is a package with its own pyproject.toml (much like Rust's workspaces).
- Modules: A more novel approach with just a single pyproject.toml, inspired by python-polylith.
Within this context, we use the following words frequently:
lib
: a module or package that will be imported but not run.app
: a module or package that will be run but never imported.project
: a package with no code but only dependencies (only used in the Modules style).
Currently it works with the following build backends, but more will follow:
All instructions and examples use Rye for local development, but there is nothing inherently Rye-specific about the tool.
Examples
You can see examples for each of the two styles here:
Quickstart
This will give you a quick view of how this all works.
A packages
style will be used by default, as it is probably more familiar to most.
rye init unarepo # choose another name if you prefer
cd unarepo
rye add --dev una
Then setup the Una workspace. This will generate a structure and an example lib and app.
rye run una create workspace
rye sync
Have a look at what's been generated:
tree
Have a look at the generated __init__.py
files in the apps/printer
and libs/greeter
packages.
An external dependency (cowsay-python) has also been added to the latter's pyproject.toml
.
The magic of Una then comes in to resolve the graph of direct and transitive dependencies, which looks like this:
printer --> greeter --> cowsay-python
You can do this by running the following:
# this checks all imports and ensures they are added to
# [tool.una.libs] in the appropriate pyproject.toml
rye run una sync
Have a look at what happened:
tail apps/printer/pyproject.toml
It added greeter
as an internal dependency to printer
.
It didn't add cowsay-python
, as external dependencies are only resolved at build-time (keep reading).
Now you can build your app:
rye build --package printer
# this will inject the cowsay-python externel dependency
And see the result:
ls dist/
And you can do whatever you want with that wheel! What about stick it in a Dockerfile, have you ever seen such a simple one?
FROM python
COPY dist dist
RUN pip install dist/*.whl
And run it:
docker build --tag unarepo-printer .
docker run --rm -it unarepo-printer python -c 'from unarepo.printer import run; run()'
Installation
The CLI tool isn't strictly necessary, as all the stuff that lets the monorepo builds work is in the separate (and tiny) hatch-una package. But you will likely struggle to manage your monorepo without the tool!
So you may as well install it:
rye add --dev una
As for the build-time hatch-una
, it will automatically be installed by build tools when it spots this in your pyproject.toml
(this will be configured automatically by the CLI):
[build-system]
requires = ["hatchling", "hatch-una"]
build-backend = "hatchling.build"
Usage
The CLI has a few commands and options, have a look:
rye run una --help
Usage: una [OPTIONS] COMMAND [ARGS]...
╭─ Options ───────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰─────────────────────────────────────────────────────────────────────────╯
╭─ Commands ──────────────────────────────────────────────────────────────╮
│ create Commands for creating a workspace, apps, libs and projects. │
│ diff Shows changed int_deps compared to the latest git tag. │
│ info Info about the Una workspace. │
│ sync Update pyproject.toml with missing int_deps. │
╰─────────────────────────────────────────────────────────────────────────╯
Documentation
Read more at the official documentation.
It covers additional things like:
- type-checking, testing, editor integration
- more detail on the packages vs modules styles
- and more!
Contributing
See the instructions at the official documentation.
Very briefly, local development is with Rye:
rye sync
rye run all # will fmt, lint, typecheck and test
Then open a PR.
License
Una is distributed under the terms of the MIT license. Significant parts of the code are from the python-polylith project (c) 2022 David Vujic
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.