Call hosted LLM and model APIs such as Fireworks AI, OpenAI, and Anthropic from Flyte tasks and apps, with API keys stored as secrets.
Providers
Tasks and apps can call a hosted model API using a key from your own provider account. Billing, rate limits, and data handling stay under your agreement with the provider. You store the key as a secret, and your code reads it from an environment variable at runtime.
Supported providers
These guides cover setup and a complete task for the most common providers:
Other OpenAI-compatible providers
These providers work with the OpenAI SDK by changing the base URL. Start from the Fireworks AI task, and change the base URL, the secret, the environment variable, and the model.
| Provider | Get an API key | Base URL | Conventional variable |
|---|---|---|---|
| Azure OpenAI | Your Azure resource | https://<your-resource>.openai.azure.com/openai/v1/ |
AZURE_OPENAI_API_KEY |
| Gemini API | Google AI Studio | https://generativelanguage.googleapis.com/v1beta/openai/ |
GEMINI_API_KEY |
| Mistral AI | Mistral console, API Keys | https://api.mistral.ai/v1 |
MISTRAL_API_KEY |
| Cohere | API keys | https://api.cohere.ai/compatibility/v1 |
CO_API_KEY |
| Groq | API keys | https://api.groq.com/openai/v1 |
GROQ_API_KEY |
| DeepSeek | DeepSeek platform, API keys | https://api.deepseek.com |
DEEPSEEK_API_KEY |
| Grok API | xAI console, API Keys | https://api.x.ai/v1 |
XAI_API_KEY |
| Perplexity | API keys | https://api.perplexity.ai/v1 |
PERPLEXITY_API_KEY |
| Cerebras | Cerebras Cloud console, API Keys | https://api.cerebras.ai/v1 |
CEREBRAS_API_KEY |
| OpenRouter | API keys | https://openrouter.ai/api/v1 |
OPENROUTER_API_KEY |
| Hugging Face Inference Providers | Access tokens | https://router.huggingface.co/v1 |
HF_TOKEN |
| Nebius Token Factory | Token Factory console | https://api.tokenfactory.nebius.com/v1/ |
NEBIUS_API_KEY |
| Sarvam AI | Key management | https://api.sarvam.ai/v2 |
SARVAM_API_KEY |
| Wafer | Wafer dashboard | https://pass.wafer.ai/v1 |
Your choice |
Two of these differ from the task:
- Azure OpenAI: Set
modelto the name of your deployment, not the name of the underlying model. - Perplexity: Its Agent API uses OpenAI’s Responses format, so call
client.responses.create()instead ofclient.chat.completions.create(). Support for its earlier Sonar Chat Completions API has ended.
Providers with their own SDK
These providers don’t document an OpenAI-compatible endpoint for production use. Add the SDK to the image and pass it the key from the environment. See the Anthropic guide for the pattern.
| Provider | Get an API key | Python package | Conventional variable | Models |
|---|---|---|---|---|
| Anthropic | API keys | anthropic |
ANTHROPIC_API_KEY |
Chat |
| ElevenLabs | API keys | elevenlabs |
ELEVENLABS_API_KEY |
Speech |
| Runway | Developer portal | runwayml |
RUNWAYML_API_SECRET |
Video and image |
| TypeSafe | TypeSafe console | typesafe-sdk |
TYPESAFE_API_KEY |
Typed answers |
Store the API key as a secret
Run this command without --value and paste the key at the prompt, which keeps it out of your shell history:
flyte create secret fireworks-api-key --project <your-project> --domain developmentLeave out --project and --domain to make the secret available across your organization. Prefer a project and domain, so that one team’s tasks can’t use another team’s key.
Check that the secret exists:
flyte get secret --project <your-project> --domain developmentThe output lists metadata such as the name and scope. It never includes the value.
Call the provider from a task
Declare the secret on the environment and read it from the environment variable. This task calls Fireworks AI through the OpenAI SDK:
import asyncio
import os
import flyte
env = flyte.TaskEnvironment(
name="fireworks-inference",
image=flyte.Image.from_debian_base().with_pip_packages("openai"),
secrets=flyte.Secret(key="fireworks-api-key", as_env_var="FIREWORKS_API_KEY"),
)
@env.task
async def summarize(text: str) -> str:
from openai import AsyncOpenAI
client = AsyncOpenAI(
base_url="https://api.fireworks.ai/inference/v1",
api_key=os.environ["FIREWORKS_API_KEY"],
)
response = await client.chat.completions.create(
model="accounts/fireworks/models/glm-5p3-flash",
messages=[{"role": "user", "content": f"Summarize in two sentences:\n\n{text}"}],
)
return response.choices[0].message.content
@env.task
async def main(texts: list[str]) -> list[str]:
return await asyncio.gather(*(summarize(text) for text in texts))
if __name__ == "__main__":
flyte.init_from_config()
run = flyte.run(main, texts=["First document...", "Second document..."])
print(run.url)
A task can only read a secret whose scope covers the project and domain it runs in. Provider model IDs change often, so check the provider’s model catalog for current names.
Call the provider from an app
AppEnvironment takes the same secrets argument, and the app reads the same environment variable:
app_env = FastAPIAppEnvironment(
name="summarizer-api",
app=app,
image=flyte.Image.from_debian_base().with_pip_packages("fastapi", "uvicorn", "openai"),
secrets=flyte.Secret(key="fireworks-api-key", as_env_var="FIREWORKS_API_KEY"),
)
Use a different key for one call
Override the secret for a single invocation when the same task needs different credentials, for example per team:
team_b = summarize.override(
secrets=flyte.Secret(key="fireworks-api-key-team-b", as_env_var="FIREWORKS_API_KEY")
)
result = await team_b(text=text)
The override replaces the environment’s secrets for that call. On a reusable container it raises an error unless you also pass reusable="off". See Overriding secrets.
Keep keys safe
- Never return a key from a task. Task outputs are written in plaintext to your object store and appear in the UI and in downstream tasks.
- Keep keys out of code, task inputs, and
flyte.run()arguments. Inputs are stored and displayed the same way as outputs. - Rotate without downtime. Create a key at the provider, delete and re-create the secret with the new value, redeploy apps that use it, and then revoke the old key.
Troubleshooting
The provider returns 401: The key is invalid, revoked, or was stored with a typo. Test it outside Flyte with the provider’s REST API, then re-create the secret.
The task fails before it runs, with a secret not found error:
The secret’s scope doesn’t cover the task’s project and domain. List secrets with the same --project and --domain the task uses.
The provider returns 429: You’ve reached a rate limit on your provider account. Check its limits and your usage in the provider’s console.