mistralai 1.3.1__py3-none-any.whl → 1.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. mistralai/__init__.py +10 -1
  2. mistralai/_version.py +4 -1
  3. mistralai/agents.py +58 -14
  4. mistralai/chat.py +140 -14
  5. mistralai/classifiers.py +32 -20
  6. mistralai/embeddings.py +16 -10
  7. mistralai/extra/README.md +56 -0
  8. mistralai/extra/__init__.py +5 -0
  9. mistralai/extra/struct_chat.py +41 -0
  10. mistralai/extra/tests/__init__.py +0 -0
  11. mistralai/extra/tests/test_struct_chat.py +103 -0
  12. mistralai/extra/tests/test_utils.py +162 -0
  13. mistralai/extra/utils/__init__.py +3 -0
  14. mistralai/extra/utils/_pydantic_helper.py +20 -0
  15. mistralai/extra/utils/response_format.py +24 -0
  16. mistralai/files.py +94 -34
  17. mistralai/fim.py +30 -14
  18. mistralai/httpclient.py +50 -0
  19. mistralai/jobs.py +80 -32
  20. mistralai/mistral_jobs.py +64 -24
  21. mistralai/models/__init__.py +8 -0
  22. mistralai/models/agentscompletionrequest.py +5 -0
  23. mistralai/models/agentscompletionstreamrequest.py +5 -0
  24. mistralai/models/chatcompletionrequest.py +5 -0
  25. mistralai/models/chatcompletionstreamrequest.py +5 -0
  26. mistralai/models/fileschema.py +3 -2
  27. mistralai/models/function.py +3 -0
  28. mistralai/models/jsonschema.py +55 -0
  29. mistralai/models/prediction.py +26 -0
  30. mistralai/models/responseformat.py +36 -1
  31. mistralai/models/responseformats.py +1 -1
  32. mistralai/models/retrievefileout.py +3 -2
  33. mistralai/models/toolcall.py +3 -0
  34. mistralai/models/uploadfileout.py +3 -2
  35. mistralai/models_.py +92 -48
  36. mistralai/sdk.py +13 -3
  37. mistralai/sdkconfiguration.py +10 -4
  38. {mistralai-1.3.1.dist-info → mistralai-1.5.0.dist-info}/METADATA +41 -42
  39. {mistralai-1.3.1.dist-info → mistralai-1.5.0.dist-info}/RECORD +43 -33
  40. {mistralai-1.3.1.dist-info → mistralai-1.5.0.dist-info}/WHEEL +1 -1
  41. mistralai_azure/_hooks/custom_user_agent.py +1 -1
  42. mistralai_gcp/sdk.py +1 -2
  43. py.typed +0 -1
  44. {mistralai-1.3.1.dist-info → mistralai-1.5.0.dist-info}/LICENSE +0 -0
mistralai/files.py CHANGED
@@ -21,7 +21,7 @@ class Files(BaseSDK):
21
21
  server_url: Optional[str] = None,
22
22
  timeout_ms: Optional[int] = None,
23
23
  http_headers: Optional[Mapping[str, str]] = None,
24
- ) -> Optional[models.UploadFileOut]:
24
+ ) -> models.UploadFileOut:
25
25
  r"""Upload File
26
26
 
27
27
  Upload a file that can be used across various endpoints.
@@ -95,8 +95,13 @@ class Files(BaseSDK):
95
95
  )
96
96
 
97
97
  if utils.match_response(http_res, "200", "application/json"):
98
- return utils.unmarshal_json(http_res.text, Optional[models.UploadFileOut])
99
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
98
+ return utils.unmarshal_json(http_res.text, models.UploadFileOut)
99
+ if utils.match_response(http_res, "4XX", "*"):
100
+ http_res_text = utils.stream_to_text(http_res)
101
+ raise models.SDKError(
102
+ "API error occurred", http_res.status_code, http_res_text, http_res
103
+ )
104
+ if utils.match_response(http_res, "5XX", "*"):
100
105
  http_res_text = utils.stream_to_text(http_res)
101
106
  raise models.SDKError(
102
107
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -120,7 +125,7 @@ class Files(BaseSDK):
120
125
  server_url: Optional[str] = None,
121
126
  timeout_ms: Optional[int] = None,
122
127
  http_headers: Optional[Mapping[str, str]] = None,
123
- ) -> Optional[models.UploadFileOut]:
128
+ ) -> models.UploadFileOut:
124
129
  r"""Upload File
