A Python package that automatically checks PyPI for new versions of your dependencies and updates your requirements files with comprehensive format support.
- 🔍 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, andpyproject.tomlfiles - 🔄 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
pip install pypi-package-updaterOr install with development dependencies:
pip install pypi-package-updater[dev]# 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# 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-updaterYou can download pre-built packages from the GitHub Releases page:
- Python Wheel (
.whl): For manual pip installationpip install pypi_package_updater-X.X.X-py3-none-any.whl
- Source Distribution (
.tar.gz): For building from sourcepip install pypi_package_updater-X.X.X.tar.gz
- Debian Package (
.deb): For Debian/Ubuntu systemssudo dpkg -i pypi-package-updater_X.X.X-1_all.deb
git clone https://github.com/adambirds/pypi-package-updater.git
cd pypi-package-updater
pip install -e .- Python 3.11+
- aiohttp
- packaging
- tomli (for pyproject.toml support)
pypi-update --check-onlypypi-updatepypi-update requirements/common.in requirements/dev.inpypi-update --dry-runpypi-update --non-interactivepypi-update --no-compileimport 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())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)
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
The tool supports multiple dependency file formats with automatic detection:
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
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"],
}
)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"- Parse Requirements: Scans your
.infiles to extract package names and current versions - Check PyPI: Queries the PyPI API to get the latest version for each package
- Calculate Updates: Compares current versions with latest versions
- Update Files: Modifies your
.infiles with new versions (respects dependency order) - Compile Requirements: Runs your existing compilation script to generate
.txtfiles
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.
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 packageN: Skip this package (default)q: Quit the update process
Use --dry-run to see what would be updated without making any changes:
pypi-update --dry-runThis is useful for:
- Checking what updates are available
- Testing the tool's behavior
- Generating reports for review
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
This project uses automated CI/CD to build and distribute packages across multiple platforms:
On each release, the CI/CD pipeline automatically:
- PyPI: Publishes Python packages (wheel and source distribution)
- GitHub Releases: Uploads multiple package formats for manual download
- Homebrew: Updates the Homebrew tap with the latest version
- Python Wheel (
.whl): Universal Python package forpip install - Source Distribution (
.tar.gz): Python source package - Debian Package (
.deb): For Debian/Ubuntu systems - Homebrew Formula: For macOS and Linux via Homebrew
# 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]"This project maintains high code quality standards with comprehensive tooling:
# 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 logicWe 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- 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
The project includes a complete GitHub Actions workflow (.github/workflows/ci-cd.yml):
- 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
- PyPI Publishing: Automatic release on version tags
- Release Automation: GitHub releases with changelogs
To enable full CI/CD functionality, configure these repository secrets:
-
CODECOV_TOKEN- For coverage reporting# Get from https://codecov.io/gh/adambirds/pypi-package-updater # Add to GitHub repo settings → Secrets and variables → Actions
-
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
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.
GITHUB_TOKEN- Automatically provided by GitHub Actions
- Update Version: Bump version in
pyproject.toml - Create Tag:
git tag v1.0.0 && git push origin v1.0.0 - Automatic Deployment: GitHub Actions builds and publishes to PyPI
- GitHub Release: Automatic release creation with changelog
- Tool configuration for Black, isort, mypy
- Package metadata and dependencies
- Build system configuration
- Coverage requirements (95% project, 90% patch)
- Coverage status checks configuration
- Automated linting script with
--fixmode - Colored output and comprehensive reporting
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes with tests
- Run quality checks:
python scripts/lint.py --fix && pytest - Ensure tests pass: All 263 tests should pass with maintained coverage
- Submit a pull request
- ✅ 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
MIT License - see LICENSE file for details.
See CHANGELOG.md for release history and details.