LLM inference SDK, for telemetry and internal model routing
Project description
Maniac Python SDK
The official Python client for the Maniac Inference Gateway API — an OpenAI-compatible inference gateway with telemetry, containers, evaluation, and optimization.
Installation
pip install maniac
Quick Start
from maniac import Maniac
client = Maniac() # uses MANIAC_API_KEY env var
completion = client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Hello!"}],
)
print(completion["choices"][0]["message"]["content"])
Chat Completions
Create a completion
completion = client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "What is the capital of France?"}],
)
maniac chat completions create \
--model openai/gpt-4o \
--messages '[{"role": "user", "content": "What is the capital of France?"}]'
Stream a completion
for chunk in client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Write a haiku."}],
stream=True,
):
print(chunk, end="", flush=True)
maniac chat completions create \
--model openai/gpt-4o \
--messages '[{"role": "user", "content": "Write a haiku."}]' \
--stream
List completions
completions = client.chat.completions.list(limit=10, container="my-container")
maniac chat completions list --limit 10 --container my-container
Retrieve a completion
completion = client.chat.completions.retrieve("completion-id")
maniac chat completions retrieve completion-id
Register examples
client.chat.completions.register(
container="my-container",
items=[
{
"input": {
"model": "openai/gpt-4o",
"messages": [{"role": "user", "content": "Hi"}],
},
"output": {
"choices": [{"message": {"role": "assistant", "content": "Hello!"}}],
},
}
],
)
maniac chat completions register \
--container my-container \
--items '[{"input": {"model": "openai/gpt-4o", "messages": [{"role": "user", "content": "Hi"}]}, "output": {"choices": [{"message": {"role": "assistant", "content": "Hello!"}}]}}]'
Containers
Create a container
container = client.containers.create(
label="my-container",
initial_model="openai/gpt-4o",
)
maniac containers create --label my-container --initial-model openai/gpt-4o
List containers
containers = client.containers.list()
maniac containers list
Retrieve a container
container = client.containers.retrieve("my-container")
maniac containers retrieve my-container
Delete a container
client.containers.delete("my-container")
maniac containers delete my-container
Models
List models
models = client.models.list()
maniac models list
Add a model to a container
client.models.add(
container="my-container",
model="anthropic/claude-sonnet-4.5",
slug="claude",
)
maniac models add \
--container my-container \
--model anthropic/claude-sonnet-4.5 \
--slug claude
Files
Upload a file
file = client.files.create(file="data.jsonl", purpose="fine-tune")
maniac files create data.jsonl --purpose fine-tune
List files
files = client.files.list()
maniac files list
Retrieve file metadata
file = client.files.retrieve("file-id")
maniac files retrieve file-id
Download file content
content = client.files.content("file-id")
maniac files content file-id
Delete a file
client.files.delete("file-id")
maniac files delete file-id
Evaluators
Create an evaluator
evaluator = client.evaluators.create(
type="judge",
model="openai/gpt-4o",
name="quality-judge",
prompt="Rate the quality of the response from 1-10.",
container="my-container",
)
maniac evaluators create \
--type judge \
--model openai/gpt-4o \
--name quality-judge \
--prompt "Rate the quality of the response from 1-10." \
--container my-container
List evaluators
evaluators = client.evaluators.list(container="my-container")
maniac evaluators list --container my-container
Retrieve an evaluator
evaluator = client.evaluators.retrieve("evaluator-id")
maniac evaluators retrieve evaluator-id
Update an evaluator
client.evaluators.update("evaluator-id", prompt="New prompt text.")
maniac evaluators update evaluator-id --prompt "New prompt text."
Delete an evaluator
client.evaluators.delete("evaluator-id")
maniac evaluators delete evaluator-id
Evaluation Runs
Create an evaluation run
run = client.evaluation.runs.create(
container="my-container",
evaluators=["evaluator-id"],
)
maniac evaluation runs create \
--container my-container \
--evaluators '["evaluator-id"]'
List evaluation runs
runs = client.evaluation.runs.list(container="my-container")
maniac evaluation runs list --container my-container
Retrieve an evaluation run
run = client.evaluation.runs.retrieve("run-id")
maniac evaluation runs retrieve run-id
Datasets
Create a dataset
dataset = client.datasets.create(
name="my-dataset",
container="my-container",
size=100,
)
maniac datasets create \
--name my-dataset \
--container my-container \
--size 100
List datasets
datasets = client.datasets.list(container="my-container")
maniac datasets list --container my-container
Retrieve a dataset
dataset = client.datasets.retrieve("dataset-id")
maniac datasets retrieve dataset-id
Optimization Runs
Create an optimization run
run = client.optimization.runs.create(
container="my-container",
base_models=["openai/gpt-4o"],
evals=["evaluator-id"],
methods=[{"type": "sft"}],
)
maniac optimization runs create \
--container my-container \
--base-models '["openai/gpt-4o"]' \
--evals '["evaluator-id"]' \
--methods '[{"type": "sft"}]'
OpenAI Compatibility
Maniac's inference endpoint is fully compatible with the OpenAI client. Point it at https://platform.maniac.ai/api/v1 and prefix your container label with maniac::
from openai import OpenAI
client = OpenAI(
base_url="https://platform.maniac.ai/api/v1",
api_key=os.getenv("MANIAC_API_KEY"),
)
response = client.chat.completions.create(
model="maniac:my-container",
messages=[{"role": "user", "content": "Hello!"}],
)
Async Usage
from maniac import AsyncManiac
async def main():
async with AsyncManiac() as client:
completion = await client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Hello!"}],
)
print(completion["choices"][0]["message"]["content"])
# Streaming
async for chunk in await client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Write a poem."}],
stream=True,
):
print(chunk, end="", flush=True)
Error Handling
from maniac import Maniac, AuthenticationError, RateLimitError, NotFoundError
client = Maniac()
try:
client.containers.retrieve("nonexistent")
except NotFoundError:
print("Container not found")
except AuthenticationError:
print("Invalid API key")
except RateLimitError as e:
print(f"Rate limited, retry after {e.retry_after}s")
All exceptions inherit from ManiacError. The full hierarchy:
ManiacErrorAPIError— generic API error (hasstatus_codeandcode)AuthenticationError— 401/403RateLimitError— 429 (hasretry_after)NotFoundError— 404BadRequestError— 400/422APIConnectionError— network failure
CLI Global Options
Every command supports --json for raw JSON output and --api-key / --base-url overrides:
maniac --api-key sk-... containers list --json
Run maniac --help or maniac <command> --help for full option details.
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 maniac-0.5.1.tar.gz.
File metadata
- Download URL: maniac-0.5.1.tar.gz
- Upload date:
- Size: 26.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45d4d6d5bbdf1c33df70ce30144c57e4834e9e8d646a8c4d952d75719a43ad25
|
|
| MD5 |
245fec7c4882f8e231e67c39edc4fb0e
|
|
| BLAKE2b-256 |
a517fc09720b047e321dd32fc875adfeb88752f2b2587f72bb59430e1dbfd8dc
|
File details
Details for the file maniac-0.5.1-py3-none-any.whl.
File metadata
- Download URL: maniac-0.5.1-py3-none-any.whl
- Upload date:
- Size: 26.2 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 |
69ea9fbc0b9176542a4878a998edea815af43130903989c00ef1d878c5ac6866
|
|
| MD5 |
0af48171725bafc88dd74f232ad9d173
|
|
| BLAKE2b-256 |
bc1718e25ea3716bfe3778ea6513f0cb103a57c02de413a24ab562cc011bc9fa
|