Skip to main content

Thin Python client for running Claude Code via the local claude executable.

Project description

stan_ai_client

stan_ai_client is a thin Python wrapper around the local claude executable.

It does not call Anthropic APIs directly. Claude Code must already be installed and authenticated on the machine.

The library is intentionally small and pragmatic:

  • run_text() for plain-text Claude output
  • run_json() for --output-format json
  • run_structured() for schema-validated structured output
  • typed results
  • structured exceptions
  • local JSON Schema validation
  • rate-limit parsing helpers
  • stdlib logging

Why Use It

Use stan_ai_client when you want:

  • a small Python API on top of Claude Code
  • text mode and JSON mode without hand-rolling subprocess logic
  • strongly guided structured output with local validation
  • command metadata, typed JSON payloads, and normalized exceptions
  • safe-by-default prompt logging behavior
  • local automation that already depends on Claude Code being installed

Typical use cases:

  • article summarization
  • tagging or YAML generation
  • one-shot repository or directory analysis
  • local scripts that need Claude session metadata, cost, or duration

It is not a replacement for the Anthropic API SDK, and it is not trying to abstract multiple providers.

Install

From PyPI

pip install stan-ai-client

From a local checkout

python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

From GitHub

pip install "git+https://github.com/<your-user>/stan_ai_client.git"

Releases

  • the package version lives in pyproject.toml
  • every non-bot push or merge to main bumps patch automatically
  • tags use vX.Y.Z
  • main releases build and publish to PyPI automatically
  • release commits are created by GitHub Actions as chore: release vX.Y.Z [skip ci]

Quickstart

1. Install Claude Code

Make sure claude is already available on your machine and authenticated:

claude --version

2. Run the smoke test

python examples/smoke_test.py

That runs one text-mode call and one JSON-mode call.

Minimal Usage

Text mode

from stan_ai_client import ClaudeCodeClient

client = ClaudeCodeClient()
result = client.run_text("Reply with the single word: ok")
print(result.text)

JSON mode

from pathlib import Path

from stan_ai_client import ClaudeCodeClient, RunOptions

client = ClaudeCodeClient(
    default_model="claude-opus-4-6",
    default_effort="max",
    default_timeout_seconds=180,
)

result = client.run_json(
    "Summarize this article.",
    options=RunOptions(
        cwd=Path("."),
        allowed_tools=("Read", "Glob", "Grep", "Bash"),
    ),
)

print(result.payload.result)
print(result.payload.total_cost_usd)
print(result.payload.session_id)

Structured mode

from stan_ai_client import ClaudeCodeClient, StructuredSchema

client = ClaudeCodeClient()

schema = StructuredSchema.from_dict(
    {
        "type": "object",
        "properties": {
            "summary": {"type": "string"},
            "tags": {"type": "array", "items": {"type": "string"}},
        },
        "required": ["summary", "tags"],
        "additionalProperties": False,
    }
)

result = client.run_structured(
    "Summarize this article and return tags.",
    schema=schema,
)

print(result.structured_output["summary"])
print(result.payload.session_id)
print(result.payload.total_cost_usd)

run_structured() validates the schema before Claude runs, requires structured_output in the response, and validates the returned object locally against the same schema.

Logging

import logging

from stan_ai_client import ClaudeCodeClient

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("my_app.claude")

client = ClaudeCodeClient(
    logger=logger,
    log_prompts=False,
)

client.run_text("Reply with the single word: ok")

By default, logging includes execution metadata, not full prompt text. Set log_prompts=True only if you explicitly want prompts written to logs.

Error handling

If you automate Claude Code, treat ClaudeLimitError as a normal control-flow case: wait until exc.reset_at or sleep exc.retry_after_seconds, then retry.

import time

from stan_ai_client import ClaudeCodeClient, ClaudeLimitError

client = ClaudeCodeClient()

