Intelligent, incremental dependency resolution and caching for Python applications
Project description
ChaCC Dependency Manager
Smart dependency resolution with intelligent caching - 20x faster than pip for repeated installs.
๐ฏ When to Use This
Use this instead of pip when you:
- Build Docker images frequently
- Have large/complex dependency trees
- Work with modular applications
- Need faster CI/CD pipelines
- Want automatic cache management
Keep using pip for:
- Simple single-file projects
- One-off dependency installs
- Basic development workflows
๐ฆ Installation
# Basic installation (library only)
pip install chacc-dependency-manager
# With CLI commands (recommended)
pip install chacc-dependency-manager[resolver]
# Full development setup
pip install chacc-dependency-manager[full]
๐ Quick Usage
Command Line (Easiest)
# Install from requirements.txt
cdm install -r requirements.txt
# Install specific packages
cdm install fastapi uvicorn
# Check cache status
cdm cache --info
Python Code
from chacc import DependencyManager
dm = DependencyManager()
await dm.resolve_dependencies()
Docker
FROM python:3.11-slim
RUN pip install chacc-dependency-manager[resolver]
COPY requirements.txt .
RUN cdm install
๐ป Command Reference
Available commands: chacc-dependency-manager, chacc-dm, or cdm
One of these can be used. A good example can be cdm install -r requirements.txt or chacc-dependency-manager install -r requirements.txt
Install Dependencies
# From requirements file
cdm install -r requirements.txt
# Specific packages
cdm install fastapi uvicorn sqlalchemy
# Auto-discover all requirements
cdm install
Resolve Only (No Install)
# Check what would be installed
cdm resolve
# Specific file
cdm resolve -r requirements-dev.txt
Cache Management
# View cache info
cdm cache --info
# Clear all cache
cdm cache --clear
# Clear specific module
cdm cache --clear --module auth
๐ Why Use This Over Pip?
Perfect for Docker builds and complex dependency trees:
| Scenario | pip install | chacc-dependency-manager | Speed Improvement |
|---|---|---|---|
| Docker rebuild (no changes) | 45s | <2s | 22x faster โก |
| CI/CD pipeline | 60s | 3s | 20x faster โก |
| Large monorepo | 120s | 15s | 8x faster โก |
| First run | 45s | 45s | Same (expected) |
Additional Benefits:
- ๐ง Smart caching - Only resolves changed dependencies
- ๐ฆ Multi-file support - Handles complex requirement structures
- ๐ Incremental updates - No full reinstalls
- ๐ณ Docker-optimized - Layer caching friendly
๐ Auto-Discovery Patterns
Supported Patterns
"requirements.txt"- Single file (default)"*.txt"- All .txt files in search directories"requirements-*.txt"- Pattern matching"deps.txt"- Custom filename"pyproject.toml"- Future support planned
Search Directories
- Specified
modules_dir(if exists) - Current directory (
.)
Example Directory Structures
# Single app
myapp/
โโโ requirements.txt # Auto-discovered
โโโ main.py
# Modular app
myapp/
โโโ modules/
โ โโโ auth/
โ โ โโโ requirements.txt
โ โโโ api/
โ โ โโโ requirements.txt
โ โโโ db/
โ โโโ requirements.txt
โโโ main.py
# Custom naming
myapp/
โโโ deps-web.txt # Web dependencies
โโโ deps-db.txt # Database dependencies
โโโ deps-dev.txt # Development dependencies
๐ณ Pipeline & Container Caching
๐ณ Docker Usage
Simple, Cache-Friendly Docker Builds:
FROM python:3.11-slim
# Install the dependency manager
RUN pip install chacc-dependency-manager[resolver]
# Copy requirements files
COPY requirements*.txt ./
# Install with intelligent caching (only resolves when requirements change)
RUN cdm install
# Copy your application
COPY . .
# Run your app
CMD ["python", "app.py"]
CI/CD Pipeline Caching
GitHub Actions
- name: Cache dependencies
uses: actions/cache@v3
with:
path: .dependency_cache
key: deps-${{ hashFiles('requirements*.txt', 'pyproject.toml') }}
restore-keys: |
deps-
- name: Install dependencies
run: cdm install
Cache Persistence Strategies
1. Volume Mounts (Docker)
# Mount cache volume
docker run -v $(pwd)/.dependency_cache:/app/.dependency_cache \
-v $(pwd):/app \
myapp cdm install
2. Multi-Stage Builds
# Stage 1: Resolve dependencies
FROM python:3.11-slim AS deps
RUN pip install chacc-dependency-manager[resolver]
COPY requirements*.txt ./
RUN cdm install
# Stage 2: Runtime
FROM python:3.11-slim
COPY --from=deps /root/.dependency_cache /app/.dependency_cache
# ... rest of your app
3. Cache Warming
# Pre-warm cache for common scenarios
cdm install pip-tools setuptools pytest pytest-cov black flake8 mypy
Cache Invalidation
The dependency manager automatically invalidates cache when:
- Requirements content changes (hash-based detection)
- Manual cache clearing via
dm.invalidate_cache() - Module-specific clearing via
dm.invalidate_module_cache(module_name)
For forced rebuilds in pipelines:
# Force clean install
rm -rf .dependency_cache
cdm install
Best Practices
- Cache Location: Use consistent cache directories across environments
- Cache Keys: Include all requirement files in cache keys
- Fallback: Always have fallback to full resolution if cache fails
- Monitoring: Log cache hit/miss ratios for optimization
- Security: Clear cache when switching between branches with different deps
๐ ๏ธ Programmatic Resolution Features
DependencyManager Class / API Referrence
Constructor
DependencyManager(
cache_dir: Optional[str] = None, # Cache directory (default: ".dependency_cache")
logger: Optional[logging.Logger] = None, # Custom logger (default: built-in logging)
pre_resolve_hook: Optional[Callable] = None, # Pre-resolution callback
post_resolve_hook: Optional[Callable] = None, # Post-resolution callback
install_hook: Optional[Callable] = None # Custom installation callback
)
Methods
resolve_dependencies(modules_requirements=None, requirements_file_pattern="requirements.txt", search_dirs=None)invalidate_cache()invalidate_module_cache(module_name)calculate_module_hash(module_name, content)get_installed_packages()
Convenience Functions
re_resolve_dependencies(modules_requirements=None, requirements_file_pattern="requirements.txt", search_dirs=None)invalidate_dependency_cache()invalidate_module_cache(module_name)
Integration Custom Hooks
pre_resolve_hookpost_resolve_hookinstall_hook
For advanced use in applications:
from chacc import DependencyManager
# Basic usage
dm = DependencyManager()
await dm.resolve_dependencies()
# With custom options
dm = DependencyManager(
cache_dir="/tmp/.cache",
logger=logging.getLogger("myapp")
)
# With integration hooks
dm = DependencyManager(
pre_resolve_hook=lambda name, reqs: print(f"Resolving {name}"),
post_resolve_hook=lambda name, packages: print(f"Resolved {len(packages)} packages")
)
await dm.resolve_dependencies()
Custom Logger Integration
import logging
from chacc import DependencyManager
logger = logging.getLogger("myapp")
dm = DependencyManager(logger=logger)
Custom Search Directories
# Search in specific directories
await dm.resolve_dependencies(
requirements_file_pattern="requirements.txt",
search_dirs=["./src", "./plugins", "./libs"]
)
Selective Resolution
# Only resolve specific modules
await dm.resolve_dependencies({
"web": "fastapi\nuvicorn",
"db": "sqlalchemy\npsycopg2"
})
The DependencyManager can be extended with custom hooks for integration with other systems:
Pre/Post Resolution Hooks
def log_resolution_start(module_name: str, requirements: str):
"""Called before resolving dependencies for a module."""
print(f"Starting resolution for {module_name}")
def log_resolution_complete(module_name: str, resolved_packages: dict):
"""Called after resolving dependencies for a module."""
print(f"Resolved {len(resolved_packages)} packages for {module_name}")
dm = DependencyManager(
pre_resolve_hook=log_resolution_start,
post_resolve_hook=log_resolution_complete
)
Custom Installation Hook
def custom_installer(resolved_packages: dict, installed_packages: set) -> bool:
"""Custom installation logic. Return True if successful."""
try:
# Your custom installation logic here
for package, version in resolved_packages.items():
if package.lower() not in installed_packages:
# Custom install logic
pass
return True
except Exception:
return False
dm = DependencyManager(install_hook=custom_installer)
Integration Examples
FastAPI Integration
from fastapi import FastAPI
from chacc import DependencyManager
app = FastAPI()
@app.on_event("startup")
async def startup_event():
# Initialize dependency manager
dm = DependencyManager(
cache_dir=".fastapi_cache",
modules_dir="fastapi_modules"
)
# Resolve dependencies on startup
await dm.resolve_dependencies()
# Or resolve specific module dependencies
modules = {
"auth": "fastapi-security>=0.8.0\npython-jose>=3.3.0",
"database": "sqlalchemy>=1.4.0\nalembic>=1.7.0"
}
await dm.resolve_dependencies(modules)
Django Integration
# In Django settings.py or apps.py
from chacc import DependencyManager
# Initialize with Django-specific paths
dm = DependencyManager(
cache_dir=os.path.join(BASE_DIR, '.django_cache'),
modules_dir=os.path.join(BASE_DIR, 'django_apps'),
)
# In management command or startup hook
await dm.resolve_dependencies()
Flask Integration
from flask import Flask
from chacc import DependencyManager
app = Flask(__name__)
# Initialize dependency manager
dm = DependencyManager(
cache_dir=".flask_cache",
modules_dir="flask_plugins"
)
with app.app_context():
# Resolve dependencies
await dm.resolve_dependencies()
Any Other App Integration Example
from chacc import DependencyManager
# Another system can inject its own logger and hooks
dm = DependencyManager(
logger=custom_logger,
pre_resolve_hook=chacc_pre_resolve,
post_resolve_hook=chacc_post_resolve,
install_hook=chacc_installer
)
# Use as normal - hooks will be called automatically
await dm.resolve_dependencies()
Architecture
Cache Structure
{
"module_caches": {
"authentication": {
"hash": "abc123...",
"packages": {"fastapi": "==0.116.1", "pydantic": "==2.5.0"},
"last_updated": "2024-01-01T12:00:00"
},
"feature_x": {
"hash": "def456...",
"packages": {"requests": "==2.31.0"},
"last_updated": "2024-01-01T12:05:00"
}
},
"backbone_hash": "ghi789...",
"combined_hash": "jkl012...",
"resolved_packages": {
"fastapi": "==0.116.1",
"pydantic": "==2.5.0",
"requests": "==2.31.0"
}
}
Error Handling
The dependency manager provides comprehensive error handling:
- Cache Corruption: Automatically recreates corrupted cache files
- Network Issues: Graceful fallback for pip network problems
- Version Conflicts: Intelligent conflict resolution with logging
- Permission Issues: Clear error messages for file system problems
Future Enhancements
- Parallel Resolution: Resolve multiple modules concurrently
- Dependency Graph: Visualize module dependencies
- Security Scanning: Integrate with vulnerability scanners
- Container Optimization: Optimize for containerized deployments
Contributing
This dependency manager is designed to be published as a standalone package. To contribute:
- Ensure all tests pass
- Add comprehensive documentation
- Follow semantic versioning
- Maintain backward compatibility
๐ License
MIT License - See LICENSE file for 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
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 chacc_dependency_manager-1.0.1.tar.gz.
File metadata
- Download URL: chacc_dependency_manager-1.0.1.tar.gz
- Upload date:
- Size: 14.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c942002c49a2ba33291ef80308be64ff60dbfdd7d488f5740544d507887da49d
|
|
| MD5 |
68dbec37c7e1cbbeef98055061d2be6f
|
|
| BLAKE2b-256 |
8d7e78469aa79f9573d7dcc023288e5380466f99894df887219484c50df1e48c
|
File details
Details for the file chacc_dependency_manager-1.0.1-py3-none-any.whl.
File metadata
- Download URL: chacc_dependency_manager-1.0.1-py3-none-any.whl
- Upload date:
- Size: 14.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
171cbb2695717a351ace3e98dda5c8a7b4e5ee9c7f4efcfb5cff80eb059523a8
|
|
| MD5 |
f7a110de8692782dc510bc7a4cc9749a
|
|
| BLAKE2b-256 |
8064724c82eba9f12ba48ce84d4885f649e753c59253b2be3a838727b3245ae4
|