Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.aspect.build/llms.txt

Use this file to discover all available pages before exploring further.

aspect_rules_py is a layer on top of the community rules_python ruleset that replaces the end-user rules py_library, py_binary, and py_test with implementations that behave more like standard Python tooling. It pairs with uv for fast, reproducible dependency management and cross-platform container builds.
Stuck?

Create a new project

1

Install the Aspect CLI

brew install aspect-build/aspect/aspect
For other installation methods, see Aspect CLI.
2

Add the init command

aspect axl add gh:aspect-build/aspect-workflows-template
3

Scaffold your project

aspect init # select Python
This generates a Bazel workspace with uv for dependency management, Gazelle for BUILD file generation, and ruff for linting.
4

Set up your dev environment

direnv allow
Follow the prompts to run bazel run //tools:bazel_env, which installs project tools to your PATH. direnv is optional but recommended; without it you have to install tools yourself.
5

Add a dependency

Add packages to pyproject.toml, then update the lockfile:
uv add requests
./tools/repin
6

Generate BUILD files and run

bazel run gazelle      # generate BUILD files from your source
bazel run //app:app    # run your app
bazel test //...       # run all tests

Explore Bazel with Python

Starter Template

If you just want the code, clone the starter repository and explore a working Bazel + Python setup immediately.Use GitHub’s Codespace for an instant playground.

Bazel 102: Python Training

A hands-on course for building, testing, and shipping Python with Bazel.Covers dependency pinning, virtualenvs, pytest, linting, and container images.

Key features

  • Idiomatic Python behavior. Uses the standard site-packages folder layout instead of manipulating $PYTHONPATH, so your code behaves the same way under Bazel as it does in a normal Python environment.
  • Real virtualenvs. Each build runs in a virtualenv, which means IDE support (autocomplete, jump-to-definition) works in PyCharm, VS Code, and others without extra configuration.
  • Truly hermetic. The launcher uses Bash rather than Python, so there’s no dependency on a system Python interpreter, even when using a hermetic toolchain.
  • Truly cross-platform. Build Linux container images from Mac. Build Windows-compatible binaries from Linux. Build across architectures and target custom platforms with ease.
  • uv instead of pip. One uv.lock file replaces per-platform requirements.txt files and works with private package registries out of the box.

Ecosystem

Manage dependencies with uv

One lockfile for all platforms. Fast, reproducible installs and cross-platform container builds.

Migrating from rules_python

Already using rules_python? Migration is mostly a drop-in replacement.

Video: Python at Monorepo World

Watch Alex Eagle’s talk for a quick demo of how rules_py makes Python with Bazel easy.

Package management with PyPI

Use pyproject.toml to declare direct dependencies. Use uv to pin the dependency versions in a uv.lock file. This aligns Bazel builds with standard Python packaging while preserving hermetic, reproducible resolution. rules_uv and pip_compile targets update lockfiles, and pip.parse in MODULE.bazel exposes packages to Bazel targets.
After changing dependencies, repin before building. In the starter template, run ./tools/repin to update runtime requirements, transitive locks, and the Gazelle Python manifest together.
Quickstart:
  • Create app/__main__.py with a simple program (for example importing requests).
  • Add dependencies in pyproject.toml, then run ./tools/repin to refresh pinned requirements and manifests.
  • Run bazel run gazelle to generate BUILD files, then bazel run //app:app_bin to execute the binary.

Python programs

Generate BUILD files with Gazelle, then use py_library, py_binary, and py_test for code organization, executables, and tests. Bazel runs these targets with a hermetic Python toolchain instead of relying on a system interpreter. API reference: Python rules | toolchains | repositories

Developer workflow

For day-to-day development, Bazel-generated virtualenv targets improve editor integration and local debugging while staying aligned with Bazel’s dependency graph.

Monorepo dependencies

In a live-at-HEAD monorepo workflow, local libraries and services can be consumed directly without publishing intermediate package versions. Layered requirements and regular lockfile regeneration keep dependency resolution consistent across all packages. Typical flow:
  • Scaffold the new library/service in-repo, then add its requirements file into requirements/all.in.
  • Update Bazel inputs for dependency compilation (for example add new requirement files to requirements/BUILD data).
  • Run ./tools/repin and bazel run gazelle, then import and use the new package directly from application code.

Code generation and tools

Python console scripts can be exposed as Bazel tools and invoked from build actions. Use py_console_script_binary and run_binary to model code generation with explicit inputs and outputs. Training: Integrate Python console scripts as tools

Shipping artifacts

Bazel can package Python applications into OCI images and load them locally for quick verification. For release pipelines, stamping can embed build metadata in otherwise deterministic outputs. Training: Shipping artifacts

Cross-builds

Cross-build scenarios require careful handling of host, exec, and target platforms, especially when dependencies include non-pure Python wheels or source builds. Training: Cross-builds

Formatting and linting

The starter workflow follows a simple two-step loop:
  1. Format tracked files:
    bazel run format
    
  2. Run lint checks (and apply safe fixes when offered):
    bazel lint app/...
    
Configure tool behavior in pyproject.toml and keep linting in CI so style and correctness checks stay consistent across the team. API reference:

Additional APIs