Skip to main content

Python monorepo tooling

Project description

Una

Una logo

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:

  1. Enable builds of individual apps or projects within a monorepo.
  2. 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 works much like a Rust workspace, with each package having its own pyproject.toml. In general, packages should either be libraries (imported but not run) or apps (run but never imported), but Una will not enforce this.

Currently it works with the following build backends, but more will follow:

  • Hatch (used by default and and in all documentation)
  • PDM

All instructions and examples use Rye for local development, but there is nothing inherently Rye-specific about the tool.

Examples

You can see an example repo here:

Quickstart

This will give you a quick view of how this all works.

First install Rye:

curl -sSf https://rye.astral.sh/get | bash

And start your workspace:

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.deps] 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:

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

una-0.3.0a1.tar.gz (26.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

una-0.3.0a1-py3-none-any.whl (17.4 kB view details)

Uploaded Python 3

File details

Details for the file una-0.3.0a1.tar.gz.

File metadata

  • Download URL: una-0.3.0a1.tar.gz
  • Upload date:
  • Size: 26.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.0 CPython/3.12.5

File hashes

Hashes for una-0.3.0a1.tar.gz
Algorithm Hash digest
SHA256 9e5c73631e7b0a9aa3b60db157b6e912949eed7adb81f6e63d93117a8e4e093d
MD5 6c70de140514d6174d1f4f86b4fed728
BLAKE2b-256 62745cebc817c3cbdcaa04f6b4f4d211246cbbe68cdc162818f8fc6813f3bfe4

See more details on using hashes here.

File details

Details for the file una-0.3.0a1-py3-none-any.whl.

File metadata

  • Download URL: una-0.3.0a1-py3-none-any.whl
  • Upload date:
  • Size: 17.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.0 CPython/3.12.5

File hashes

Hashes for una-0.3.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 f32b373f18867dba5d6989b4fcbaa7f9d4b4a3c165aaf9e15310a6fe51d85cf9
MD5 d7e58cf19ffdca4d80b6f2a796077600
BLAKE2b-256 526da1461179fa9fba67811e43dc5c6cd18ee8746a32898849e0f360c07c45d0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page