# angela A fast CLI tool that updates Python dependencies in `pyproject.toml` and scans for known vulnerabilities using [OSV.dev](https://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 ```bash go install github.com/CarterPerez-dev/angela@latest ``` Or build from source: ```bash git clone https://github.com/CarterPerez-dev/angela.git cd angela go build -o bin/angela ./cmd/angela ``` --- ## Usage ### Update all dependencies ```bash 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) ```bash angela check ``` Shows available updates and vulnerabilities without modifying any files. ### Scan for vulnerabilities only ```bash angela scan ``` Checks all pinned dependencies against the OSV.dev vulnerability database. ### Update with vulnerability scan ```bash angela update --scan-vulns ``` Updates dependencies and reports any known CVEs in your current versions. ### Skip major version bumps ```bash angela update --safe ``` Only applies minor and patch updates, skipping anything that crosses a major version boundary. ### Include pre-release versions ```bash angela update --include-prerelease ``` Considers alpha, beta, release candidate, and dev versions when resolving the latest. ### Specify a different file ```bash angela update --file path/to/pyproject.toml ``` ### Clear the local cache ```bash 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](https://github.com/casey/just). ```bash 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](https://github.com/CarterPerez-dev/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/`](learn/) directory for deep dives into the techniques used here. --- ## License MIT