Skip to content

Commit 969c992

Browse files
authored
feat!: align Azure/GCP SDKs with namespace vision (API-1988) (#351)
Migrate Azure/GCP provider SDKs to PEP 420 namespace sub-packages: - mistralai_azure → mistralai.azure.client.MistralAzure - mistralai_gcp → mistralai.gcp.client.MistralGCP Azure: auto-inject api_version query param, warn on custom client conflict GCP: auto-detect credentials via google.auth.default(), refresh tokens only when expired, dynamically construct Vertex AI paths from model name Added 348 parity tests, async FIM integration tests, lint coverage for provider packages.
1 parent 8490078 commit 969c992

File tree

390 files changed

+4238
-2521
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

390 files changed

+4238
-2521
lines changed

.genignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pyproject.toml
22
examples/*
33
/utils/*
4-
src/mistral/extra/*
4+
src/mistralai/extra/*
55
pylintrc
66
scripts/prepare_readme.py

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ repos:
44
hooks:
55
- id: ruff
66
args: [--fix]
7-
files: ^(example/|src/mistralai/).*\.py$
7+
files: ^(examples/|src/mistralai/|packages/(azure|gcp)/src/mistralai/).*\.py$
88
exclude: ^src/mistralai/(__init__|sdkhooks|types)\.py$
99
- repo: https://github.com/RobertCraigie/pyright-python
1010
rev: v1.1.401
1111
hooks:
1212
- id: pyright
13-
files: ^(example/|src/mistralai/).*\.py$
13+
files: ^(examples/|src/mistralai/|packages/(azure|gcp)/src/mistralai/).*\.py$
1414
exclude: ^src/mistralai/(__init__|sdkhooks|types)\.py$
1515
- repo: https://github.com/pre-commit/mirrors-mypy
1616
rev: v1.15.0
1717
hooks:
1818
- id: mypy
19-
files: ^(example/|src/mistralai/).*\.py$
19+
files: ^(examples/|src/mistralai/|packages/(azure|gcp)/src/mistralai/).*\.py$
2020
exclude: ^src/mistralai/(__init__|sdkhooks|types)\.py$

.speakeasy/workflow.lock

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ speakeasyVersion: 1.685.0
22
sources:
33
mistral-azure-source:
44
sourceNamespace: mistral-openapi-azure
5-
sourceRevisionDigest: sha256:d303e640ad565cc8a9801519b20dc7eab226efdfdab951c11256962d9e479f74
6-
sourceBlobDigest: sha256:6e4c789de61b2c9c604bf581e0abbadae90e360491d95ec4247678f4f70cee87
5+
sourceRevisionDigest: sha256:e32d21a6317d1bca6ab29f05603b96038e841752c2698aab47f434ea0d6530b7
6+
sourceBlobDigest: sha256:2dad2b1b7a79de6917c363ce7e870d11efe31ac08e3bfe0258f72823fe1ad13e
77
tags:
88
- latest
99
mistral-google-cloud-source:
1010
sourceNamespace: mistral-openapi-google-cloud
11-
sourceRevisionDigest: sha256:351c4d392b8b2220c337a207e98ed5665ed27fd85de854871a70c4bc2b9c0784
12-
sourceBlobDigest: sha256:d79b21f70efb93b0cd261d2044939a288beaf8707a7caae86aca5c4d5de3821b
11+
sourceRevisionDigest: sha256:4d9938ab74c4d41d62cd24234c8b8109e286c4aeec093e21d369259a43173113
12+
sourceBlobDigest: sha256:5a558d5ea7a936723c7a5540db5a1fba63d85d25b453372e1cf16395b30c98d3
1313
tags:
1414
- latest
1515
mistral-openapi:
@@ -22,24 +22,24 @@ targets:
2222
mistralai-azure-sdk:
2323
source: mistral-azure-source
2424
sourceNamespace: mistral-openapi-azure
25-
sourceRevisionDigest: sha256:d303e640ad565cc8a9801519b20dc7eab226efdfdab951c11256962d9e479f74
26-
sourceBlobDigest: sha256:6e4c789de61b2c9c604bf581e0abbadae90e360491d95ec4247678f4f70cee87
25+
sourceRevisionDigest: sha256:e32d21a6317d1bca6ab29f05603b96038e841752c2698aab47f434ea0d6530b7
26+
sourceBlobDigest: sha256:2dad2b1b7a79de6917c363ce7e870d11efe31ac08e3bfe0258f72823fe1ad13e
2727
codeSamplesNamespace: mistral-openapi-azure-code-samples
28-
codeSamplesRevisionDigest: sha256:0109302b87fa17b0103ef1e372fae76356811b3c552103e659bd5373d537d759
28+
codeSamplesRevisionDigest: sha256:a34c3049c604d0bb67101d042e959f14098964fe784f98975a9201c84dbf44d0
2929
mistralai-gcp-sdk:
3030
source: mistral-google-cloud-source
3131
sourceNamespace: mistral-openapi-google-cloud
32-
sourceRevisionDigest: sha256:351c4d392b8b2220c337a207e98ed5665ed27fd85de854871a70c4bc2b9c0784
33-
sourceBlobDigest: sha256:d79b21f70efb93b0cd261d2044939a288beaf8707a7caae86aca5c4d5de3821b
32+
sourceRevisionDigest: sha256:4d9938ab74c4d41d62cd24234c8b8109e286c4aeec093e21d369259a43173113
33+
sourceBlobDigest: sha256:5a558d5ea7a936723c7a5540db5a1fba63d85d25b453372e1cf16395b30c98d3
3434
codeSamplesNamespace: mistral-openapi-google-cloud-code-samples
35-
codeSamplesRevisionDigest: sha256:09bb7cbf291076170d228116db05d1c9606af541b301b6564609c4d76633258a
35+
codeSamplesRevisionDigest: sha256:fa36e5999e79c32e8b2c1317cc0d6ed179912ced15194f02b5f80da22e45ae5f
3636
mistralai-sdk:
3737
source: mistral-openapi
3838
sourceNamespace: mistral-openapi
3939
sourceRevisionDigest: sha256:74d0de7750f6a1878b68c9da683eba7a447d7c367131d0cb8f5c3b1e05829624
4040
sourceBlobDigest: sha256:41e8354c48993fc29be68959d835ea4f8e0cc1d4b4fbd527afcd970bc02c62a2
4141
codeSamplesNamespace: mistral-openapi-code-samples
42-
codeSamplesRevisionDigest: sha256:f37fb6188ad25957bef4cadaa03f454a4f9ab0c045db633a46d9cc89af145ba2
42+
codeSamplesRevisionDigest: sha256:99fcae1bc81801e3825648a44f5ffa62a8f124e3186e5570be40414de164e7f2
4343
workflow:
4444
workflowVersion: 1.0.0
4545
speakeasyVersion: 1.685.0
@@ -57,7 +57,7 @@ workflow:
5757
mistralai-azure-sdk:
5858
target: python
5959
source: mistral-azure-source
60-
output: ./packages/mistralai_azure
60+
output: ./packages/azure
6161
publish:
6262
pypi:
6363
token: $pypi_token
@@ -68,7 +68,7 @@ workflow:
6868
mistralai-gcp-sdk:
6969
target: python
7070
source: mistral-google-cloud-source
71-
output: ./packages/mistralai_gcp
71+
output: ./packages/gcp
7272
publish:
7373
pypi:
7474
token: $pypi_token

.speakeasy/workflow.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ targets:
1414
mistralai-azure-sdk:
1515
target: python
1616
source: mistral-azure-source
17-
output: ./packages/mistralai_azure
17+
output: ./packages/azure
1818
publish:
1919
pypi:
2020
token: $pypi_token
@@ -25,7 +25,7 @@ targets:
2525
mistralai-gcp-sdk:
2626
target: python
2727
source: mistral-google-cloud-source
28-
output: ./packages/mistralai_gcp
28+
output: ./packages/gcp
2929
publish:
3030
pypi:
3131
token: $pypi_token

MIGRATION.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,26 @@ from mistralai.client.types import BaseModel
3333
| `from mistralai.types import ...` | `from mistralai.client.types import ...` |
3434
| `from mistralai.utils import ...` | `from mistralai.client.utils import ...` |
3535

36+
### Azure & GCP Import Changes
37+
38+
Azure and GCP SDKs now live under the `mistralai` namespace as separate distributions:
39+
40+
| v1 | v2 |
41+
|---|---|
42+
| `from mistralai_azure import MistralAzure` | `from mistralai.azure.client import MistralAzure` |
43+
| `from mistralai_azure.models import ...` | `from mistralai.azure.client.models import ...` |
44+
| `from mistralai_gcp import MistralGoogleCloud` | `from mistralai.gcp.client import MistralGCP` |
45+
| `from mistralai_gcp.models import ...` | `from mistralai.gcp.client.models import ...` |
46+
47+
#### Installation Changes
48+
49+
| v1 | v2 |
50+
|---|---|
51+
| `pip install mistralai` | `pip install mistralai` (includes Azure and GCP) |
52+
| `pip install mistralai[gcp]` (for GCP auth) | `pip install "mistralai[gcp]"` (for GCP auth dependencies) |
53+
54+
Azure and GCP are now standalone distributions that can be installed independently of the core SDK. The `mistralai[azure]` and `mistralai[gcp]` extras are syntactic sugar that pull in the respective distributions.
55+
3656
### What Stays the Same
3757

3858
- The `Mistral` client API is unchanged

README.md

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ It's also possible to write a standalone Python script without needing to set up
104104
```python
105105
#!/usr/bin/env -S uv run --script
106106
# /// script
107-
# requires-python = ">=3.9"
107+
# requires-python = ">=3.10"
108108
# dependencies = [
109109
# "mistralai",
110110
# ]
@@ -374,38 +374,41 @@ You can run the examples in the `examples/` directory using `uv run`.
374374

375375
**Prerequisites**
376376

377-
Before you begin, ensure you have `AZUREAI_ENDPOINT` and an `AZURE_API_KEY`. To obtain these, you will need to deploy Mistral on Azure AI.
377+
Before you begin, ensure you have `AZURE_ENDPOINT` and an `AZURE_API_KEY`. To obtain these, you will need to deploy Mistral on Azure AI.
378378
See [instructions for deploying Mistral on Azure AI here](https://docs.mistral.ai/deployment/cloud/azure/).
379379

380+
**Step 1: Install**
381+
382+
```bash
383+
pip install mistralai
384+
```
385+
386+
**Step 2: Example Usage**
387+
380388
Here's a basic example to get you started. You can also run [the example in the `examples` directory](/examples/azure).
381389

382390
```python
383-
import asyncio
384391
import os
392+
from mistralai.azure.client import MistralAzure
385393

386-
from mistralai_azure import MistralAzure
387-
394+
# The SDK automatically injects api-version as a query parameter
388395
client = MistralAzure(
389-
azure_api_key=os.getenv("AZURE_API_KEY", ""),
390-
azure_endpoint=os.getenv("AZURE_ENDPOINT", "")
396+
api_key=os.environ["AZURE_API_KEY"],
397+
server_url=os.environ["AZURE_ENDPOINT"],
398+
api_version="2024-05-01-preview", # Optional, this is the default
391399
)
392400

393-
async def main() -> None:
394-
res = await client.chat.complete_async(
395-
max_tokens= 100,
396-
temperature= 0.5,
397-
messages= [
398-
{
399-
"content": "Hello there!",
400-
"role": "user"
401-
}
402-
]
403-
)
404-
print(res)
405-
406-
asyncio.run(main())
401+
res = client.chat.complete(
402+
model=os.environ["AZURE_MODEL"],
403+
messages=[
404+
{
405+
"role": "user",
406+
"content": "Hello there!",
407+
}
408+
],
409+
)
410+
print(res.choices[0].message.content)
407411
```
408-
The documentation for the Azure SDK is available [here](packages/mistralai_azure/README.md).
409412

410413
### Google Cloud
411414

@@ -422,40 +425,43 @@ gcloud auth application-default login
422425

423426
**Step 1: Install**
424427

425-
Install the extras dependencies specific to Google Cloud:
426-
427428
```bash
429+
pip install mistralai
430+
# For GCP authentication support (required):
428431
pip install "mistralai[gcp]"
429432
```
430433

431434
**Step 2: Example Usage**
432435

433-
Here's a basic example to get you started.
434-
435-
```python
436-
import asyncio
437-
from mistralai_gcp import MistralGoogleCloud
436+
Here's a basic example to get you started. You can also run [the example in the `examples` directory](/examples/gcp).
438437

439-
client = MistralGoogleCloud()
438+
The SDK automatically:
439+
- Detects credentials via `google.auth.default()`
440+
- Auto-refreshes tokens when they expire
441+
- Builds the Vertex AI URL from `project_id` and `region`
440442

443+
```python
444+
import os
445+
from mistralai.gcp.client import MistralGCP
441446

442-
async def main() -> None:
443-
res = await client.chat.complete_async(
444-
model= "mistral-small-2402",
445-
messages= [
446-
{
447-
"content": "Hello there!",
448-
"role": "user"
449-
}
450-
]
451-
)
452-
print(res)
447+
# The SDK auto-detects credentials and builds the Vertex AI URL
448+
client = MistralGCP(
449+
project_id=os.environ.get("GCP_PROJECT_ID"), # Optional: auto-detected from credentials
450+
region="us-central1", # Default: europe-west4
451+
)
453452

454-
asyncio.run(main())
453+
res = client.chat.complete(
454+
model="mistral-small-2503",
455+
messages=[
456+
{
457+
"role": "user",
458+
"content": "Hello there!",
459+
}
460+
],
461+
)
462+
print(res.choices[0].message.content)
455463
```
456464

457-
The documentation for the GCP SDK is available [here](packages/mistralai_gcp/README.md).
458-
459465

460466
<!-- Start Available Resources and Operations [operations] -->
461467
## Available Resources and Operations
@@ -674,8 +680,8 @@ with Mistral(
674680
api_key=os.getenv("MISTRAL_API_KEY", ""),
675681
) as mistral:
676682

677-
res = mistral.models.list(,
678-
RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False))
683+
res = mistral.models.list(
684+
retries=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False))
679685

680686
# Handle response
681687
print(res)

examples/azure/.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
AZURE_API_KEY=your-azure-api-key
2+
AZURE_ENDPOINT=https://your-endpoint.services.ai.azure.com/models
3+
AZURE_MODEL=your-deployment-name
4+
AZURE_API_VERSION=2024-05-01-preview

examples/azure/az_chat_no_streaming.py

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
import os
22

3-
from mistralai_azure import MistralAzure
4-
from mistralai_azure.models import ChatCompletionRequestMessages, UserMessage
3+
from mistralai.azure.client import MistralAzure
4+
from mistralai.azure.client.models import ChatCompletionRequestMessage, UserMessage
55

6+
AZURE_API_KEY = os.environ.get("AZURE_API_KEY", "")
7+
AZURE_ENDPOINT = os.environ.get("AZURE_ENDPOINT", "")
8+
AZURE_MODEL = os.environ.get("AZURE_MODEL", "mistral-small-2503")
9+
AZURE_API_VERSION = os.environ.get("AZURE_API_VERSION", "2024-05-01-preview")
10+
11+
# The SDK automatically injects api-version as a query parameter
612
client = MistralAzure(
7-
azure_api_key=os.environ["AZURE_API_KEY"],
8-
azure_endpoint=os.environ["AZURE_ENDPOINT"],
13+
api_key=AZURE_API_KEY,
14+
server_url=AZURE_ENDPOINT,
15+
api_version=AZURE_API_VERSION,
916
)
1017

11-
messages: list[ChatCompletionRequestMessages] = [
18+
messages: list[ChatCompletionRequestMessage] = [
1219
UserMessage(content="What is the capital of France?"),
1320
]
14-
res = client.chat.complete(messages=messages)
21+
res = client.chat.complete(model=AZURE_MODEL, messages=messages)
1522
print(res.choices[0].message.content)

examples/gcp/.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
GCP_PROJECT_ID=your-gcp-project-id
2+
GCP_REGION=us-central1
3+
GCP_MODEL=mistral-small-2503

0 commit comments

Comments
 (0)