125
130
 
126
131
  Upload a file that can be used across various endpoints.
@@ -194,8 +199,13 @@ class Files(BaseSDK):
194
199
  )
195
200
 
196
201
  if utils.match_response(http_res, "200", "application/json"):
197
- return utils.unmarshal_json(http_res.text, Optional[models.UploadFileOut])
198
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
202
+ return utils.unmarshal_json(http_res.text, models.UploadFileOut)
203
+ if utils.match_response(http_res, "4XX", "*"):
204
+ http_res_text = await utils.stream_to_text_async(http_res)
205
+ raise models.SDKError(
206
+ "API error occurred", http_res.status_code, http_res_text, http_res
207
+ )
208
+ if utils.match_response(http_res, "5XX", "*"):
199
209
  http_res_text = await utils.stream_to_text_async(http_res)
200
210
  raise models.SDKError(
201
211
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -223,7 +233,7 @@ class Files(BaseSDK):
223
233
  server_url: Optional[str] = None,
224
234
  timeout_ms: Optional[int] = None,
225
235
  http_headers: Optional[Mapping[str, str]] = None,
226
- ) -> Optional[models.ListFilesOut]:
236
+ ) -> models.ListFilesOut:
227
237
  r"""List Files
228
238
 
229
239
  Returns a list of files that belong to the user's organization.
@@ -294,8 +304,13 @@ class Files(BaseSDK):
294
304
  )
295
305
 
296
306
  if utils.match_response(http_res, "200", "application/json"):
297
- return utils.unmarshal_json(http_res.text, Optional[models.ListFilesOut])
298
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
307
+ return utils.unmarshal_json(http_res.text, models.ListFilesOut)
308
+ if utils.match_response(http_res, "4XX", "*"):
309
+ http_res_text = utils.stream_to_text(http_res)
310
+ raise models.SDKError(
311
+ "API error occurred", http_res.status_code, http_res_text, http_res
312
+ )
313
+ if utils.match_response(http_res, "5XX", "*"):
299
314
  http_res_text = utils.stream_to_text(http_res)
300
315
  raise models.SDKError(
301
316
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -323,7 +338,7 @@ class Files(BaseSDK):
323
338
  server_url: Optional[str] = None,
324
339
  timeout_ms: Optional[int] = None,
325
340
  http_headers: Optional[Mapping[str, str]] = None,
326
- ) -> Optional[models.ListFilesOut]:
341
+ ) -> models.ListFilesOut:
327
342
  r"""List Files
328
343
 
329
344
  Returns a list of files that belong to the user's organization.
@@ -394,8 +409,13 @@ class Files(BaseSDK):
394
409
  )
395
410
 
396
411
  if utils.match_response(http_res, "200", "application/json"):
397
- return utils.unmarshal_json(http_res.text, Optional[models.ListFilesOut])
398
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
412
+ return utils.unmarshal_json(http_res.text, models.ListFilesOut)
413
+ if utils.match_response(http_res, "4XX", "*"):
414
+ http_res_text = await utils.stream_to_text_async(http_res)
415
+ raise models.SDKError(
416
+ "API error occurred", http_res.status_code, http_res_text, http_res
417
+ )
418
+ if utils.match_response(http_res, "5XX", "*"):
399
419
  http_res_text = await utils.stream_to_text_async(http_res)
