Skip to main content

Makes any LLM behave like a regular REST API. Define the contract, specllm enforces it.

Project description

specllm

The production framework for spec-first LLM APIs.

Define a REST API spec. specllm turns it into a live service where every response is powered by an LLM — validated, cached, and retried automatically. The caller never knows an LLM is involved.

┌──────────┐       ┌─────────────────────────────────────┐       ┌─────────┐
│ Your App │──────▶│ specllm                             │──────▶│   LLM   │
│          │◀──────│ (validates, retries, caches, serves)│◀──────│(any LLM)│
└──────────┘ JSON  └─────────────────────────────────────┘ JSON  └─────────┘
from specllm import SpecLLM

app = SpecLLM.from_openapi("./api.yaml")  # provider inferred from spec
app.serve(port=8080)

Install

pip install specllm
pip install specllm[anthropic]  # for Claude
pip install specllm[openai]     # for GPT-4

How It Works

Request → [Input Validation] → [Resolve Constraints] → [Cache Check] → [Build Prompt] → [Call LLM]
                                                                                              ↓
Response ← [Cache Store] ← [Output Validation] ←──── Valid? ←──── [LLM Response]
                                                       ↓ No
                                              [Retry with feedback] (up to 3x)
                                                       ↓ Still invalid
                                              [422 structured error]

Bad input → instant 400 (zero LLM cost). Invalid output → retry with error feedback. Still invalid → structured 422. Valid → cache and return.

Features

Model Selection via Spec

Specify the model in your spec. specllm infers the provider:

info:
  x-specllm-model: claude-sonnet-4-20250514   # default for all endpoints

paths:
  /v1/fast-route:
    post:
      x-specllm-model: claude-haiku-4          # override: cheap/fast

Built-in providers: Anthropic (claude-*) and OpenAI (gpt-*, o1-*, o3-*). Custom providers just implement one method:

class MyProvider(LLMProvider):
    def call(self, prompt: str, system_prompt=None) -> str:
        ...  # return raw text or dict — pipeline handles JSON extraction

Dynamic Response Constraints (x-constrain-from)

Let the caller control what the LLM can return — per request:

intent:
  type: string
  x-constrain-from: "intents"    # enum pulled from request body field "intents"

score:
  type: integer
  x-constrain-from:
    minimum: "min_score"          # range pulled from request body
    maximum: "max_score"

If the LLM picks outside the caller's options, specllm retries with feedback automatically.

Configuration (optional overrides)

app = SpecLLM.from_openapi("./api.yaml", config={
    "timeout_seconds": 30,
    "fallback_provider": backup_provider,
    "cost_limit_daily": 50.0,
    "cache_ttl": 3600,
})

Custom Validation & Prompts

@app.validate("/v1/route-ticket")
def only_enterprise(body):
    if body.get("customer_tier") != "enterprise":
        return "Only enterprise tickets accepted"

@app.prompt("/v1/answer")
def grounded_prompt(body):
    return (
        f"Answer ONLY from the following context. If the answer is not in the context, say so.\n\n"
        f"Context:\n{body['context']}\n\n"
        f"Question: {body['question']}"
    )

Observability

Every response includes headers: X-SpecLLM-Request-Id, X-SpecLLM-Latency-Ms, X-SpecLLM-Tokens-Used, X-SpecLLM-Retries, X-SpecLLM-Cache-Hit.

Testing (no LLM credentials needed)

from specllm.testing.record_replay import RecordReplayProvider

# Record locally, replay in CI:
provider = RecordReplayProvider(provider=real_provider, cassette="tests/tape.json")

Error Handling

Scenario HTTP Code
Bad input 400 INPUT_VALIDATION_FAILED
Output failed after retries 422 OUTPUT_SCHEMA_VIOLATION
Provider down/timeout 503/504 PROVIDER_UNAVAILABLE / PROVIDER_TIMEOUT
Cost limit hit 503 COST_LIMIT_REACHED

All errors return structured JSON with code, status, message, request_id, timestamp.

Architecture

specllm (zero required dependencies)

├── spec/         → OpenAPI parser + $ref resolution + JSON Schema validator
├── pipeline/     → Request orchestration, cache, retry, constraints, JSON extraction
├── llm/          → Provider ABC + Anthropic + OpenAI + MockProvider
├── server/       → ThreadingHTTPServer + async server
└── testing/      → Record/replay

Roadmap

  • ⬜ Redis cache backend
  • ⬜ Prometheus metrics + OpenTelemetry tracing

License

Apache License 2.0

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

specllm-0.1.0.tar.gz (29.3 kB view details)

Uploaded Source

Built Distribution

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

specllm-0.1.0-py3-none-any.whl (24.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: specllm-0.1.0.tar.gz
  • Upload date:
  • Size: 29.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for specllm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 41582d56e00d89b6f03287f984c66e02e496b3886a6d94bb29083e2210becb8e
MD5 22acf9385123a4223af9fcb7804ee289
BLAKE2b-256 d691145bc4fa5cb27bed615cdc0c2192dad37c73d001bd9d2c8a9d647152c349

See more details on using hashes here.

File details

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

File metadata

  • Download URL: specllm-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 24.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for specllm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 961cbc130c568c8d7f1a20c8ec9056c76ec6b9527f586663ac23123ea48fbdb5
MD5 299749cb83096eef6d028eb756ca6bb2
BLAKE2b-256 0deea1a8688a24e0293e915c160600052a60b8e80d1dcc413d95e27577696eca

See more details on using hashes here.

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