Model/infrastructure/openai/openai_client.py

60 lines
1.8 KiB
Python

from __future__ import annotations
import os
from typing import Optional
from openai import OpenAI
from openai.types.chat import ChatCompletionMessageParam
from infrastructure.openai.exceptions import OpenAiClientError
class OpenAiChatClient:
"""Thin wrapper over the OpenAI Chat Completions API.
Sends a single prompt and returns the assistant's reply as plain text.
"""
DEFAULT_MODEL = "gpt-4o-mini"
def __init__(
self,
api_key: Optional[str] = None,
model: Optional[str] = None,
) -> None:
key = api_key or os.environ.get("OPENAI_API_KEY")
if not key:
raise OpenAiClientError(
"No OpenAI API key provided. "
"Pass api_key or set the OPENAI_API_KEY environment variable."
)
self._client = OpenAI(api_key=key)
self._model = model or self.DEFAULT_MODEL
def generate(
self,
prompt: str,
system_prompt: Optional[str] = None,
) -> str:
"""Send a prompt to the model and return its reply text.
Args:
prompt: The user message to send.
system_prompt: Optional instruction that sets the model's behaviour.
Raises:
OpenAiClientError: If the model returns an empty response.
"""
messages: list[ChatCompletionMessageParam] = []
if system_prompt:
messages.append({"role": "system", "content": system_prompt})
messages.append({"role": "user", "content": prompt})
response = self._client.chat.completions.create(
model=self._model,
messages=messages,
)
content = response.choices[0].message.content
if content is None:
raise OpenAiClientError("OpenAI returned an empty response.")
return content