flawed
A static-analysis engine for Python web applications. flawed builds a framework-aware model of a Python web app — its routes, request inputs, state effects, call graph, and value flow — and exposes that model as a Python library and a command-line tool.
Python API
The top-level flawed package is the analysis API — the same surface the
bundled rules are built on, usable directly from a REPL or a script.
open_repo() loads a repository's model:
from flawed import open_repo
from flawed.route import POST
repo = open_repo("path/to/app") # build (or load cached) the model
repo.routes # RouteCollection(75) [Route(GET / → index, …), …]
repo.routes.count_by(lambda r: "/".join(sorted(m.name for m in r.methods)))
# Counter({'GET': 35, 'POST': 28, 'GET/POST': 12, ...})
# Which POST routes write state but declare no guard in their handler stack?
for route in repo.routes.accepting(POST):
if route.reachable.effects() and not route.full_stack.checks():
print(route)
load_findings() is its mirror image — comb through a scan you already ran:
from flawed import load_findings
findings = load_findings("scan.json") # a --json or --sarif capture
findings.count_by("rule_id").most_common(5) # which rules fired most
findings.min_severity("high").in_dir("auth/") # high-sev findings under auth/
findings.diff(load_findings("baseline.json")).added # new findings vs a baseline
Both return immutable, chainable collections (group_by / count_by /
tabulate / | / slicing). See Python API for the full
surface.
Command line
flawed is also a command-line scanner that runs rule modules over a repository:
flawed # orientation dashboard (does not scan)
flawed . # scan the current directory
flawed scan path/to/repo # scan a repository: L1 index + L2 semantic + L3 rules
flawed scan . --rules-dir ./my_rules # run your own rule modules instead of the built-ins
Findings stream to stdout, progress and diagnostics to stderr. See
CLI for output formats (--json, --sarif), exit codes,
baseline diffing, and the full command list.
Documentation
End-user docs live in docs/:
- Writing rules — the rule-authoring guide: the
@detectorcontract, the objects a rule navigates, and running your own rules with--rules-dir. - The analysis model — what the engine models (routes, inputs, effects, call graph, value flow) and how to think about it.
- CLI — running scans, output formats, and configuration.
- Python API — querying the model interactively from a REPL or script.
- Provider authoring — teaching the engine a new framework so your rules see its routes, inputs, and effects.
Setup
flawed uses mise for project tools and task entry points, and uv for Python
dependency resolution.
mise install # Python + uv, pinned in mise.toml
mise deps # uv sync --all-extras
Development
mise run install-hooks # install the version-controlled pre-commit gate
mise run check # full gate: lockfile + lint + format + mypy + layers + framework/dep/subprocess checks + tests
mise run check -- PATH... # scope the gate to specific files or directories
mise run test # run affected tests (testmon)
mise run test -- tests/unit/ # scope tests to a directory or file
The pre-commit hook is tracked at tools/hooks/pre-commit; mise run install-hooks copies it into the repository's git hooks directory (idempotent,
and worktree-aware). Edit the tracked file and reinstall — never edit the copy
under .git/hooks/ directly.
Configuration
Global config: ~/.config/flawed/config.yaml
data_dir: <path> # where L1 cache artifacts are stored
repo_local: false # true = store cache next to each repo
observability_enabled: true # local run/scan metrics; set false to opt out
type_enrichment:
enable_mypy_batch: false # opt-in experimental mypy oracle
By default each scan appends local observability records — a runs.jsonl plus a
per-repo scan_metrics.jsonl under the data dir. These are written locally
only (no network, no telemetry); set observability_enabled: false to turn
them off.
Per-repo cache uses <data_dir>/owner__name/ layout. The index is cached after
the first run; subsequent scans skip L1 extraction.
License
flawed is released under the Apache License 2.0.
Metadata
Release files for flawed 0.7.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| flawed-0.7.2.tar.gz | 562.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| flawed-0.7.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.2 MB
Release files / flawed-0.7.2.tar.gz
| Download URL | flawed-0.7.2.tar.gz |
|---|---|
| Size | 562.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4492cc1d8926a1ddb79dae6a1a6d613071c2cb0b7ec4190c4e0dffdea8905662
|
|
BLAKE2b-256 checksum How to use checksums |
bb514b8fb5f2492c834e01b02d7c78a5315f3ce1eda6babb8c4faeb8a6a42157
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 6, 2026.
Transparency logRelease files / flawed-0.7.2-py3-none-any.whl
| Download URL | flawed-0.7.2-py3-none-any.whl |
|---|---|
| Size | 675.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0f0ad360b9c8ff4d82284e5cff2e1fa81fed3500d3c3c6ec5c559a96da1facfc
|
|
BLAKE2b-256 checksum How to use checksums |
f489e9b312f76d69fead727d7c6c0af52b204acb1061cfb5950c56697daee588
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 6, 2026.
Transparency log