for attempt in range(3):
    try:
        result = client.run_json("Summarize this repository.")
        break
    except ClaudeLimitError as exc:
        if attempt == 2 or exc.retry_after_seconds is None:
            raise
        time.sleep(exc.retry_after_seconds)

Public Surface

Top-level exports:

from stan_ai_client import (
    __version__,
    ClaudeCodeClient,
    RunOptions,
    TextRunResult,
    JsonRunResult,
    StructuredRunResult,
    ClaudeJsonPayload,
    CommandMetadata,
    StructuredSchema,
    ClaudeCodeError,
    ClaudeExecutableNotFoundError,
    ClaudeLimitError,
    ClaudeTimeoutError,
    ClaudeProcessError,
    ClaudeProtocolError,
    ClaudeRateLimitError,
    ClaudeSchemaValidationError,
    ClaudeStructuredOutputMissingError,
    ClaudeStructuredOutputValidationError,
    RateLimitInfo,
    parse_rate_limit_info,
)

Supported Features

  • text mode via run_text()
  • JSON mode via run_json()
  • structured mode via run_structured()
  • prompts sent over stdin by default
  • optional argv prompt mode
  • per-call working directory control
  • model, effort, timeout, environment, and session controls
  • support for Claude CLI flags via typed RunOptions
  • raw stdout and stderr preserved on results and errors
  • opt-in stdlib logging with safe default prompt handling
  • typed JSON payload parsing with unknown fields preserved in extras
  • local input and output validation for structured mode
  • rate-limit detection and reset-time parsing

Examples

Documentation

See DOCS.md for:

  • full RunOptions reference
  • logging behavior
  • result types
  • structured output usage
  • exception model
  • rate-limit handling
  • session usage
  • common patterns
  • current limitations
  • maintainer release flow

Notes

  • prompts default to stdin instead of argv
  • JSON mode always requests --output-format json
  • structured mode always requests --output-format json and --json-schema
  • text mode always requests --output-format text
  • logging uses stdlib logging
  • prompts are not written to logs unless log_prompts=True
  • the library is sync-only in 0.1.x
  • streaming is intentionally out of scope right now

Current Limitations

  • no streaming support
  • no async API
  • no built-in retry loop
  • no standalone CLI wrapper command
  • no first-class typed wrapper yet for every Claude Code flag
  • structured mode accepts dict-backed JSON Schema objects only

For unsupported Claude Code flags, use RunOptions(extra_args=...).

Development

pytest
mypy src tests

Project details


Download files

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

Source Distribution

stan_ai_client-0.1.2.tar.gz (19.1 kB view details)

Uploaded Source

Built Distribution

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

stan_ai_client-0.1.2-py3-none-any.whl (16.2 kB view details)

Uploaded Python 3

File details

Details for the file stan_ai_client-0.1.2.tar.gz.

File metadata

  • Download URL: stan_ai_client-0.1.2.tar.gz
  • Upload date:
  • Size: 19.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for stan_ai_client-0.1.2.tar.gz
Algorithm Hash digest
SHA256 daf5ed4574a8db56ef7004b63221a3db03448cd0448f2dffa24049f63533d763
MD5 f1611a30560eb1d19f363725a26a3305
BLAKE2b-256 f0aead30a5f3158951c9609154c8ba888fe492fb6f7404f27bb78b6074d27b7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for stan_ai_client-0.1.2.tar.gz:

Publisher: ci.yml on stanislavkozlovski/stan_ai_client

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

File details

Details for the file stan_ai_client-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: stan_ai_client-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 16.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for stan_ai_client-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e34ff9e0331fcc3f4c92a68b8c5242604f7bf414ff7fc7210543db54f3ec038d
MD5 e0a282c0afa6353ca676869ece19d978
BLAKE2b-256 22092ae4f9b4002170edb94767cec79f430fc4e5d75b35d92b2c8aca68ee1818

See more details on using hashes here.

Provenance

The following attestation bundles were made for stan_ai_client-0.1.2-py3-none-any.whl:

Publisher: ci.yml on stanislavkozlovski/stan_ai_client

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page