Skip to main content

CleanLibrary Python SDK

cleanlib-sdk is the Python client library for CleanLibrary. It wraps the same HTTP surface that powers the CLI, the MCP server, and the VS Code extension behind a small, typed API you can drop into any Python program — a service, a CLI tool, a CI gate, or a serverless function.

1. What it does

The Python SDK answers the same package-manager-layer questions as the CLI, but from inside a Python program rather than from a shell:

  1. Is this version safe to install?client.fetch_verdict(...)
  2. What does my policy do with this package?client.policy_preview(...)
  3. Should I accept the risk on this finding?client.risk_accept(...)

The wire contract is identical to every other CleanLibrary client. A verdict returned by the Python SDK has the same shape as a verdict returned by the CLI or the MCP server, so you can mix-and-match clients within one workflow.

2. Install

pip install cleanlib-sdk

uv users:

uv pip install cleanlib-sdk

Virtualenv:

python -m venv .venv && source .venv/bin/activate
pip install cleanlib-sdk

The SDK targets Python 3.9+ and depends only on httpx and the standard library.

3. Quickstart

import os
from cleanlib_sdk import Client

client = Client(
endpoint="https://cleanapp.clnstrt.dev",
api_key=os.environ["CLEANLIB_API_KEY"],
)

verdict = client.fetch_verdict("npm", "lodash", "4.17.21")

print(f"verdict_id: {verdict.verdict_id}")
print(f"severity: {verdict.severity}")
print(f"source: {verdict.source}")

Output:

verdict_id: <stable-identifier>
severity: NONE
source: ALLOWED_NO_FINDINGS

4. Configuration

The Client constructor accepts these positional and keyword arguments:

ArgumentPurposeDefault
endpointBase URL of the CleanLibrary backend(required)
api_keyBearer token (typically from CLEANLIB_API_KEY env var)None
api_versionAPI version path segment"v1"
timeout_secsPer-request timeout in seconds30.0

The convention for production deployments is to read endpoint and api_key from environment variables and let everything else default:

client = Client(
endpoint=os.environ["CLEANLIB_ENDPOINT"],
api_key=os.environ["CLEANLIB_API_KEY"],
)

5. API reference

client.fetch_verdict(ecosystem, package, version) -> Verdict

Returns a verdict for a single (ecosystem, package, version) tuple. The Verdict carries the verdict identifier, severity, source label, freshness fields, and remediation hints.

class Verdict:
verdict_id: str # stable identifier for this decision
source: str # ALLOWED_NO_FINDINGS | VECTOR_VERDICT | DM_THRESHOLD_BLOCK | INSUFFICIENT_DATA
severity: str # NONE | LOW | MEDIUM | HIGH | CRITICAL
composite_score: int # 0-100 confidence in the decision
reasoning: str
suggested_actions: list[str]
# Plus freshness, similar_to, evidence_gaps, attestation, and rich-data fields

client.scan(packages) -> ScanResponse

Scans a list of PackageRef entries in one round-trip and returns a ScanResponse containing a verdict per package. Suitable for CI pipelines or admission controllers that need a single round-trip.

client.policy_preview(policy_yaml, packages) -> PolicyPreviewResponse

Returns what your candidate policy would decide for the given packages, with the matching policy rule attached. Useful for "if I add this rule, will it break my CI?" checks before deploying the policy.

client.risk_accept(verdict_id, justification) -> RiskAcceptResponse

Records a customer-side risk-acceptance against a specific verdict. The justification is stored alongside the verdict for audit purposes.

client.audit(window) -> AuditWindowResponse

Returns the customer-side audit log for a time window — verdicts fetched, policies previewed, risk-acceptances recorded.

client.fetch_bytes(ecosystem, package, version) -> bytes

Returns the verified upstream bytes for an (ecosystem, package, version) tuple — useful when you want CleanLibrary to fetch the artifact for policy evaluation or attestation signing.

6. Error handling

The SDK raises typed exceptions for known failure modes. Common exception types:

ExceptionWhen it raises
AuthenticationErrorMissing, malformed, or rejected api_key
InsufficientDataErrorThe catalog has no verdict for this (ecosystem, package, version) yet
IntegrityFailureErrorAn attestation or signature check failed
CleanLibraryErrorBase class for all SDK errors

A verdict is not raised — it's a successful response with a verdict-aware shape. Use the verdict's severity and source to drive flow control, not exception handling.

7. CI integration

Drop the SDK into a build step and exit non-zero on a denied verdict:

# build/precheck.py
import sys, os
from cleanlib_sdk import Client, AuthenticationError

client = Client(
endpoint=os.environ["CLEANLIB_ENDPOINT"],
api_key=os.environ["CLEANLIB_API_KEY"],
)

try:
v = client.fetch_verdict("npm", "lodash", "4.17.21")
except AuthenticationError:
print("BLOCKED: invalid API key", file=sys.stderr)
sys.exit(2)

if v.source == "DM_THRESHOLD_BLOCK":
print(f"BLOCKED: npm/lodash@4.17.21 — {v.reasoning}", file=sys.stderr)
sys.exit(1)

For multi-package scans, prefer client.scan(...) over a loop of client.fetch_verdict(...) calls — one round-trip is cheaper than N.

8. Versioning

The SDK follows Semantic Versioning. The verdict envelope wire contract is stable across the v0.4 series — clients can mix v0.4.0 and v0.4.3 against the same backend without coordination.

v0.4.x envelopes are byte-identical with the Go, JavaScript, and Rust SDKs against the same backend version — verdicts produced by each SDK derive the same status for the same (ecosystem, package, version) tuple.

9. Where to go next

  • CLI — the same verdicts and remediation surface from the terminal, for ad-hoc queries and CI gates
  • MCP Server — surface CleanLibrary inside any MCP-compatible AI coding agent
  • SDK — Go — Go programmatic access to the same verdict surface
  • SDK — JavaScript — JavaScript / TypeScript programmatic access
  • SDK — Rust — Rust programmatic access
  • Integration Surfaces — the full integration matrix (admission, CI, IDE, agent)
  • Architecture — how CleanLibrary's verdict-and-enrichment surface composes end to end