|
|
||
|---|---|---|
| .. | ||
| cmd/angela | ||
| internal | ||
| learn | ||
| pkg/types | ||
| testdata | ||
| .gitignore | ||
| .golangci.yml | ||
| Justfile | ||
| README.md | ||
| go.mod | ||
| go.sum | ||
README.md
angela
A fast CLI tool that updates Python dependencies in pyproject.toml and scans for known vulnerabilities using OSV.dev.
Built in Go for speed — parallel HTTP requests, local caching with ETag support, and a single binary with zero runtime dependencies.
Why
The Python ecosystem lacks a single tool that updates all dependencies in pyproject.toml the way pnpm update works for JavaScript. Existing options either show outdated packages without updating them (pip list --outdated), upgrade one at a time (pip install --upgrade), or require CI infrastructure (Dependabot, Renovate).
angela fills this gap: one command updates everything, with built-in CVE scanning.
Install
go install github.com/CarterPerez-dev/angela@latest
Or build from source:
git clone https://github.com/CarterPerez-dev/angela.git
cd angela
go build -o bin/angela ./cmd/angela
Usage
Update all dependencies
angela update
Reads pyproject.toml in the current directory, queries PyPI for the latest stable versions, and writes the updates back to the file.
Dry run (show what would change)
angela check
Shows available updates and vulnerabilities without modifying any files.
Scan for vulnerabilities only
angela scan
Checks all pinned dependencies against the OSV.dev vulnerability database.
Update with vulnerability scan
angela update --scan-vulns
Updates dependencies and reports any known CVEs in your current versions.
Skip major version bumps
angela update --safe
Only applies minor and patch updates, skipping anything that crosses a major version boundary.
Include pre-release versions
angela update --include-prerelease
Considers alpha, beta, release candidate, and dev versions when resolving the latest.
Specify a different file
angela update --file path/to/pyproject.toml
Clear the local cache
angela cache clear
Removes all cached PyPI responses from ~/.angela/cache/.
Example output
Scanning 9 dependencies...
Updates available:
django 3.2.0 -> 5.1.5 (major)
requests 2.28.0 -> 2.32.3 (minor)
click 8.0.0 -> 8.1.8 (patch)
pydantic 2.0.0 -> 2.10.6 (minor)
flask 2.0.0 -> 3.1.0 (major)
pytest 7.0.0 -> 8.3.4 (major)
black 23.0.0 -> 25.1.0 (major)
ruff 0.1.0 -> 0.9.4 (minor)
mypy 1.0.0 -> 1.14.1 (minor)
Vulnerabilities found:
django
GHSA-2hrw-hx67-34x6 [CRITICAL] Potential denial-of-service in django.utils.text.Truncator
Fixed in: 4.2.16
requests
GHSA-9wx4-h78v-vm56 [MEDIUM] Requests `Session` object does not verify requests after making first request with verify=False
Fixed in: 2.32.0
Updated pyproject.toml
9 packages checked
9 updated
36 vulnerabilities found
Done in 2.4s
How it works
1. Parse pyproject.toml
Extract all [project.dependencies] and [project.optional-dependencies]
2. Query PyPI Simple API (parallel)
Fetch version lists using the lightweight JSON format
ETag-based caching avoids redundant downloads
3. Resolve updates
Parse versions per PEP 440 (epochs, pre-releases, post-releases)
Filter to stable releases by default
Classify changes as major, minor, or patch
4. Scan for vulnerabilities (optional)
Batch query OSV.dev for all dependencies
Hydrate results with full advisory details
Deduplicate overlapping CVE/GHSA identifiers
5. Write updates
Regex-based surgery preserves comments and formatting
Atomic write via temp file + rename
Architecture
cmd/angela/main.go CLI entry point
internal/
cli/
update.go Command definitions and orchestration
output.go Terminal formatting with color
pypi/
version.go PEP 440 parser and comparator
client.go PyPI Simple API client with retry
cache.go File-backed ETag cache
osv/
client.go OSV.dev batch vulnerability scanner
pyproject/
parser.go TOML parsing and PEP 508 splitting
writer.go Comment-preserving regex updater
pkg/types/
types.go Shared domain types
Development
Requires Go 1.24+ and just.
just test # Run all tests with race detector
just lint # Run golangci-lint
just build # Build binary to bin/angela
just cover # Generate HTML coverage report
just check # Lint + test in one step
just run check # Run angela check via go run
Part of Cybersecurity-Projects
This tool is project #1 in the Cybersecurity-Projects repository — a collection of 60 security-focused projects built for learning and reference. The code is written to be educational: clear structure, proper error handling, and thorough testing.
See the learn/ directory for deep dives into the techniques used here.
License
MIT