Skip to main content

A tool to update Python package dependencies across multiple file formats

Project description

PyPI Package Updater

CI/CD codecov Python 3.11+ Code style: black Mypy coverage

A Python package that automatically checks PyPI for new versions of your dependencies and updates your requirements files with comprehensive format support.

Features

  • 🔍 Automatic Update Detection: Checks PyPI for the latest versions of all packages in your requirements files
  • 📝 Universal Format Support: Handles requirements.txt, requirements.in, setup.py, and pyproject.toml files
  • 🔄 Dependency-Aware Updates: Understands your requirements file hierarchy and updates in the correct order
  • 🎯 Selective Updates: Update specific files or packages, or update everything at once
  • 🛡️ Safe by Default: Dry-run mode and interactive confirmation before making changes
  • 🔨 Integration: Automatically runs your existing compilation script after updates
  • 📊 Detailed Reporting: Comprehensive summary of what was updated, failed, or skipped
  • High Code Quality: 99% test coverage with comprehensive branch coverage
  • 🚀 CI/CD Ready: Full GitHub Actions workflow with automated testing and deployment

Installation

Via pip (Python Package Index)

pip install pypi-package-updater

Or install with development dependencies:

pip install pypi-package-updater[dev]

Via Homebrew (macOS/Linux)

# Add the tap and install (one-time setup)
brew tap adambirds/homebrew-pypi-package-updater
brew install pypi-package-updater

# Or install directly without tapping
brew install adambirds/homebrew-pypi-package-updater/pypi-package-updater

Via APT (Debian/Ubuntu)

From the ADB APT Repository (Recommended)

# Add the custom APT repository
echo "deb https://adambirds.github.io/adb-apt-repo stable main" | sudo tee /etc/apt/sources.list.d/adb-apt-repo.list
curl -fsSL https://adambirds.github.io/adb-apt-repo/pubkey.gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/adb-apt-repo.gpg
sudo apt update
sudo apt install pypi-package-updater

Manual Installation from GitHub Releases

You can download pre-built packages from the GitHub Releases page:

  • Python Wheel (.whl): For manual pip installation
    pip install pypi_package_updater-X.X.X-py3-none-any.whl
    
  • Source Distribution (.tar.gz): For building from source
    pip install pypi_package_updater-X.X.X.tar.gz
    
  • Debian Package (.deb): For Debian/Ubuntu systems
    sudo dpkg -i pypi-package-updater_X.X.X-1_all.deb
    

From Source

git clone https://github.com/adambirds/pypi-package-updater.git
cd pypi-package-updater
pip install -e .

Requirements

  • Python 3.11+
  • aiohttp
  • packaging
  • tomli (for pyproject.toml support)

Usage

Command Line Interface

Check for available updates (without making changes):

pypi-update --check-only

Update all packages interactively:

pypi-update

Update specific files:

pypi-update requirements/common.in requirements/dev.in

Dry run (see what would be updated):

pypi-update --dry-run

Non-interactive mode (update everything automatically):

pypi-update --non-interactive

Skip compilation after updates:

pypi-update --no-compile

Python API

import asyncio
from pypi_updater import PyPIUpdater

async def main():
    updater = PyPIUpdater(requirements_dir="requirements", tools_dir="tools")
    
    # Check for updates
    updates = await updater.check_for_updates()
    
    # Update packages
    summary = await updater.update_packages(
        dry_run=False,
        auto_compile=True,
        interactive=True
    )
    
    # Print summary
    updater.print_update_summary(summary)

asyncio.run(main())

Configuration

Supported File Formats

The tool automatically detects and supports multiple dependency file formats:

  • requirements.txt - Standard pip requirements files
  • requirements.in - pip-tools input files with -c, -e, compilation comments
  • setup.py - setuptools configuration with install_requires
  • pyproject.toml - Modern Python packaging format (PEP 518)

Directory Structure

The tool expects your project to follow this structure:

your-project/
├── requirements/
│   ├── common.in       # Base requirements
│   ├── dev.in          # Development requirements
│   ├── prod.in         # Production requirements
│   └── *.txt          # Compiled requirements (generated)
├── setup.py           # Optional: setuptools configuration
├── pyproject.toml     # Optional: modern Python packaging
└── tools/
    └── update-locked-requirements  # Your compilation script

Requirements File Format

