Skip to main content

Unified Python interface for LLMs across local and cloud backends.

Project description

polyrt

Unified Python interface for LLMs across local and cloud backends.

polyrt is a typed adapter library that exposes a single small surface — generate, stream, and their async variants — backed by Anthropic's Claude, OpenAI's GPT models, and local Apple-Silicon models via MLX. It does not route, it does not orchestrate, it does not run a server: it gives you one consistent function call shape and one consistent return type, regardless of which backend you point it at.

PyPI Python License

Install

Backend Install
Claude (Anthropic) pip install polyrt[anthropic]
OpenAI pip install polyrt[openai]
MLX (Apple Silicon) pip install polyrt[mlx]
All of the above pip install polyrt[all]

Python 3.11+ required.

Quickstart

Sync

"""Synchronous one-shot generation."""

import polyrt

result = polyrt.generate(
    "claude",
    model="claude-haiku-4-5",
    messages=[{"role": "user", "content": "Say hello in one word."}],
    max_tokens=20,
)
print(result.text)
print(f"Tokens: {result.usage.input_tokens} in, {result.usage.output_tokens} out")

Async streaming

"""Async streaming generation."""

import asyncio

import polyrt


async def main() -> None:
    async for event in polyrt.astream(
        "openai",
        model="gpt-4.1-mini",
        messages=[{"role": "user", "content": "Count to five."}],
        max_tokens=40,
    ):
        if event.type == "token":
            print(event.delta, end="", flush=True)
        elif event.type == "done" and event.usage is not None:
            print(f"\n\n[{event.usage.total_tokens} tokens]")


asyncio.run(main())

Structured output

"""Schema-constrained structured output."""

from pydantic import BaseModel

import polyrt


class City(BaseModel):
    name: str
    country: str
    population: int


result = polyrt.generate(
    "claude",
    model="claude-haiku-4-5",
    messages=[{"role": "user", "content": "Pick a notable city and return its data."}],
    schema=City,
)
assert isinstance(result.parsed, City)
print(f"{result.parsed.name}, {result.parsed.country} — pop {result.parsed.population:,}")

Backends

Backend Capabilities Extra
claude (alias: anthropic) schema, tools, vision, streaming polyrt[anthropic]
openai schema, tools, vision, streaming polyrt[openai]
mlx streaming (schema/tools/vision come in v0.2) polyrt[mlx]

polyrt.generate("anthropic", ...) and polyrt.generate("claude", ...) are equivalent — pick whichever name reads better in your call site.

Schema enforcement

When you pass schema=SomeModel, polyrt asks the backend to constrain its output to that Pydantic model and parses the result for you. The strategy differs by backend:

  • Claude — passes the schema as a single tool with tool_choice forced to that tool, then parses the tool's input payload.
  • OpenAI — uses Structured Outputs (response_format with type=json_schema, strict=true) so the model is constrained at decode time.
  • MLX — not yet supported in v0.1; raises NotSupportedError. v0.2 will add support via outlines or lm-format-enforcer.

Response.parsed is your validated Pydantic instance when it works, None otherwise.

What polyrt is not

  • Not a router that picks a backend for you
  • Not an agent framework
  • Not a model server or proxy
  • Not a fine-tuning toolkit
  • Not a prompt template engine

It is a typed adapter. If you want one of the things above, this is the layer you would build it on top of.

Adding a backend

  1. Subclass Backend (or duck-type the protocol) and implement the seven methods.
  2. Call polyrt.registry.register("<name>", YourFactory) at module import time.
  3. Either ship inside polyrt/backends/<name>.py, or expose your factory as a polyrt.backends entry point so users get it via pip install.

See docs/backends.md for the full contract.

License

Apache 2.0. See LICENSE.

Acknowledgments

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

polyrt-0.1.1.tar.gz (26.9 kB view details)

Uploaded Source

Built Distribution

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

polyrt-0.1.1-py3-none-any.whl (24.5 kB view details)

Uploaded Python 3

File details

Details for the file polyrt-0.1.1.tar.gz.

File metadata

  • Download URL: polyrt-0.1.1.tar.gz
  • Upload date:
  • Size: 26.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.9 {"installer":{"name":"uv","version":"0.11.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}

File hashes

Hashes for polyrt-0.1.1.tar.gz
Algorithm Hash digest
SHA256 4b21ce885ed207b9faacccd294e76fd37f4b36a8acf09dd7a16727d03558f923
MD5 183b9088f694df551c469285e7bf4a93
BLAKE2b-256 1186335523b91ff2ea9fb950f5327783faa6409cf80e520621851aa31de621eb

See more details on using hashes here.

File details

Details for the file polyrt-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: polyrt-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 24.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.9 {"installer":{"name":"uv","version":"0.11.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}

File hashes

Hashes for polyrt-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e6cb059f02c961ddccce947b45657444b7ab35339ee232bf504b84fa160619ad
MD5 e7dc5c89f43e446f74308e3fb8e04d75
BLAKE2b-256 ffdcbaeebf04acc8c79daeaaaa18bfc533d667c952010f40ef7401ff7bd12052

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