Current collected state Current
Observed since 21 Oct, 10:45 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
aigateway-sdk
Unified AI Gateway - Multi-provider LLM routing, observability, and evaluation platform
A unified AI Gateway SDK for LLM routing, observability, and evaluation.
pip install Ai_Gateway
# With all providers
pip install Ai_Gateway[all-providers]
# With semantic caching
pip install Ai_Gateway[semantic-cache]
# Everything
pip install Ai_Gateway[full]
import aigateway
# Initialize with your API keys
aigateway.init(
openai_api_key="sk-...",
anthropic_api_key="sk-ant-...",
google_api_key="...",
)
# Use the unified gateway
response = aigateway.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
from openai import OpenAI
import aigateway
# Initialize AIGateway
aigateway.init()
# Wrap your existing client
client = OpenAI()
aigateway.monitor(client)
# All calls are now automatically traced
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}]
)
import aigateway
aigateway.init(
openai_api_key="sk-...",
anthropic_api_key="sk-ant-...",
fallback_providers=["anthropic"], # Fallback to Anthropic if OpenAI fails
)
# Will automatically retry with Anthropic if OpenAI fails
response = aigateway.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}]
)
import aigateway
from aigateway import trace, span
@trace(name="my_workflow")
async def process_request(query: str):
# Create spans for sub-operations
with span("retrieve_context"):
context = await retrieve_documents(query)
with span("generate_response"):
response = await generate_answer(query, context)
return response
import aigateway
# Evaluate LLM outputs
result = await aigateway.evaluate(
input_text="What is Python?",
output_text="Python is a programming language...",
metrics=["relevance", "coherence", "toxicity"]
)
print(f"Overall Score: {result.overall_score}")
print(f"Passed: {result.passed}")
for metric in result.metrics:
print(f" {metric.name}: {metric.score:.2f}")
import aigateway
# Track user feedback on responses
aigateway.track_feedback(
trace_id="...",
value="thumbs_up",
comment="Very helpful response!"
)
AIGATEWAY_API_KEY=your-cloud-api-key
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_API_KEY=...
AIGATEWAY_DEFAULT_PROVIDER=openai
AIGATEWAY_STORAGE_BACKEND=sqlite
AIGATEWAY_TRACING_ENABLED=true
AIGATEWAY_CACHE_ENABLED=true
import aigateway
aigateway.init(
# Provider keys
openai_api_key="sk-...",
anthropic_api_key="sk-ant-...",
# Gateway settings
default_provider="openai",
fallback_providers=["anthropic", "google"],
# Tracing
tracing_enabled=True,
sample_rate=1.0,
# Storage (sqlite, postgresql, cloud, memory)
storage_backend="sqlite",
storage_path="./aigateway.db",
# Caching
cache_enabled=True,
cache_backend="memory",
# Debug
debug=False,
)
from aigateway import AIGateway
gateway = AIGateway()
# Async completion
response = await gateway.complete(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}],
temperature=0.7,
max_tokens=1000,
)
# Streaming
async for chunk in gateway.complete_stream(
model="gpt-4",
messages=[{"role": "user", "content": "Tell me a story"}],
):
print(chunk.choices[0].delta.content, end="")
# Embeddings
embeddings = await gateway.embed(
model="text-embedding-3-small",
input="Hello, world!"
)
from aigateway import Trace, Span, SpanKind
# Manual tracing
with Trace(name="my_request", user_id="user123") as trace:
with trace.span("step1", kind=SpanKind.LLM) as span:
span.set_input({"query": "Hello"})
result = do_llm_call()
span.set_output({"response": result})
span.set_llm_info(model="gpt-4", provider="openai")
from aigateway.evaluation import (
Evaluator,
RelevanceMetric,
CoherenceMetric,
ToxicityMetric,
CustomMetric,
)
# Custom evaluator
evaluator = Evaluator(metrics=[
RelevanceMetric(threshold=0.8),
CoherenceMetric(threshold=0.6),
ToxicityMetric(threshold=0.2),
])
result = await evaluator.evaluate(
input_text="...",
output_text="...",
context="...", # Optional
)
from aigateway.storage import SQLiteStorage, CloudStorage, MemoryStorage
# SQLite (local)
storage = SQLiteStorage(db_path="./data.db")
await storage.initialize()
# Cloud (remote)
storage = CloudStorage(
endpoint="https://api.aigateway.io",
api_key="your-api-key"
)
await storage.initialize()
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black src tests
ruff check src tests
# Type checking
mypy src
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE for details.
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
aiosqliteEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | aiosqlite>=0.19.0 | runtime |
contextvarsEnvironment{
"extras": "",
"marker": "python_version < \"3.7\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | contextvars>=2.4; python_version < "3.7" | runtime |
httpxEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | httpx>=0.25.0 | runtime |
pydantic-settingsEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pydantic-settings>=2.0.0 | runtime |
pydanticEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pydantic>=2.0.0 | runtime |
python-dotenvEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | python-dotenv>=1.0.0 | runtime |
structlogEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | structlog>=23.1.0 | runtime |
tenacityEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | tenacity>=8.2.0 | runtime |
tiktokenEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | tiktoken>=0.5.0 | runtime |
anthropicEnvironment{
"extras": "",
"marker": "extra == \"all-providers\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | anthropic>=0.18.0; extra == "all-providers" | runtime |
google-generativeaiEnvironment{
"extras": "",
"marker": "extra == \"all-providers\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | google-generativeai>=0.3.0; extra == "all-providers" | runtime |
openaiEnvironment{
"extras": "",
"marker": "extra == \"all-providers\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | openai>=1.0.0; extra == "all-providers" | runtime |
anthropicEnvironment{
"extras": "",
"marker": "extra == \"anthropic\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | anthropic>=0.18.0; extra == "anthropic" | runtime |
blackEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | black>=23.0.0; extra == "dev" | runtime |
httpxEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | httpx>=0.25.0; extra == "dev" | runtime |
mypyEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | mypy>=1.5.0; extra == "dev" | runtime |
pre-commitEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pre-commit>=3.4.0; extra == "dev" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=0.21.0; extra == "dev" | runtime |
pytest-covEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pytest-cov>=4.1.0; extra == "dev" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | pytest>=7.4.0; extra == "dev" | runtime |
ruffEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | ruff>=0.1.0; extra == "dev" | runtime |
mkdocs-materialEnvironment{
"extras": "",
"marker": "extra == \"docs\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | mkdocs-material>=9.4.0; extra == "docs" | runtime |
mkdocsEnvironment{
"extras": "",
"marker": "extra == \"docs\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | mkdocs>=1.5.0; extra == "docs" | runtime |
mkdocstringsEnvironment{
"extras": "python",
"marker": "extra == \"docs\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | mkdocstrings[python]>=0.23.0; extra == "docs" | runtime |
aigatewayEnvironment{
"extras": "all-providers,dev,docs,postgres,redis,semantic-cache,server",
"marker": "extra == \"full\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | aigateway[all-providers,dev,docs,postgres,redis,semantic-cache,server]; extra == "full" | runtime |
google-generativeaiEnvironment{
"extras": "",
"marker": "extra == \"google\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | google-generativeai>=0.3.0; extra == "google" | runtime |
openaiEnvironment{
"extras": "",
"marker": "extra == \"openai\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | openai>=1.0.0; extra == "openai" | runtime |
asyncpgEnvironment{
"extras": "",
"marker": "extra == \"postgres\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | asyncpg>=0.29.0; extra == "postgres" | runtime |
sqlalchemyEnvironment{
"extras": "asyncio",
"marker": "extra == \"postgres\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | sqlalchemy[asyncio]>=2.0.0; extra == "postgres" | runtime |
redisEnvironment{
"extras": "",
"marker": "extra == \"redis\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | redis>=5.0.0; extra == "redis" | runtime |
numpyEnvironment{
"extras": "",
"marker": "extra == \"semantic-cache\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | numpy>=1.24.0; extra == "semantic-cache" | runtime |
sentence-transformersEnvironment{
"extras": "",
"marker": "extra == \"semantic-cache\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | sentence-transformers>=2.2.0; extra == "semantic-cache" | runtime |
fastapiEnvironment{
"extras": "",
"marker": "extra == \"server\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | fastapi>=0.109.0; extra == "server" | runtime |
python-multipartEnvironment{
"extras": "",
"marker": "extra == \"server\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | python-multipart>=0.0.6; extra == "server" | runtime |
uvicornEnvironment{
"extras": "standard",
"marker": "extra == \"server\"",
"requires_python": ">=3.9",
"evaluation": "NOT_EVALUATED"
} | uvicorn[standard]>=0.27.0; extra == "server" | runtime |
bdist_wheel · 195.47 KB · Python py3
sdist · 165.21 KB · Python source
Observed since 21 Oct, 10:45 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:a07e68466b29eb73d2cc4cabcca01d1c9f4534900ed4f8d5e898c64731cdaff5