The tool supports multiple dependency file formats with automatic detection:

requirements.txt / requirements.in

Standard pip requirements format with:

  • Version pinning: Django==4.2.0
  • Version ranges: requests>=2.25.0
  • Includes: -r common.in
  • Comments: # This is a comment
  • Extras: django[postgres]==4.2.0

Example requirements/common.in:

# Core Dependencies
Django==4.2.0
requests>=2.25.0
celery==5.2.0

# Database
psycopg2==2.9.5

setup.py

Supports setuptools configuration:

from setuptools import setup

setup(
    name="my-package",
    install_requires=[
        "Django>=4.2.0",
        "requests>=2.25.0",
    ],
    extras_require={
        "dev": ["pytest>=6.0"],
    }
)

pyproject.toml

Modern Python packaging format (PEP 518):

[project]
dependencies = [
    "Django>=4.2.0",
    "requests>=2.25.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=6.0",
    "black>=22.0",
]

# Poetry format also supported
[tool.poetry.dependencies]
python = "^3.11"
Django = "^4.2.0"

How It Works

  1. Parse Requirements: Scans your .in files to extract package names and current versions
  2. Check PyPI: Queries the PyPI API to get the latest version for each package
  3. Calculate Updates: Compares current versions with latest versions
  4. Update Files: Modifies your .in files with new versions (respects dependency order)
  5. Compile Requirements: Runs your existing compilation script to generate .txt files

Advanced Features

Dependency Resolution

The tool understands your requirements hierarchy through -r includes and updates files in the correct order:

dev.in +-> prod.in +-> common.in
   |
   v
mypy.in

Files with no dependencies (like common.in) are updated first, followed by files that depend on them.

Interactive Mode

In interactive mode, you'll be prompted for each update:

Package: Django
  Current: 4.1.0
  Latest:  4.2.0
  File:    requirements/common.in
Update Django from 4.1.0 to 4.2.0? [y/N/q]:
  • y: Update this package
  • N: Skip this package (default)
  • q: Quit the update process

Dry Run Mode

Use --dry-run to see what would be updated without making any changes:

pypi-update --dry-run

This is useful for:

  • Checking what updates are available
  • Testing the tool's behavior
  • Generating reports for review

Error Handling

The tool handles various error conditions gracefully:

  • Network issues: Retries and timeouts for PyPI API calls
  • Invalid packages: Warns about packages not found on PyPI
  • File permissions: Clear error messages for file access issues
  • Version parsing: Handles non-standard version formats

Release and Distribution

This project uses automated CI/CD to build and distribute packages across multiple platforms:

Automated Publishing

On each release, the CI/CD pipeline automatically:

  1. PyPI: Publishes Python packages (wheel and source distribution)
  2. GitHub Releases: Uploads multiple package formats for manual download
  3. Homebrew: Updates the Homebrew tap with the latest version

Package Formats Available

  • Python Wheel (.whl): Universal Python package for pip install
  • Source Distribution (.tar.gz): Python source package
  • Debian Package (.deb): For Debian/Ubuntu systems
  • Homebrew Formula: For macOS and Linux via Homebrew

Development

Development Setup

# Clone the repository
git clone https://github.com/adambirds/pypi-package-updater.git
cd pypi-package-updater

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install in development mode with all dependencies
pip install -e ".[dev]"

Code Quality & Testing

This project maintains high code quality standards with comprehensive tooling:

Running Tests

# Run all tests (263 tests with 99% coverage)
pytest

# Run tests with coverage report
pytest --cov=pypi_updater --cov-report=html

# Run specific test categories
pytest tests/test_basic.py                    # Basic functionality
pytest tests/test_branch_coverage.py         # Branch coverage tests
pytest tests/test_formats.py                 # File format handling
pytest tests/test_updater.py                 # Main updater logic

Code Linting & Formatting

We use automated linting with Black, isort, and mypy:

# Run all linters (check mode)
python scripts/lint.py

# Run all linters with automatic fixes
python scripts/lint.py --fix

# Individual tools
black pypi_updater/ tests/                   # Code formatting
isort pypi_updater/ tests/                   # Import sorting  
mypy pypi_updater/                           # Type checking

Test Coverage

  • Current Coverage: 99% (654 statements, 262 branches)
  • Statement Coverage: 100% (all lines covered)
  • Branch Coverage: 99% (252/262 branches covered)
  • Total Tests: 263 comprehensive tests