400
420
  raise models.SDKError(
401
421
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -418,7 +438,7 @@ class Files(BaseSDK):
418
438
  server_url: Optional[str] = None,
419
439
  timeout_ms: Optional[int] = None,
420
440
  http_headers: Optional[Mapping[str, str]] = None,
421
- ) -> Optional[models.RetrieveFileOut]:
441
+ ) -> models.RetrieveFileOut:
422
442
  r"""Retrieve File
423
443
 
424
444
  Returns information about a specific file.
@@ -479,8 +499,13 @@ class Files(BaseSDK):
479
499
  )
480
500
 
481
501
  if utils.match_response(http_res, "200", "application/json"):
482
- return utils.unmarshal_json(http_res.text, Optional[models.RetrieveFileOut])
483
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
502
+ return utils.unmarshal_json(http_res.text, models.RetrieveFileOut)
503
+ if utils.match_response(http_res, "4XX", "*"):
504
+ http_res_text = utils.stream_to_text(http_res)
505
+ raise models.SDKError(
506
+ "API error occurred", http_res.status_code, http_res_text, http_res
507
+ )
508
+ if utils.match_response(http_res, "5XX", "*"):
484
509
  http_res_text = utils.stream_to_text(http_res)
485
510
  raise models.SDKError(
486
511
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -503,7 +528,7 @@ class Files(BaseSDK):
503
528
  server_url: Optional[str] = None,
504
529
  timeout_ms: Optional[int] = None,
505
530
  http_headers: Optional[Mapping[str, str]] = None,
506
- ) -> Optional[models.RetrieveFileOut]:
531
+ ) -> models.RetrieveFileOut:
507
532
  r"""Retrieve File
508
533
 
509
534
  Returns information about a specific file.
@@ -564,8 +589,13 @@ class Files(BaseSDK):
564
589
  )
565
590
 
566
591
  if utils.match_response(http_res, "200", "application/json"):
567
- return utils.unmarshal_json(http_res.text, Optional[models.RetrieveFileOut])
568
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
592
+ return utils.unmarshal_json(http_res.text, models.RetrieveFileOut)
593
+ if utils.match_response(http_res, "4XX", "*"):
594
+ http_res_text = await utils.stream_to_text_async(http_res)
595
+ raise models.SDKError(
596
+ "API error occurred", http_res.status_code, http_res_text, http_res
597
+ )
598
+ if utils.match_response(http_res, "5XX", "*"):
569
599
  http_res_text = await utils.stream_to_text_async(http_res)
570
600
  raise models.SDKError(
571
601
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -588,7 +618,7 @@ class Files(BaseSDK):
588
618
  server_url: Optional[str] = None,
589
619
  timeout_ms: Optional[int] = None,
590
620
  http_headers: Optional[Mapping[str, str]] = None,
591
- ) -> Optional[models.DeleteFileOut]:
621
+ ) -> models.DeleteFileOut:
592
622
  r"""Delete File
593
623
 
594
624
  Delete a file.
@@ -649,8 +679,13 @@ class Files(BaseSDK):
649
679
  )
650
680
 
651
681
  if utils.match_response(http_res, "200", "application/json"):
652
- return utils.unmarshal_json(http_res.text, Optional[models.DeleteFileOut])
653
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
682
+ return utils.unmarshal_json(http_res.text, models.DeleteFileOut)
683
+ if utils.match_response(http_res, "4XX", "*"):
684
+ http_res_text = utils.stream_to_text(http_res)
685
+ raise models.SDKError(
686
+ "API error occurred", http_res.status_code, http_res_text, http_res
687
+ )
688
+ if utils.match_response(http_res, "5XX", "*"):
654
689
  http_res_text = utils.stream_to_text(http_res)
655
690
  raise models.SDKError(
656
691
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -673,7 +708,7 @@ class Files(BaseSDK):
673
708
  server_url: Optional[str] = None,
674
709
  timeout_ms: Optional[int] = None,
675
710
  http_headers: Optional[Mapping[str, str]] = None,
676
- ) -> Optional[models.DeleteFileOut]:
711
+ ) -> models.DeleteFileOut:
677
712
  r"""Delete File
678
713
 
679
714
  Delete a file.
@@ -734,8 +769,13 @@ class Files(BaseSDK):
734
769
  )
735
770
 
736
771
  if utils.match_response(http_res, "200", "application/json"):
737
- return utils.unmarshal_json(http_res.text, Optional[models.DeleteFileOut])
738
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
772
+ return utils.unmarshal_json(http_res.text, models.DeleteFileOut)
773
+ if utils.match_response(http_res, "4XX", "*"):
774
+ http_res_text = await utils.stream_to_text_async(http_res)
775
+ raise models.SDKError(
776
+ "API error occurred", http_res.status_code, http_res_text, http_res
777
+ )
778
+ if utils.match_response(http_res, "5XX", "*"):
739
779
  http_res_text = await utils.stream_to_text_async(http_res)
