Skip to main content

Sutro Logo

PyPI - Version PyPI - Downloads

Sutro Python SDK

Sutro helps teams build grounded LLM judges, classifiers, and extractors, then run them confidently at scale.

Use Sutro when you need reliable offline AI over tables, traces, documents, or other collections of unstructured data:

  • Judge model outputs, agent traces, and QA gates
  • Classify tickets, leads, documents, events, and messy business records
  • Extract structured fields, spans, labels, and normalized schemas
  • Run large-scale evals, synthetic data generation, semantic tagging, and embeddings

Visit sutro.sh, read the docs, or get access to start using Sutro. Sutro Functions are currently in research preview; contact team@sutro.sh for access, design-partner support, higher quotas, or enterprise deployment options.

What You Can Run

Sutro Functions

Sutro Functions are task-specific judges, classifiers, and extractors aligned to your decision preferences. Instead of hand-maintaining prompts, you define the task, review ambiguous examples, add rationale where needed, and deploy a reusable Function that can be invoked online or in batch.

Typical Functions include:

  • Support-agent pass/fail judges
  • Lead qualification and routing
  • Trust, safety, fraud, spam, or compliance classifiers
  • Document categorization and structured extraction
  • Data quality filters and normalization steps
  • Model and query routers

Sutro Batch

Sutro Batch is serverless async inference for high-volume AI workloads. Run Sutro Functions or pre-trained open-source LLMs over large datasets with machine-time pricing in GPU-hours, DataFrame-friendly inputs and outputs, live observability, and result downloads.

Batch is best when latency is less important than quality, cost, throughput, and reproducibility.

Quickstart

Install

pip install sutro

With uv:

uv pip install sutro

Authenticate

Create a deployment API key in your Sutro deployment and copy the key when it is created.

Configure the SDK with your deployment URL and key:

export SUTRO_API_URL="https://your-sutro-deployment.example.com"
export SUTRO_API_KEY="sk_..."

SUTRO_API_URL may be the Sutro deployment base URL or the same URL with /v1 appended. The SDK normalizes either form to /v1 and sends all requests through that deployment.

You can instead persist both values interactively for future SDK and CLI calls:

sutro login

Or configure the shared Python client directly:

import sutro as so

so.set_api_url("https://your-sutro-deployment.example.com")
so.set_api_key("sk_...")

Set the URL first: changing deployments clears the current key so it cannot be sent to another deployment accidentally.

Explicit constructor values take precedence over environment variables, which take precedence over saved sutro login credentials. Sutro(api_key="...") can use SUTRO_API_URL, but it will not borrow a saved deployment URL because that URL may be paired with a different saved key. An explicit URL similarly reuses a fallback key only when the normalized URLs match exactly.

Run a Sutro Function

If your team has published a Function, call it by name with rows whose fields match its input schema:

import polars as pl
import sutro as so


df = pl.DataFrame(
    {
        "conversation": [
            "Customer: I cannot log in. Agent: I reset your password.",
            "Customer: Where is my refund? Agent: Please contact your bank.",
        ],
        "rubric": [
            "Pass if the agent directly resolves the customer issue.",
            "Pass if the agent gives a correct refund status or next step.",
        ],
    }
)

job_id = so.batch_run_function(
    name="support-agent-judge",
    data=df,
    job_priority=1,
    job_name="support-agent-eval",
)

results = so.await_job_completion(job_id)
print(results)

Function inputs must match the schema configured for that Function in Sutro. Replace the Function name and fields above with your published Function.

Run Standalone Batch Inference

You can also run pre-trained LLMs directly with infer. This is useful for prototyping, evals, extraction, classification, generation, and one-off data transformations.

import polars as pl
import sutro as so
from pydantic import BaseModel


df = pl.DataFrame(
    {
        "review": [
            "The battery life is terrible.",
            "Great camera and build quality!",
            "Too expensive for what it offers.",
        ]
    }
)


class ReviewSentiment(BaseModel):
    sentiment: str
    rationale: str


job_id = so.infer(
    data=df,
    column="review",
    model="gpt-oss-20b",
    system_prompt=(
        "Classify each product review as positive, neutral, or negative. "
        "Return a short rationale."
    ),
    output_schema=ReviewSentiment,
    stay_attached=False,
)

results = so.await_job_completion(job_id)
print(results)

infer() returns a job ID. Priority 0 jobs are the default and are meant for prototyping; if you omit stay_attached=False, the SDK streams progress and prints a result preview in your terminal.

Prototyping Job Result

Move to Production

Sutro supports two Batch priorities today:

  • job_priority=0: prototyping jobs for smaller runs and fast iteration
  • job_priority=1: production jobs for larger workloads and higher quotas

