Skip to main content

Sanopy

CI PyPI - Version PyPI - Python Versions Ruff Mypy Pyright License

Sanopy is a CLI tool for improving Python code quality. It runs multiple linters concurrently and emits findings as JSON to stdout.

Requirements

  • Python 3.12+
  • uv

Installation

pip install sanopy

# Optional with uv
uv venv .venv
uv pip install sanopy

Quick Start

1. Configure

Sanopy always uses a local .sanopy.toml in the current project.

  • If .sanopy.toml does not exist, Sanopy creates it automatically with defaults.
  • Use init to customize settings manually or in automation.
# Interactive (manual)
sanopy init

# Non-interactive (CI/automation)
sanopy init --only ruff,mypy --skip bandit

2. Scan a Codebase

sanopy scan src/

By default, machine-readable JSON is printed to stdout in a versioned envelope:

{
  "schema_version": "1.0.0",
  "run": {
    "target": "src",
    "generated_at": "2026-08-09T00:00:00+00:00",
    "active_linters": ["ruff", "pylint", "mypy"],
    "finding_count": 0
  },
  "findings": []
}

Use human output mode for terminal-friendly progress and summaries:

sanopy scan src/ --output-mode human

You can scan multiple directories or files at once:

sanopy scan src/ tests/

When scanning multiple targets, the results are merged into a single JSON document, and run.target becomes an array of the scanned paths.

Generate a human-readable Markdown report:

sanopy scan src/ --human-readable

The report is saved as linting-report-<target>.md (e.g., linting-report-src.md).

Save results to a custom file:

sanopy scan src/ -o my-scan.json

Linter Filtering

Run only selected linters:

sanopy scan . --only ruff,mypy

Skip selected linters:

sanopy scan . --skip safety

You can also set default only_linters and skip_linters values in .sanopy.toml via sanopy init.

Supported Linters

Linter Category Detects
Ruff Style PEP 8, imports, code smells
Pylint Style Code quality, conventions
Bandit Security Common security vulnerabilities
MyPy Typing Static type checking
Pyright Typing Advanced type inference
Semgrep Semantic Pattern-based analysis
Vulture Dead code Unused variables, functions
Radon Complexity Cyclomatic complexity
Safety Dependencies Known vulnerabilities
pip-audit Dependencies Known vulnerabilities in dependency tree

Configuration File

The .sanopy.toml file controls linter defaults for the current project.

  • Manual workflow: run sanopy init and answer prompts.
  • CI/AI workflow: run sanopy init --only ... --skip ... in scripts.
  • If the file is missing, Sanopy creates .sanopy.toml with defaults.
[linters]
only_linters = []
skip_linters = []

[linters.pylint]
disable = ["duplicate-code", "too-many-locals"]

[linters.bandit]
skips = []

[linters.ruff]
select = ["E", "F", "W", "I", "N", "UP", "B", "A", "C4", "SIM", "PTH"]
ignore = []

[safety]
ignore_cves = ["CVE-2026-0994"]

[pip-audit]
ignore_vulns = ["PYSEC-2026-3482"]

The [safety] section lists CVE IDs that the Safety linter should suppress. By default a small set of known-unresolvable CVEs is ignored; set ignore_cves = [] to disable all suppressions.

The [pip-audit] section lists vulnerability IDs (or aliases) that the pip-audit linter should suppress, matched by primary ID or alias.

The optional [linters.<name>] sections provide the configuration that Sanopy passes to linters shipping bundled defaults (pylint, bandit, and ruff). A nested [linters.<name>.test] table overrides the settings used for test code. Sections and keys you omit fall back to the bundled defaults; a freshly generated .sanopy.toml materializes all of them so they are visible and editable.

Example CI step:

steps:
  - name: Configure Sanopy
    run: sanopy init --only ruff,mypy --skip bandit
  - name: Run scan
    run: sanopy scan src/ tests/

Development

Clone the repo and install dependencies:

git clone https://github.com/lpozo/sanopy.git
cd sanopy
uv sync

Run tests:

uv run pytest

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sanopy-0.1.0.tar.gz (160.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sanopy-0.1.0-py3-none-any.whl (38.0 kB view details)

Uploaded Python 3

File details

Details for the file sanopy-0.1.0.tar.gz.

File metadata

  • Download URL: sanopy-0.1.0.tar.gz
  • Upload date:
  • Size: 160.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sanopy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0255c1bf702ff71267a5b002a56427387d27b13ceaeae7d8dd513da96d3d36a5
MD5 886833dea2427a18d83b71dba71c7271
BLAKE2b-256 0b6482a9bd1246884df4805de2ae2c4687025b46ed9dd018b0c451cc6504eef3

See more details on using hashes here.

Provenance

The following attestation bundles were made for sanopy-0.1.0.tar.gz:

Publisher: publish.yml on lpozo/sanopy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sanopy-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: sanopy-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 38.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for sanopy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d5f668be77ae19424f15c8a23950c5c63141272516a471bbdcce14164784971f
MD5 b34f16b5d37354335d343ba6567739e9
BLAKE2b-256 92e9b5f318a091305ed0a8875f85eaf052c20c15ef33a7bbad0f6655a988c322

See more details on using hashes here.

Provenance

The following attestation bundles were made for sanopy-0.1.0-py3-none-any.whl:

Publisher: publish.yml on lpozo/sanopy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

This release

0.1.0 This release

2 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