The official openai Python package works with Promptix unchanged. Point it at the Promptix base URL, use your Promptix key, and pick any model id from the catalog.
Install
pip install --upgrade openaiConfigure the client
Set base_url and api_key. Everything else in your code stays the same.
import osfrom openai import OpenAI client = OpenAI( base_url="https://promptix.tn/api/v1", # the only line that changes api_key=os.environ["PROMPTIX_API_KEY"],)Alternatively, without touching the code, set the environment variables the SDK reads by default:
export OPENAI_BASE_URL="https://promptix.tn/api/v1"export OPENAI_API_KEY="$PROMPTIX_API_KEY" # Existing code that calls OpenAI() with no arguments now goes through PromptixChat completion
import osfrom openai import OpenAI client = OpenAI( base_url="https://promptix.tn/api/v1", api_key=os.environ["PROMPTIX_API_KEY"],) completion = client.chat.completions.create( model="anthropic/claude-sonnet-4", messages=[ {"role": "system", "content": "You are a helpful assistant who answers in French."}, {"role": "user", "content": "Explain what a VAT number is in two sentences."}, ], temperature=0.3, max_tokens=300,) print(completion.choices[0].message.content)print(completion.usage.total_tokens, "tokens")Streaming
Pass stream=True and iterate over the chunks. The last chunk carries usage and may have an empty choices list, hence the check. See Streaming.
stream = client.chat.completions.create( model="openai/gpt-4o-mini", messages=[{"role": "user", "content": "List five dishes from Tunisian cuisine."}], stream=True,) for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="", flush=True)Async client
AsyncOpenAI takes the same options. Useful for web servers (FastAPI, Django async views) and batch jobs.
import asyncioimport osfrom openai import AsyncOpenAI client = AsyncOpenAI( base_url="https://promptix.tn/api/v1", api_key=os.environ["PROMPTIX_API_KEY"],) async def summarize(text: str) -> str: completion = await client.chat.completions.create( model="openai/gpt-4o-mini", messages=[{"role": "user", "content": f"Summarize in one sentence:\n\n{text}"}], max_tokens=100, ) return completion.choices[0].message.content async def main(): texts = ["First document...", "Second document...", "Third document..."] # Keep concurrency modest: providers rate-limit bursts semaphore = asyncio.Semaphore(4) async def bounded(t: str) -> str: async with semaphore: return await summarize(t) for summary in await asyncio.gather(*(bounded(t) for t in texts)): print(summary) asyncio.run(main())Structured output
On models that support JSON schema output, the SDK's parse helper returns typed objects:
from pydantic import BaseModel class Invoice(BaseModel): city: str amount_tnd: float completion = client.chat.completions.parse( model="openai/gpt-4o-mini", messages=[{"role": "user", "content": "Invoice from Sousse, total due 245.500 dinars."}], response_format=Invoice,) invoice = completion.choices[0].message.parsedprint(invoice.city, invoice.amount_tnd)Errors and retries
The SDK retries 408, 409, 429 and 5xx responses twice by default (set max_retries on the client to change it) and raises typed exceptions. Promptix-specific cases are described in Errors and limits.
import openai try: completion = client.chat.completions.create( model="openai/gpt-4o-mini", messages=[{"role": "user", "content": "Hello"}], )except openai.AuthenticationError: ... # 401: invalid or revoked keyexcept openai.RateLimitError: ... # 429: provider throttling (already retried by the SDK)except openai.APIStatusError as e: if e.status_code == 402: ... # balance too low, or key_monthly_limit reached raiseWhat is not available
Promptix exposes chat completions. Other OpenAI endpoints (embeddings, images, audio, responses, files, models.list()) are not available through the Promptix base URL. To list models, use the public model list.