Skip to main content

Dependency graph and boundary enforcement for Python Polylith workspaces.

Project description

polydep

Dependency graph and boundary enforcement for Python Polylith workspaces.

polydep analyzes inter-brick imports in a Python Polylith monorepo and outputs a Mermaid dependency graph. It complements the poly CLI by adding graph visualization, dependency chain explanation, and CI-friendly boundary checks.

Read-only — never modifies workspace files.

Install

pip install polydep
# or
uv tool install polydep

Requires Python 3.11+.

Quick start

# Generate a dependency graph as Mermaid
polydep graph

# Specify a workspace root
polydep graph --root /path/to/workspace

# Save to polydep.expected.mermaid
polydep graph --save

Example output:

graph LR
  subgraph bases
    consumer
    greet_api
  end
  subgraph components
    database
    greeting
    kafka
    log
  end
  consumer --> kafka
  consumer --> log
  greet_api --> greeting
  greet_api --> log
  kafka --> log

Commands

polydep graph

Print the dependency graph as a Mermaid diagram to stdout.

polydep graph [--root <path>] [--save]
Flag Default Description
--root <path> . Workspace root directory
--save Write to polydep.expected.mermaid instead of printing

polydep why

Explain why brick A depends on brick B — shows all dependency paths with exact file and line provenance.

polydep why <source_brick> <target_brick> [--root <path>]

Example output:

consumer depends on log via 2 paths:

Path 1 (direct):
  consumer -> log
    bases/example/consumer/core.py:3  from example import kafka, log

Path 2 (transitive, length 2):
  consumer -> kafka -> log
    bases/example/consumer/core.py:3  from example import kafka, log
    components/example/kafka/consumer.py:5  from example import log
    components/example/kafka/producer.py:3  from example import log

polydep check

Compare actual dependencies against an expected graph file. Designed for CI — exits non-zero on mismatch.

polydep check [--expected <path>] [--root <path>]
Flag Default Description
--expected <path> polydep.expected.mermaid Path to expected graph file
--root <path> . Workspace root directory

The expected graph file is a Mermaid file, typically generated by polydep graph --save. Strict comparison — unexpected edges (boundary violations) and missing edges (stale graph) cause failure. Unexpected edges include file and line provenance.

Exit code Meaning
0 Actual graph matches expected graph
1 Mismatch detected
2 Error (file not found, parse error, etc.)

CI integration

Bootstrap an expected graph

polydep graph --save
git add polydep.expected.mermaid && git commit -m "Add expected dependency graph"

GitHub Actions

- uses: astral-sh/setup-uv@v5
- run: uv tool install polydep
- run: polydep check

Pre-commit hook

# .pre-commit-config.yaml
- repo: local
  hooks:
    - id: polydep-check
      name: polydep boundary check
      entry: uv run polydep check
      language: system
      pass_filenames: false

How it works

  1. Workspace discovery — finds workspace.toml (or pyproject.toml with [tool.polylith]) and reads the namespace
  2. Brick enumeration — scans components/<namespace>/*/ and bases/<namespace>/*/
  3. Import extraction — parses every .py file with Python's ast module, collecting all absolute imports (relative imports are skipped as they're internal to a brick)
  4. Graph construction — filters imports to those targeting known bricks (matching <namespace>.<brick_name>), excludes self-imports, and builds a deduplicated edge set
  5. Output — renders the graph as a Mermaid diagram with subgraph grouping by brick type

Comparison with poly CLI

Feature poly CLI polydep
Dependency table poly deps --
Dependency graph (Mermaid) -- polydep graph
Dependency explanation -- polydep why
Boundary enforcement -- polydep check
Missing deps in project poly check --
Library analysis poly libs --

polydep complements rather than replaces poly. It focuses on the inter-brick dependency graph.

Development

Setup

git clone https://github.com/aulme/polydep.git
cd polydep
uv sync

Common commands

uv run pytest              # Run tests
uv run ruff check .        # Lint
uv run ruff format .       # Format
uv run ty check src/ tests/  # Type check
uv run polydep graph --root sample_project  # Smoke test

CI

GitHub Actions runs three parallel jobs on every push and PR:

  • testpytest
  • lintruff check + ruff format --check
  • typecheckty check

Test strategy

Tests use two approaches:

  • Unit tests construct Workspace/DependencyGraph objects directly in memory — fast, no filesystem
  • Integration tests use a sample_project/ fixture (a real Polylith workspace with 10 bricks and known dependencies)

Dependencies

Dependency Purpose
click CLI framework
ast (stdlib) Import extraction
tomllib (stdlib) Config parsing

Dev tools: uv, pytest, ruff, ty

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

polydep-0.1.0.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

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

polydep-0.1.0-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file polydep-0.1.0.tar.gz.

File metadata

  • Download URL: polydep-0.1.0.tar.gz
  • Upload date:
  • Size: 25.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for polydep-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c33bd6042cef1aacd4f41aaf6e3b7ae40c5ad6f302d3d85c47d06379a26cd0dd
MD5 e14d4273f3e74b6a157c30d290e3c778
BLAKE2b-256 f090dbdd0d6dadd3438244dab072976b36077912ac640da8b7f58ba31e4a3bbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for polydep-0.1.0.tar.gz:

Publisher: ci.yml on aulme/polydep

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file polydep-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: polydep-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for polydep-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d516a17da985818df710c618466019ef09901bba751676566704f7e581c03e34
MD5 d1735ae893c7a04e4dd207ae8608130b
BLAKE2b-256 739ad0733b4ba6efb73e3367b0cd9e8337ed2ef5b29ced3364f6375abfcc70f4

See more details on using hashes here.

Provenance

The following attestation bundles were made for polydep-0.1.0-py3-none-any.whl:

Publisher: ci.yml on aulme/polydep

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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