Skip to main content

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 @detector contract, 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)

Source distribution for flawed 0.7.2
File Size Uploaded
flawed-0.7.2.tar.gz 562.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for flawed 0.7.2
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.7.2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page