Before running a large job, use dry_run=True to create an estimate job. The SDK waits for and prints the estimate, then returns its job ID. This does not launch the full workload; sufficiently large priority-1 estimates measure inference time on a small sample and extrapolate the charge at the job's saved hourly rate.

import polars as pl
import sutro as so


df = pl.read_parquet(
    "hf://datasets/sutro/synthetic-product-reviews-20k/results.parquet"
)

estimate_job_id = so.infer(
    data=df,
    column="review_text",
    model="gpt-oss-20b",
    system_prompt="Summarize the review in one sentence.",
    job_priority=1,
    dry_run=True,
)
print(estimate_job_id)

job_id = so.infer(
    data=df,
    column="review_text",
    model="gpt-oss-20b",
    system_prompt="Summarize the review in one sentence.",
    job_priority=1,
    name="review-summary-prod",
    stay_attached=False,
)

so.await_job_completion(job_id, obtain_results=False)
if so.get_job_status(job_id) != "SUCCEEDED":
    raise RuntimeError("Job did not complete successfully")

results = so.get_job_results(job_id, include_inputs=True)
print(results.head())

The result helper above is convenient for manageable result sets. For large production results, use the resumable Parquet results-download workflow in the Batch documentation. You can also monitor live progress, inspect samples, tag jobs, and share results from the Sutro web app.

Production Job Result

Data Sources

The SDK accepts:

  • Python lists
  • Pandas and Polars DataFrames
  • Local CSV, Parquet, and TXT files
  • HTTP(S) CSV or Parquet download URLs

Results preserve input order. SDK result helpers return Polars DataFrames by default and can join results back to the original Pandas or Polars DataFrame.

Structured JSON results preserve customer properties, including objects named content alongside reasoning_content. Reasoning envelopes are no longer flattened automatically because that shape can also be valid customer data. For jobs whose outputs are known legacy reasoning envelopes, opt in to the previous flattening behavior:

results = so.get_job_results(job_id, unwrap_reasoning=True)
# Also supported by so.await_job_completion(job_id, unwrap_reasoning=True).

Use unpack_json=False to retain the original output strings. These options apply equally to cached and freshly fetched results.

More SDK Patterns

Multi-model comparison

import sutro as so


job_ids = so.infer_per_model(
    data=["Explain quantum computing in simple terms."],
    models=["gpt-oss-20b", "gpt-oss-120b"],
    names=["gpt-oss-20b-test", "gpt-oss-120b-test"],
    system_prompt="Give a concise, accurate answer.",
)

Embeddings

import sutro as so


results = so.embed(
    data=["battery life", "camera quality", "price sensitivity"],
    model="qwen-3-embedding-0.6b",
)

Job management

so.list_jobs()
so.get_job_status(job_id)
so.attach(job_id)
so.await_job_completion(job_id)
so.get_job_results(job_id, include_inputs=True)
so.cancel_job(job_id)
so.get_quotas()

CLI equivalents:

sutro jobs list
sutro jobs status <job_id>
sutro jobs attach <job_id>
sutro jobs results <job_id> --save --save-format parquet
sutro quotas

Documentation

Security and Deployment

The SDK has no centralized API fallback. Requests and deployment API keys are sent only to the Sutro deployment configured by SUTRO_API_URL. Manage and revoke those keys from that deployment's API Keys panel.

Job data is retained for up to 90 days by default, with configurable retention options in the web app. Enterprise deployments can support custom retention, custom integrations, or isolated cloud requirements.

For security, deployment, or procurement questions, contact team@sutro.sh.

Contributing

We welcome contributions and feedback. Please reach out at team@sutro.sh before larger changes so we can coordinate.

License

Apache-2.0

Metadata

Release files for sutro 0.1.67

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sutro 0.1.67
File Size Uploaded Provenance
sutro-0.1.67.tar.gz 55.1 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for sutro 0.1.67
File Interpreter ABI Platform
sutro-0.1.67-py3-none-any.whl Python 3 none any Details

Total release size: 112.5 kB

Release files / sutro-0.1.67.tar.gz

Download URL sutro-0.1.67.tar.gz
Size 55.1 kB
Tags Source
SHA-256 checksum
How to use checksums
335548c257e43020cafe20e87a0961e5e36e0623af9e4cd9a183c41e048c043d
BLAKE2b-256 checksum
How to use checksums
ba551aad0a1f97293c5a967570aab6e4ecb25054edcb36caab66aba95c40bbb7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / sutro-0.1.67-py3-none-any.whl

Download URL sutro-0.1.67-py3-none-any.whl
Size 57.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3200e0d43e471620aa9949d3e2867935affbb005d194cc98f446d8b0727a541b
BLAKE2b-256 checksum
How to use checksums
79dba3849d6344ce629bbbe40c2557e9e201d888142b4c561132546f1f22d8fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for sutro 0.1.67

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.67 This release

2 release files No provenance

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