omnirouter-api / src /providers /openai_client.py
sumitrwk's picture
Upload 33 files
b534a53 verified
from openai import AsyncOpenAI
import logging
# Import our strict schemas and base blueprint
from src.schemas import RouterConfig, LLMResponse
from src.providers.base import BaseLLMProvider
# Set up logging for professional debugging
logger = logging.getLogger(__name__)
class OpenAIProvider(BaseLLMProvider):
"""
The concrete implementation for OpenAI's API.
How it strictly fulfills the contract defined in BaseLLMProvider.
"""
def __init__(self, api_key: str):
# Call the parent class initialization
super().__init__(api_key)
# CRITICAL: We initialize the ASYNC client, not the standard synchronous one.
# This is what allows our router to handle hundreds of concurrent requests.
self.client = AsyncOpenAI(api_key=self.api_key)
async def async_generate(self, prompt: str, config: RouterConfig) -> LLMResponse:
logger.info(f"Routing request to OpenAI using model: {config.model}")
# 1. Execute the Async API Call
response = await self.client.chat.completions.create(
model=config.model,
messages=[{"role": "user", "content": prompt}],
temperature=config.temperature,
# We will add top_p, frequency_penalty, etc. later as needed
)
# 2. Extract Data from OpenAI's specific object structure
content = response.choices[0].message.content
prompt_tokens = response.usage.prompt_tokens
completion_tokens = response.usage.completion_tokens
# 3. Calculate Cost dynamically
cost = self.calculate_cost(prompt_tokens, completion_tokens, config.model)
# 4. Standardize the Output
# We transform OpenAI's proprietary response into our universal LLMResponse schema.
# Now, the rest of our application doesn't need to know anything about OpenAI's specific formatting.
return LLMResponse(
content=content,
provider_used="openai",
model_used=config.model,
prompt_tokens=prompt_tokens,
completion_tokens=completion_tokens,
cost_estimate=cost
)
def calculate_cost(self, prompt_tokens: int, completion_tokens: int, model_name: str) -> float:
"""
Calculates the exact cost of the API call based on OpenAI's pricing (per 1M tokens).
This is a massive value-add for your open-source repository.
"""
# A dictionary acting as a simple pricing database
pricing = {
"gpt-4-turbo": {"prompt": 10.0, "completion": 30.0},
"gpt-4o": {"prompt": 5.0, "completion": 15.0},
"gpt-3.5-turbo": {"prompt": 0.5, "completion": 1.5}
}
# If they use a model not in our dict, default to 0.0 to prevent crashes
rates = pricing.get(model_name, {"prompt": 0.0, "completion": 0.0})
# Math: (tokens / 1,000,000) * rate
cost = (prompt_tokens / 1_000_000) * rates["prompt"] + \
(completion_tokens / 1_000_000) * rates["completion"]
return round(cost, 6)