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.
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 |
schema, tools, vision, streaming | polyrt[anthropic] |
openai |
schema, tools, vision, streaming | polyrt[openai] |
mlx |
streaming (schema/tools/vision come in v0.2) | polyrt[mlx] |
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_choiceforced to that tool, then parses the tool'sinputpayload. - OpenAI — uses Structured Outputs (
response_formatwithtype=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 viaoutlinesorlm-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
- Subclass
Backend(or duck-type the protocol) and implement the seven methods. - Call
polyrt.registry.register("<name>", YourFactory)at module import time. - Either ship inside
polyrt/backends/<name>.py, or expose your factory as apolyrt.backendsentry point so users get it viapip install.
See docs/backends.md for the full contract.
License
Apache 2.0. See LICENSE.
Acknowledgments
anthropic-sdk-pythonopenai-pythonmlx-lmlitellm— prior art for the unified-interface idea.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file polyrt-0.1.0.tar.gz.
File metadata
- Download URL: polyrt-0.1.0.tar.gz
- Upload date:
- Size: 25.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
24e5a252e1dfc7876ae63f1d39de9450da7ca3a614eeb797346240506ec9bdeb
|
|
| MD5 |
84c1a8a5fcd2cc8286e438c90043d431
|
|
| BLAKE2b-256 |
4227ef71cf5b8c6ec40bcc224799f7d4ba533772e8027598db3ad18fa722e7f9
|
File details
Details for the file polyrt-0.1.0-py3-none-any.whl.
File metadata
- Download URL: polyrt-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07cace5092cf9811b678f6ea76c52eb79095b67188217c2a003782680e30b1ee
|
|
| MD5 |
4cd3f1ef045cf8864ae78c2d78aef60b
|
|
| BLAKE2b-256 |
5014e8849dd3f6cc43945d043b065d5799e0b08477a0a5b8cc98b95d1cbe9d67
|