CI/CD Pipeline

The project includes a complete GitHub Actions workflow (.github/workflows/ci-cd.yml):

Continuous Integration

  • Multi-Python Testing: Python 3.11, 3.12, 3.13
  • Code Quality Checks: Black, isort, mypy validation
  • Test Execution: Full test suite with coverage reporting
  • Coverage Upload: Automatic codecov.io integration

Continuous Deployment

  • PyPI Publishing: Automatic release on version tags
  • Release Automation: GitHub releases with changelogs

GitHub Secrets Setup

To enable full CI/CD functionality, configure these repository secrets:

Required Secrets

  1. CODECOV_TOKEN - For coverage reporting

    # Get from https://codecov.io/gh/adambirds/pypi-package-updater
    # Add to GitHub repo settings → Secrets and variables → Actions
    
  2. PAT_TOKEN - Personal Access Token for updating homebrew tap

    # Create at GitHub Settings → Developer settings → Personal access tokens
    # Scope: repo (full repository access)
    # Add as repository secret named: PAT_TOKEN
    # Used to update the separate homebrew tap repository
    

PyPI Publishing

This project uses PyPI Trusted Publishing for secure, token-free publishing to PyPI. No PYPI_API_TOKEN is required - the publishing is authenticated automatically through GitHub's OIDC provider.

Automatically Provided

  • GITHUB_TOKEN - Automatically provided by GitHub Actions

Release Process

  1. Update Version: Bump version in pyproject.toml
  2. Create Tag: git tag v1.0.0 && git push origin v1.0.0
  3. Automatic Deployment: GitHub Actions builds and publishes to PyPI
  4. GitHub Release: Automatic release creation with changelog

Configuration Files

pyproject.toml

  • Tool configuration for Black, isort, mypy
  • Package metadata and dependencies
  • Build system configuration

codecov.yaml

  • Coverage requirements (95% project, 90% patch)
  • Coverage status checks configuration

scripts/lint.py

  • Automated linting script with --fix mode
  • Colored output and comprehensive reporting

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes with tests
  4. Run quality checks: python scripts/lint.py --fix && pytest
  5. Ensure tests pass: All 263 tests should pass with maintained coverage
  6. Submit a pull request

Pull Request Requirements

  • ✅ All tests pass (99%+ coverage maintained)
  • ✅ Code follows Black formatting
  • ✅ Imports sorted with isort
  • ✅ Type hints pass mypy validation
  • ✅ New features include tests
  • ✅ Documentation updated if needed

License

MIT License - see LICENSE file for details.

Changelog

See CHANGELOG.md for release history and details.

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

pypi_package_updater-0.2.23.tar.gz (303.9 kB view details)

Uploaded Source

Built Distribution

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

pypi_package_updater-0.2.23-py3-none-any.whl (76.5 kB view details)

Uploaded Python 3

File details

Details for the file pypi_package_updater-0.2.23.tar.gz.

File metadata

  • Download URL: pypi_package_updater-0.2.23.tar.gz
  • Upload date:
  • Size: 303.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for pypi_package_updater-0.2.23.tar.gz
Algorithm Hash digest
SHA256 68012f16de833394cc31b0e71b79714759722466dbe1032a907858620b1050fa
MD5 381966fd747113ccf86562968673e7e7
BLAKE2b-256 98fc6cd63eaf347d548be8bf7ceef08bdce3c37da7cc3ffcdc4bbf1d4a2dd5ba

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypi_package_updater-0.2.23.tar.gz:

Publisher: ci-cd.yml on adambirds/pypi-package-updater

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

File details

Details for the file pypi_package_updater-0.2.23-py3-none-any.whl.

File metadata

File hashes

Hashes for pypi_package_updater-0.2.23-py3-none-any.whl
Algorithm Hash digest
SHA256 189689adb179de8f6ff519eab840863f08e746b723ad682f3d84450f7df91541
MD5 42bb84dc99c3be0f2bbdc9990c06fb6f
BLAKE2b-256 c5375e93988f792fc0b4232d4f40fac36e598552fd3e4a8a55430259294ee672

See more details on using hashes here.

Provenance

The following attestation bundles were made for pypi_package_updater-0.2.23-py3-none-any.whl:

Publisher: ci-cd.yml on adambirds/pypi-package-updater

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