diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index d59c2911..e2422227 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,12 +1,12 @@ lockVersion: 2.0.0 id: 2d045ec7-2ebb-4f4d-ad25-40953b132161 management: - docChecksum: d066d98bdd0ef905d4126e0e69940946 + docChecksum: 36ad3563d9d2b3af47015100d060570b docVersion: 0.0.2 - speakeasyVersion: 1.440.1 - generationVersion: 2.460.1 - releaseVersion: 1.2.3 - configChecksum: 25fa33668bf14110dfe5bac267dcc8b4 + speakeasyVersion: 1.451.1 + generationVersion: 2.470.1 + releaseVersion: 1.2.4 + configChecksum: 4fe789bac842073beb4e2d9c6c3f833d repoURL: https://github.com/mistralai/client-python.git installationURL: https://github.com/mistralai/client-python.git published: true @@ -14,7 +14,7 @@ features: python: additionalDependencies: 1.0.0 constsAndDefaults: 1.0.5 - core: 5.6.5 + core: 5.6.8 defaultEnabledRetries: 0.2.0 downloadStreams: 1.0.1 enumUnions: 0.1.0 @@ -34,11 +34,10 @@ features: responseFormat: 1.0.1 retries: 3.0.2 sdkHooks: 1.0.0 - serverEvents: 1.0.4 + serverEvents: 1.0.7 serverEventsSentinels: 0.1.0 serverIDs: 3.0.0 - tests: 1.6.0 - unions: 3.0.3 + unions: 3.0.4 uploadStreams: 1.0.0 generatedFiles: - .gitattributes @@ -107,16 +106,17 @@ generatedFiles: - docs/models/filepurpose.md - docs/models/filesapiroutesdeletefilerequest.md - docs/models/filesapiroutesdownloadfilerequest.md + - docs/models/filesapiroutesgetsignedurlrequest.md - docs/models/filesapirouteslistfilesrequest.md - docs/models/filesapiroutesretrievefilerequest.md - docs/models/filesapiroutesuploadfilemultipartbodyparams.md - docs/models/fileschema.md + - docs/models/filesignedurl.md - docs/models/fimcompletionrequest.md - docs/models/fimcompletionrequeststop.md - docs/models/fimcompletionresponse.md - docs/models/fimcompletionstreamrequest.md - docs/models/fimcompletionstreamrequeststop.md - - docs/models/finetuneablemodel.md - docs/models/finishreason.md - docs/models/ftmodelcapabilitiesout.md - docs/models/ftmodelcard.md @@ -282,14 +282,15 @@ generatedFiles: - src/mistralai/models/filepurpose.py - src/mistralai/models/files_api_routes_delete_fileop.py - src/mistralai/models/files_api_routes_download_fileop.py + - src/mistralai/models/files_api_routes_get_signed_urlop.py - src/mistralai/models/files_api_routes_list_filesop.py - src/mistralai/models/files_api_routes_retrieve_fileop.py - src/mistralai/models/files_api_routes_upload_fileop.py - src/mistralai/models/fileschema.py + - src/mistralai/models/filesignedurl.py - src/mistralai/models/fimcompletionrequest.py - src/mistralai/models/fimcompletionresponse.py - src/mistralai/models/fimcompletionstreamrequest.py - - src/mistralai/models/finetuneablemodel.py - src/mistralai/models/ftmodelcapabilitiesout.py - src/mistralai/models/ftmodelcard.py - src/mistralai/models/ftmodelout.py @@ -454,7 +455,7 @@ examples: application/json: {"model": "codestral-latest"} responses: "200": - application/json: {"id": "a621cf02-1cd9-4cf5-8403-315211a509a3", "auto_start": false, "model": "open-mistral-7b", "status": "FAILED", "job_type": "", "created_at": 550483, "modified_at": 906537, "training_files": ["74c2becc-3769-4177-b5e0-24985613de0e"]} + application/json: {"id": "a621cf02-1cd9-4cf5-8403-315211a509a3", "auto_start": false, "model": "2", "status": "FAILED", "job_type": "", "created_at": 550483, "modified_at": 906537, "training_files": ["74c2becc-3769-4177-b5e0-24985613de0e"]} jobs_api_routes_fine_tuning_get_fine_tuning_job: speakeasy-default-jobs-api-routes-fine-tuning-get-fine-tuning-job: parameters: @@ -521,7 +522,7 @@ examples: application/json: {"input": ["Embed this sentence.", "As well as this one."], "model": "Wrangler"} responses: "200": - application/json: {"id": "cmpl-e5cc70bb28c444948073e77776eb30ef", "object": "chat.completion", "model": "mistral-small-latest", "usage": {"prompt_tokens": 16, "completion_tokens": 34, "total_tokens": 50}, "data": [{"object": "embedding", "embedding": [0.1, 0.2, 0.3], "index": 0}]} + application/json: {"id": "cmpl-e5cc70bb28c444948073e77776eb30ef", "object": "chat.completion", "model": "mistral-small-latest", "usage": {"prompt_tokens": 16, "completion_tokens": 34, "total_tokens": 50}, "data": [{"object": "embedding", "embedding": [0.1, 0.2, 0.3], "index": 0}, {"object": "embedding", "embedding": [0.4, 0.5, 0.6], "index": 1}]} "422": {} files_api_routes_download_file: speakeasy-default-files-api-routes-download-file: @@ -572,3 +573,13 @@ examples: "200": application/json: {"id": "mod-e5cc70bb28c444948073e77776eb30ef"} "422": {} + files_api_routes_get_signed_url: + speakeasy-default-files-api-routes-get-signed-url: + parameters: + path: + file_id: "" + query: {} + responses: + "200": + application/json: {"url": "https://scornful-daughter.com/"} +generatedTests: {} diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 68a158cd..dfee8409 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -13,7 +13,7 @@ generation: oAuth2ClientCredentialsEnabled: true oAuth2PasswordEnabled: false python: - version: 1.2.3 + version: 1.2.4 additionalDependencies: dev: pytest: ^8.2.2 diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index e61ff013..4d2a32b8 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,46 +1,45 @@ -speakeasyVersion: 1.440.1 +speakeasyVersion: 1.451.1 sources: mistral-azure-source: sourceNamespace: mistral-azure-source - sourceRevisionDigest: sha256:c441f2d21e7879f5fb9d8d99e2ae242d1e5a84c0c06db971911eb578173e7f62 - sourceBlobDigest: sha256:de4af0f100f15fef89e093a6b5393302b2218fb154230594ec811aacdd4f2ec7 + sourceRevisionDigest: sha256:9c35eed0174f2d8165807bcd7c8e7b7111fa97c059a77ae7eeaa352ca7e83b4d + sourceBlobDigest: sha256:07283bfde08363f9f69b133888b482472c4bf12d2e5b59cb33c8993c517278e3 tags: - latest mistral-google-cloud-source: sourceNamespace: mistral-google-cloud-source - sourceRevisionDigest: sha256:d3e3d15303dcc1acb27b8895aa3064328bd5b8013ea635c2bce553b6e647b498 - sourceBlobDigest: sha256:db72004ee842a27c3e77980be28a727811e0581daa7a51ad34d142302f8ba2f3 + sourceRevisionDigest: sha256:e0fd58ce2dbba068f375d3a23d758b8678c2a68cf4fc7bc46ea7e1b37abe0647 + sourceBlobDigest: sha256:0707d8d2566a9ef4ef286bb0abe467f8696ccf83ba73091065d7caf627a06611 tags: - latest mistral-openapi: sourceNamespace: mistral-openapi - sourceRevisionDigest: sha256:9b6ad47076b570f4e23494bf744a7822547d0003e4b10985f26f1c3b5128e631 - sourceBlobDigest: sha256:150e3da2a6bfb74e86e2ce864e9a094fc796f3a08df91f6a6e8745b54b3e16bc + sourceRevisionDigest: sha256:f74c08bdc7ae39f5fe2394df8f31ae623ece30a7f65019ab6b7bcea352953f05 + sourceBlobDigest: sha256:5de08a038994ec94c0889341d434b598f541459d114f9935deb9ef3b3af90c5f tags: - latest - - speakeasy-sdk-regen-1731693697 targets: mistralai-azure-sdk: source: mistral-azure-source sourceNamespace: mistral-azure-source - sourceRevisionDigest: sha256:c441f2d21e7879f5fb9d8d99e2ae242d1e5a84c0c06db971911eb578173e7f62 - sourceBlobDigest: sha256:de4af0f100f15fef89e093a6b5393302b2218fb154230594ec811aacdd4f2ec7 + sourceRevisionDigest: sha256:9c35eed0174f2d8165807bcd7c8e7b7111fa97c059a77ae7eeaa352ca7e83b4d + sourceBlobDigest: sha256:07283bfde08363f9f69b133888b482472c4bf12d2e5b59cb33c8993c517278e3 codeSamplesNamespace: mistral-openapi-azure-code-samples - codeSamplesRevisionDigest: sha256:5db0b04cc2b3962de41cb07e87fe817dd5ec8bc5d8b0254245b26faf70ede027 + codeSamplesRevisionDigest: sha256:79a227720579444358a825b1a272c153f3d9dd48cd0913be6c988d7931a44241 mistralai-gcp-sdk: source: mistral-google-cloud-source sourceNamespace: mistral-google-cloud-source - sourceRevisionDigest: sha256:d3e3d15303dcc1acb27b8895aa3064328bd5b8013ea635c2bce553b6e647b498 - sourceBlobDigest: sha256:db72004ee842a27c3e77980be28a727811e0581daa7a51ad34d142302f8ba2f3 + sourceRevisionDigest: sha256:e0fd58ce2dbba068f375d3a23d758b8678c2a68cf4fc7bc46ea7e1b37abe0647 + sourceBlobDigest: sha256:0707d8d2566a9ef4ef286bb0abe467f8696ccf83ba73091065d7caf627a06611 codeSamplesNamespace: mistral-openapi-google-cloud-code-samples - codeSamplesRevisionDigest: sha256:7d95ba7aa230088b9975be341ba638e51cc574b6e863bd3a0f53e9c5ee261bba + codeSamplesRevisionDigest: sha256:0657ec41e473356a5a0eeaca3dff137e9ff16080ec1fb50e72553245aa86ffe5 mistralai-sdk: source: mistral-openapi sourceNamespace: mistral-openapi - sourceRevisionDigest: sha256:9b6ad47076b570f4e23494bf744a7822547d0003e4b10985f26f1c3b5128e631 - sourceBlobDigest: sha256:150e3da2a6bfb74e86e2ce864e9a094fc796f3a08df91f6a6e8745b54b3e16bc + sourceRevisionDigest: sha256:f74c08bdc7ae39f5fe2394df8f31ae623ece30a7f65019ab6b7bcea352953f05 + sourceBlobDigest: sha256:5de08a038994ec94c0889341d434b598f541459d114f9935deb9ef3b3af90c5f codeSamplesNamespace: mistral-openapi-code-samples - codeSamplesRevisionDigest: sha256:d1ea6603d96bdc063cc747cde1cadcbf443be580935e12438e7b915d0cd9a019 + codeSamplesRevisionDigest: sha256:09212fda8fc13e0f486f157495d028138bc9babedfba6dd85f7024575f30fd0e workflow: workflowVersion: 1.0.0 speakeasyVersion: latest diff --git a/README.md b/README.md index 24c744ab..7a886085 100644 --- a/README.md +++ b/README.md @@ -27,19 +27,26 @@ Mistral AI API: Our Chat Completion and Embeddings APIs specification. Create yo ## Table of Contents + +* [Mistral Python Client](#mistral-python-client) + * [Migration warning](#migration-warning) + * [API Key Setup](#api-key-setup) + * [SDK Installation](#sdk-installation) + * [SDK Example Usage](#sdk-example-usage) + * [Providers' SDKs Example Usage](#providers-sdks-example-usage) + * [Available Resources and Operations](#available-resources-and-operations) + * [Server-sent event streaming](#server-sent-event-streaming) + * [File uploads](#file-uploads) + * [Retries](#retries) + * [Error Handling](#error-handling) + * [Server Selection](#server-selection) + * [Custom HTTP Client](#custom-http-client) + * [Authentication](#authentication) + * [Debugging](#debugging) + * [IDE Support](#ide-support) +* [Development](#development) + * [Contributions](#contributions) -* [SDK Installation](#sdk-installation) -* [IDE Support](#ide-support) -* [SDK Example Usage](#sdk-example-usage) -* [Available Resources and Operations](#available-resources-and-operations) -* [Server-sent event streaming](#server-sent-event-streaming) -* [File uploads](#file-uploads) -* [Retries](#retries) -* [Error Handling](#error-handling) -* [Server Selection](#server-selection) -* [Custom HTTP Client](#custom-http-client) -* [Authentication](#authentication) -* [Debugging](#debugging) @@ -76,20 +83,19 @@ This example shows how to create chat completions. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.chat.complete(model="mistral-small-latest", messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, -]) +) as s: + res = s.chat.complete(model="mistral-small-latest", messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ]) -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ```
@@ -102,18 +108,19 @@ from mistralai import Mistral import os async def main(): - s = Mistral( + async with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), - ) - res = await s.chat.complete_async(model="mistral-small-latest", messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, - ]) - if res is not None: - # handle response - pass + ) as s: + res = await s.chat.complete_async(model="mistral-small-latest", messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ]) + + if res is not None: + # handle response + pass asyncio.run(main()) ``` @@ -127,18 +134,17 @@ This example shows how to upload a file. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.files.upload(file={ - "file_name": "example.file", - "content": open("example.file", "rb"), -}) +) as s: + res = s.files.upload(file={ + "file_name": "example.file", + "content": open("example.file", "rb"), + }) -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ```
@@ -151,16 +157,17 @@ from mistralai import Mistral import os async def main(): - s = Mistral( + async with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), - ) - res = await s.files.upload_async(file={ - "file_name": "example.file", - "content": open("example.file", "rb"), - }) - if res is not None: - # handle response - pass + ) as s: + res = await s.files.upload_async(file={ + "file_name": "example.file", + "content": open("example.file", "rb"), + }) + + if res is not None: + # handle response + pass asyncio.run(main()) ``` @@ -174,20 +181,19 @@ This example shows how to create agents completions. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.agents.complete(messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, -], agent_id="") +) as s: + res = s.agents.complete(messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ], agent_id="") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ```
@@ -200,18 +206,19 @@ from mistralai import Mistral import os async def main(): - s = Mistral( + async with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), - ) - res = await s.agents.complete_async(messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, - ], agent_id="") - if res is not None: - # handle response - pass + ) as s: + res = await s.agents.complete_async(messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ], agent_id="") + + if res is not None: + # handle response + pass asyncio.run(main()) ``` @@ -225,18 +232,17 @@ This example shows how to create embedding request. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.embeddings.create(inputs=[ - "Embed this sentence.", - "As well as this one.", -], model="Wrangler") +) as s: + res = s.embeddings.create(inputs=[ + "Embed this sentence.", + "As well as this one.", + ], model="Wrangler") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ```
@@ -249,16 +255,17 @@ from mistralai import Mistral import os async def main(): - s = Mistral( + async with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), - ) - res = await s.embeddings.create_async(inputs=[ - "Embed this sentence.", - "As well as this one.", - ], model="Wrangler") - if res is not None: - # handle response - pass + ) as s: + res = await s.embeddings.create_async(inputs=[ + "Embed this sentence.", + "As well as this one.", + ], model="Wrangler") + + if res is not None: + # handle response + pass asyncio.run(main()) ``` @@ -401,6 +408,7 @@ The documentation for the GCP SDK is available [here](packages/mistralai_gcp/REA * [retrieve](docs/sdks/files/README.md#retrieve) - Retrieve File * [delete](docs/sdks/files/README.md#delete) - Delete File * [download](docs/sdks/files/README.md#download) - Download File +* [get_signed_url](docs/sdks/files/README.md#get_signed_url) - Get Signed Url ### [fim](docs/sdks/fim/README.md) @@ -438,32 +446,36 @@ The documentation for the GCP SDK is available [here](packages/mistralai_gcp/REA operations. These operations will expose the stream as [Generator][generator] that can be consumed using a simple `for` loop. The loop will terminate when the server no longer has any events to send and closes the -underlying connection. +underlying connection. + +The stream is also a [Context Manager][context-manager] and can be used with the `with` statement and will close the +underlying connection when the context is exited. ```python from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.chat.stream(model="mistral-small-latest", messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, -]) +) as s: + res = s.chat.stream(model="mistral-small-latest", messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ]) -if res is not None: - for event in res: - # handle event - print(event, flush=True) + if res is not None: + with res as event_stream: + for event in event_stream: + # handle event + print(event, flush=True) ``` [mdn-sse]: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events -[generator]: https://wiki.python.org/moin/Generators +[generator]: https://book.pythontips.com/en/latest/generators.html +[context-manager]: https://book.pythontips.com/en/latest/context_managers.html @@ -480,18 +492,17 @@ Certain SDK methods accept file objects as part of a request body or multi-part from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.files.upload(file={ - "file_name": "example.file", - "content": open("example.file", "rb"), -}) +) as s: + res = s.files.upload(file={ + "file_name": "example.file", + "content": open("example.file", "rb"), + }) -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -507,16 +518,15 @@ from mistral.utils import BackoffStrategy, RetryConfig from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.models.list(, + RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False)) -res = s.models.list(, - RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False)) - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -526,16 +536,15 @@ from mistral.utils import BackoffStrategy, RetryConfig from mistralai import Mistral import os -s = Mistral( +with Mistral( retry_config=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False), api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.models.list() +) as s: + res = s.models.list() -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -567,24 +576,23 @@ When custom error responses are specified for an operation, the SDK may also rai from mistralai import Mistral, models import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = None -try: - res = s.models.list() - - if res is not None: - # handle response - pass - -except models.HTTPValidationError as e: - # handle e.data: models.HTTPValidationErrorData - raise(e) -except models.SDKError as e: - # handle exception - raise(e) +) as s: + res = None + try: + res = s.models.list() + + if res is not None: + # handle response + pass + + except models.HTTPValidationError as e: + # handle e.data: models.HTTPValidationErrorData + raise(e) + except models.SDKError as e: + # handle exception + raise(e) ``` @@ -605,16 +613,15 @@ You can override the default server globally by passing a server name to the `se from mistralai import Mistral import os -s = Mistral( +with Mistral( server="eu", api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.models.list() +) as s: + res = s.models.list() -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -625,16 +632,15 @@ The default server can also be overridden globally by passing a URL to the `serv from mistralai import Mistral import os -s = Mistral( +with Mistral( server_url="https://api.mistral.ai", api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.models.list() +) as s: + res = s.models.list() -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -736,15 +742,14 @@ To authenticate with the API the `api_key` parameter must be set when initializi from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.models.list() +) as s: + res = s.models.list() -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` diff --git a/RELEASES.md b/RELEASES.md index b8f671ba..845891e8 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -88,4 +88,14 @@ Based on: ### Generated - [python v1.2.3] . ### Releases -- [PyPI v1.2.3] https://pypi.org/project/mistralai/1.2.3 - . \ No newline at end of file +- [PyPI v1.2.3] https://pypi.org/project/mistralai/1.2.3 - . + +## 2024-12-02 14:25:56 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.440.1 (2.460.1) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.2.4] . +### Releases +- [PyPI v1.2.4] https://pypi.org/project/mistralai/1.2.4 - . \ No newline at end of file diff --git a/USAGE.md b/USAGE.md index 7d9d2ce2..e523aa92 100644 --- a/USAGE.md +++ b/USAGE.md @@ -8,20 +8,19 @@ This example shows how to create chat completions. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.chat.complete(model="mistral-small-latest", messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, -]) - -if res is not None: - # handle response - pass +) as s: + res = s.chat.complete(model="mistral-small-latest", messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ]) + + if res is not None: + # handle response + pass ```
@@ -34,18 +33,19 @@ from mistralai import Mistral import os async def main(): - s = Mistral( + async with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), - ) - res = await s.chat.complete_async(model="mistral-small-latest", messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, - ]) - if res is not None: - # handle response - pass + ) as s: + res = await s.chat.complete_async(model="mistral-small-latest", messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ]) + + if res is not None: + # handle response + pass asyncio.run(main()) ``` @@ -59,18 +59,17 @@ This example shows how to upload a file. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.files.upload(file={ - "file_name": "example.file", - "content": open("example.file", "rb"), -}) +) as s: + res = s.files.upload(file={ + "file_name": "example.file", + "content": open("example.file", "rb"), + }) -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ```
@@ -83,16 +82,17 @@ from mistralai import Mistral import os async def main(): - s = Mistral( + async with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), - ) - res = await s.files.upload_async(file={ - "file_name": "example.file", - "content": open("example.file", "rb"), - }) - if res is not None: - # handle response - pass + ) as s: + res = await s.files.upload_async(file={ + "file_name": "example.file", + "content": open("example.file", "rb"), + }) + + if res is not None: + # handle response + pass asyncio.run(main()) ``` @@ -106,20 +106,19 @@ This example shows how to create agents completions. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.agents.complete(messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, -], agent_id="") - -if res is not None: - # handle response - pass +) as s: + res = s.agents.complete(messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ], agent_id="") + + if res is not None: + # handle response + pass ```
@@ -132,18 +131,19 @@ from mistralai import Mistral import os async def main(): - s = Mistral( + async with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), - ) - res = await s.agents.complete_async(messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, - ], agent_id="") - if res is not None: - # handle response - pass + ) as s: + res = await s.agents.complete_async(messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ], agent_id="") + + if res is not None: + # handle response + pass asyncio.run(main()) ``` @@ -157,18 +157,17 @@ This example shows how to create embedding request. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.embeddings.create(inputs=[ - "Embed this sentence.", - "As well as this one.", -], model="Wrangler") +) as s: + res = s.embeddings.create(inputs=[ + "Embed this sentence.", + "As well as this one.", + ], model="Wrangler") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ```
@@ -181,16 +180,17 @@ from mistralai import Mistral import os async def main(): - s = Mistral( + async with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), - ) - res = await s.embeddings.create_async(inputs=[ - "Embed this sentence.", - "As well as this one.", - ], model="Wrangler") - if res is not None: - # handle response - pass + ) as s: + res = await s.embeddings.create_async(inputs=[ + "Embed this sentence.", + "As well as this one.", + ], model="Wrangler") + + if res is not None: + # handle response + pass asyncio.run(main()) ``` diff --git a/docs/models/apiendpoint.md b/docs/models/apiendpoint.md index 5dfa68ae..700b932f 100644 --- a/docs/models/apiendpoint.md +++ b/docs/models/apiendpoint.md @@ -8,4 +8,5 @@ | `ROOT_V1_CHAT_COMPLETIONS` | /v1/chat/completions | | `ROOT_V1_EMBEDDINGS` | /v1/embeddings | | `ROOT_V1_FIM_COMPLETIONS` | /v1/fim/completions | -| `ROOT_V1_MODERATIONS` | /v1/moderations | \ No newline at end of file +| `ROOT_V1_MODERATIONS` | /v1/moderations | +| `ROOT_V1_CHAT_MODERATIONS` | /v1/chat/moderations | \ No newline at end of file diff --git a/docs/models/detailedjobout.md b/docs/models/detailedjobout.md index 3eae6b30..f7470327 100644 --- a/docs/models/detailedjobout.md +++ b/docs/models/detailedjobout.md @@ -8,7 +8,7 @@ | `id` | *str* | :heavy_check_mark: | N/A | | `auto_start` | *bool* | :heavy_check_mark: | N/A | | `hyperparameters` | [models.TrainingParameters](../models/trainingparameters.md) | :heavy_check_mark: | N/A | -| `model` | [models.FineTuneableModel](../models/finetuneablemodel.md) | :heavy_check_mark: | The name of the model to fine-tune. | +| `model` | *str* | :heavy_check_mark: | The name of the model to fine-tune. | | `status` | [models.DetailedJobOutStatus](../models/detailedjoboutstatus.md) | :heavy_check_mark: | N/A | | `job_type` | *str* | :heavy_check_mark: | N/A | | `created_at` | *int* | :heavy_check_mark: | N/A | diff --git a/docs/models/filesapiroutesgetsignedurlrequest.md b/docs/models/filesapiroutesgetsignedurlrequest.md new file mode 100644 index 00000000..dbe3c801 --- /dev/null +++ b/docs/models/filesapiroutesgetsignedurlrequest.md @@ -0,0 +1,9 @@ +# FilesAPIRoutesGetSignedURLRequest + + +## Fields + +| Field | Type | Required | Description | +| --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | +| `file_id` | *str* | :heavy_check_mark: | N/A | +| `expiry` | *Optional[int]* | :heavy_minus_sign: | Number of hours before the url becomes invalid. Defaults to 24h | \ No newline at end of file diff --git a/docs/models/filesignedurl.md b/docs/models/filesignedurl.md new file mode 100644 index 00000000..52ce3f4f --- /dev/null +++ b/docs/models/filesignedurl.md @@ -0,0 +1,8 @@ +# FileSignedURL + + +## Fields + +| Field | Type | Required | Description | +| ------------------ | ------------------ | ------------------ | ------------------ | +| `url` | *str* | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/finetuneablemodel.md b/docs/models/finetuneablemodel.md deleted file mode 100644 index cb429284..00000000 --- a/docs/models/finetuneablemodel.md +++ /dev/null @@ -1,14 +0,0 @@ -# FineTuneableModel - -The name of the model to fine-tune. - - -## Values - -| Name | Value | -| ---------------------- | ---------------------- | -| `OPEN_MISTRAL_7B` | open-mistral-7b | -| `MISTRAL_SMALL_LATEST` | mistral-small-latest | -| `CODESTRAL_LATEST` | codestral-latest | -| `MISTRAL_LARGE_LATEST` | mistral-large-latest | -| `OPEN_MISTRAL_NEMO` | open-mistral-nemo | \ No newline at end of file diff --git a/docs/models/jobin.md b/docs/models/jobin.md index ebaed9a9..6fd661cf 100644 --- a/docs/models/jobin.md +++ b/docs/models/jobin.md @@ -5,7 +5,7 @@ | Field | Type | Required | Description | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `model` | [models.FineTuneableModel](../models/finetuneablemodel.md) | :heavy_check_mark: | The name of the model to fine-tune. | +| `model` | *str* | :heavy_check_mark: | The name of the model to fine-tune. | | `hyperparameters` | [models.TrainingParametersIn](../models/trainingparametersin.md) | :heavy_check_mark: | The fine-tuning hyperparameter settings used in a fine-tune job. | | `training_files` | List[[models.TrainingFile](../models/trainingfile.md)] | :heavy_minus_sign: | N/A | | `validation_files` | List[*str*] | :heavy_minus_sign: | A list containing the IDs of uploaded files that contain validation data. If you provide these files, the data is used to generate validation metrics periodically during fine-tuning. These metrics can be viewed in `checkpoints` when getting the status of a running fine-tuning job. The same data should not be present in both train and validation files. | diff --git a/docs/models/jobout.md b/docs/models/jobout.md index 2fe60fd8..652c9d16 100644 --- a/docs/models/jobout.md +++ b/docs/models/jobout.md @@ -8,7 +8,7 @@ | `id` | *str* | :heavy_check_mark: | The ID of the job. | | `auto_start` | *bool* | :heavy_check_mark: | N/A | | `hyperparameters` | [models.TrainingParameters](../models/trainingparameters.md) | :heavy_check_mark: | N/A | -| `model` | [models.FineTuneableModel](../models/finetuneablemodel.md) | :heavy_check_mark: | The name of the model to fine-tune. | +| `model` | *str* | :heavy_check_mark: | The name of the model to fine-tune. | | `status` | [models.Status](../models/status.md) | :heavy_check_mark: | The current status of the fine-tuning job. | | `job_type` | *str* | :heavy_check_mark: | The type of job (`FT` for fine-tuning). | | `created_at` | *int* | :heavy_check_mark: | The UNIX timestamp (in seconds) for when the fine-tuning job was created. | diff --git a/docs/sdks/agents/README.md b/docs/sdks/agents/README.md index 3eb946a8..792b796d 100644 --- a/docs/sdks/agents/README.md +++ b/docs/sdks/agents/README.md @@ -20,20 +20,19 @@ Agents Completion from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.agents.complete(messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, -], agent_id="") - -if res is not None: - # handle response - pass +) as s: + res = s.agents.complete(messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ], agent_id="") + + if res is not None: + # handle response + pass ``` @@ -76,21 +75,21 @@ Mistral AI provides the ability to stream responses back to a client in order to from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.agents.stream(messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, -], agent_id="") - -if res is not None: - for event in res: - # handle event - print(event, flush=True) +) as s: + res = s.agents.stream(messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ], agent_id="") + + if res is not None: + with res as event_stream: + for event in event_stream: + # handle event + print(event, flush=True) ``` @@ -114,7 +113,7 @@ if res is not None: ### Response -**[Union[Generator[models.CompletionEvent, None, None], AsyncGenerator[models.CompletionEvent, None]]](../../models/.md)** +**[Union[eventstreaming.EventStream[models.CompletionEvent], eventstreaming.EventStreamAsync[models.CompletionEvent]]](../../models/.md)** ### Errors diff --git a/docs/sdks/batch/README.md b/docs/sdks/batch/README.md index 55a9c135..ec7d8340 100644 --- a/docs/sdks/batch/README.md +++ b/docs/sdks/batch/README.md @@ -1,2 +1,6 @@ # Batch -(*batch*) \ No newline at end of file +(*batch*) + +## Overview + +### Available Operations diff --git a/docs/sdks/chat/README.md b/docs/sdks/chat/README.md index d6f4a768..6e00d3d2 100644 --- a/docs/sdks/chat/README.md +++ b/docs/sdks/chat/README.md @@ -20,20 +20,19 @@ Chat Completion from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.chat.complete(model="mistral-small-latest", messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, -]) - -if res is not None: - # handle response - pass +) as s: + res = s.chat.complete(model="mistral-small-latest", messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ]) + + if res is not None: + # handle response + pass ``` @@ -79,21 +78,21 @@ Mistral AI provides the ability to stream responses back to a client in order to from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.chat.stream(model="mistral-small-latest", messages=[ - { - "content": "Who is the best French painter? Answer in one short sentence.", - "role": "user", - }, -]) - -if res is not None: - for event in res: - # handle event - print(event, flush=True) +) as s: + res = s.chat.stream(model="mistral-small-latest", messages=[ + { + "content": "Who is the best French painter? Answer in one short sentence.", + "role": "user", + }, + ]) + + if res is not None: + with res as event_stream: + for event in event_stream: + # handle event + print(event, flush=True) ``` @@ -120,7 +119,7 @@ if res is not None: ### Response -**[Union[Generator[models.CompletionEvent, None, None], AsyncGenerator[models.CompletionEvent, None]]](../../models/.md)** +**[Union[eventstreaming.EventStream[models.CompletionEvent], eventstreaming.EventStreamAsync[models.CompletionEvent]]](../../models/.md)** ### Errors diff --git a/docs/sdks/classifiers/README.md b/docs/sdks/classifiers/README.md index 7e59fa2c..da90019a 100644 --- a/docs/sdks/classifiers/README.md +++ b/docs/sdks/classifiers/README.md @@ -20,17 +20,16 @@ Moderations from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.classifiers.moderate(inputs=[ + "", + ]) -res = s.classifiers.moderate(inputs=[ - "", -]) - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -63,26 +62,24 @@ Moderations Chat from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.classifiers.moderate_chat(inputs=[ - [ - { - "content": [ - { - "text": "", - "type": "text", - }, - ], - }, - ], -], model="V90") - -if res is not None: - # handle response - pass +) as s: + res = s.classifiers.moderate_chat(inputs=[ + [ + { + "content": [ + { + "text": "", + }, + ], + }, + ], + ], model="V90") + + if res is not None: + # handle response + pass ``` diff --git a/docs/sdks/embeddings/README.md b/docs/sdks/embeddings/README.md index 9f47e703..1f9f1956 100644 --- a/docs/sdks/embeddings/README.md +++ b/docs/sdks/embeddings/README.md @@ -19,18 +19,17 @@ Embeddings from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.embeddings.create(inputs=[ - "Embed this sentence.", - "As well as this one.", -], model="Wrangler") - -if res is not None: - # handle response - pass +) as s: + res = s.embeddings.create(inputs=[ + "Embed this sentence.", + "As well as this one.", + ], model="Wrangler") + + if res is not None: + # handle response + pass ``` diff --git a/docs/sdks/files/README.md b/docs/sdks/files/README.md index fc5784a4..ad2e0f09 100644 --- a/docs/sdks/files/README.md +++ b/docs/sdks/files/README.md @@ -12,6 +12,7 @@ Files API * [retrieve](#retrieve) - Retrieve File * [delete](#delete) - Delete File * [download](#download) - Download File +* [get_signed_url](#get_signed_url) - Get Signed Url ## upload @@ -27,18 +28,17 @@ Please contact us if you need to increase these storage limits. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.files.upload(file={ + "file_name": "example.file", + "content": open("example.file", "rb"), + }) -res = s.files.upload(file={ - "file_name": "example.file", - "content": open("example.file", "rb"), -}) - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -70,15 +70,14 @@ Returns a list of files that belong to the user's organization. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.files.list() +) as s: + res = s.files.list() -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -114,15 +113,14 @@ Returns information about a specific file. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.files.retrieve(file_id="") +) as s: + res = s.files.retrieve(file_id="") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -153,15 +151,14 @@ Delete a file. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.files.delete(file_id="") -res = s.files.delete(file_id="") - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -192,15 +189,14 @@ Download a file from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.files.download(file_id="") +) as s: + res = s.files.download(file_id="") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -217,6 +213,45 @@ if res is not None: ### Errors +| Error Type | Status Code | Content Type | +| --------------- | --------------- | --------------- | +| models.SDKError | 4XX, 5XX | \*/\* | + +## get_signed_url + +Get Signed Url + +### Example Usage + +```python +from mistralai import Mistral +import os + +with Mistral( + api_key=os.getenv("MISTRAL_API_KEY", ""), +) as s: + res = s.files.get_signed_url(file_id="") + + if res is not None: + # handle response + pass + +``` + +### Parameters + +| Parameter | Type | Required | Description | +| ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------- | +| `file_id` | *str* | :heavy_check_mark: | N/A | +| `expiry` | *Optional[int]* | :heavy_minus_sign: | Number of hours before the url becomes invalid. Defaults to 24h | +| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.md) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | + +### Response + +**[models.FileSignedURL](../../models/filesignedurl.md)** + +### Errors + | Error Type | Status Code | Content Type | | --------------- | --------------- | --------------- | | models.SDKError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/docs/sdks/fim/README.md b/docs/sdks/fim/README.md index d9811521..eed1893e 100644 --- a/docs/sdks/fim/README.md +++ b/docs/sdks/fim/README.md @@ -20,15 +20,14 @@ FIM completion. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.fim.complete(model="codestral-2405", prompt="def", suffix="return a+b") -res = s.fim.complete(model="codestral-2405", prompt="def", suffix="return a+b") - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -69,16 +68,16 @@ Mistral AI provides the ability to stream responses back to a client in order to from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.fim.stream(model="codestral-2405", prompt="def", suffix="return a+b") +) as s: + res = s.fim.stream(model="codestral-2405", prompt="def", suffix="return a+b") -if res is not None: - for event in res: - # handle event - print(event, flush=True) + if res is not None: + with res as event_stream: + for event in event_stream: + # handle event + print(event, flush=True) ``` @@ -100,7 +99,7 @@ if res is not None: ### Response -**[Union[Generator[models.CompletionEvent, None, None], AsyncGenerator[models.CompletionEvent, None]]](../../models/.md)** +**[Union[eventstreaming.EventStream[models.CompletionEvent], eventstreaming.EventStreamAsync[models.CompletionEvent]]](../../models/.md)** ### Errors diff --git a/docs/sdks/finetuning/README.md b/docs/sdks/finetuning/README.md index fdcbd62a..3e0f12ce 100644 --- a/docs/sdks/finetuning/README.md +++ b/docs/sdks/finetuning/README.md @@ -1,2 +1,6 @@ # FineTuning -(*fine_tuning*) \ No newline at end of file +(*fine_tuning*) + +## Overview + +### Available Operations diff --git a/docs/sdks/jobs/README.md b/docs/sdks/jobs/README.md index 6ecf6e51..b4779580 100644 --- a/docs/sdks/jobs/README.md +++ b/docs/sdks/jobs/README.md @@ -21,15 +21,14 @@ Get a list of fine-tuning jobs for your organization and user. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.fine_tuning.jobs.list() -res = s.fine_tuning.jobs.list() - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -68,15 +67,14 @@ Create a new fine-tuning job, it will be queued for processing. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.fine_tuning.jobs.create(model="codestral-latest", hyperparameters={}) +) as s: + res = s.fine_tuning.jobs.create(model="codestral-latest", hyperparameters={}) -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -84,7 +82,7 @@ if res is not None: | Parameter | Type | Required | Description | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `model` | [models.FineTuneableModel](../../models/finetuneablemodel.md) | :heavy_check_mark: | The name of the model to fine-tune. | +| `model` | *str* | :heavy_check_mark: | The name of the model to fine-tune. | | `hyperparameters` | [models.TrainingParametersIn](../../models/trainingparametersin.md) | :heavy_check_mark: | The fine-tuning hyperparameter settings used in a fine-tune job. | | `training_files` | List[[models.TrainingFile](../../models/trainingfile.md)] | :heavy_minus_sign: | N/A | | `validation_files` | List[*str*] | :heavy_minus_sign: | A list containing the IDs of uploaded files that contain validation data. If you provide these files, the data is used to generate validation metrics periodically during fine-tuning. These metrics can be viewed in `checkpoints` when getting the status of a running fine-tuning job. The same data should not be present in both train and validation files. | @@ -114,15 +112,14 @@ Get a fine-tuned job details by its UUID. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.fine_tuning.jobs.get(job_id="b18d8d81-fd7b-4764-a31e-475cb1f36591") +) as s: + res = s.fine_tuning.jobs.get(job_id="b18d8d81-fd7b-4764-a31e-475cb1f36591") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -153,15 +150,14 @@ Request the cancellation of a fine tuning job. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.fine_tuning.jobs.cancel(job_id="03fa7112-315a-4072-a9f2-43f3f1ec962e") -res = s.fine_tuning.jobs.cancel(job_id="03fa7112-315a-4072-a9f2-43f3f1ec962e") - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -192,15 +188,14 @@ Request the start of a validated fine tuning job. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.fine_tuning.jobs.start(job_id="0eb0f807-fb9f-4e46-9c13-4e257df6e1ba") +) as s: + res = s.fine_tuning.jobs.start(job_id="0eb0f807-fb9f-4e46-9c13-4e257df6e1ba") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` diff --git a/docs/sdks/mistral/README.md b/docs/sdks/mistral/README.md index 0189a6c4..4b9573d0 100644 --- a/docs/sdks/mistral/README.md +++ b/docs/sdks/mistral/README.md @@ -2,4 +2,6 @@ ## Overview -Mistral AI API: Our Chat Completion and Embeddings APIs specification. Create your account on [La Plateforme](https://console.mistral.ai) to get access and read the [docs](https://docs.mistral.ai) to learn how to use it. \ No newline at end of file +Mistral AI API: Our Chat Completion and Embeddings APIs specification. Create your account on [La Plateforme](https://console.mistral.ai) to get access and read the [docs](https://docs.mistral.ai) to learn how to use it. + +### Available Operations diff --git a/docs/sdks/mistraljobs/README.md b/docs/sdks/mistraljobs/README.md index 5852c2cb..1880c83e 100644 --- a/docs/sdks/mistraljobs/README.md +++ b/docs/sdks/mistraljobs/README.md @@ -20,15 +20,14 @@ Get a list of batch jobs for your organization and user. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.batch.jobs.list() -res = s.batch.jobs.list() - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -65,17 +64,16 @@ Create a new batch job, it will be queued for processing. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.batch.jobs.create(input_files=[ - "a621cf02-1cd9-4cf5-8403-315211a509a3", -], endpoint="/v1/fim/completions", model="2") +) as s: + res = s.batch.jobs.create(input_files=[ + "a621cf02-1cd9-4cf5-8403-315211a509a3", + ], endpoint="/v1/fim/completions", model="2") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -110,15 +108,14 @@ Get a batch job details by its UUID. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.batch.jobs.get(job_id="b888f774-3e7c-4135-a18c-6b985523c4bc") -res = s.batch.jobs.get(job_id="b888f774-3e7c-4135-a18c-6b985523c4bc") - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -149,15 +146,14 @@ Request the cancellation of a batch job. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.batch.jobs.cancel(job_id="0f713502-9233-41c6-9ebd-c570b7edb496") +) as s: + res = s.batch.jobs.cancel(job_id="0f713502-9233-41c6-9ebd-c570b7edb496") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` diff --git a/docs/sdks/models/README.md b/docs/sdks/models/README.md index 2ad489e0..78884947 100644 --- a/docs/sdks/models/README.md +++ b/docs/sdks/models/README.md @@ -24,15 +24,14 @@ List all models available to the user. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.models.list() -res = s.models.list() - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -63,15 +62,14 @@ Retrieve a model information. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.models.retrieve(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") +) as s: + res = s.models.retrieve(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -103,15 +101,14 @@ Delete a fine-tuned model. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.models.delete(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") +) as s: + res = s.models.delete(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -143,15 +140,14 @@ Update a model name or description. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) +) as s: + res = s.models.update(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") -res = s.models.update(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") - -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -184,15 +180,14 @@ Archive a fine-tuned model. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.models.archive(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") +) as s: + res = s.models.archive(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` @@ -223,15 +218,14 @@ Un-archive a fine-tuned model. from mistralai import Mistral import os -s = Mistral( +with Mistral( api_key=os.getenv("MISTRAL_API_KEY", ""), -) - -res = s.models.unarchive(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") +) as s: + res = s.models.unarchive(model_id="ft:open-mistral-7b:587a6b29:20240514:7e773925") -if res is not None: - # handle response - pass + if res is not None: + # handle response + pass ``` diff --git a/packages/mistralai_azure/.speakeasy/gen.lock b/packages/mistralai_azure/.speakeasy/gen.lock index 518aba16..15388f4c 100644 --- a/packages/mistralai_azure/.speakeasy/gen.lock +++ b/packages/mistralai_azure/.speakeasy/gen.lock @@ -1,10 +1,10 @@ lockVersion: 2.0.0 id: dc40fa48-2c4d-46ad-ac8b-270749770f34 management: - docChecksum: d0000cbe03848bfe843794965cba332f + docChecksum: 26271aa279a7a7182f7af19df8b67038 docVersion: 0.0.2 - speakeasyVersion: 1.440.1 - generationVersion: 2.460.1 + speakeasyVersion: 1.451.1 + generationVersion: 2.470.1 releaseVersion: 1.2.3 configChecksum: 60295c765204eb0aa26205ec02e574fc published: true @@ -12,7 +12,7 @@ features: python: additionalDependencies: 1.0.0 constsAndDefaults: 1.0.5 - core: 5.6.5 + core: 5.6.8 defaultEnabledRetries: 0.2.0 enumUnions: 0.1.0 envVarSecurityUsage: 0.3.2 @@ -29,11 +29,10 @@ features: responseFormat: 1.0.1 retries: 3.0.2 sdkHooks: 1.0.0 - serverEvents: 1.0.4 + serverEvents: 1.0.7 serverEventsSentinels: 0.1.0 serverIDs: 3.0.0 - tests: 1.6.0 - unions: 3.0.3 + unions: 3.0.4 generatedFiles: - .gitattributes - .python-version @@ -166,3 +165,4 @@ examples: "200": application/json: {"id": "cmpl-e5cc70bb28c444948073e77776eb30ef", "object": "chat.completion", "model": "mistral-small-latest", "usage": {"prompt_tokens": 16, "completion_tokens": 34, "total_tokens": 50}, "created": 1702256327, "choices": []} "422": {} +generatedTests: {} diff --git a/packages/mistralai_azure/pyproject.toml b/packages/mistralai_azure/pyproject.toml index 75b1d0c4..a7a0a374 100644 --- a/packages/mistralai_azure/pyproject.toml +++ b/packages/mistralai_azure/pyproject.toml @@ -21,11 +21,11 @@ eval-type-backport = "^0.2.0" httpx = "^0.27.0" jsonpath-python = "^1.0.6" pydantic = "~2.9.2" -python-dateutil = "2.8.2" +python-dateutil = "^2.8.2" typing-inspect = "^0.9.0" [tool.poetry.group.dev.dependencies] -mypy = "==1.10.1" +mypy = "==1.13.0" pylint = "==3.2.3" pytest = "^8.2.2" pytest-asyncio = "^0.23.7" diff --git a/packages/mistralai_azure/src/mistralai_azure/chat.py b/packages/mistralai_azure/src/mistralai_azure/chat.py index fb443e52..afab9ba4 100644 --- a/packages/mistralai_azure/src/mistralai_azure/chat.py +++ b/packages/mistralai_azure/src/mistralai_azure/chat.py @@ -5,7 +5,7 @@ from mistralai_azure._hooks import HookContext from mistralai_azure.types import OptionalNullable, UNSET from mistralai_azure.utils import eventstreaming -from typing import Any, AsyncGenerator, Generator, List, Optional, Union +from typing import Any, List, Optional, Union class Chat(BaseSDK): @@ -41,7 +41,7 @@ def stream( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[Generator[models.CompletionEvent, None, None]]: + ) -> Optional[eventstreaming.EventStream[models.CompletionEvent]]: r"""Stream chat completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -135,7 +135,7 @@ def stream( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events( + return eventstreaming.EventStream( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", @@ -189,7 +189,7 @@ async def stream_async( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[AsyncGenerator[models.CompletionEvent, None]]: + ) -> Optional[eventstreaming.EventStreamAsync[models.CompletionEvent]]: r"""Stream chat completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -283,7 +283,7 @@ async def stream_async( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events_async( + return eventstreaming.EventStreamAsync( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", diff --git a/packages/mistralai_azure/src/mistralai_azure/httpclient.py b/packages/mistralai_azure/src/mistralai_azure/httpclient.py index 36b642a0..167cea4e 100644 --- a/packages/mistralai_azure/src/mistralai_azure/httpclient.py +++ b/packages/mistralai_azure/src/mistralai_azure/httpclient.py @@ -41,6 +41,9 @@ def build_request( ) -> httpx.Request: pass + def close(self) -> None: + pass + @runtime_checkable class AsyncHttpClient(Protocol): @@ -76,3 +79,6 @@ def build_request( extensions: Optional[httpx._types.RequestExtensions] = None, ) -> httpx.Request: pass + + async def aclose(self) -> None: + pass diff --git a/packages/mistralai_azure/src/mistralai_azure/models/assistantmessage.py b/packages/mistralai_azure/src/mistralai_azure/models/assistantmessage.py index 5d978f01..031677cf 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/assistantmessage.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/assistantmessage.py @@ -12,13 +12,17 @@ ) from pydantic import model_serializer from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -AssistantMessageContentTypedDict = Union[str, List[ContentChunkTypedDict]] +AssistantMessageContentTypedDict = TypeAliasType( + "AssistantMessageContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -AssistantMessageContent = Union[str, List[ContentChunk]] +AssistantMessageContent = TypeAliasType( + "AssistantMessageContent", Union[str, List[ContentChunk]] +) AssistantMessageRole = Literal["assistant"] diff --git a/packages/mistralai_azure/src/mistralai_azure/models/chatcompletionrequest.py b/packages/mistralai_azure/src/mistralai_azure/models/chatcompletionrequest.py index beedf520..3e4e9a3a 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/chatcompletionrequest.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/chatcompletionrequest.py @@ -19,23 +19,30 @@ from mistralai_azure.utils import get_discriminator from pydantic import Discriminator, Tag, model_serializer from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -ChatCompletionRequestStopTypedDict = Union[str, List[str]] +ChatCompletionRequestStopTypedDict = TypeAliasType( + "ChatCompletionRequestStopTypedDict", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -ChatCompletionRequestStop = Union[str, List[str]] +ChatCompletionRequestStop = TypeAliasType( + "ChatCompletionRequestStop", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -ChatCompletionRequestMessagesTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +ChatCompletionRequestMessagesTypedDict = TypeAliasType( + "ChatCompletionRequestMessagesTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) ChatCompletionRequestMessages = Annotated[ @@ -49,10 +56,15 @@ ] -ChatCompletionRequestToolChoiceTypedDict = Union[ToolChoiceTypedDict, ToolChoiceEnum] +ChatCompletionRequestToolChoiceTypedDict = TypeAliasType( + "ChatCompletionRequestToolChoiceTypedDict", + Union[ToolChoiceTypedDict, ToolChoiceEnum], +) -ChatCompletionRequestToolChoice = Union[ToolChoice, ToolChoiceEnum] +ChatCompletionRequestToolChoice = TypeAliasType( + "ChatCompletionRequestToolChoice", Union[ToolChoice, ToolChoiceEnum] +) class ChatCompletionRequestTypedDict(TypedDict): diff --git a/packages/mistralai_azure/src/mistralai_azure/models/chatcompletionstreamrequest.py b/packages/mistralai_azure/src/mistralai_azure/models/chatcompletionstreamrequest.py index 9d78371b..6d1f6bb7 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/chatcompletionstreamrequest.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/chatcompletionstreamrequest.py @@ -19,23 +19,26 @@ from mistralai_azure.utils import get_discriminator from pydantic import Discriminator, Tag, model_serializer from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -StopTypedDict = Union[str, List[str]] +StopTypedDict = TypeAliasType("StopTypedDict", Union[str, List[str]]) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -Stop = Union[str, List[str]] +Stop = TypeAliasType("Stop", Union[str, List[str]]) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -MessagesTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +MessagesTypedDict = TypeAliasType( + "MessagesTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) Messages = Annotated[ @@ -49,12 +52,15 @@ ] -ChatCompletionStreamRequestToolChoiceTypedDict = Union[ - ToolChoiceTypedDict, ToolChoiceEnum -] +ChatCompletionStreamRequestToolChoiceTypedDict = TypeAliasType( + "ChatCompletionStreamRequestToolChoiceTypedDict", + Union[ToolChoiceTypedDict, ToolChoiceEnum], +) -ChatCompletionStreamRequestToolChoice = Union[ToolChoice, ToolChoiceEnum] +ChatCompletionStreamRequestToolChoice = TypeAliasType( + "ChatCompletionStreamRequestToolChoice", Union[ToolChoice, ToolChoiceEnum] +) class ChatCompletionStreamRequestTypedDict(TypedDict): diff --git a/packages/mistralai_azure/src/mistralai_azure/models/contentchunk.py b/packages/mistralai_azure/src/mistralai_azure/models/contentchunk.py index e8013323..70c94e70 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/contentchunk.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/contentchunk.py @@ -6,10 +6,12 @@ from mistralai_azure.utils import get_discriminator from pydantic import Discriminator, Tag from typing import Union -from typing_extensions import Annotated +from typing_extensions import Annotated, TypeAliasType -ContentChunkTypedDict = Union[TextChunkTypedDict, ReferenceChunkTypedDict] +ContentChunkTypedDict = TypeAliasType( + "ContentChunkTypedDict", Union[TextChunkTypedDict, ReferenceChunkTypedDict] +) ContentChunk = Annotated[ diff --git a/packages/mistralai_azure/src/mistralai_azure/models/deltamessage.py b/packages/mistralai_azure/src/mistralai_azure/models/deltamessage.py index bb394494..112eb127 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/deltamessage.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/deltamessage.py @@ -12,13 +12,15 @@ ) from pydantic import model_serializer from typing import List, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -ContentTypedDict = Union[str, List[ContentChunkTypedDict]] +ContentTypedDict = TypeAliasType( + "ContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -Content = Union[str, List[ContentChunk]] +Content = TypeAliasType("Content", Union[str, List[ContentChunk]]) class DeltaMessageTypedDict(TypedDict): diff --git a/packages/mistralai_azure/src/mistralai_azure/models/functioncall.py b/packages/mistralai_azure/src/mistralai_azure/models/functioncall.py index d2f136cd..dd93c462 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/functioncall.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/functioncall.py @@ -3,13 +3,13 @@ from __future__ import annotations from mistralai_azure.types import BaseModel from typing import Any, Dict, Union -from typing_extensions import TypedDict +from typing_extensions import TypeAliasType, TypedDict -ArgumentsTypedDict = Union[Dict[str, Any], str] +ArgumentsTypedDict = TypeAliasType("ArgumentsTypedDict", Union[Dict[str, Any], str]) -Arguments = Union[Dict[str, Any], str] +Arguments = TypeAliasType("Arguments", Union[Dict[str, Any], str]) class FunctionCallTypedDict(TypedDict): diff --git a/packages/mistralai_azure/src/mistralai_azure/models/referencechunk.py b/packages/mistralai_azure/src/mistralai_azure/models/referencechunk.py index ddc89195..4df3bfbc 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/referencechunk.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/referencechunk.py @@ -2,11 +2,8 @@ from __future__ import annotations from mistralai_azure.types import BaseModel -from mistralai_azure.utils import validate_const -import pydantic -from pydantic.functional_validators import AfterValidator from typing import List, Literal, Optional -from typing_extensions import Annotated, TypedDict +from typing_extensions import NotRequired, TypedDict ReferenceChunkType = Literal["reference"] @@ -14,15 +11,10 @@ class ReferenceChunkTypedDict(TypedDict): reference_ids: List[int] - type: ReferenceChunkType + type: NotRequired[ReferenceChunkType] class ReferenceChunk(BaseModel): reference_ids: List[int] - TYPE: Annotated[ - Annotated[ - Optional[ReferenceChunkType], AfterValidator(validate_const("reference")) - ], - pydantic.Field(alias="type"), - ] = "reference" + type: Optional[ReferenceChunkType] = "reference" diff --git a/packages/mistralai_azure/src/mistralai_azure/models/systemmessage.py b/packages/mistralai_azure/src/mistralai_azure/models/systemmessage.py index 3c00a82b..b7d975b6 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/systemmessage.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/systemmessage.py @@ -4,13 +4,17 @@ from .textchunk import TextChunk, TextChunkTypedDict from mistralai_azure.types import BaseModel from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -SystemMessageContentTypedDict = Union[str, List[TextChunkTypedDict]] +SystemMessageContentTypedDict = TypeAliasType( + "SystemMessageContentTypedDict", Union[str, List[TextChunkTypedDict]] +) -SystemMessageContent = Union[str, List[TextChunk]] +SystemMessageContent = TypeAliasType( + "SystemMessageContent", Union[str, List[TextChunk]] +) Role = Literal["system"] diff --git a/packages/mistralai_azure/src/mistralai_azure/models/textchunk.py b/packages/mistralai_azure/src/mistralai_azure/models/textchunk.py index 583ce18d..be60c8f9 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/textchunk.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/textchunk.py @@ -2,11 +2,8 @@ from __future__ import annotations from mistralai_azure.types import BaseModel -from mistralai_azure.utils import validate_const -import pydantic -from pydantic.functional_validators import AfterValidator from typing import Literal, Optional -from typing_extensions import Annotated, TypedDict +from typing_extensions import NotRequired, TypedDict Type = Literal["text"] @@ -14,13 +11,10 @@ class TextChunkTypedDict(TypedDict): text: str - type: Type + type: NotRequired[Type] class TextChunk(BaseModel): text: str - TYPE: Annotated[ - Annotated[Optional[Type], AfterValidator(validate_const("text"))], - pydantic.Field(alias="type"), - ] = "text" + type: Optional[Type] = "text" diff --git a/packages/mistralai_azure/src/mistralai_azure/models/toolmessage.py b/packages/mistralai_azure/src/mistralai_azure/models/toolmessage.py index 1004c439..3e9aa3da 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/toolmessage.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/toolmessage.py @@ -11,13 +11,15 @@ ) from pydantic import model_serializer from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -ToolMessageContentTypedDict = Union[str, List[ContentChunkTypedDict]] +ToolMessageContentTypedDict = TypeAliasType( + "ToolMessageContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -ToolMessageContent = Union[str, List[ContentChunk]] +ToolMessageContent = TypeAliasType("ToolMessageContent", Union[str, List[ContentChunk]]) ToolMessageRole = Literal["tool"] diff --git a/packages/mistralai_azure/src/mistralai_azure/models/usermessage.py b/packages/mistralai_azure/src/mistralai_azure/models/usermessage.py index eddfb856..8cce1745 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/usermessage.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/usermessage.py @@ -5,13 +5,15 @@ from mistralai_azure.types import BaseModel, Nullable, UNSET_SENTINEL from pydantic import model_serializer from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -UserMessageContentTypedDict = Union[str, List[ContentChunkTypedDict]] +UserMessageContentTypedDict = TypeAliasType( + "UserMessageContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -UserMessageContent = Union[str, List[ContentChunk]] +UserMessageContent = TypeAliasType("UserMessageContent", Union[str, List[ContentChunk]]) UserMessageRole = Literal["user"] diff --git a/packages/mistralai_azure/src/mistralai_azure/models/validationerror.py b/packages/mistralai_azure/src/mistralai_azure/models/validationerror.py index aa8eaff9..4caff4a6 100644 --- a/packages/mistralai_azure/src/mistralai_azure/models/validationerror.py +++ b/packages/mistralai_azure/src/mistralai_azure/models/validationerror.py @@ -3,13 +3,13 @@ from __future__ import annotations from mistralai_azure.types import BaseModel from typing import List, Union -from typing_extensions import TypedDict +from typing_extensions import TypeAliasType, TypedDict -LocTypedDict = Union[str, int] +LocTypedDict = TypeAliasType("LocTypedDict", Union[str, int]) -Loc = Union[str, int] +Loc = TypeAliasType("Loc", Union[str, int]) class ValidationErrorTypedDict(TypedDict): diff --git a/packages/mistralai_azure/src/mistralai_azure/sdkconfiguration.py b/packages/mistralai_azure/src/mistralai_azure/sdkconfiguration.py index 8f64c457..191aa320 100644 --- a/packages/mistralai_azure/src/mistralai_azure/sdkconfiguration.py +++ b/packages/mistralai_azure/src/mistralai_azure/sdkconfiguration.py @@ -29,8 +29,8 @@ class SDKConfiguration: language: str = "python" openapi_doc_version: str = "0.0.2" sdk_version: str = "1.2.3" - gen_version: str = "2.460.1" - user_agent: str = "speakeasy-sdk/python 1.2.3 2.460.1 0.0.2 mistralai_azure" + gen_version: str = "2.470.1" + user_agent: str = "speakeasy-sdk/python 1.2.3 2.470.1 0.0.2 mistralai_azure" retry_config: OptionalNullable[RetryConfig] = Field(default_factory=lambda: UNSET) timeout_ms: Optional[int] = None diff --git a/packages/mistralai_azure/src/mistralai_azure/utils/annotations.py b/packages/mistralai_azure/src/mistralai_azure/utils/annotations.py index 5b3bbb02..387874ed 100644 --- a/packages/mistralai_azure/src/mistralai_azure/utils/annotations.py +++ b/packages/mistralai_azure/src/mistralai_azure/utils/annotations.py @@ -1,30 +1,55 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from enum import Enum -from typing import Any +from typing import Any, Optional def get_discriminator(model: Any, fieldname: str, key: str) -> str: - if isinstance(model, dict): - try: - return f'{model.get(key)}' - except AttributeError as e: - raise ValueError(f'Could not find discriminator key {key} in {model}') from e + """ + Recursively search for the discriminator attribute in a model. - if hasattr(model, fieldname): - attr = getattr(model, fieldname) + Args: + model (Any): The model to search within. + fieldname (str): The name of the field to search for. + key (str): The key to search for in dictionaries. - if isinstance(attr, Enum): - return f'{attr.value}' + Returns: + str: The name of the discriminator attribute. - return f'{attr}' + Raises: + ValueError: If the discriminator attribute is not found. + """ + upper_fieldname = fieldname.upper() - fieldname = fieldname.upper() - if hasattr(model, fieldname): - attr = getattr(model, fieldname) + def get_field_discriminator(field: Any) -> Optional[str]: + """Search for the discriminator attribute in a given field.""" - if isinstance(attr, Enum): - return f'{attr.value}' + if isinstance(field, dict): + if key in field: + return f'{field[key]}' - return f'{attr}' + if hasattr(field, fieldname): + attr = getattr(field, fieldname) + if isinstance(attr, Enum): + return f'{attr.value}' + return f'{attr}' + + if hasattr(field, upper_fieldname): + attr = getattr(field, upper_fieldname) + if isinstance(attr, Enum): + return f'{attr.value}' + return f'{attr}' + + return None + + + if isinstance(model, list): + for field in model: + discriminator = get_field_discriminator(field) + if discriminator is not None: + return discriminator + + discriminator = get_field_discriminator(model) + if discriminator is not None: + return discriminator raise ValueError(f'Could not find discriminator field {fieldname} in {model}') diff --git a/packages/mistralai_azure/src/mistralai_azure/utils/eventstreaming.py b/packages/mistralai_azure/src/mistralai_azure/utils/eventstreaming.py index 553b386b..74a63f75 100644 --- a/packages/mistralai_azure/src/mistralai_azure/utils/eventstreaming.py +++ b/packages/mistralai_azure/src/mistralai_azure/utils/eventstreaming.py @@ -2,12 +2,72 @@ import re import json -from typing import Callable, TypeVar, Optional, Generator, AsyncGenerator, Tuple +from typing import ( + Callable, + Generic, + TypeVar, + Optional, + Generator, + AsyncGenerator, + Tuple, +) import httpx T = TypeVar("T") +class EventStream(Generic[T]): + response: httpx.Response + generator: Generator[T, None, None] + + def __init__( + self, + response: httpx.Response, + decoder: Callable[[str], T], + sentinel: Optional[str] = None, + ): + self.response = response + self.generator = stream_events(response, decoder, sentinel) + + def __iter__(self): + return self + + def __next__(self): + return next(self.generator) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.response.close() + + +class EventStreamAsync(Generic[T]): + response: httpx.Response + generator: AsyncGenerator[T, None] + + def __init__( + self, + response: httpx.Response, + decoder: Callable[[str], T], + sentinel: Optional[str] = None, + ): + self.response = response + self.generator = stream_events_async(response, decoder, sentinel) + + def __aiter__(self): + return self + + async def __anext__(self): + return await self.generator.__anext__() + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.response.aclose() + + class ServerEvent: id: Optional[str] = None event: Optional[str] = None diff --git a/packages/mistralai_gcp/.speakeasy/gen.lock b/packages/mistralai_gcp/.speakeasy/gen.lock index 4ac979ee..ee99e6bb 100644 --- a/packages/mistralai_gcp/.speakeasy/gen.lock +++ b/packages/mistralai_gcp/.speakeasy/gen.lock @@ -1,10 +1,10 @@ lockVersion: 2.0.0 id: ec60f2d8-7869-45c1-918e-773d41a8cf74 management: - docChecksum: e6c0a4254e61b1f171b409862f717867 + docChecksum: d50a06ac34844141709fa2e57cc940c5 docVersion: 0.0.2 - speakeasyVersion: 1.440.1 - generationVersion: 2.460.1 + speakeasyVersion: 1.451.1 + generationVersion: 2.470.1 releaseVersion: 1.2.3 configChecksum: 3fc99d7ec7ee057a323b593ebf8fdb8c published: true @@ -12,7 +12,7 @@ features: python: additionalDependencies: 1.0.0 constsAndDefaults: 1.0.5 - core: 5.6.5 + core: 5.6.8 defaultEnabledRetries: 0.2.0 enumUnions: 0.1.0 envVarSecurityUsage: 0.3.2 @@ -29,11 +29,10 @@ features: responseFormat: 1.0.1 retries: 3.0.2 sdkHooks: 1.0.0 - serverEvents: 1.0.4 + serverEvents: 1.0.7 serverEventsSentinels: 0.1.0 serverIDs: 3.0.0 - tests: 1.6.0 - unions: 3.0.3 + unions: 3.0.4 generatedFiles: - .gitattributes - .python-version @@ -187,3 +186,4 @@ examples: "200": application/json: {"id": "cmpl-e5cc70bb28c444948073e77776eb30ef", "object": "chat.completion", "model": "codestral-latest", "usage": {"prompt_tokens": 16, "completion_tokens": 34, "total_tokens": 50}, "created": 1702256327, "choices": []} "422": {} +generatedTests: {} diff --git a/packages/mistralai_gcp/pyproject.toml b/packages/mistralai_gcp/pyproject.toml index f20d9b17..670c1e3a 100644 --- a/packages/mistralai_gcp/pyproject.toml +++ b/packages/mistralai_gcp/pyproject.toml @@ -22,12 +22,12 @@ google-auth = "2.27.0" httpx = "^0.27.0" jsonpath-python = "^1.0.6" pydantic = "~2.9.2" -python-dateutil = "2.8.2" +python-dateutil = "^2.8.2" requests = "^2.32.3" typing-inspect = "^0.9.0" [tool.poetry.group.dev.dependencies] -mypy = "==1.10.1" +mypy = "==1.13.0" pylint = "==3.2.3" pytest = "^8.2.2" pytest-asyncio = "^0.23.7" diff --git a/packages/mistralai_gcp/src/mistralai_gcp/chat.py b/packages/mistralai_gcp/src/mistralai_gcp/chat.py index 17913668..19c92651 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/chat.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/chat.py @@ -5,7 +5,7 @@ from mistralai_gcp._hooks import HookContext from mistralai_gcp.types import Nullable, OptionalNullable, UNSET from mistralai_gcp.utils import eventstreaming -from typing import Any, AsyncGenerator, Generator, List, Optional, Union +from typing import Any, List, Optional, Union class Chat(BaseSDK): @@ -40,7 +40,7 @@ def stream( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[Generator[models.CompletionEvent, None, None]]: + ) -> Optional[eventstreaming.EventStream[models.CompletionEvent]]: r"""Stream chat completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -132,7 +132,7 @@ def stream( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events( + return eventstreaming.EventStream( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", @@ -185,7 +185,7 @@ async def stream_async( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[AsyncGenerator[models.CompletionEvent, None]]: + ) -> Optional[eventstreaming.EventStreamAsync[models.CompletionEvent]]: r"""Stream chat completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -277,7 +277,7 @@ async def stream_async( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events_async( + return eventstreaming.EventStreamAsync( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", diff --git a/packages/mistralai_gcp/src/mistralai_gcp/fim.py b/packages/mistralai_gcp/src/mistralai_gcp/fim.py index fb3bf902..bddc010f 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/fim.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/fim.py @@ -5,7 +5,7 @@ from mistralai_gcp._hooks import HookContext from mistralai_gcp.types import Nullable, OptionalNullable, UNSET from mistralai_gcp.utils import eventstreaming -from typing import Any, AsyncGenerator, Generator, Optional, Union +from typing import Any, Optional, Union class Fim(BaseSDK): @@ -32,7 +32,7 @@ def stream( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[Generator[models.CompletionEvent, None, None]]: + ) -> Optional[eventstreaming.EventStream[models.CompletionEvent]]: r"""Stream fim completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -112,7 +112,7 @@ def stream( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events( + return eventstreaming.EventStream( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", @@ -157,7 +157,7 @@ async def stream_async( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[AsyncGenerator[models.CompletionEvent, None]]: + ) -> Optional[eventstreaming.EventStreamAsync[models.CompletionEvent]]: r"""Stream fim completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -237,7 +237,7 @@ async def stream_async( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events_async( + return eventstreaming.EventStreamAsync( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", diff --git a/packages/mistralai_gcp/src/mistralai_gcp/httpclient.py b/packages/mistralai_gcp/src/mistralai_gcp/httpclient.py index 36b642a0..167cea4e 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/httpclient.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/httpclient.py @@ -41,6 +41,9 @@ def build_request( ) -> httpx.Request: pass + def close(self) -> None: + pass + @runtime_checkable class AsyncHttpClient(Protocol): @@ -76,3 +79,6 @@ def build_request( extensions: Optional[httpx._types.RequestExtensions] = None, ) -> httpx.Request: pass + + async def aclose(self) -> None: + pass diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/assistantmessage.py b/packages/mistralai_gcp/src/mistralai_gcp/models/assistantmessage.py index f93a06cf..6a9b58f2 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/assistantmessage.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/assistantmessage.py @@ -12,13 +12,17 @@ ) from pydantic import model_serializer from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -AssistantMessageContentTypedDict = Union[str, List[ContentChunkTypedDict]] +AssistantMessageContentTypedDict = TypeAliasType( + "AssistantMessageContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -AssistantMessageContent = Union[str, List[ContentChunk]] +AssistantMessageContent = TypeAliasType( + "AssistantMessageContent", Union[str, List[ContentChunk]] +) AssistantMessageRole = Literal["assistant"] diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/chatcompletionrequest.py b/packages/mistralai_gcp/src/mistralai_gcp/models/chatcompletionrequest.py index 1f956d0a..b8ebfc91 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/chatcompletionrequest.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/chatcompletionrequest.py @@ -19,23 +19,30 @@ from mistralai_gcp.utils import get_discriminator from pydantic import Discriminator, Tag, model_serializer from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -ChatCompletionRequestStopTypedDict = Union[str, List[str]] +ChatCompletionRequestStopTypedDict = TypeAliasType( + "ChatCompletionRequestStopTypedDict", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -ChatCompletionRequestStop = Union[str, List[str]] +ChatCompletionRequestStop = TypeAliasType( + "ChatCompletionRequestStop", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -ChatCompletionRequestMessagesTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +ChatCompletionRequestMessagesTypedDict = TypeAliasType( + "ChatCompletionRequestMessagesTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) ChatCompletionRequestMessages = Annotated[ @@ -49,10 +56,15 @@ ] -ChatCompletionRequestToolChoiceTypedDict = Union[ToolChoiceTypedDict, ToolChoiceEnum] +ChatCompletionRequestToolChoiceTypedDict = TypeAliasType( + "ChatCompletionRequestToolChoiceTypedDict", + Union[ToolChoiceTypedDict, ToolChoiceEnum], +) -ChatCompletionRequestToolChoice = Union[ToolChoice, ToolChoiceEnum] +ChatCompletionRequestToolChoice = TypeAliasType( + "ChatCompletionRequestToolChoice", Union[ToolChoice, ToolChoiceEnum] +) class ChatCompletionRequestTypedDict(TypedDict): diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/chatcompletionstreamrequest.py b/packages/mistralai_gcp/src/mistralai_gcp/models/chatcompletionstreamrequest.py index f12a5477..b710a27d 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/chatcompletionstreamrequest.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/chatcompletionstreamrequest.py @@ -19,23 +19,26 @@ from mistralai_gcp.utils import get_discriminator from pydantic import Discriminator, Tag, model_serializer from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -StopTypedDict = Union[str, List[str]] +StopTypedDict = TypeAliasType("StopTypedDict", Union[str, List[str]]) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -Stop = Union[str, List[str]] +Stop = TypeAliasType("Stop", Union[str, List[str]]) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -MessagesTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +MessagesTypedDict = TypeAliasType( + "MessagesTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) Messages = Annotated[ @@ -49,12 +52,15 @@ ] -ChatCompletionStreamRequestToolChoiceTypedDict = Union[ - ToolChoiceTypedDict, ToolChoiceEnum -] +ChatCompletionStreamRequestToolChoiceTypedDict = TypeAliasType( + "ChatCompletionStreamRequestToolChoiceTypedDict", + Union[ToolChoiceTypedDict, ToolChoiceEnum], +) -ChatCompletionStreamRequestToolChoice = Union[ToolChoice, ToolChoiceEnum] +ChatCompletionStreamRequestToolChoice = TypeAliasType( + "ChatCompletionStreamRequestToolChoice", Union[ToolChoice, ToolChoiceEnum] +) class ChatCompletionStreamRequestTypedDict(TypedDict): diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/contentchunk.py b/packages/mistralai_gcp/src/mistralai_gcp/models/contentchunk.py index 1c882f7e..4da1153a 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/contentchunk.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/contentchunk.py @@ -6,10 +6,12 @@ from mistralai_gcp.utils import get_discriminator from pydantic import Discriminator, Tag from typing import Union -from typing_extensions import Annotated +from typing_extensions import Annotated, TypeAliasType -ContentChunkTypedDict = Union[TextChunkTypedDict, ReferenceChunkTypedDict] +ContentChunkTypedDict = TypeAliasType( + "ContentChunkTypedDict", Union[TextChunkTypedDict, ReferenceChunkTypedDict] +) ContentChunk = Annotated[ diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/deltamessage.py b/packages/mistralai_gcp/src/mistralai_gcp/models/deltamessage.py index bb540c96..f9f0868b 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/deltamessage.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/deltamessage.py @@ -12,13 +12,15 @@ ) from pydantic import model_serializer from typing import List, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -ContentTypedDict = Union[str, List[ContentChunkTypedDict]] +ContentTypedDict = TypeAliasType( + "ContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -Content = Union[str, List[ContentChunk]] +Content = TypeAliasType("Content", Union[str, List[ContentChunk]]) class DeltaMessageTypedDict(TypedDict): diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/fimcompletionrequest.py b/packages/mistralai_gcp/src/mistralai_gcp/models/fimcompletionrequest.py index 3a851768..81c87b7e 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/fimcompletionrequest.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/fimcompletionrequest.py @@ -10,14 +10,18 @@ ) from pydantic import model_serializer from typing import List, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -FIMCompletionRequestStopTypedDict = Union[str, List[str]] +FIMCompletionRequestStopTypedDict = TypeAliasType( + "FIMCompletionRequestStopTypedDict", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -FIMCompletionRequestStop = Union[str, List[str]] +FIMCompletionRequestStop = TypeAliasType( + "FIMCompletionRequestStop", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/fimcompletionstreamrequest.py b/packages/mistralai_gcp/src/mistralai_gcp/models/fimcompletionstreamrequest.py index f47937b9..356758d3 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/fimcompletionstreamrequest.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/fimcompletionstreamrequest.py @@ -10,14 +10,18 @@ ) from pydantic import model_serializer from typing import List, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -FIMCompletionStreamRequestStopTypedDict = Union[str, List[str]] +FIMCompletionStreamRequestStopTypedDict = TypeAliasType( + "FIMCompletionStreamRequestStopTypedDict", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -FIMCompletionStreamRequestStop = Union[str, List[str]] +FIMCompletionStreamRequestStop = TypeAliasType( + "FIMCompletionStreamRequestStop", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/functioncall.py b/packages/mistralai_gcp/src/mistralai_gcp/models/functioncall.py index 02da9bba..99554c88 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/functioncall.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/functioncall.py @@ -3,13 +3,13 @@ from __future__ import annotations from mistralai_gcp.types import BaseModel from typing import Any, Dict, Union -from typing_extensions import TypedDict +from typing_extensions import TypeAliasType, TypedDict -ArgumentsTypedDict = Union[Dict[str, Any], str] +ArgumentsTypedDict = TypeAliasType("ArgumentsTypedDict", Union[Dict[str, Any], str]) -Arguments = Union[Dict[str, Any], str] +Arguments = TypeAliasType("Arguments", Union[Dict[str, Any], str]) class FunctionCallTypedDict(TypedDict): diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/referencechunk.py b/packages/mistralai_gcp/src/mistralai_gcp/models/referencechunk.py index d409a70d..c4fa3b8b 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/referencechunk.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/referencechunk.py @@ -2,11 +2,8 @@ from __future__ import annotations from mistralai_gcp.types import BaseModel -from mistralai_gcp.utils import validate_const -import pydantic -from pydantic.functional_validators import AfterValidator from typing import List, Literal, Optional -from typing_extensions import Annotated, TypedDict +from typing_extensions import NotRequired, TypedDict ReferenceChunkType = Literal["reference"] @@ -14,15 +11,10 @@ class ReferenceChunkTypedDict(TypedDict): reference_ids: List[int] - type: ReferenceChunkType + type: NotRequired[ReferenceChunkType] class ReferenceChunk(BaseModel): reference_ids: List[int] - TYPE: Annotated[ - Annotated[ - Optional[ReferenceChunkType], AfterValidator(validate_const("reference")) - ], - pydantic.Field(alias="type"), - ] = "reference" + type: Optional[ReferenceChunkType] = "reference" diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/systemmessage.py b/packages/mistralai_gcp/src/mistralai_gcp/models/systemmessage.py index 87798558..f14acf12 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/systemmessage.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/systemmessage.py @@ -4,13 +4,17 @@ from .textchunk import TextChunk, TextChunkTypedDict from mistralai_gcp.types import BaseModel from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -SystemMessageContentTypedDict = Union[str, List[TextChunkTypedDict]] +SystemMessageContentTypedDict = TypeAliasType( + "SystemMessageContentTypedDict", Union[str, List[TextChunkTypedDict]] +) -SystemMessageContent = Union[str, List[TextChunk]] +SystemMessageContent = TypeAliasType( + "SystemMessageContent", Union[str, List[TextChunk]] +) Role = Literal["system"] diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/textchunk.py b/packages/mistralai_gcp/src/mistralai_gcp/models/textchunk.py index 48367e4e..12f666cd 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/textchunk.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/textchunk.py @@ -2,11 +2,8 @@ from __future__ import annotations from mistralai_gcp.types import BaseModel -from mistralai_gcp.utils import validate_const -import pydantic -from pydantic.functional_validators import AfterValidator from typing import Literal, Optional -from typing_extensions import Annotated, TypedDict +from typing_extensions import NotRequired, TypedDict Type = Literal["text"] @@ -14,13 +11,10 @@ class TextChunkTypedDict(TypedDict): text: str - type: Type + type: NotRequired[Type] class TextChunk(BaseModel): text: str - TYPE: Annotated[ - Annotated[Optional[Type], AfterValidator(validate_const("text"))], - pydantic.Field(alias="type"), - ] = "text" + type: Optional[Type] = "text" diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/toolmessage.py b/packages/mistralai_gcp/src/mistralai_gcp/models/toolmessage.py index ad6b800c..886b6ff1 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/toolmessage.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/toolmessage.py @@ -11,13 +11,15 @@ ) from pydantic import model_serializer from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -ToolMessageContentTypedDict = Union[str, List[ContentChunkTypedDict]] +ToolMessageContentTypedDict = TypeAliasType( + "ToolMessageContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -ToolMessageContent = Union[str, List[ContentChunk]] +ToolMessageContent = TypeAliasType("ToolMessageContent", Union[str, List[ContentChunk]]) ToolMessageRole = Literal["tool"] diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/usermessage.py b/packages/mistralai_gcp/src/mistralai_gcp/models/usermessage.py index 229dbaf9..287bb1b4 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/usermessage.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/usermessage.py @@ -5,13 +5,15 @@ from mistralai_gcp.types import BaseModel, Nullable, UNSET_SENTINEL from pydantic import model_serializer from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -UserMessageContentTypedDict = Union[str, List[ContentChunkTypedDict]] +UserMessageContentTypedDict = TypeAliasType( + "UserMessageContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -UserMessageContent = Union[str, List[ContentChunk]] +UserMessageContent = TypeAliasType("UserMessageContent", Union[str, List[ContentChunk]]) UserMessageRole = Literal["user"] diff --git a/packages/mistralai_gcp/src/mistralai_gcp/models/validationerror.py b/packages/mistralai_gcp/src/mistralai_gcp/models/validationerror.py index b8bd4345..033d4b63 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/models/validationerror.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/models/validationerror.py @@ -3,13 +3,13 @@ from __future__ import annotations from mistralai_gcp.types import BaseModel from typing import List, Union -from typing_extensions import TypedDict +from typing_extensions import TypeAliasType, TypedDict -LocTypedDict = Union[str, int] +LocTypedDict = TypeAliasType("LocTypedDict", Union[str, int]) -Loc = Union[str, int] +Loc = TypeAliasType("Loc", Union[str, int]) class ValidationErrorTypedDict(TypedDict): diff --git a/packages/mistralai_gcp/src/mistralai_gcp/sdk.py b/packages/mistralai_gcp/src/mistralai_gcp/sdk.py index 7e7adbdc..d2b41dcf 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/sdk.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/sdk.py @@ -26,11 +26,12 @@ "mistral-nemo-2407": "mistral-nemo@2407", } -def get_model_info(model: str) -> Tuple[str,str]: +def get_model_info(model: str) -> Tuple[str, str]: # if the model requiers the legacy fomat, use it, else do nothing. - model_id = LEGACY_MODEL_ID_FORMAT.get(model, model) - model = "-".join(model.split("-")[:-1]) - return model, model_id + if model in LEGACY_MODEL_ID_FORMAT: + return "-".join(model.split("-")[:-1]), LEGACY_MODEL_ID_FORMAT[model] + else: + return model, model diff --git a/packages/mistralai_gcp/src/mistralai_gcp/sdkconfiguration.py b/packages/mistralai_gcp/src/mistralai_gcp/sdkconfiguration.py index 061467eb..b5800815 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/sdkconfiguration.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/sdkconfiguration.py @@ -29,8 +29,8 @@ class SDKConfiguration: language: str = "python" openapi_doc_version: str = "0.0.2" sdk_version: str = "1.2.3" - gen_version: str = "2.460.1" - user_agent: str = "speakeasy-sdk/python 1.2.3 2.460.1 0.0.2 mistralai-gcp" + gen_version: str = "2.470.1" + user_agent: str = "speakeasy-sdk/python 1.2.3 2.470.1 0.0.2 mistralai-gcp" retry_config: OptionalNullable[RetryConfig] = Field(default_factory=lambda: UNSET) timeout_ms: Optional[int] = None diff --git a/packages/mistralai_gcp/src/mistralai_gcp/utils/annotations.py b/packages/mistralai_gcp/src/mistralai_gcp/utils/annotations.py index 5b3bbb02..387874ed 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/utils/annotations.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/utils/annotations.py @@ -1,30 +1,55 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from enum import Enum -from typing import Any +from typing import Any, Optional def get_discriminator(model: Any, fieldname: str, key: str) -> str: - if isinstance(model, dict): - try: - return f'{model.get(key)}' - except AttributeError as e: - raise ValueError(f'Could not find discriminator key {key} in {model}') from e + """ + Recursively search for the discriminator attribute in a model. - if hasattr(model, fieldname): - attr = getattr(model, fieldname) + Args: + model (Any): The model to search within. + fieldname (str): The name of the field to search for. + key (str): The key to search for in dictionaries. - if isinstance(attr, Enum): - return f'{attr.value}' + Returns: + str: The name of the discriminator attribute. - return f'{attr}' + Raises: + ValueError: If the discriminator attribute is not found. + """ + upper_fieldname = fieldname.upper() - fieldname = fieldname.upper() - if hasattr(model, fieldname): - attr = getattr(model, fieldname) + def get_field_discriminator(field: Any) -> Optional[str]: + """Search for the discriminator attribute in a given field.""" - if isinstance(attr, Enum): - return f'{attr.value}' + if isinstance(field, dict): + if key in field: + return f'{field[key]}' - return f'{attr}' + if hasattr(field, fieldname): + attr = getattr(field, fieldname) + if isinstance(attr, Enum): + return f'{attr.value}' + return f'{attr}' + + if hasattr(field, upper_fieldname): + attr = getattr(field, upper_fieldname) + if isinstance(attr, Enum): + return f'{attr.value}' + return f'{attr}' + + return None + + + if isinstance(model, list): + for field in model: + discriminator = get_field_discriminator(field) + if discriminator is not None: + return discriminator + + discriminator = get_field_discriminator(model) + if discriminator is not None: + return discriminator raise ValueError(f'Could not find discriminator field {fieldname} in {model}') diff --git a/packages/mistralai_gcp/src/mistralai_gcp/utils/eventstreaming.py b/packages/mistralai_gcp/src/mistralai_gcp/utils/eventstreaming.py index 553b386b..74a63f75 100644 --- a/packages/mistralai_gcp/src/mistralai_gcp/utils/eventstreaming.py +++ b/packages/mistralai_gcp/src/mistralai_gcp/utils/eventstreaming.py @@ -2,12 +2,72 @@ import re import json -from typing import Callable, TypeVar, Optional, Generator, AsyncGenerator, Tuple +from typing import ( + Callable, + Generic, + TypeVar, + Optional, + Generator, + AsyncGenerator, + Tuple, +) import httpx T = TypeVar("T") +class EventStream(Generic[T]): + response: httpx.Response + generator: Generator[T, None, None] + + def __init__( + self, + response: httpx.Response, + decoder: Callable[[str], T], + sentinel: Optional[str] = None, + ): + self.response = response + self.generator = stream_events(response, decoder, sentinel) + + def __iter__(self): + return self + + def __next__(self): + return next(self.generator) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.response.close() + + +class EventStreamAsync(Generic[T]): + response: httpx.Response + generator: AsyncGenerator[T, None] + + def __init__( + self, + response: httpx.Response, + decoder: Callable[[str], T], + sentinel: Optional[str] = None, + ): + self.response = response + self.generator = stream_events_async(response, decoder, sentinel) + + def __aiter__(self): + return self + + async def __anext__(self): + return await self.generator.__anext__() + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.response.aclose() + + class ServerEvent: id: Optional[str] = None event: Optional[str] = None diff --git a/pyproject.toml b/pyproject.toml index 7cd81a7a..ddd41722 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "mistralai" -version = "1.2.3" +version = "1.2.4" description = "Python Client SDK for the Mistral AI API." authors = ["Mistral"] readme = "README-PYPI.md" diff --git a/src/mistralai/_version.py b/src/mistralai/_version.py index 326a3e6e..41970f16 100644 --- a/src/mistralai/_version.py +++ b/src/mistralai/_version.py @@ -3,7 +3,7 @@ import importlib.metadata __title__: str = "mistralai" -__version__: str = "1.2.3" +__version__: str = "1.2.4" try: if __package__ is not None: diff --git a/src/mistralai/agents.py b/src/mistralai/agents.py index a45bcec3..246cab4e 100644 --- a/src/mistralai/agents.py +++ b/src/mistralai/agents.py @@ -5,7 +5,7 @@ from mistralai._hooks import HookContext from mistralai.types import OptionalNullable, UNSET from mistralai.utils import eventstreaming, get_security_from_env -from typing import Any, AsyncGenerator, Generator, List, Optional, Union +from typing import Any, List, Optional, Union class Agents(BaseSDK): @@ -336,7 +336,7 @@ def stream( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[Generator[models.CompletionEvent, None, None]]: + ) -> Optional[eventstreaming.EventStream[models.CompletionEvent]]: r"""Stream Agents completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -428,7 +428,7 @@ def stream( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events( + return eventstreaming.EventStream( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", @@ -487,7 +487,7 @@ async def stream_async( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[AsyncGenerator[models.CompletionEvent, None]]: + ) -> Optional[eventstreaming.EventStreamAsync[models.CompletionEvent]]: r"""Stream Agents completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -579,7 +579,7 @@ async def stream_async( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events_async( + return eventstreaming.EventStreamAsync( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", diff --git a/src/mistralai/chat.py b/src/mistralai/chat.py index 53313ca7..4b7aad3b 100644 --- a/src/mistralai/chat.py +++ b/src/mistralai/chat.py @@ -5,7 +5,7 @@ from mistralai._hooks import HookContext from mistralai.types import Nullable, OptionalNullable, UNSET from mistralai.utils import eventstreaming, get_security_from_env -from typing import Any, AsyncGenerator, Generator, List, Optional, Union +from typing import Any, List, Optional, Union class Chat(BaseSDK): @@ -337,7 +337,7 @@ def stream( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[Generator[models.CompletionEvent, None, None]]: + ) -> Optional[eventstreaming.EventStream[models.CompletionEvent]]: r"""Stream chat completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -435,7 +435,7 @@ def stream( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events( + return eventstreaming.EventStream( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", @@ -497,7 +497,7 @@ async def stream_async( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[AsyncGenerator[models.CompletionEvent, None]]: + ) -> Optional[eventstreaming.EventStreamAsync[models.CompletionEvent]]: r"""Stream chat completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -595,7 +595,7 @@ async def stream_async( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events_async( + return eventstreaming.EventStreamAsync( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", diff --git a/src/mistralai/files.py b/src/mistralai/files.py index 6cf0fcb7..e2977be2 100644 --- a/src/mistralai/files.py +++ b/src/mistralai/files.py @@ -891,3 +891,169 @@ async def download_async( http_res_text, http_res, ) + + def get_signed_url( + self, + *, + file_id: str, + expiry: Optional[int] = 24, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + ) -> Optional[models.FileSignedURL]: + r"""Get Signed Url + + :param file_id: + :param expiry: Number of hours before the url becomes invalid. Defaults to 24h + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + + request = models.FilesAPIRoutesGetSignedURLRequest( + file_id=file_id, + expiry=expiry, + ) + + req = self.build_request( + method="GET", + path="/v1/files/{file_id}/url", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = self.do_request( + hook_ctx=HookContext( + operation_id="files_api_routes_get_signed_url", + oauth2_scopes=[], + security_source=get_security_from_env( + self.sdk_configuration.security, models.Security + ), + ), + request=req, + error_status_codes=["4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.FileSignedURL]) + if utils.match_response(http_res, ["4XX", "5XX"], "*"): + http_res_text = utils.stream_to_text(http_res) + raise models.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = utils.stream_to_text(http_res) + raise models.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) + + async def get_signed_url_async( + self, + *, + file_id: str, + expiry: Optional[int] = 24, + retries: OptionalNullable[utils.RetryConfig] = UNSET, + server_url: Optional[str] = None, + timeout_ms: Optional[int] = None, + ) -> Optional[models.FileSignedURL]: + r"""Get Signed Url + + :param file_id: + :param expiry: Number of hours before the url becomes invalid. Defaults to 24h + :param retries: Override the default retry configuration for this method + :param server_url: Override the default server URL for this method + :param timeout_ms: Override the default request timeout configuration for this method in milliseconds + """ + base_url = None + url_variables = None + if timeout_ms is None: + timeout_ms = self.sdk_configuration.timeout_ms + + if server_url is not None: + base_url = server_url + + request = models.FilesAPIRoutesGetSignedURLRequest( + file_id=file_id, + expiry=expiry, + ) + + req = self.build_request_async( + method="GET", + path="/v1/files/{file_id}/url", + base_url=base_url, + url_variables=url_variables, + request=request, + request_body_required=False, + request_has_path_params=True, + request_has_query_params=True, + user_agent_header="user-agent", + accept_header_value="application/json", + security=self.sdk_configuration.security, + timeout_ms=timeout_ms, + ) + + if retries == UNSET: + if self.sdk_configuration.retry_config is not UNSET: + retries = self.sdk_configuration.retry_config + + retry_config = None + if isinstance(retries, utils.RetryConfig): + retry_config = (retries, ["429", "500", "502", "503", "504"]) + + http_res = await self.do_request_async( + hook_ctx=HookContext( + operation_id="files_api_routes_get_signed_url", + oauth2_scopes=[], + security_source=get_security_from_env( + self.sdk_configuration.security, models.Security + ), + ), + request=req, + error_status_codes=["4XX", "5XX"], + retry_config=retry_config, + ) + + if utils.match_response(http_res, "200", "application/json"): + return utils.unmarshal_json(http_res.text, Optional[models.FileSignedURL]) + if utils.match_response(http_res, ["4XX", "5XX"], "*"): + http_res_text = await utils.stream_to_text_async(http_res) + raise models.SDKError( + "API error occurred", http_res.status_code, http_res_text, http_res + ) + + content_type = http_res.headers.get("Content-Type") + http_res_text = await utils.stream_to_text_async(http_res) + raise models.SDKError( + f"Unexpected response received (code: {http_res.status_code}, type: {content_type})", + http_res.status_code, + http_res_text, + http_res, + ) diff --git a/src/mistralai/fim.py b/src/mistralai/fim.py index 8f8c8529..6f036311 100644 --- a/src/mistralai/fim.py +++ b/src/mistralai/fim.py @@ -5,7 +5,7 @@ from mistralai._hooks import HookContext from mistralai.types import Nullable, OptionalNullable, UNSET from mistralai.utils import eventstreaming, get_security_from_env -from typing import Any, AsyncGenerator, Generator, Optional, Union +from typing import Any, Optional, Union class Fim(BaseSDK): @@ -278,7 +278,7 @@ def stream( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[Generator[models.CompletionEvent, None, None]]: + ) -> Optional[eventstreaming.EventStream[models.CompletionEvent]]: r"""Stream fim completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -360,7 +360,7 @@ def stream( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events( + return eventstreaming.EventStream( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", @@ -405,7 +405,7 @@ async def stream_async( retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, - ) -> Optional[AsyncGenerator[models.CompletionEvent, None]]: + ) -> Optional[eventstreaming.EventStreamAsync[models.CompletionEvent]]: r"""Stream fim completion Mistral AI provides the ability to stream responses back to a client in order to allow partial results for certain requests. Tokens will be sent as data-only server-sent events as they become available, with the stream terminated by a data: [DONE] message. Otherwise, the server will hold the request open until the timeout or until completion, with the response containing the full result as JSON. @@ -487,7 +487,7 @@ async def stream_async( data: Any = None if utils.match_response(http_res, "200", "text/event-stream"): - return eventstreaming.stream_events_async( + return eventstreaming.EventStreamAsync( http_res, lambda raw: utils.unmarshal_json(raw, models.CompletionEvent), sentinel="[DONE]", diff --git a/src/mistralai/httpclient.py b/src/mistralai/httpclient.py index 36b642a0..167cea4e 100644 --- a/src/mistralai/httpclient.py +++ b/src/mistralai/httpclient.py @@ -41,6 +41,9 @@ def build_request( ) -> httpx.Request: pass + def close(self) -> None: + pass + @runtime_checkable class AsyncHttpClient(Protocol): @@ -76,3 +79,6 @@ def build_request( extensions: Optional[httpx._types.RequestExtensions] = None, ) -> httpx.Request: pass + + async def aclose(self) -> None: + pass diff --git a/src/mistralai/jobs.py b/src/mistralai/jobs.py index 9f472de1..17085b9d 100644 --- a/src/mistralai/jobs.py +++ b/src/mistralai/jobs.py @@ -225,7 +225,7 @@ async def list_async( def create( self, *, - model: models.FineTuneableModel, + model: str, hyperparameters: Union[ models.TrainingParametersIn, models.TrainingParametersInTypedDict ], @@ -354,7 +354,7 @@ def create( async def create_async( self, *, - model: models.FineTuneableModel, + model: str, hyperparameters: Union[ models.TrainingParametersIn, models.TrainingParametersInTypedDict ], diff --git a/src/mistralai/models/__init__.py b/src/mistralai/models/__init__.py index c62bebc1..4e7e4d12 100644 --- a/src/mistralai/models/__init__.py +++ b/src/mistralai/models/__init__.py @@ -133,6 +133,10 @@ FilesAPIRoutesDownloadFileRequest, FilesAPIRoutesDownloadFileRequestTypedDict, ) +from .files_api_routes_get_signed_urlop import ( + FilesAPIRoutesGetSignedURLRequest, + FilesAPIRoutesGetSignedURLRequestTypedDict, +) from .files_api_routes_list_filesop import ( FilesAPIRoutesListFilesRequest, FilesAPIRoutesListFilesRequestTypedDict, @@ -148,6 +152,7 @@ FilesAPIRoutesUploadFileMultiPartBodyParamsTypedDict, ) from .fileschema import FileSchema, FileSchemaTypedDict +from .filesignedurl import FileSignedURL, FileSignedURLTypedDict from .fimcompletionrequest import ( FIMCompletionRequest, FIMCompletionRequestStop, @@ -161,7 +166,6 @@ FIMCompletionStreamRequestStopTypedDict, FIMCompletionStreamRequestTypedDict, ) -from .finetuneablemodel import FineTuneableModel from .ftmodelcapabilitiesout import ( FTModelCapabilitiesOut, FTModelCapabilitiesOutTypedDict, @@ -468,18 +472,21 @@ "FilePurpose", "FileSchema", "FileSchemaTypedDict", + "FileSignedURL", + "FileSignedURLTypedDict", "FileTypedDict", "FilesAPIRoutesDeleteFileRequest", "FilesAPIRoutesDeleteFileRequestTypedDict", "FilesAPIRoutesDownloadFileRequest", "FilesAPIRoutesDownloadFileRequestTypedDict", + "FilesAPIRoutesGetSignedURLRequest", + "FilesAPIRoutesGetSignedURLRequestTypedDict", "FilesAPIRoutesListFilesRequest", "FilesAPIRoutesListFilesRequestTypedDict", "FilesAPIRoutesRetrieveFileRequest", "FilesAPIRoutesRetrieveFileRequestTypedDict", "FilesAPIRoutesUploadFileMultiPartBodyParams", "FilesAPIRoutesUploadFileMultiPartBodyParamsTypedDict", - "FineTuneableModel", "FinishReason", "Function", "FunctionCall", diff --git a/src/mistralai/models/agentscompletionrequest.py b/src/mistralai/models/agentscompletionrequest.py index bce326a5..5f53dddb 100644 --- a/src/mistralai/models/agentscompletionrequest.py +++ b/src/mistralai/models/agentscompletionrequest.py @@ -13,23 +13,30 @@ from mistralai.utils import get_discriminator from pydantic import Discriminator, Tag, model_serializer from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -AgentsCompletionRequestStopTypedDict = Union[str, List[str]] +AgentsCompletionRequestStopTypedDict = TypeAliasType( + "AgentsCompletionRequestStopTypedDict", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -AgentsCompletionRequestStop = Union[str, List[str]] +AgentsCompletionRequestStop = TypeAliasType( + "AgentsCompletionRequestStop", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -AgentsCompletionRequestMessagesTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +AgentsCompletionRequestMessagesTypedDict = TypeAliasType( + "AgentsCompletionRequestMessagesTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) AgentsCompletionRequestMessages = Annotated[ @@ -43,10 +50,15 @@ ] -AgentsCompletionRequestToolChoiceTypedDict = Union[ToolChoiceTypedDict, ToolChoiceEnum] +AgentsCompletionRequestToolChoiceTypedDict = TypeAliasType( + "AgentsCompletionRequestToolChoiceTypedDict", + Union[ToolChoiceTypedDict, ToolChoiceEnum], +) -AgentsCompletionRequestToolChoice = Union[ToolChoice, ToolChoiceEnum] +AgentsCompletionRequestToolChoice = TypeAliasType( + "AgentsCompletionRequestToolChoice", Union[ToolChoice, ToolChoiceEnum] +) class AgentsCompletionRequestTypedDict(TypedDict): diff --git a/src/mistralai/models/agentscompletionstreamrequest.py b/src/mistralai/models/agentscompletionstreamrequest.py index 94cc983a..fdc15328 100644 --- a/src/mistralai/models/agentscompletionstreamrequest.py +++ b/src/mistralai/models/agentscompletionstreamrequest.py @@ -13,23 +13,30 @@ from mistralai.utils import get_discriminator from pydantic import Discriminator, Tag, model_serializer from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -AgentsCompletionStreamRequestStopTypedDict = Union[str, List[str]] +AgentsCompletionStreamRequestStopTypedDict = TypeAliasType( + "AgentsCompletionStreamRequestStopTypedDict", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -AgentsCompletionStreamRequestStop = Union[str, List[str]] +AgentsCompletionStreamRequestStop = TypeAliasType( + "AgentsCompletionStreamRequestStop", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -AgentsCompletionStreamRequestMessagesTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +AgentsCompletionStreamRequestMessagesTypedDict = TypeAliasType( + "AgentsCompletionStreamRequestMessagesTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) AgentsCompletionStreamRequestMessages = Annotated[ @@ -43,12 +50,15 @@ ] -AgentsCompletionStreamRequestToolChoiceTypedDict = Union[ - ToolChoiceTypedDict, ToolChoiceEnum -] +AgentsCompletionStreamRequestToolChoiceTypedDict = TypeAliasType( + "AgentsCompletionStreamRequestToolChoiceTypedDict", + Union[ToolChoiceTypedDict, ToolChoiceEnum], +) -AgentsCompletionStreamRequestToolChoice = Union[ToolChoice, ToolChoiceEnum] +AgentsCompletionStreamRequestToolChoice = TypeAliasType( + "AgentsCompletionStreamRequestToolChoice", Union[ToolChoice, ToolChoiceEnum] +) class AgentsCompletionStreamRequestTypedDict(TypedDict): diff --git a/src/mistralai/models/apiendpoint.py b/src/mistralai/models/apiendpoint.py index 00621eba..a1b42e88 100644 --- a/src/mistralai/models/apiendpoint.py +++ b/src/mistralai/models/apiendpoint.py @@ -1,9 +1,17 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from typing import Literal +from mistralai.types import UnrecognizedStr +from typing import Literal, Union -APIEndpoint = Literal[ - "/v1/chat/completions", "/v1/embeddings", "/v1/fim/completions", "/v1/moderations" +APIEndpoint = Union[ + Literal[ + "/v1/chat/completions", + "/v1/embeddings", + "/v1/fim/completions", + "/v1/moderations", + "/v1/chat/moderations", + ], + UnrecognizedStr, ] diff --git a/src/mistralai/models/assistantmessage.py b/src/mistralai/models/assistantmessage.py index d7b929bf..c9a28945 100644 --- a/src/mistralai/models/assistantmessage.py +++ b/src/mistralai/models/assistantmessage.py @@ -6,13 +6,17 @@ from mistralai.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL from pydantic import model_serializer from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -AssistantMessageContentTypedDict = Union[str, List[ContentChunkTypedDict]] +AssistantMessageContentTypedDict = TypeAliasType( + "AssistantMessageContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -AssistantMessageContent = Union[str, List[ContentChunk]] +AssistantMessageContent = TypeAliasType( + "AssistantMessageContent", Union[str, List[ContentChunk]] +) AssistantMessageRole = Literal["assistant"] diff --git a/src/mistralai/models/batchjobin.py b/src/mistralai/models/batchjobin.py index 20f054b8..e249e526 100644 --- a/src/mistralai/models/batchjobin.py +++ b/src/mistralai/models/batchjobin.py @@ -3,9 +3,11 @@ from __future__ import annotations from .apiendpoint import APIEndpoint from mistralai.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL +from mistralai.utils import validate_open_enum from pydantic import model_serializer +from pydantic.functional_validators import PlainValidator from typing import Dict, List, Optional -from typing_extensions import NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypedDict class BatchJobInTypedDict(TypedDict): @@ -19,7 +21,7 @@ class BatchJobInTypedDict(TypedDict): class BatchJobIn(BaseModel): input_files: List[str] - endpoint: APIEndpoint + endpoint: Annotated[APIEndpoint, PlainValidator(validate_open_enum(False))] model: str diff --git a/src/mistralai/models/chatclassificationrequest.py b/src/mistralai/models/chatclassificationrequest.py index 6b4cc136..6f3967dc 100644 --- a/src/mistralai/models/chatclassificationrequest.py +++ b/src/mistralai/models/chatclassificationrequest.py @@ -10,15 +10,18 @@ import pydantic from pydantic import Discriminator, Tag, model_serializer from typing import List, Union -from typing_extensions import Annotated, TypedDict +from typing_extensions import Annotated, TypeAliasType, TypedDict -TwoTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +TwoTypedDict = TypeAliasType( + "TwoTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) Two = Annotated[ @@ -32,12 +35,15 @@ ] -OneTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +OneTypedDict = TypeAliasType( + "OneTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) One = Annotated[ @@ -51,13 +57,16 @@ ] -ChatClassificationRequestInputsTypedDict = Union[ - List[OneTypedDict], List[List[TwoTypedDict]] -] +ChatClassificationRequestInputsTypedDict = TypeAliasType( + "ChatClassificationRequestInputsTypedDict", + Union[List[OneTypedDict], List[List[TwoTypedDict]]], +) r"""Chat to classify""" -ChatClassificationRequestInputs = Union[List[One], List[List[Two]]] +ChatClassificationRequestInputs = TypeAliasType( + "ChatClassificationRequestInputs", Union[List[One], List[List[Two]]] +) r"""Chat to classify""" diff --git a/src/mistralai/models/chatcompletionrequest.py b/src/mistralai/models/chatcompletionrequest.py index b3435d52..195ea593 100644 --- a/src/mistralai/models/chatcompletionrequest.py +++ b/src/mistralai/models/chatcompletionrequest.py @@ -13,23 +13,26 @@ from mistralai.utils import get_discriminator from pydantic import Discriminator, Tag, model_serializer from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -StopTypedDict = Union[str, List[str]] +StopTypedDict = TypeAliasType("StopTypedDict", Union[str, List[str]]) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -Stop = Union[str, List[str]] +Stop = TypeAliasType("Stop", Union[str, List[str]]) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -MessagesTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +MessagesTypedDict = TypeAliasType( + "MessagesTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) Messages = Annotated[ @@ -43,10 +46,15 @@ ] -ChatCompletionRequestToolChoiceTypedDict = Union[ToolChoiceTypedDict, ToolChoiceEnum] +ChatCompletionRequestToolChoiceTypedDict = TypeAliasType( + "ChatCompletionRequestToolChoiceTypedDict", + Union[ToolChoiceTypedDict, ToolChoiceEnum], +) -ChatCompletionRequestToolChoice = Union[ToolChoice, ToolChoiceEnum] +ChatCompletionRequestToolChoice = TypeAliasType( + "ChatCompletionRequestToolChoice", Union[ToolChoice, ToolChoiceEnum] +) class ChatCompletionRequestTypedDict(TypedDict): diff --git a/src/mistralai/models/chatcompletionstreamrequest.py b/src/mistralai/models/chatcompletionstreamrequest.py index a98eb335..fee65092 100644 --- a/src/mistralai/models/chatcompletionstreamrequest.py +++ b/src/mistralai/models/chatcompletionstreamrequest.py @@ -13,23 +13,30 @@ from mistralai.utils import get_discriminator from pydantic import Discriminator, Tag, model_serializer from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -ChatCompletionStreamRequestStopTypedDict = Union[str, List[str]] +ChatCompletionStreamRequestStopTypedDict = TypeAliasType( + "ChatCompletionStreamRequestStopTypedDict", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -ChatCompletionStreamRequestStop = Union[str, List[str]] +ChatCompletionStreamRequestStop = TypeAliasType( + "ChatCompletionStreamRequestStop", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -ChatCompletionStreamRequestMessagesTypedDict = Union[ - SystemMessageTypedDict, - UserMessageTypedDict, - AssistantMessageTypedDict, - ToolMessageTypedDict, -] +ChatCompletionStreamRequestMessagesTypedDict = TypeAliasType( + "ChatCompletionStreamRequestMessagesTypedDict", + Union[ + SystemMessageTypedDict, + UserMessageTypedDict, + AssistantMessageTypedDict, + ToolMessageTypedDict, + ], +) ChatCompletionStreamRequestMessages = Annotated[ @@ -43,12 +50,15 @@ ] -ChatCompletionStreamRequestToolChoiceTypedDict = Union[ - ToolChoiceTypedDict, ToolChoiceEnum -] +ChatCompletionStreamRequestToolChoiceTypedDict = TypeAliasType( + "ChatCompletionStreamRequestToolChoiceTypedDict", + Union[ToolChoiceTypedDict, ToolChoiceEnum], +) -ChatCompletionStreamRequestToolChoice = Union[ToolChoice, ToolChoiceEnum] +ChatCompletionStreamRequestToolChoice = TypeAliasType( + "ChatCompletionStreamRequestToolChoice", Union[ToolChoice, ToolChoiceEnum] +) class ChatCompletionStreamRequestTypedDict(TypedDict): diff --git a/src/mistralai/models/classificationrequest.py b/src/mistralai/models/classificationrequest.py index d2426c4d..d18ffa61 100644 --- a/src/mistralai/models/classificationrequest.py +++ b/src/mistralai/models/classificationrequest.py @@ -5,14 +5,18 @@ import pydantic from pydantic import model_serializer from typing import List, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -ClassificationRequestInputsTypedDict = Union[str, List[str]] +ClassificationRequestInputsTypedDict = TypeAliasType( + "ClassificationRequestInputsTypedDict", Union[str, List[str]] +) r"""Text to classify.""" -ClassificationRequestInputs = Union[str, List[str]] +ClassificationRequestInputs = TypeAliasType( + "ClassificationRequestInputs", Union[str, List[str]] +) r"""Text to classify.""" diff --git a/src/mistralai/models/contentchunk.py b/src/mistralai/models/contentchunk.py index 717ba828..feeda7cd 100644 --- a/src/mistralai/models/contentchunk.py +++ b/src/mistralai/models/contentchunk.py @@ -7,12 +7,13 @@ from mistralai.utils import get_discriminator from pydantic import Discriminator, Tag from typing import Union -from typing_extensions import Annotated +from typing_extensions import Annotated, TypeAliasType -ContentChunkTypedDict = Union[ - TextChunkTypedDict, ImageURLChunkTypedDict, ReferenceChunkTypedDict -] +ContentChunkTypedDict = TypeAliasType( + "ContentChunkTypedDict", + Union[TextChunkTypedDict, ImageURLChunkTypedDict, ReferenceChunkTypedDict], +) ContentChunk = Annotated[ diff --git a/src/mistralai/models/deltamessage.py b/src/mistralai/models/deltamessage.py index 7a966e09..b46cf641 100644 --- a/src/mistralai/models/deltamessage.py +++ b/src/mistralai/models/deltamessage.py @@ -6,13 +6,15 @@ from mistralai.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL from pydantic import model_serializer from typing import List, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -ContentTypedDict = Union[str, List[ContentChunkTypedDict]] +ContentTypedDict = TypeAliasType( + "ContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -Content = Union[str, List[ContentChunk]] +Content = TypeAliasType("Content", Union[str, List[ContentChunk]]) class DeltaMessageTypedDict(TypedDict): diff --git a/src/mistralai/models/detailedjobout.py b/src/mistralai/models/detailedjobout.py index a4be707d..b2a1c8d9 100644 --- a/src/mistralai/models/detailedjobout.py +++ b/src/mistralai/models/detailedjobout.py @@ -3,7 +3,6 @@ from __future__ import annotations from .checkpointout import CheckpointOut, CheckpointOutTypedDict from .eventout import EventOut, EventOutTypedDict -from .finetuneablemodel import FineTuneableModel from .githubrepositoryout import GithubRepositoryOut, GithubRepositoryOutTypedDict from .jobmetadataout import JobMetadataOut, JobMetadataOutTypedDict from .trainingparameters import TrainingParameters, TrainingParametersTypedDict @@ -48,7 +47,7 @@ class DetailedJobOutTypedDict(TypedDict): id: str auto_start: bool hyperparameters: TrainingParametersTypedDict - model: FineTuneableModel + model: str r"""The name of the model to fine-tune.""" status: DetailedJobOutStatus job_type: str @@ -75,7 +74,7 @@ class DetailedJobOut(BaseModel): hyperparameters: TrainingParameters - model: FineTuneableModel + model: str r"""The name of the model to fine-tune.""" status: DetailedJobOutStatus diff --git a/src/mistralai/models/embeddingrequest.py b/src/mistralai/models/embeddingrequest.py index 61e181ce..4de8c312 100644 --- a/src/mistralai/models/embeddingrequest.py +++ b/src/mistralai/models/embeddingrequest.py @@ -5,14 +5,14 @@ import pydantic from pydantic import model_serializer from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -InputsTypedDict = Union[str, List[str]] +InputsTypedDict = TypeAliasType("InputsTypedDict", Union[str, List[str]]) r"""Text to embed.""" -Inputs = Union[str, List[str]] +Inputs = TypeAliasType("Inputs", Union[str, List[str]]) r"""Text to embed.""" diff --git a/src/mistralai/models/files_api_routes_get_signed_urlop.py b/src/mistralai/models/files_api_routes_get_signed_urlop.py new file mode 100644 index 00000000..708d40ab --- /dev/null +++ b/src/mistralai/models/files_api_routes_get_signed_urlop.py @@ -0,0 +1,25 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from mistralai.types import BaseModel +from mistralai.utils import FieldMetadata, PathParamMetadata, QueryParamMetadata +from typing import Optional +from typing_extensions import Annotated, NotRequired, TypedDict + + +class FilesAPIRoutesGetSignedURLRequestTypedDict(TypedDict): + file_id: str + expiry: NotRequired[int] + r"""Number of hours before the url becomes invalid. Defaults to 24h""" + + +class FilesAPIRoutesGetSignedURLRequest(BaseModel): + file_id: Annotated[ + str, FieldMetadata(path=PathParamMetadata(style="simple", explode=False)) + ] + + expiry: Annotated[ + Optional[int], + FieldMetadata(query=QueryParamMetadata(style="form", explode=True)), + ] = 24 + r"""Number of hours before the url becomes invalid. Defaults to 24h""" diff --git a/src/mistralai/models/filesignedurl.py b/src/mistralai/models/filesignedurl.py new file mode 100644 index 00000000..092be7f8 --- /dev/null +++ b/src/mistralai/models/filesignedurl.py @@ -0,0 +1,13 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from mistralai.types import BaseModel +from typing_extensions import TypedDict + + +class FileSignedURLTypedDict(TypedDict): + url: str + + +class FileSignedURL(BaseModel): + url: str diff --git a/src/mistralai/models/fimcompletionrequest.py b/src/mistralai/models/fimcompletionrequest.py index 409aa256..fb72ba41 100644 --- a/src/mistralai/models/fimcompletionrequest.py +++ b/src/mistralai/models/fimcompletionrequest.py @@ -4,14 +4,18 @@ from mistralai.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL from pydantic import model_serializer from typing import List, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -FIMCompletionRequestStopTypedDict = Union[str, List[str]] +FIMCompletionRequestStopTypedDict = TypeAliasType( + "FIMCompletionRequestStopTypedDict", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -FIMCompletionRequestStop = Union[str, List[str]] +FIMCompletionRequestStop = TypeAliasType( + "FIMCompletionRequestStop", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" diff --git a/src/mistralai/models/fimcompletionstreamrequest.py b/src/mistralai/models/fimcompletionstreamrequest.py index 8f9c1dac..5e16a170 100644 --- a/src/mistralai/models/fimcompletionstreamrequest.py +++ b/src/mistralai/models/fimcompletionstreamrequest.py @@ -4,14 +4,18 @@ from mistralai.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL from pydantic import model_serializer from typing import List, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -FIMCompletionStreamRequestStopTypedDict = Union[str, List[str]] +FIMCompletionStreamRequestStopTypedDict = TypeAliasType( + "FIMCompletionStreamRequestStopTypedDict", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" -FIMCompletionStreamRequestStop = Union[str, List[str]] +FIMCompletionStreamRequestStop = TypeAliasType( + "FIMCompletionStreamRequestStop", Union[str, List[str]] +) r"""Stop generation if this token is detected. Or if one of these tokens is detected when providing an array""" diff --git a/src/mistralai/models/finetuneablemodel.py b/src/mistralai/models/finetuneablemodel.py deleted file mode 100644 index 947991c2..00000000 --- a/src/mistralai/models/finetuneablemodel.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" - -from __future__ import annotations -from typing import Literal - - -FineTuneableModel = Literal[ - "open-mistral-7b", - "mistral-small-latest", - "codestral-latest", - "mistral-large-latest", - "open-mistral-nemo", -] -r"""The name of the model to fine-tune.""" diff --git a/src/mistralai/models/functioncall.py b/src/mistralai/models/functioncall.py index a57d2350..0cce622a 100644 --- a/src/mistralai/models/functioncall.py +++ b/src/mistralai/models/functioncall.py @@ -3,13 +3,13 @@ from __future__ import annotations from mistralai.types import BaseModel from typing import Any, Dict, Union -from typing_extensions import TypedDict +from typing_extensions import TypeAliasType, TypedDict -ArgumentsTypedDict = Union[Dict[str, Any], str] +ArgumentsTypedDict = TypeAliasType("ArgumentsTypedDict", Union[Dict[str, Any], str]) -Arguments = Union[Dict[str, Any], str] +Arguments = TypeAliasType("Arguments", Union[Dict[str, Any], str]) class FunctionCallTypedDict(TypedDict): diff --git a/src/mistralai/models/imageurlchunk.py b/src/mistralai/models/imageurlchunk.py index 1c37fe3b..498690f5 100644 --- a/src/mistralai/models/imageurlchunk.py +++ b/src/mistralai/models/imageurlchunk.py @@ -3,26 +3,26 @@ from __future__ import annotations from .imageurl import ImageURL, ImageURLTypedDict from mistralai.types import BaseModel -from mistralai.utils import validate_const -import pydantic -from pydantic.functional_validators import AfterValidator from typing import Literal, Optional, Union -from typing_extensions import Annotated, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -ImageURLChunkType = Literal["image_url"] +ImageURLChunkImageURLTypedDict = TypeAliasType( + "ImageURLChunkImageURLTypedDict", Union[ImageURLTypedDict, str] +) + -ImageURLChunkImageURLTypedDict = Union[ImageURLTypedDict, str] +ImageURLChunkImageURL = TypeAliasType("ImageURLChunkImageURL", Union[ImageURL, str]) -ImageURLChunkImageURL = Union[ImageURL, str] +ImageURLChunkType = Literal["image_url"] class ImageURLChunkTypedDict(TypedDict): r"""{\"type\":\"image_url\",\"image_url\":{\"url\":\"data:image/png;base64,iVBORw0""" image_url: ImageURLChunkImageURLTypedDict - type: ImageURLChunkType + type: NotRequired[ImageURLChunkType] class ImageURLChunk(BaseModel): @@ -30,9 +30,4 @@ class ImageURLChunk(BaseModel): image_url: ImageURLChunkImageURL - TYPE: Annotated[ - Annotated[ - Optional[ImageURLChunkType], AfterValidator(validate_const("image_url")) - ], - pydantic.Field(alias="type"), - ] = "image_url" + type: Optional[ImageURLChunkType] = "image_url" diff --git a/src/mistralai/models/jobin.py b/src/mistralai/models/jobin.py index a294d292..0ef66da3 100644 --- a/src/mistralai/models/jobin.py +++ b/src/mistralai/models/jobin.py @@ -1,7 +1,6 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from .finetuneablemodel import FineTuneableModel from .githubrepositoryin import GithubRepositoryIn, GithubRepositoryInTypedDict from .trainingfile import TrainingFile, TrainingFileTypedDict from .trainingparametersin import TrainingParametersIn, TrainingParametersInTypedDict @@ -25,7 +24,7 @@ class JobInTypedDict(TypedDict): - model: FineTuneableModel + model: str r"""The name of the model to fine-tune.""" hyperparameters: TrainingParametersInTypedDict r"""The fine-tuning hyperparameter settings used in a fine-tune job.""" @@ -42,7 +41,7 @@ class JobInTypedDict(TypedDict): class JobIn(BaseModel): - model: FineTuneableModel + model: str r"""The name of the model to fine-tune.""" hyperparameters: TrainingParametersIn diff --git a/src/mistralai/models/jobout.py b/src/mistralai/models/jobout.py index 71edce01..c3ffb248 100644 --- a/src/mistralai/models/jobout.py +++ b/src/mistralai/models/jobout.py @@ -1,7 +1,6 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from .finetuneablemodel import FineTuneableModel from .githubrepositoryout import GithubRepositoryOut, GithubRepositoryOutTypedDict from .jobmetadataout import JobMetadataOut, JobMetadataOutTypedDict from .trainingparameters import TrainingParameters, TrainingParametersTypedDict @@ -49,7 +48,7 @@ class JobOutTypedDict(TypedDict): r"""The ID of the job.""" auto_start: bool hyperparameters: TrainingParametersTypedDict - model: FineTuneableModel + model: str r"""The name of the model to fine-tune.""" status: Status r"""The current status of the fine-tuning job.""" @@ -85,7 +84,7 @@ class JobOut(BaseModel): hyperparameters: TrainingParameters - model: FineTuneableModel + model: str r"""The name of the model to fine-tune.""" status: Status diff --git a/src/mistralai/models/jobs_api_routes_fine_tuning_create_fine_tuning_jobop.py b/src/mistralai/models/jobs_api_routes_fine_tuning_create_fine_tuning_jobop.py index 1925a1a6..d7a5d10d 100644 --- a/src/mistralai/models/jobs_api_routes_fine_tuning_create_fine_tuning_jobop.py +++ b/src/mistralai/models/jobs_api_routes_fine_tuning_create_fine_tuning_jobop.py @@ -4,13 +4,18 @@ from .jobout import JobOut, JobOutTypedDict from .legacyjobmetadataout import LegacyJobMetadataOut, LegacyJobMetadataOutTypedDict from typing import Union +from typing_extensions import TypeAliasType -JobsAPIRoutesFineTuningCreateFineTuningJobResponseTypedDict = Union[ - LegacyJobMetadataOutTypedDict, JobOutTypedDict -] +JobsAPIRoutesFineTuningCreateFineTuningJobResponseTypedDict = TypeAliasType( + "JobsAPIRoutesFineTuningCreateFineTuningJobResponseTypedDict", + Union[LegacyJobMetadataOutTypedDict, JobOutTypedDict], +) r"""OK""" -JobsAPIRoutesFineTuningCreateFineTuningJobResponse = Union[LegacyJobMetadataOut, JobOut] +JobsAPIRoutesFineTuningCreateFineTuningJobResponse = TypeAliasType( + "JobsAPIRoutesFineTuningCreateFineTuningJobResponse", + Union[LegacyJobMetadataOut, JobOut], +) r"""OK""" diff --git a/src/mistralai/models/modellist.py b/src/mistralai/models/modellist.py index 97ae4c38..394cb3fa 100644 --- a/src/mistralai/models/modellist.py +++ b/src/mistralai/models/modellist.py @@ -7,10 +7,12 @@ from mistralai.utils import get_discriminator from pydantic import Discriminator, Tag from typing import List, Optional, Union -from typing_extensions import Annotated, NotRequired, TypedDict +from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -DataTypedDict = Union[BaseModelCardTypedDict, FTModelCardTypedDict] +DataTypedDict = TypeAliasType( + "DataTypedDict", Union[BaseModelCardTypedDict, FTModelCardTypedDict] +) Data = Annotated[ diff --git a/src/mistralai/models/referencechunk.py b/src/mistralai/models/referencechunk.py index 33acdb35..4a5503f2 100644 --- a/src/mistralai/models/referencechunk.py +++ b/src/mistralai/models/referencechunk.py @@ -2,11 +2,8 @@ from __future__ import annotations from mistralai.types import BaseModel -from mistralai.utils import validate_const -import pydantic -from pydantic.functional_validators import AfterValidator from typing import List, Literal, Optional -from typing_extensions import Annotated, TypedDict +from typing_extensions import NotRequired, TypedDict ReferenceChunkType = Literal["reference"] @@ -14,15 +11,10 @@ class ReferenceChunkTypedDict(TypedDict): reference_ids: List[int] - type: ReferenceChunkType + type: NotRequired[ReferenceChunkType] class ReferenceChunk(BaseModel): reference_ids: List[int] - TYPE: Annotated[ - Annotated[ - Optional[ReferenceChunkType], AfterValidator(validate_const("reference")) - ], - pydantic.Field(alias="type"), - ] = "reference" + type: Optional[ReferenceChunkType] = "reference" diff --git a/src/mistralai/models/retrieve_model_v1_models_model_id_getop.py b/src/mistralai/models/retrieve_model_v1_models_model_id_getop.py index dd4bcccc..bfe62474 100644 --- a/src/mistralai/models/retrieve_model_v1_models_model_id_getop.py +++ b/src/mistralai/models/retrieve_model_v1_models_model_id_getop.py @@ -7,7 +7,7 @@ from mistralai.utils import FieldMetadata, PathParamMetadata, get_discriminator from pydantic import Discriminator, Tag from typing import Union -from typing_extensions import Annotated, TypedDict +from typing_extensions import Annotated, TypeAliasType, TypedDict class RetrieveModelV1ModelsModelIDGetRequestTypedDict(TypedDict): @@ -22,9 +22,10 @@ class RetrieveModelV1ModelsModelIDGetRequest(BaseModel): r"""The ID of the model to retrieve.""" -RetrieveModelV1ModelsModelIDGetResponseRetrieveModelV1ModelsModelIDGetTypedDict = Union[ - BaseModelCardTypedDict, FTModelCardTypedDict -] +RetrieveModelV1ModelsModelIDGetResponseRetrieveModelV1ModelsModelIDGetTypedDict = TypeAliasType( + "RetrieveModelV1ModelsModelIDGetResponseRetrieveModelV1ModelsModelIDGetTypedDict", + Union[BaseModelCardTypedDict, FTModelCardTypedDict], +) r"""Successful Response""" diff --git a/src/mistralai/models/systemmessage.py b/src/mistralai/models/systemmessage.py index f6f30743..7827ac4b 100644 --- a/src/mistralai/models/systemmessage.py +++ b/src/mistralai/models/systemmessage.py @@ -4,13 +4,17 @@ from .textchunk import TextChunk, TextChunkTypedDict from mistralai.types import BaseModel from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -SystemMessageContentTypedDict = Union[str, List[TextChunkTypedDict]] +SystemMessageContentTypedDict = TypeAliasType( + "SystemMessageContentTypedDict", Union[str, List[TextChunkTypedDict]] +) -SystemMessageContent = Union[str, List[TextChunk]] +SystemMessageContent = TypeAliasType( + "SystemMessageContent", Union[str, List[TextChunk]] +) Role = Literal["system"] diff --git a/src/mistralai/models/textchunk.py b/src/mistralai/models/textchunk.py index 130a91c5..02b115f6 100644 --- a/src/mistralai/models/textchunk.py +++ b/src/mistralai/models/textchunk.py @@ -2,11 +2,8 @@ from __future__ import annotations from mistralai.types import BaseModel -from mistralai.utils import validate_const -import pydantic -from pydantic.functional_validators import AfterValidator from typing import Literal, Optional -from typing_extensions import Annotated, TypedDict +from typing_extensions import NotRequired, TypedDict TextChunkType = Literal["text"] @@ -14,13 +11,10 @@ class TextChunkTypedDict(TypedDict): text: str - type: TextChunkType + type: NotRequired[TextChunkType] class TextChunk(BaseModel): text: str - TYPE: Annotated[ - Annotated[Optional[TextChunkType], AfterValidator(validate_const("text"))], - pydantic.Field(alias="type"), - ] = "text" + type: Optional[TextChunkType] = "text" diff --git a/src/mistralai/models/toolmessage.py b/src/mistralai/models/toolmessage.py index c42f34e9..bee9c700 100644 --- a/src/mistralai/models/toolmessage.py +++ b/src/mistralai/models/toolmessage.py @@ -5,13 +5,15 @@ from mistralai.types import BaseModel, Nullable, OptionalNullable, UNSET, UNSET_SENTINEL from pydantic import model_serializer from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -ToolMessageContentTypedDict = Union[str, List[ContentChunkTypedDict]] +ToolMessageContentTypedDict = TypeAliasType( + "ToolMessageContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -ToolMessageContent = Union[str, List[ContentChunk]] +ToolMessageContent = TypeAliasType("ToolMessageContent", Union[str, List[ContentChunk]]) ToolMessageRole = Literal["tool"] diff --git a/src/mistralai/models/usermessage.py b/src/mistralai/models/usermessage.py index af698955..dac2618a 100644 --- a/src/mistralai/models/usermessage.py +++ b/src/mistralai/models/usermessage.py @@ -5,13 +5,15 @@ from mistralai.types import BaseModel, Nullable, UNSET_SENTINEL from pydantic import model_serializer from typing import List, Literal, Optional, Union -from typing_extensions import NotRequired, TypedDict +from typing_extensions import NotRequired, TypeAliasType, TypedDict -UserMessageContentTypedDict = Union[str, List[ContentChunkTypedDict]] +UserMessageContentTypedDict = TypeAliasType( + "UserMessageContentTypedDict", Union[str, List[ContentChunkTypedDict]] +) -UserMessageContent = Union[str, List[ContentChunk]] +UserMessageContent = TypeAliasType("UserMessageContent", Union[str, List[ContentChunk]]) UserMessageRole = Literal["user"] diff --git a/src/mistralai/models/validationerror.py b/src/mistralai/models/validationerror.py index 03ce9845..e971e016 100644 --- a/src/mistralai/models/validationerror.py +++ b/src/mistralai/models/validationerror.py @@ -3,13 +3,13 @@ from __future__ import annotations from mistralai.types import BaseModel from typing import List, Union -from typing_extensions import TypedDict +from typing_extensions import TypeAliasType, TypedDict -LocTypedDict = Union[str, int] +LocTypedDict = TypeAliasType("LocTypedDict", Union[str, int]) -Loc = Union[str, int] +Loc = TypeAliasType("Loc", Union[str, int]) class ValidationErrorTypedDict(TypedDict): diff --git a/src/mistralai/sdk.py b/src/mistralai/sdk.py index 71c60fcf..7778560e 100644 --- a/src/mistralai/sdk.py +++ b/src/mistralai/sdk.py @@ -129,3 +129,17 @@ def _init_sdks(self): self.agents = Agents(self.sdk_configuration) self.embeddings = Embeddings(self.sdk_configuration) self.classifiers = Classifiers(self.sdk_configuration) + + def __enter__(self): + return self + + async def __aenter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + if self.sdk_configuration.client is not None: + self.sdk_configuration.client.close() + + async def __aexit__(self, exc_type, exc_val, exc_tb): + if self.sdk_configuration.async_client is not None: + await self.sdk_configuration.async_client.aclose() diff --git a/src/mistralai/sdkconfiguration.py b/src/mistralai/sdkconfiguration.py index f4351c2e..1f8261ae 100644 --- a/src/mistralai/sdkconfiguration.py +++ b/src/mistralai/sdkconfiguration.py @@ -28,9 +28,9 @@ class SDKConfiguration: server: Optional[str] = "" language: str = "python" openapi_doc_version: str = "0.0.2" - sdk_version: str = "1.2.3" - gen_version: str = "2.460.1" - user_agent: str = "speakeasy-sdk/python 1.2.3 2.460.1 0.0.2 mistralai" + sdk_version: str = "1.2.4" + gen_version: str = "2.470.1" + user_agent: str = "speakeasy-sdk/python 1.2.4 2.470.1 0.0.2 mistralai" retry_config: OptionalNullable[RetryConfig] = Field(default_factory=lambda: UNSET) timeout_ms: Optional[int] = None diff --git a/src/mistralai/utils/annotations.py b/src/mistralai/utils/annotations.py index 5b3bbb02..387874ed 100644 --- a/src/mistralai/utils/annotations.py +++ b/src/mistralai/utils/annotations.py @@ -1,30 +1,55 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from enum import Enum -from typing import Any +from typing import Any, Optional def get_discriminator(model: Any, fieldname: str, key: str) -> str: - if isinstance(model, dict): - try: - return f'{model.get(key)}' - except AttributeError as e: - raise ValueError(f'Could not find discriminator key {key} in {model}') from e + """ + Recursively search for the discriminator attribute in a model. - if hasattr(model, fieldname): - attr = getattr(model, fieldname) + Args: + model (Any): The model to search within. + fieldname (str): The name of the field to search for. + key (str): The key to search for in dictionaries. - if isinstance(attr, Enum): - return f'{attr.value}' + Returns: + str: The name of the discriminator attribute. - return f'{attr}' + Raises: + ValueError: If the discriminator attribute is not found. + """ + upper_fieldname = fieldname.upper() - fieldname = fieldname.upper() - if hasattr(model, fieldname): - attr = getattr(model, fieldname) + def get_field_discriminator(field: Any) -> Optional[str]: + """Search for the discriminator attribute in a given field.""" - if isinstance(attr, Enum): - return f'{attr.value}' + if isinstance(field, dict): + if key in field: + return f'{field[key]}' - return f'{attr}' + if hasattr(field, fieldname): + attr = getattr(field, fieldname) + if isinstance(attr, Enum): + return f'{attr.value}' + return f'{attr}' + + if hasattr(field, upper_fieldname): + attr = getattr(field, upper_fieldname) + if isinstance(attr, Enum): + return f'{attr.value}' + return f'{attr}' + + return None + + + if isinstance(model, list): + for field in model: + discriminator = get_field_discriminator(field) + if discriminator is not None: + return discriminator + + discriminator = get_field_discriminator(model) + if discriminator is not None: + return discriminator raise ValueError(f'Could not find discriminator field {fieldname} in {model}') diff --git a/src/mistralai/utils/eventstreaming.py b/src/mistralai/utils/eventstreaming.py index 553b386b..74a63f75 100644 --- a/src/mistralai/utils/eventstreaming.py +++ b/src/mistralai/utils/eventstreaming.py @@ -2,12 +2,72 @@ import re import json -from typing import Callable, TypeVar, Optional, Generator, AsyncGenerator, Tuple +from typing import ( + Callable, + Generic, + TypeVar, + Optional, + Generator, + AsyncGenerator, + Tuple, +) import httpx T = TypeVar("T") +class EventStream(Generic[T]): + response: httpx.Response + generator: Generator[T, None, None] + + def __init__( + self, + response: httpx.Response, + decoder: Callable[[str], T], + sentinel: Optional[str] = None, + ): + self.response = response + self.generator = stream_events(response, decoder, sentinel) + + def __iter__(self): + return self + + def __next__(self): + return next(self.generator) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.response.close() + + +class EventStreamAsync(Generic[T]): + response: httpx.Response + generator: AsyncGenerator[T, None] + + def __init__( + self, + response: httpx.Response, + decoder: Callable[[str], T], + sentinel: Optional[str] = None, + ): + self.response = response + self.generator = stream_events_async(response, decoder, sentinel) + + def __aiter__(self): + return self + + async def __anext__(self): + return await self.generator.__anext__() + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self.response.aclose() + + class ServerEvent: id: Optional[str] = None event: Optional[str] = None