740
780
  raise models.SDKError(
741
781
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -758,7 +798,7 @@ class Files(BaseSDK):
758
798
  server_url: Optional[str] = None,
759
799
  timeout_ms: Optional[int] = None,
760
800
  http_headers: Optional[Mapping[str, str]] = None,
761
- ) -> Optional[httpx.Response]:
801
+ ) -> httpx.Response:
762
802
  r"""Download File
763
803
 
764
804
  Download a file
@@ -821,7 +861,12 @@ class Files(BaseSDK):
821
861
 
822
862
  if utils.match_response(http_res, "200", "application/octet-stream"):
823
863
  return http_res
824
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
864
+ if utils.match_response(http_res, "4XX", "*"):
865
+ http_res_text = utils.stream_to_text(http_res)
866
+ raise models.SDKError(
867
+ "API error occurred", http_res.status_code, http_res_text, http_res
868
+ )
869
+ if utils.match_response(http_res, "5XX", "*"):
825
870
  http_res_text = utils.stream_to_text(http_res)
826
871
  raise models.SDKError(
827
872
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -844,7 +889,7 @@ class Files(BaseSDK):
844
889
  server_url: Optional[str] = None,
845
890
  timeout_ms: Optional[int] = None,
846
891
  http_headers: Optional[Mapping[str, str]] = None,
847
- ) -> Optional[httpx.Response]:
892
+ ) -> httpx.Response:
848
893
  r"""Download File
849
894
 
850
895
  Download a file
@@ -907,7 +952,12 @@ class Files(BaseSDK):
907
952
 
908
953
  if utils.match_response(http_res, "200", "application/octet-stream"):
909
954
  return http_res
910
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
955
+ if utils.match_response(http_res, "4XX", "*"):
956
+ http_res_text = await utils.stream_to_text_async(http_res)
957
+ raise models.SDKError(
958
+ "API error occurred", http_res.status_code, http_res_text, http_res
959
+ )
960
+ if utils.match_response(http_res, "5XX", "*"):
911
961
  http_res_text = await utils.stream_to_text_async(http_res)
912
962
  raise models.SDKError(
913
963
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -931,7 +981,7 @@ class Files(BaseSDK):
931
981
  server_url: Optional[str] = None,
932
982
  timeout_ms: Optional[int] = None,
933
983
  http_headers: Optional[Mapping[str, str]] = None,
934
- ) -> Optional[models.FileSignedURL]:
984
+ ) -> models.FileSignedURL:
935
985
  r"""Get Signed Url
936
986
 
937
987
  :param file_id:
@@ -992,8 +1042,13 @@ class Files(BaseSDK):
992
1042
  )
993
1043
 
994
1044
  if utils.match_response(http_res, "200", "application/json"):
995
- return utils.unmarshal_json(http_res.text, Optional[models.FileSignedURL])
996
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
1045
+ return utils.unmarshal_json(http_res.text, models.FileSignedURL)
1046
+ if utils.match_response(http_res, "4XX", "*"):
1047
+ http_res_text = utils.stream_to_text(http_res)
1048
+ raise models.SDKError(
1049
+ "API error occurred", http_res.status_code, http_res_text, http_res
1050
+ )
1051
+ if utils.match_response(http_res, "5XX", "*"):
997
1052
  http_res_text = utils.stream_to_text(http_res)
998
1053
  raise models.SDKError(
999
1054
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -1017,7 +1072,7 @@ class Files(BaseSDK):
1017
1072
  server_url: Optional[str] = None,
1018
1073
  timeout_ms: Optional[int] = None,
1019
1074
  http_headers: Optional[Mapping[str, str]] = None,
1020
- ) -> Optional[models.FileSignedURL]:
1075
+ ) -> models.FileSignedURL:
1021
1076
  r"""Get Signed Url
1022
1077
 
1023
1078
  :param file_id:
@@ -1078,8 +1133,13 @@ class Files(BaseSDK):
1078
1133
  )
1079
1134
 
1080
1135
  if utils.match_response(http_res, "200", "application/json"):
