A dependency governance platform for Python projects
Project description
DEPENDAPY
v0.2.0 โ Rewritten with a clean Onion Architecture for extensibility and testability.
Features
- ๐ Scan & Analyze: Recursively scans repositories for
pyproject.tomlfiles and identifies outdated dependencies - ๐ Python Version Check: Ensures compatibility with the three latest Python 3 minor versions via endoflife.date
- ๐ Smart PR Handling: Creates new pull requests or generates offline Git patches
- ๐ ๏ธ uv Compatible: Works seamlessly with the modern
uvpackage manager from astral.sh - ๐ค GitHub Action: Runs automatically on a schedule via GitHub Actions
- ๐๏ธ Onion Architecture: Clean domain model โ no GitHub-specific logic inside the core
- ๐งช Result Pattern: Explicit
Ok[T] | Err[E]error handling throughout (no exceptions for control flow)
Architecture
dependapy v0.2.0 is built on a strict Onion Architecture with four layers:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Presentation (CLI) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Application (Use Cases) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Infrastructure (PyPI, GitHub, Filesystem) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Domain (Entities, Ports) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Domain layer defines the core business logic and abstract Protocol interfaces (Ports).
Infrastructure adapters implement those protocols โ the domain never imports from infrastructure.
Key Concepts
| Concept | Description |
|---|---|
Result[T, E] |
Ok(value) or Err(error) โ replaces sentinel values and bare exceptions |
Version |
Wraps packaging.version.Version, immutable value object |
PackageRegistry |
Port (Protocol) for fetching latest package versions |
ProjectRepository |
Port for loading/saving pyproject.toml files |
VCSPort |
Port for branch, commit, push, PR operations |
PyPIAdapter |
Implements PackageRegistry with caching and parallel batch queries |
FileSystemProjectRepository |
Implements ProjectRepository for pyproject.toml |
GitHubVCSAdapter |
Implements VCSPort via PyGithub |
OfflinePatchAdapter |
Implements VCSPort via git format-patch |
Application |
Frozen dataclass โ composition root wired in bootstrap.py |
Installation
From PyPI (recommended)
# With uv
uv add dependapy
# With pip
pip install dependapy
From Source (for development)
git clone https://github.com/stefanposs/dependapy.git
cd dependapy
# Install in development mode with uv
uv sync --group dev
Configuration
dependapy reads configuration from environment variables (prefix DEPENDAPY_) or a .env file:
| Variable | Default | Description |
|---|---|---|
DEPENDAPY_VCS_TOKEN |
โ | GitHub / GitLab token |
DEPENDAPY_VCS_PROVIDER |
offline |
github or offline |
DEPENDAPY_VCS_BASE_BRANCH |
main |
Target branch for PRs |
DEPENDAPY_BRANCH_PREFIX |
dependapy/ |
Prefix for update branches |
DEPENDAPY_API_TIMEOUT |
10 |
HTTP timeout in seconds |
DEPENDAPY_LOG_LEVEL |
INFO |
Logging level |
DEPENDAPY_PYPI_BASE_URL |
https://pypi.org/pypi/{package_name}/json |
PyPI API base URL |
DEPENDAPY_PYTHON_EOL_API_URL |
https://endoflife.date/api/python.json |
Python EOL API |
DEPENDAPY_NUM_LATEST_PYTHON_VERSIONS |
3 |
Number of latest Python versions to check |
Usage
Running Locally
# Set your GitHub token
export DEPENDAPY_VCS_TOKEN=your_github_token
# Run dependapy (analyzes current directory, creates PR)
dependapy
# Dry run โ no changes made
dependapy --dry-run
# Skip PR creation, only update files locally
dependapy --no-pr
# Use offline patch instead of GitHub API
dependapy --provider offline --patch-output updates.patch
Command Line Options
usage: dependapy [-h] [--repo-path PATH] [--token TOKEN] [--provider {github,offline}]
[--base-branch BRANCH] [--no-pr] [--offline-pr] [--patch-output PATH]
[--dry-run] [--log-level LEVEL]
Analyze and update Python dependencies
options:
-h, --help show this help message and exit
--repo-path PATH Path to the repository to scan (default: current directory)
--token TOKEN VCS token (or set DEPENDAPY_VCS_TOKEN)
--provider {github,offline}
VCS provider to use (default: offline)
--base-branch BRANCH Target branch for PRs (default: main)
--no-pr Update files locally without creating a PR
--offline-pr Create a Git patch instead of using GitHub API (legacy alias)
--patch-output PATH Patch file path when using --provider offline
--dry-run Report changes without making them
--log-level LEVEL Logging level (default: INFO)
Offline PR Mode
For environments without GitHub API access:
dependapy --provider offline --patch-output my-updates.patch
# Apply later on a machine with GitHub access
git apply my-updates.patch
git checkout -b dependapy/updates
git commit -am "Apply dependapy updates"
git push origin dependapy/updates
# Then create a PR via the GitHub UI
Setting Up as a GitHub Action
name: Dependapy
on:
schedule:
- cron: '0 2 * * 0' # Every Sunday at 02:00 UTC
workflow_dispatch:
jobs:
update-dependencies:
name: Update Dependencies
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Install dependapy
run: pip install dependapy
- name: Run dependapy
env:
DEPENDAPY_VCS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: dependapy
Migration from v0.1.x
The CLI interface is fully backward-compatible. The old --offline-pr flag maps to --provider offline.
The internal Python API has changed. Legacy modules (analyzer, updater, github_api, offline_pr)
are still importable but will be removed in v0.3.0. Please migrate to the new API:
# Old (v0.1.x)
from dependapy.analyzer import analyze_project
from dependapy.github_api import create_pull_request
# New (v0.2.x)
from dependapy.bootstrap import bootstrap
from dependapy.application.config import AppConfig
app = bootstrap(AppConfig.from_env())
result = app.analyze.execute(Path("."))
How It Works
- Repository Scanning: Finds all
pyproject.tomlfiles recursively - Dependency Analysis:
- Reads
[project],[project.optional-dependencies], and[dependency-groups]sections - Checks PyPI for latest versions (parallel batch queries with caching)
- Checks endoflife.date for current Python version support
- Reads
- Update Planning: Generates
UpdatePlanrespecting patch/minor/major limits - File Updates: Applies version bumps in-place using regex (preserves file formatting)
- PR Submission: Creates branch โ commit โ push โ PR via configured VCS provider
Development
# Install dev dependencies
uv sync --group dev
# Run tests
uv run pytest tests/
# Run linter
uv run ruff check .
uv run ruff format --check .
# Check import layer contracts
uv run lint-imports
# Type checking
pyright dependapy/
# Full CI pipeline
just ci
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.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dependapy-0.2.0.tar.gz.
File metadata
- Download URL: dependapy-0.2.0.tar.gz
- Upload date:
- Size: 131.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75d9a4034933302a9e551e9af31ce66f3115cb462c6b4c8f6caeb5d5dfddb609
|
|
| MD5 |
3ad488c0e36c327fb7bf5ebbcb2faa9a
|
|
| BLAKE2b-256 |
20cbe0fa6be2bfc6b27437d8dfa83de1bee66acf3ff4f3d96d828214e120c0a1
|
File details
Details for the file dependapy-0.2.0-py3-none-any.whl.
File metadata
- Download URL: dependapy-0.2.0-py3-none-any.whl
- Upload date:
- Size: 38.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1be264b85e92044f78dc00f30164036ffea23bc0cc32bf5b55c94a1412312392
|
|
| MD5 |
d33b336b8cb748e8f280038d234e6b5c
|
|
| BLAKE2b-256 |
88ee3046261b949d88ebd04572eddaf1bf935b4c3e626777556220e85519c29f
|