Static analysis for Python — locally, in 60 seconds.

Scan your Python project for complexity outliers, vulnerable dependencies, dead helpers, bare except: clauses, and magic constants buried in business logic — with the ik CLI. Pairs cleanly with ruff and mypy; inkode contributes the historical, structural, and security signal those tools don't.

Install the CLI Wire up GitHub Action

Running on a Flask app

$ ik run inkode · flask-quotes-api Running 20 checks... Complexity 4 findings 180ms (chamele, in-process) Dependency Audit 3 findings 5.4s (pip-audit) Dead Code 7 findings 1.1s (vulture) Magic Numbers 9 findings 920ms (pylint) Error Handling 2 findings 85ms (bare-except regex) Test Presence no issues 12ms (pytest detected) Import Graph no issues 95ms Score 68 / 100 grade D Report .ik/brief.html Share https://api.inkode.co/r/Pq7M3vBjLn8X

What we check, and how.

CheckToolWhat it catches in Python
Complexitychamele (in-process)Functions and methods exceeding cyclomatic-complexity threshold (default 10), via the in-process chamele library — no radon install, never skipped. Catches the deeply-nested generators AI tools love to write.
Dependency Auditpip-auditCVEs against requirements.txt via the PyPI Advisory Database + OSV. Every vuln → Error finding (no severity threshold; pip-audit doesn't expose one consistently).
Dead CodevultureUnused functions, classes, imports, and variables at --min-confidence=80. Tuned conservatively so the signal-to-noise ratio stays high on real codebases.
Magic Numberspylint (fallback: regex)pylint --enable=magic-value-comparison. Falls back to a regex scan with Python-aware skip rules (imports, from, comments) when pylint isn't installed.
Error HandlingregexBare except: clauses and except Exception: swallow-alls. Surfaces line-by-line so reviewers can see context, not just counts.
Test Presencefs walktest_*.py and *_test.py classified as test files. pytest framework detected via requirements.txt.
Import Graphbuilt-in ast-based parserCycles in the module graph, fan-in / fan-out outliers, god modules. Uses Python's own ast for accuracy.
Semantic Duplicationembedded LLMPython functions extracted at indent levels 0 and 4 (module-level + single-class nesting), embedded via Qwen2.5-Coder-0.5B, paired by cosine similarity. Catches helpers regenerated from scratch in different modules.
AI Stackmanifest scanOpenAI SDK, Anthropic SDK, LangChain, LlamaIndex, Hugging Face, CrewAI, AutoGen, Ollama detected in requirements.txt and pyproject.toml.
Secrets, Hotspots, Coupling, Duplication, Line Count, Infra, Scripts, TODO Densitylanguage-agnosticSame as every other language — gitleaks for secrets, git-log analysis for hotspots / coupling, jscpd for textual duplication, etc.

The smells nobody refactors out.

Bare except: swallow-alls

A perfectly-valid-looking try / except / pass that masks every kind of error. AI emits these to "make the test pass" and they live forever.

Unused helpers + dead imports

Functions and modules imported "for future use" that are never called. vulture finds them at 80% confidence so noise stays manageable.

Outdated requirements.txt

Pinned versions of requests, urllib3, cryptography, etc. with known CVEs. pip-audit checks the PyPI Advisory Database + OSV in one pass.

Magic literals in business logic

Timeouts, retry counts, page sizes hardcoded as integers inline. Changing one means a code review; named constants make the change obvious in the diff.

Run it on your Python project.

Install in one line, scan in under a minute. No account required.

$ curl -fsSL https://inkode.co/install.sh | sh $ pipx install pip-audit vulture pylint # one-time (complexity needs no install) $ cd your-python-project && ik init && ik run
Book an Expert Review

Scan another language

C# Go Java Rust TypeScript All scanners

Cross-cutting checks: secret scanning · dependency vulnerability scanning · AI code review