1081
- return utils.unmarshal_json(http_res.text, Optional[models.FileSignedURL])
1082
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
1136
+ return utils.unmarshal_json(http_res.text, models.FileSignedURL)
1137
+ if utils.match_response(http_res, "4XX", "*"):
1138
+ http_res_text = await utils.stream_to_text_async(http_res)
1139
+ raise models.SDKError(
1140
+ "API error occurred", http_res.status_code, http_res_text, http_res
1141
+ )
1142
+ if utils.match_response(http_res, "5XX", "*"):
1083
1143
  http_res_text = await utils.stream_to_text_async(http_res)
1084
1144
  raise models.SDKError(
1085
1145
  "API error occurred", http_res.status_code, http_res_text, http_res
mistralai/fim.py CHANGED
@@ -33,7 +33,7 @@ class Fim(BaseSDK):
33
33
  server_url: Optional[str] = None,
34
34
  timeout_ms: Optional[int] = None,
35
35
  http_headers: Optional[Mapping[str, str]] = None,
36
- ) -> Optional[models.FIMCompletionResponse]:
36
+ ) -> models.FIMCompletionResponse:
37
37
  r"""Fim Completion
38
38
 
39
39
  FIM completion.
@@ -116,13 +116,16 @@ class Fim(BaseSDK):
116
116
 
117
117
  data: Any = None
118
118
  if utils.match_response(http_res, "200", "application/json"):
119
- return utils.unmarshal_json(
120
- http_res.text, Optional[models.FIMCompletionResponse]
121
- )
119
+ return utils.unmarshal_json(http_res.text, models.FIMCompletionResponse)
122
120
  if utils.match_response(http_res, "422", "application/json"):
123
121
  data = utils.unmarshal_json(http_res.text, models.HTTPValidationErrorData)
124
122
  raise models.HTTPValidationError(data=data)
125
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
123
+ if utils.match_response(http_res, "4XX", "*"):
124
+ http_res_text = utils.stream_to_text(http_res)
125
+ raise models.SDKError(
126
+ "API error occurred", http_res.status_code, http_res_text, http_res
127
+ )
128
+ if utils.match_response(http_res, "5XX", "*"):
126
129
  http_res_text = utils.stream_to_text(http_res)
127
130
  raise models.SDKError(
128
131
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -159,7 +162,7 @@ class Fim(BaseSDK):
159
162
  server_url: Optional[str] = None,
160
163
  timeout_ms: Optional[int] = None,
161
164
  http_headers: Optional[Mapping[str, str]] = None,
162
- ) -> Optional[models.FIMCompletionResponse]:
165
+ ) -> models.FIMCompletionResponse:
163
166
  r"""Fim Completion
164
167
 
165
168
  FIM completion.
@@ -242,13 +245,16 @@ class Fim(BaseSDK):
242
245
 
243
246
  data: Any = None
244
247
  if utils.match_response(http_res, "200", "application/json"):
245
- return utils.unmarshal_json(
246
- http_res.text, Optional[models.FIMCompletionResponse]
247
- )
248
+ return utils.unmarshal_json(http_res.text, models.FIMCompletionResponse)
248
249
  if utils.match_response(http_res, "422", "application/json"):
249
250
  data = utils.unmarshal_json(http_res.text, models.HTTPValidationErrorData)
250
251
  raise models.HTTPValidationError(data=data)
251
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
252
+ if utils.match_response(http_res, "4XX", "*"):
253
+ http_res_text = await utils.stream_to_text_async(http_res)
254
+ raise models.SDKError(
255
+ "API error occurred", http_res.status_code, http_res_text, http_res
256
+ )
257
+ if utils.match_response(http_res, "5XX", "*"):
252
258
  http_res_text = await utils.stream_to_text_async(http_res)
