Last verified: July 18, 2026
You can call LumeAPI from Python with the official OpenAI client by setting base_url to https://api.lumeapi.site/v1, loading your LumeAPI key from an environment variable, and choosing a model ID from the [LumeAPI model catalog](/models). Existing Chat Completions code usually needs only three changes: the API key, base URL, and model name.
This guide takes you from a minimal request to streaming and production-ready error handling. It uses Chat Completions because that is the OpenAI-compatible text endpoint currently documented by LumeAPI.
What you need
Before writing code, prepare:
- Python 3.9 or newer.
- A LumeAPI account and API key.
- A model available in the [LumeAPI documentation](/docs).
- The current
openaiPython package.
Install or upgrade the SDK:
python -m pip install --upgrade openaiThe official OpenAI Python library supports a custom base_url, so you do not need a provider-specific client just to use an OpenAI-compatible gateway.
Store the API key outside your code
Do not paste an API key into a Python file or commit it to Git. Set a local environment variable instead.
On macOS or Linux:
export LUMEAPI_KEY='your-lumeapi-key'In PowerShell:
$env:LUMEAPI_KEY = 'your-lumeapi-key'For a deployed application, store the key in your hosting platform's secret manager. Keep development, staging, and production keys separate when your deployment process supports it.
Send your first Python request
Create app.py:
import os
from openai import OpenAI
api_key = os.environ.get('LUMEAPI_KEY')
if not api_key:
raise RuntimeError('Set LUMEAPI_KEY before running this script.')
client = OpenAI(
api_key=api_key,
base_url='https://api.lumeapi.site/v1',
)
completion = client.chat.completions.create(
model='gpt-5.4-mini',
messages=[
{
'role': 'user',
'content': 'Explain what an API gateway does in two sentences.',
}
],
)
print(completion.choices[0].message.content)Run it:
python app.pyThe OpenAI client combines the configured base URL with the Chat Completions path. The resulting request is sent to https://api.lumeapi.site/v1/chat/completions.
The response keeps the familiar Chat Completions shape, so the generated text is available at completion.choices[0].message.content.
Make the model configurable
Hard-coding a model is acceptable for a minimal example, but an environment variable makes testing and deployment safer.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ['LUMEAPI_KEY'],
base_url='https://api.lumeapi.site/v1',
)
model = os.getenv('LUMEAPI_MODEL', 'gpt-5.4-mini')
completion = client.chat.completions.create(
model=model,
messages=[
{'role': 'system', 'content': 'Answer clearly and concisely.'},
{'role': 'user', 'content': 'Give me three names for a coding assistant.'},
],
)
print(completion.choices[0].message.content)You can then switch models without editing the file:
export LUMEAPI_MODEL='gpt-5.6-terra'
python app.pyCurrent examples in the LumeAPI catalog include gpt-5.4-mini, gpt-5.6-terra, claude-sonnet-4-6, and gemini-3.5-flash. Availability can change, so confirm the exact model ID in the [model documentation](/docs) before deployment. Do not translate a display name into a guessed ID.
Stream the answer as it is generated
Streaming improves perceived responsiveness in chat interfaces because your application can display text before the full response is complete.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ['LUMEAPI_KEY'],
base_url='https://api.lumeapi.site/v1',
)
stream = client.chat.completions.create(
model=os.getenv('LUMEAPI_MODEL', 'gpt-5.4-mini'),
messages=[
{'role': 'user', 'content': 'Write a four-line welcome message.'}
],
stream=True,
)
for chunk in stream:
if not chunk.choices:
continue
text = chunk.choices[0].delta.content
if text:
print(text, end='', flush=True)
print()A streaming chunk may not contain text, so check choices and delta.content before printing. In a web application, forward these chunks to the browser with Server-Sent Events or a streaming HTTP response instead of concatenating the entire result on the server.
Add timeouts, retries, and useful error handling
A production service should not rely on an unlimited wait or return the same generic error for every failure. Configure an explicit timeout and handle authentication, rate limiting, network failures, and provider responses separately.
import os
import openai
from openai import OpenAI
client = OpenAI(
api_key=os.environ['LUMEAPI_KEY'],
base_url='https://api.lumeapi.site/v1',
timeout=30.0,
max_retries=2,
)
def generate_answer(question: str) -> str:
try:
completion = client.chat.completions.create(
model=os.getenv('LUMEAPI_MODEL', 'gpt-5.4-mini'),
messages=[{'role': 'user', 'content': question}],
)
return completion.choices[0].message.content or ''
except openai.AuthenticationError as exc:
raise RuntimeError(
'Authentication failed. Check LUMEAPI_KEY and its environment.'
) from exc
except openai.RateLimitError as exc:
raise RuntimeError(
'The request was rate limited. Retry later with backoff.'
) from exc
except openai.APITimeoutError as exc:
raise RuntimeError(
'The model request timed out. Retry or choose a faster model.'
) from exc
except openai.APIConnectionError as exc:
raise RuntimeError(
'Could not reach the API gateway. Check DNS and network access.'
) from exc
except openai.APIStatusError as exc:
request_id = getattr(exc, 'request_id', None)
raise RuntimeError(
f'API returned HTTP {exc.status_code}; request_id={request_id}'
) from exc
print(generate_answer('What should an API health check verify?'))The official Python SDK retries selected transient failures automatically, but retry policy is still an application decision. Keep the retry count bounded, add exponential backoff and jitter for high-concurrency workloads, and never retry a bad API key or invalid model name indefinitely. For a broader production strategy, see [LLM API timeouts, 429s, and provider failures](/research/handle-llm-api-timeouts-429-errors-provider-failures-production-lumeapi).
Common problems
401 authentication error
Confirm that LUMEAPI_KEY exists in the same process that runs Python. Printing the whole key is unsafe; log only whether the variable is present. Also verify that the client uses the LumeAPI key rather than an unrelated provider key.
404 or model-not-found error
Check the exact model ID in the live catalog. A marketing name and an API model ID are not always identical. Also confirm that base_url includes /v1.
429 rate-limit response
Reduce concurrent requests, use bounded backoff, and inspect whether the limit applies to the account, model, or upstream provider. Queue background work instead of making every caller retry at the same moment.
The script still calls api.openai.com
Make sure base_url='https://api.lumeapi.site/v1' is passed to the OpenAI constructor used by the request. If your project creates clients in several modules, centralize client construction so one file owns the base URL.
The program prints None while streaming
Not every stream event contains a text delta. Ignore chunks without choices or without delta.content, as shown in the streaming example.
A small reusable client module
Centralizing configuration prevents different parts of an application from silently using different endpoints, timeouts, or models.
# lume_client.py
import os
from openai import OpenAI
LUMEAPI_BASE_URL = 'https://api.lumeapi.site/v1'
DEFAULT_MODEL = 'gpt-5.4-mini'
def get_client() -> OpenAI:
return OpenAI(
api_key=os.environ['LUMEAPI_KEY'],
base_url=LUMEAPI_BASE_URL,
timeout=30.0,
max_retries=2,
)
def get_model() -> str:
return os.getenv('LUMEAPI_MODEL', DEFAULT_MODEL)Application code can import get_client() and get_model() instead of repeating gateway configuration. This also makes it easier to replace the client with a test double during unit tests.
Production checklist
Before sending real traffic:
- Keep the API key in a secret manager or environment variable.
- Pin and periodically update the Python SDK version.
- Verify model IDs against the live catalog.
- Set a request timeout appropriate for the workload.
- Retry only transient failures with bounded exponential backoff.
- Log HTTP status, latency, selected model, and request ID when available.
- Avoid logging prompts or model output if they may contain sensitive data.
- Add spend, error-rate, and latency alerts.
- Test a fallback or queueing strategy before a provider incident.
Can existing OpenAI Python code be migrated?
Usually, yes. If an application already uses client.chat.completions.create, start by changing the client key, base_url, and model ID. Then test the exact parameters your application uses. OpenAI compatibility covers the common request and response shape; it does not mean every provider-specific feature or model parameter is identical.
Review the [OpenAI-compatible API overview](/openai-compatible-api), the [LumeAPI docs](/docs), and the selected model's documentation before production rollout.
Sources and verification
- [LumeAPI documentation](/docs) for the gateway base URL, endpoint, and current model IDs.
- [Official OpenAI Python library](https://github.com/openai/openai-python) for client initialization, Chat Completions, streaming, retries, timeout configuration, and error classes.
The examples in this article were checked for Python syntax and current documented SDK structure on July 18, 2026. A billable end-to-end request requires a customer LumeAPI key, so model output and latency are intentionally not claimed here.