mistralai
mistralai is the official Python SDK for the Mistral AI platform (La Plateforme): chat completions, embeddings, vision, OCR, transcription, fine-tuning, file management, and the beta agents and conversations APIs. It is generated with Speakeasy from the OpenAPI spec, which means complete endpoint coverage, typed Pydantic models, sync and async variants of every call, and built-in retry configuration, but also a generated-code feel rather than a hand-crafted one. Version 2 renamed the import path to mistralai.client and shipped breaking changes documented in a migration guide. Subclients exist for Azure AI and Google Cloud Vertex deployments of Mistral models.
The right client if you are committed to Mistral's platform and want full endpoint coverage with types. If multi-provider flexibility matters more than day-one access to Mistral-specific features, an OpenAI-compatible layer keeps your options open.
Use it if
- You are calling Mistral models (mistral-large, mistral-medium, codestral, mistral-embed) and want first-party, fully typed access to every endpoint including OCR, transcription, and fine-tuning
- You need both sync and async in one client; every method has a _async twin on the same Mistral object, so mixed codebases do not need two libraries
- You use the beta agents and conversations APIs, which third-party wrappers lag behind or skip entirely
- You deploy Mistral through Azure AI or Vertex; the MistralAzure and MistralGoogleCloud subclients handle those endpoints' auth and routing
- You want provider portability; the OpenAI-compatible surface via litellm or the openai SDK pointed at Mistral's endpoint lets you swap vendors without rewriting call sites
- You are mid-project on v1: v2 changed the import path (mistralai to mistralai.client) and other breaking details, so upgrading is a migration task, not a version bump, and most tutorials online still show v1 imports
- You prefer curated, hand-written SDK ergonomics; generated code brings verbose method signatures and occasional oddities (the README's own retry example contains a syntax error), and the repo is small with 21 open issues but limited community activity
- You are building on LangChain or similar; langchain-mistralai is the integration those frameworks expect, and using both adds a second client for no benefit
Setup reality
pip install mistralai is light (httpx and pydantic underneath) and needs Python 3.10+. The gotchas are versioning, not installation: v2 code imports from mistralai.client while v1 and nearly every blog post import from mistralai, so copy-pasted examples fail with ImportError until you notice. The agents features need the extra pip install "mistralai[agents]", the client is a context manager you should close or wrap in with, and streaming responses are generator context managers with a different consumption pattern than OpenAI's SDK.
Patterns
Basic chat completionchat-completion
import os
from mistralai.client import Mistral
with Mistral(api_key=os.environ["MISTRAL_API_KEY"]) as mistral:
res = mistral.chat.complete(
model="mistral-large-latest",
messages=[{"role": "user", "content": "Say hi in French."}],
)
print(res.choices[0].message.content)In v2 the import is from mistralai.client, not from mistralai; the old path is the top ImportError source when following v1-era tutorials. The with block closes the underlying httpx client.
Async variant of any callasync-chat-completion
import asyncio, os
from mistralai.client import Mistral
async def main():
async with Mistral(api_key=os.environ["MISTRAL_API_KEY"]) as mistral:
res = await mistral.chat.complete_async(
model="mistral-large-latest",
messages=[{"role": "user", "content": "Hello"}],
)
print(res.choices[0].message.content)
asyncio.run(main())Every sync method has an _async twin on the same client class; there is no separate AsyncMistral. Use async with so the connection pool is cleaned up.
Stream a chat responsestream-chat-tokens
import os
from mistralai.client import Mistral
with Mistral(api_key=os.environ["MISTRAL_API_KEY"]) as mistral:
stream = mistral.chat.stream(
model="mistral-large-latest",
messages=[{"role": "user", "content": "Write a haiku"}],
)
with stream as events:
for event in events:
print(event.data.choices[0].delta.content or "", end="")The stream is itself a context manager; iterate inside with so the SSE connection closes. Deltas live at event.data.choices[0].delta, one level deeper than OpenAI's SDK.
Embed a batch of textscreate-embeddings
import os
from mistralai.client import Mistral
with Mistral(api_key=os.environ["MISTRAL_API_KEY"]) as mistral:
res = mistral.embeddings.create(
model="mistral-embed",
inputs=["Embed this sentence.", "As well as this one."],
)
vectors = [d.embedding for d in res.data]The parameter is inputs (plural, a list), not input as in some other SDKs. mistral-embed returns 1024-dimensional vectors.
Force JSON outputjson-mode-output
import json, os
from mistralai.client import Mistral
with Mistral(api_key=os.environ["MISTRAL_API_KEY"]) as mistral:
res = mistral.chat.complete(
model="mistral-large-latest",
messages=[{"role": "user", "content": "List 3 EU capitals as JSON with a capitals array"}],
response_format={"type": "json_object"},
)
data = json.loads(res.choices[0].message.content)json_object guarantees syntactically valid JSON, not your schema; describe the shape in the prompt and validate with pydantic. The API also supports json_schema for strict structured output on newer models.
Ask a question about an imagevision-image-input
import os
from mistralai.client import Mistral
with Mistral(api_key=os.environ["MISTRAL_API_KEY"]) as mistral:
res = mistral.chat.complete(
model="pixtral-large-latest",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "What is in this image?"},
{"type": "image_url", "image_url": "https://example.com/photo.jpg"},
],
}],
)
print(res.choices[0].message.content)Only vision-capable models (pixtral family, mistral-medium and up) accept image_url parts; text-only models reject the request. Base64 data URLs also work for local files.
Upload a file to the platformupload-file
import os
from mistralai.client import Mistral
with Mistral(api_key=os.environ["MISTRAL_API_KEY"]) as mistral:
res = mistral.files.upload(
file={
"file_name": "training.jsonl",
"content": open("training.jsonl", "rb"),
},
)
print(res.id)Pass an open binary file object as content so large files stream instead of loading into memory. Uploaded files feed fine-tuning, OCR, and document QA endpoints.
Catch and inspect API errorshandle-api-errors
import os
from mistralai.client import Mistral, errors
with Mistral(api_key=os.environ["MISTRAL_API_KEY"]) as mistral:
try:
res = mistral.chat.complete(
model="mistral-large-latest",
messages=[{"role": "user", "content": "hi"}],
)
except errors.MistralError as e:
print(e.status_code) # e.g. 429
print(e.message)
print(e.body)MistralError is the base class for all HTTP errors and exposes status_code, headers, body, and raw_response. Rate limits surface as 429s here, and the SDK does not retry them unless you configure retries.
Add retry with backoff to all callsconfigure-retries
import os
from mistralai.client import Mistral
from mistralai.client.utils import BackoffStrategy, RetryConfig
mistral = Mistral(
api_key=os.environ["MISTRAL_API_KEY"],
retry_config=RetryConfig(
"backoff",
BackoffStrategy(
initial_interval=1,
max_interval=50,
exponent=1.1,
max_elapsed_time=100,
),
False,
),
)retry_config on the constructor applies to every operation that supports retries; a RetryConfig can also be passed per call. The final bool is retry_connection_errors.
Start a conversation with the beta agents APIagents-conversation
import os
from mistralai.client import Mistral
# needs: pip install "mistralai[agents]"
with Mistral(api_key=os.environ["MISTRAL_API_KEY"]) as mistral:
res = mistral.beta.conversations.start(
inputs="Plan a 3-day trip to Lisbon",
model="mistral-large-latest",
)
print(res.outputs)Conversations keep server-side state, so you append to them by id instead of resending history. Everything under mistral.beta can change without a major version bump; pin accordingly.
Call a Mistral model deployed on Azure AIazure-deployment
import os
from mistralai.azure.client import MistralAzure
client = MistralAzure(
api_key=os.environ["AZURE_API_KEY"],
server_url=os.environ["AZURE_ENDPOINT"],
)
res = client.chat.complete(
model=os.environ["AZURE_MODEL"],
messages=[{"role": "user", "content": "Hello there!"}],
)
print(res.choices[0].message.content)The Azure subclient only exposes chat; platform features like files and fine-tuning stay on La Plateforme. MistralGoogleCloud is the equivalent for Vertex.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| openai | PyPI | You want one familiar SDK shape and call Mistral through an OpenAI-compatible endpoint |
| litellm | PyPI | You call several providers and want a single OpenAI-format interface with fallbacks and cost tracking |
| langchain-mistralai | PyPI | You are already in the LangChain or LangGraph ecosystem and need its ChatMistralAI integration |