253
259
  raise models.SDKError(
254
260
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -285,7 +291,7 @@ class Fim(BaseSDK):
285
291
  server_url: Optional[str] = None,
286
292
  timeout_ms: Optional[int] = None,
287
293
  http_headers: Optional[Mapping[str, str]] = None,
288
- ) -> Optional[eventstreaming.EventStream[models.CompletionEvent]]:
294
+ ) -> eventstreaming.EventStream[models.CompletionEvent]:
289
295
  r"""Stream fim completion
290
296
 
291
297
  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.
@@ -378,7 +384,12 @@ class Fim(BaseSDK):
378
384
  http_res_text = utils.stream_to_text(http_res)
379
385
  data = utils.unmarshal_json(http_res_text, models.HTTPValidationErrorData)
380
386
  raise models.HTTPValidationError(data=data)
381
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
387
+ if utils.match_response(http_res, "4XX", "*"):
388
+ http_res_text = utils.stream_to_text(http_res)
389
+ raise models.SDKError(
390
+ "API error occurred", http_res.status_code, http_res_text, http_res
391
+ )
392
+ if utils.match_response(http_res, "5XX", "*"):
382
393
  http_res_text = utils.stream_to_text(http_res)
383
394
  raise models.SDKError(
384
395
  "API error occurred", http_res.status_code, http_res_text, http_res
@@ -415,7 +426,7 @@ class Fim(BaseSDK):
415
426
  server_url: Optional[str] = None,
416
427
  timeout_ms: Optional[int] = None,
417
428
  http_headers: Optional[Mapping[str, str]] = None,
418
- ) -> Optional[eventstreaming.EventStreamAsync[models.CompletionEvent]]:
429
+ ) -> eventstreaming.EventStreamAsync[models.CompletionEvent]:
419
430
  r"""Stream fim completion
420
431
 
421
432
  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.
@@ -508,7 +519,12 @@ class Fim(BaseSDK):
508
519
  http_res_text = await utils.stream_to_text_async(http_res)
509
520
  data = utils.unmarshal_json(http_res_text, models.HTTPValidationErrorData)
510
521
  raise models.HTTPValidationError(data=data)
511
- if utils.match_response(http_res, ["4XX", "5XX"], "*"):
522
+ if utils.match_response(http_res, "4XX", "*"):
523
+ http_res_text = await utils.stream_to_text_async(http_res)
524
+ raise models.SDKError(
525
+ "API error occurred", http_res.status_code, http_res_text, http_res
526
+ )
527
+ if utils.match_response(http_res, "5XX", "*"):
512
528
  http_res_text = await utils.stream_to_text_async(http_res)
513
529
  raise models.SDKError(
514
530
  "API error occurred", http_res.status_code, http_res_text, http_res
mistralai/httpclient.py CHANGED
@@ -1,6 +1,8 @@
1
1
  """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
2
 
3
3
  # pyright: reportReturnType = false
4
+ import asyncio
5
+ from concurrent.futures import ThreadPoolExecutor
4
6
  from typing_extensions import Protocol, runtime_checkable
5
7
  import httpx
6
8
  from typing import Any, Optional, Union
@@ -82,3 +84,51 @@ class AsyncHttpClient(Protocol):
82
84
 
83
85
  async def aclose(self) -> None:
84
86
  pass
87
+
88
+
89
+ class ClientOwner(Protocol):
90
+ client: Union[HttpClient, None]
91
+ async_client: Union[AsyncHttpClient, None]
92
+
93
+
94
+ def close_clients(
95
+ owner: ClientOwner,
96
+ sync_client: Union[HttpClient, None],
97
+ async_client: Union[AsyncHttpClient, None],
98
+ ) -> None:
99
+ """
100
+ A finalizer function that is meant to be used with weakref.finalize to close
101
+ httpx clients used by an SDK so that underlying resources can be garbage
102
+ collected.
103
+ """
104
+
105
+ # Unset the client/async_client properties so there are no more references
106
+ # to them from the owning SDK instance and they can be reaped.
107
+ owner.client = None
108
+ owner.async_client = None
109
+
110
+ if sync_client is not None:
111
+ try:
112
+ sync_client.close()
113
+ except Exception:
114
+ pass
115
+
116
+ if async_client is not None:
117
+ is_async = False
118
+ try:
119
+ asyncio.get_running_loop()
120
+ is_async = True
121
+ except RuntimeError:
122
+ pass
123
+
124
+ try:
125
+ # If this function is called in an async loop then start another
126
+ # loop in a separate thread to close the async http client.
127
+ if is_async:
128
+ with ThreadPoolExecutor(max_workers=1) as executor:
129
+ future = executor.submit(asyncio.run, async_client.aclose())
130
+ future.result()
131
+ else:
132
+ asyncio.run(async_client.aclose())
133
+ except Exception:
134
+ pass