mistralai 0.4.2__py3-none-any.whl → 0.5.5a50__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 (240) hide show
  1. mistralai/__init__.py +5 -0
  2. mistralai/_hooks/__init__.py +5 -0
  3. mistralai/_hooks/custom_user_agent.py +16 -0
  4. mistralai/_hooks/deprecation_warning.py +26 -0
  5. mistralai/_hooks/registration.py +17 -0
  6. mistralai/_hooks/sdkhooks.py +57 -0
  7. mistralai/_hooks/types.py +76 -0
  8. mistralai/async_client.py +5 -413
  9. mistralai/basesdk.py +216 -0
  10. mistralai/chat.py +475 -0
  11. mistralai/client.py +5 -414
  12. mistralai/embeddings.py +182 -0
  13. mistralai/files.py +600 -84
  14. mistralai/fim.py +439 -0
  15. mistralai/fine_tuning.py +855 -0
  16. mistralai/httpclient.py +78 -0
  17. mistralai/models/__init__.py +80 -0
  18. mistralai/models/archiveftmodelout.py +19 -0
  19. mistralai/models/assistantmessage.py +58 -0
  20. mistralai/models/chatcompletionchoice.py +33 -0
  21. mistralai/models/chatcompletionrequest.py +114 -0
  22. mistralai/models/chatcompletionresponse.py +27 -0
  23. mistralai/models/chatcompletionstreamrequest.py +112 -0
  24. mistralai/models/checkpointout.py +25 -0
  25. mistralai/models/completionchunk.py +27 -0
  26. mistralai/models/completionevent.py +15 -0
  27. mistralai/models/completionresponsestreamchoice.py +53 -0
  28. mistralai/models/contentchunk.py +17 -0
  29. mistralai/models/delete_model_v1_models_model_id_deleteop.py +16 -0
  30. mistralai/models/deletefileout.py +24 -0
  31. mistralai/models/deletemodelout.py +25 -0
  32. mistralai/models/deltamessage.py +52 -0
  33. mistralai/models/detailedjobout.py +96 -0
  34. mistralai/models/embeddingrequest.py +66 -0
  35. mistralai/models/embeddingresponse.py +24 -0
  36. mistralai/models/embeddingresponsedata.py +19 -0
  37. mistralai/models/eventout.py +55 -0
  38. mistralai/models/files_api_routes_delete_fileop.py +16 -0
  39. mistralai/models/files_api_routes_retrieve_fileop.py +16 -0
  40. mistralai/models/files_api_routes_upload_fileop.py +51 -0
  41. mistralai/models/fileschema.py +76 -0
  42. mistralai/models/fimcompletionrequest.py +99 -0
  43. mistralai/models/fimcompletionresponse.py +27 -0
  44. mistralai/models/fimcompletionstreamrequest.py +97 -0
  45. mistralai/models/finetuneablemodel.py +8 -0
  46. mistralai/models/ftmodelcapabilitiesout.py +21 -0
  47. mistralai/models/ftmodelout.py +70 -0
  48. mistralai/models/function.py +19 -0
  49. mistralai/models/functioncall.py +16 -0
  50. mistralai/models/githubrepositoryin.py +57 -0
  51. mistralai/models/githubrepositoryout.py +57 -0
  52. mistralai/models/httpvalidationerror.py +23 -0
  53. mistralai/models/jobin.py +78 -0
  54. mistralai/models/jobmetadataout.py +59 -0
  55. mistralai/models/jobout.py +112 -0
  56. mistralai/models/jobs_api_routes_fine_tuning_archive_fine_tuned_modelop.py +16 -0
  57. mistralai/models/jobs_api_routes_fine_tuning_cancel_fine_tuning_jobop.py +18 -0
  58. mistralai/models/jobs_api_routes_fine_tuning_create_fine_tuning_jobop.py +73 -0
  59. mistralai/models/jobs_api_routes_fine_tuning_get_fine_tuning_jobop.py +18 -0
  60. mistralai/models/jobs_api_routes_fine_tuning_get_fine_tuning_jobsop.py +86 -0
  61. mistralai/models/jobs_api_routes_fine_tuning_start_fine_tuning_jobop.py +16 -0
  62. mistralai/models/jobs_api_routes_fine_tuning_unarchive_fine_tuned_modelop.py +16 -0
  63. mistralai/models/jobs_api_routes_fine_tuning_update_fine_tuned_modelop.py +19 -0
  64. mistralai/models/jobsout.py +20 -0
  65. mistralai/models/legacyjobmetadataout.py +85 -0
  66. mistralai/models/listfilesout.py +17 -0
  67. mistralai/models/metricout.py +55 -0
  68. mistralai/models/modelcapabilities.py +21 -0
  69. mistralai/models/modelcard.py +71 -0
  70. mistralai/models/modellist.py +18 -0
  71. mistralai/models/responseformat.py +18 -0
  72. mistralai/models/retrieve_model_v1_models_model_id_getop.py +16 -0
  73. mistralai/models/retrievefileout.py +76 -0
  74. mistralai/models/sampletype.py +7 -0
  75. mistralai/models/sdkerror.py +22 -0
  76. mistralai/models/security.py +16 -0
  77. mistralai/models/source.py +7 -0
  78. mistralai/models/systemmessage.py +26 -0
  79. mistralai/models/textchunk.py +17 -0
  80. mistralai/models/tool.py +18 -0
  81. mistralai/models/toolcall.py +20 -0
  82. mistralai/models/toolmessage.py +55 -0
  83. mistralai/models/trainingfile.py +17 -0
  84. mistralai/models/trainingparameters.py +53 -0
  85. mistralai/models/trainingparametersin.py +61 -0
  86. mistralai/models/unarchiveftmodelout.py +19 -0
  87. mistralai/models/updateftmodelin.py +49 -0
  88. mistralai/models/uploadfileout.py +76 -0
  89. mistralai/models/usageinfo.py +18 -0
  90. mistralai/models/usermessage.py +26 -0
  91. mistralai/models/validationerror.py +24 -0
  92. mistralai/models/wandbintegration.py +61 -0
  93. mistralai/models/wandbintegrationout.py +57 -0
  94. mistralai/models_.py +928 -0
  95. mistralai/py.typed +1 -0
  96. mistralai/sdk.py +111 -0
  97. mistralai/sdkconfiguration.py +53 -0
  98. mistralai/types/__init__.py +21 -0
  99. mistralai/types/basemodel.py +35 -0
  100. mistralai/utils/__init__.py +82 -0
  101. mistralai/utils/annotations.py +19 -0
  102. mistralai/utils/enums.py +34 -0
  103. mistralai/utils/eventstreaming.py +179 -0
  104. mistralai/utils/forms.py +207 -0
  105. mistralai/utils/headers.py +136 -0
  106. mistralai/utils/metadata.py +118 -0
  107. mistralai/utils/queryparams.py +203 -0
  108. mistralai/utils/requestbodies.py +66 -0
  109. mistralai/utils/retries.py +216 -0
  110. mistralai/utils/security.py +182 -0
  111. mistralai/utils/serializers.py +181 -0
  112. mistralai/utils/url.py +150 -0
  113. mistralai/utils/values.py +128 -0
  114. {mistralai-0.4.2.dist-info → mistralai-0.5.5a50.dist-info}/LICENSE +1 -1
  115. mistralai-0.5.5a50.dist-info/METADATA +626 -0
  116. mistralai-0.5.5a50.dist-info/RECORD +228 -0
  117. mistralai_azure/__init__.py +5 -0
  118. mistralai_azure/_hooks/__init__.py +5 -0
  119. mistralai_azure/_hooks/custom_user_agent.py +16 -0
  120. mistralai_azure/_hooks/registration.py +15 -0
  121. mistralai_azure/_hooks/sdkhooks.py +57 -0
  122. mistralai_azure/_hooks/types.py +76 -0
  123. mistralai_azure/basesdk.py +215 -0
  124. mistralai_azure/chat.py +475 -0
  125. mistralai_azure/httpclient.py +78 -0
  126. mistralai_azure/models/__init__.py +28 -0
  127. mistralai_azure/models/assistantmessage.py +58 -0
  128. mistralai_azure/models/chatcompletionchoice.py +33 -0
  129. mistralai_azure/models/chatcompletionrequest.py +114 -0
  130. mistralai_azure/models/chatcompletionresponse.py +27 -0
  131. mistralai_azure/models/chatcompletionstreamrequest.py +112 -0
  132. mistralai_azure/models/completionchunk.py +27 -0
  133. mistralai_azure/models/completionevent.py +15 -0
  134. mistralai_azure/models/completionresponsestreamchoice.py +53 -0
  135. mistralai_azure/models/contentchunk.py +17 -0
  136. mistralai_azure/models/deltamessage.py +52 -0
  137. mistralai_azure/models/function.py +19 -0
  138. mistralai_azure/models/functioncall.py +16 -0
  139. mistralai_azure/models/httpvalidationerror.py +23 -0
  140. mistralai_azure/models/responseformat.py +18 -0
  141. mistralai_azure/models/sdkerror.py +22 -0
  142. mistralai_azure/models/security.py +16 -0
  143. mistralai_azure/models/systemmessage.py +26 -0
  144. mistralai_azure/models/textchunk.py +17 -0
  145. mistralai_azure/models/tool.py +18 -0
  146. mistralai_azure/models/toolcall.py +20 -0
  147. mistralai_azure/models/toolmessage.py +55 -0
  148. mistralai_azure/models/usageinfo.py +18 -0
  149. mistralai_azure/models/usermessage.py +26 -0
  150. mistralai_azure/models/validationerror.py +24 -0
  151. mistralai_azure/py.typed +1 -0
  152. mistralai_azure/sdk.py +102 -0
  153. mistralai_azure/sdkconfiguration.py +53 -0
  154. mistralai_azure/types/__init__.py +21 -0
  155. mistralai_azure/types/basemodel.py +35 -0
  156. mistralai_azure/utils/__init__.py +80 -0
  157. mistralai_azure/utils/annotations.py +19 -0
  158. mistralai_azure/utils/enums.py +34 -0
  159. mistralai_azure/utils/eventstreaming.py +179 -0
  160. mistralai_azure/utils/forms.py +207 -0
  161. mistralai_azure/utils/headers.py +136 -0
  162. mistralai_azure/utils/metadata.py +118 -0
  163. mistralai_azure/utils/queryparams.py +203 -0
  164. mistralai_azure/utils/requestbodies.py +66 -0
  165. mistralai_azure/utils/retries.py +216 -0
  166. mistralai_azure/utils/security.py +168 -0
  167. mistralai_azure/utils/serializers.py +181 -0
  168. mistralai_azure/utils/url.py +150 -0
  169. mistralai_azure/utils/values.py +128 -0
  170. mistralai_gcp/__init__.py +5 -0
  171. mistralai_gcp/_hooks/__init__.py +5 -0
  172. mistralai_gcp/_hooks/custom_user_agent.py +16 -0
  173. mistralai_gcp/_hooks/registration.py +15 -0
  174. mistralai_gcp/_hooks/sdkhooks.py +57 -0
  175. mistralai_gcp/_hooks/types.py +76 -0
  176. mistralai_gcp/basesdk.py +215 -0
  177. mistralai_gcp/chat.py +463 -0
  178. mistralai_gcp/fim.py +439 -0
  179. mistralai_gcp/httpclient.py +78 -0
  180. mistralai_gcp/models/__init__.py +31 -0
  181. mistralai_gcp/models/assistantmessage.py +58 -0
  182. mistralai_gcp/models/chatcompletionchoice.py +33 -0
  183. mistralai_gcp/models/chatcompletionrequest.py +110 -0
  184. mistralai_gcp/models/chatcompletionresponse.py +27 -0
  185. mistralai_gcp/models/chatcompletionstreamrequest.py +108 -0
  186. mistralai_gcp/models/completionchunk.py +27 -0
  187. mistralai_gcp/models/completionevent.py +15 -0
  188. mistralai_gcp/models/completionresponsestreamchoice.py +53 -0
  189. mistralai_gcp/models/contentchunk.py +17 -0
  190. mistralai_gcp/models/deltamessage.py +52 -0
  191. mistralai_gcp/models/fimcompletionrequest.py +99 -0
  192. mistralai_gcp/models/fimcompletionresponse.py +27 -0
  193. mistralai_gcp/models/fimcompletionstreamrequest.py +97 -0
  194. mistralai_gcp/models/function.py +19 -0
  195. mistralai_gcp/models/functioncall.py +16 -0
  196. mistralai_gcp/models/httpvalidationerror.py +23 -0
  197. mistralai_gcp/models/responseformat.py +18 -0
  198. mistralai_gcp/models/sdkerror.py +22 -0
  199. mistralai_gcp/models/security.py +16 -0
  200. mistralai_gcp/models/systemmessage.py +26 -0
  201. mistralai_gcp/models/textchunk.py +17 -0
  202. mistralai_gcp/models/tool.py +18 -0
  203. mistralai_gcp/models/toolcall.py +20 -0
  204. mistralai_gcp/models/toolmessage.py +55 -0
  205. mistralai_gcp/models/usageinfo.py +18 -0
  206. mistralai_gcp/models/usermessage.py +26 -0
  207. mistralai_gcp/models/validationerror.py +24 -0
  208. mistralai_gcp/py.typed +1 -0
  209. mistralai_gcp/sdk.py +165 -0
  210. mistralai_gcp/sdkconfiguration.py +53 -0
  211. mistralai_gcp/types/__init__.py +21 -0
  212. mistralai_gcp/types/basemodel.py +35 -0
  213. mistralai_gcp/utils/__init__.py +80 -0
  214. mistralai_gcp/utils/annotations.py +19 -0
  215. mistralai_gcp/utils/enums.py +34 -0
  216. mistralai_gcp/utils/eventstreaming.py +179 -0
  217. mistralai_gcp/utils/forms.py +207 -0
  218. mistralai_gcp/utils/headers.py +136 -0
  219. mistralai_gcp/utils/metadata.py +118 -0
  220. mistralai_gcp/utils/queryparams.py +203 -0
  221. mistralai_gcp/utils/requestbodies.py +66 -0
  222. mistralai_gcp/utils/retries.py +216 -0
  223. mistralai_gcp/utils/security.py +168 -0
  224. mistralai_gcp/utils/serializers.py +181 -0
  225. mistralai_gcp/utils/url.py +150 -0
  226. mistralai_gcp/utils/values.py +128 -0
  227. py.typed +1 -0
  228. mistralai/client_base.py +0 -211
  229. mistralai/constants.py +0 -5
  230. mistralai/exceptions.py +0 -54
  231. mistralai/jobs.py +0 -172
  232. mistralai/models/chat_completion.py +0 -93
  233. mistralai/models/common.py +0 -9
  234. mistralai/models/embeddings.py +0 -19
  235. mistralai/models/files.py +0 -23
  236. mistralai/models/jobs.py +0 -100
  237. mistralai/models/models.py +0 -39
  238. mistralai-0.4.2.dist-info/METADATA +0 -82
  239. mistralai-0.4.2.dist-info/RECORD +0 -20
  240. {mistralai-0.4.2.dist-info → mistralai-0.5.5a50.dist-info}/WHEEL +0 -0
@@ -0,0 +1,207 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from typing import (
4
+ Any,
5
+ Dict,
6
+ get_type_hints,
7
+ List,
8
+ Tuple,
9
+ )
10
+ from pydantic import BaseModel
11
+ from pydantic.fields import FieldInfo
12
+
13
+ from .serializers import marshal_json
14
+
15
+ from .metadata import (
16
+ FormMetadata,
17
+ MultipartFormMetadata,
18
+ find_field_metadata,
19
+ )
20
+ from .values import _val_to_string
21
+
22
+
23
+ def _populate_form(
24
+ field_name: str,
25
+ explode: bool,
26
+ obj: Any,
27
+ delimiter: str,
28
+ form: Dict[str, List[str]],
29
+ ):
30
+ if obj is None:
31
+ return form
32
+
33
+ if isinstance(obj, BaseModel):
34
+ items = []
35
+
36
+ obj_fields: Dict[str, FieldInfo] = obj.__class__.model_fields
37
+ for name in obj_fields:
38
+ obj_field = obj_fields[name]
39
+ obj_field_name = obj_field.alias if obj_field.alias is not None else name
40
+ if obj_field_name == "":
41
+ continue
42
+
43
+ val = getattr(obj, name)
44
+ if val is None:
45
+ continue
46
+
47
+ if explode:
48
+ form[obj_field_name] = [_val_to_string(val)]
49
+ else:
50
+ items.append(f"{obj_field_name}{delimiter}{_val_to_string(val)}")
51
+
52
+ if len(items) > 0:
53
+ form[field_name] = [delimiter.join(items)]
54
+ elif isinstance(obj, Dict):
55
+ items = []
56
+ for key, value in obj.items():
57
+ if value is None:
58
+ continue
59
+
60
+ if explode:
61
+ form[key] = [_val_to_string(value)]
62
+ else:
63
+ items.append(f"{key}{delimiter}{_val_to_string(value)}")
64
+
65
+ if len(items) > 0:
66
+ form[field_name] = [delimiter.join(items)]
67
+ elif isinstance(obj, List):
68
+ items = []
69
+
70
+ for value in obj:
71
+ if value is None:
72
+ continue
73
+
74
+ if explode:
75
+ if not field_name in form:
76
+ form[field_name] = []
77
+ form[field_name].append(_val_to_string(value))
78
+ else:
79
+ items.append(_val_to_string(value))
80
+
81
+ if len(items) > 0:
82
+ form[field_name] = [delimiter.join([str(item) for item in items])]
83
+ else:
84
+ form[field_name] = [_val_to_string(obj)]
85
+
86
+ return form
87
+
88
+
89
+ def serialize_multipart_form(
90
+ media_type: str, request: Any
91
+ ) -> Tuple[str, Dict[str, Any], Dict[str, Any]]:
92
+ form: Dict[str, Any] = {}
93
+ files: Dict[str, Any] = {}
94
+
95
+ if not isinstance(request, BaseModel):
96
+ raise TypeError("invalid request body type")
97
+
98
+ request_fields: Dict[str, FieldInfo] = request.__class__.model_fields
99
+ request_field_types = get_type_hints(request.__class__)
100
+
101
+ for name in request_fields:
102
+ field = request_fields[name]
103
+
104
+ val = getattr(request, name)
105
+ if val is None:
106
+ continue
107
+
108
+ field_metadata = find_field_metadata(field, MultipartFormMetadata)
109
+ if not field_metadata:
110
+ continue
111
+
112
+ f_name = field.alias if field.alias is not None else name
113
+
114
+ if field_metadata.file:
115
+ file_fields: Dict[str, FieldInfo] = val.__class__.model_fields
116
+
117
+ file_name = ""
118
+ field_name = ""
119
+ content = None
120
+ content_type = None
121
+
122
+ for file_field_name in file_fields:
123
+ file_field = file_fields[file_field_name]
124
+
125
+ file_metadata = find_field_metadata(file_field, MultipartFormMetadata)
126
+ if file_metadata is None:
127
+ continue
128
+
129
+ if file_metadata.content:
130
+ content = getattr(val, file_field_name, None)
131
+ elif file_field_name == "content_type":
132
+ content_type = getattr(val, file_field_name, None)
133
+ else:
134
+ field_name = (
135
+ file_field.alias
136
+ if file_field.alias is not None
137
+ else file_field_name
138
+ )
139
+ file_name = getattr(val, file_field_name)
140
+
141
+ if field_name == "" or file_name == "" or content is None:
142
+ raise ValueError("invalid multipart/form-data file")
143
+
144
+ if content_type is not None:
145
+ files[field_name] = (file_name, content, content_type)
146
+ else:
147
+ files[field_name] = (file_name, content)
148
+ elif field_metadata.json:
149
+ files[f_name] = (
150
+ None,
151
+ marshal_json(val, request_field_types[name]),
152
+ "application/json",
153
+ )
154
+ else:
155
+ if isinstance(val, List):
156
+ values = []
157
+
158
+ for value in val:
159
+ if value is None:
160
+ continue
161
+ values.append(_val_to_string(value))
162
+
163
+ form[f_name + "[]"] = values
164
+ else:
165
+ form[f_name] = _val_to_string(val)
166
+ return media_type, form, files
167
+
168
+
169
+ def serialize_form_data(data: Any) -> Dict[str, Any]:
170
+ form: Dict[str, List[str]] = {}
171
+
172
+ if isinstance(data, BaseModel):
173
+ data_fields: Dict[str, FieldInfo] = data.__class__.model_fields
174
+ data_field_types = get_type_hints(data.__class__)
175
+ for name in data_fields:
176
+ field = data_fields[name]
177
+
178
+ val = getattr(data, name)
179
+ if val is None:
180
+ continue
181
+
182
+ metadata = find_field_metadata(field, FormMetadata)
183
+ if metadata is None:
184
+ continue
185
+
186
+ f_name = field.alias if field.alias is not None else name
187
+
188
+ if metadata.json:
189
+ form[f_name] = [marshal_json(val, data_field_types[name])]
190
+ else:
191
+ if metadata.style == "form":
192
+ _populate_form(
193
+ f_name,
194
+ metadata.explode,
195
+ val,
196
+ ",",
197
+ form,
198
+ )
199
+ else:
200
+ raise ValueError(f"Invalid form style for field {name}")
201
+ elif isinstance(data, Dict):
202
+ for key, value in data.items():
203
+ form[key] = [_val_to_string(value)]
204
+ else:
205
+ raise TypeError(f"Invalid request body type {type(data)} for form data")
206
+
207
+ return form
@@ -0,0 +1,136 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from typing import (
4
+ Any,
5
+ Dict,
6
+ List,
7
+ Optional,
8
+ )
9
+ from httpx import Headers
10
+ from pydantic import BaseModel
11
+ from pydantic.fields import FieldInfo
12
+
13
+ from .metadata import (
14
+ HeaderMetadata,
15
+ find_field_metadata,
16
+ )
17
+
18
+ from .values import _populate_from_globals, _val_to_string
19
+
20
+
21
+ def get_headers(headers_params: Any, gbls: Optional[Any] = None) -> Dict[str, str]:
22
+ headers: Dict[str, str] = {}
23
+
24
+ globals_already_populated = []
25
+ if headers_params is not None:
26
+ globals_already_populated = _populate_headers(headers_params, gbls, headers, [])
27
+ if gbls is not None:
28
+ _populate_headers(gbls, None, headers, globals_already_populated)
29
+
30
+ return headers
31
+
32
+
33
+ def _populate_headers(
34
+ headers_params: Any,
35
+ gbls: Any,
36
+ header_values: Dict[str, str],
37
+ skip_fields: List[str],
38
+ ) -> List[str]:
39
+ globals_already_populated: List[str] = []
40
+
41
+ if not isinstance(headers_params, BaseModel):
42
+ return globals_already_populated
43
+
44
+ param_fields: Dict[str, FieldInfo] = headers_params.__class__.model_fields
45
+ for name in param_fields:
46
+ if name in skip_fields:
47
+ continue
48
+
49
+ field = param_fields[name]
50
+ f_name = field.alias if field.alias is not None else name
51
+
52
+ metadata = find_field_metadata(field, HeaderMetadata)
53
+ if metadata is None:
54
+ continue
55
+
56
+ value, global_found = _populate_from_globals(
57
+ name, getattr(headers_params, name), HeaderMetadata, gbls
58
+ )
59
+ if global_found:
60
+ globals_already_populated.append(name)
61
+ value = _serialize_header(metadata.explode, value)
62
+
63
+ if value != "":
64
+ header_values[f_name] = value
65
+
66
+ return globals_already_populated
67
+
68
+
69
+ def _serialize_header(explode: bool, obj: Any) -> str:
70
+ if obj is None:
71
+ return ""
72
+
73
+ if isinstance(obj, BaseModel):
74
+ items = []
75
+ obj_fields: Dict[str, FieldInfo] = obj.__class__.model_fields
76
+ for name in obj_fields:
77
+ obj_field = obj_fields[name]
78
+ obj_param_metadata = find_field_metadata(obj_field, HeaderMetadata)
79
+
80
+ if not obj_param_metadata:
81
+ continue
82
+
83
+ f_name = obj_field.alias if obj_field.alias is not None else name
84
+
85
+ val = getattr(obj, name)
86
+ if val is None:
87
+ continue
88
+
89
+ if explode:
90
+ items.append(f"{f_name}={_val_to_string(val)}")
91
+ else:
92
+ items.append(f_name)
93
+ items.append(_val_to_string(val))
94
+
95
+ if len(items) > 0:
96
+ return ",".join(items)
97
+ elif isinstance(obj, Dict):
98
+ items = []
99
+
100
+ for key, value in obj.items():
101
+ if value is None:
102
+ continue
103
+
104
+ if explode:
105
+ items.append(f"{key}={_val_to_string(value)}")
106
+ else:
107
+ items.append(key)
108
+ items.append(_val_to_string(value))
109
+
110
+ if len(items) > 0:
111
+ return ",".join([str(item) for item in items])
112
+ elif isinstance(obj, List):
113
+ items = []
114
+
115
+ for value in obj:
116
+ if value is None:
117
+ continue
118
+
119
+ items.append(_val_to_string(value))
120
+
121
+ if len(items) > 0:
122
+ return ",".join(items)
123
+ else:
124
+ return f"{_val_to_string(obj)}"
125
+
126
+ return ""
127
+
128
+
129
+ def get_response_headers(headers: Headers) -> Dict[str, List[str]]:
130
+ res: Dict[str, List[str]] = {}
131
+ for k, v in headers.items():
132
+ if not k in res:
133
+ res[k] = []
134
+
135
+ res[k].append(v)
136
+ return res
@@ -0,0 +1,118 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from typing import Optional, Type, TypeVar, Union
4
+ from dataclasses import dataclass
5
+ from pydantic.fields import FieldInfo
6
+
7
+
8
+ T = TypeVar("T")
9
+
10
+
11
+ @dataclass
12
+ class SecurityMetadata:
13
+ option: bool = False
14
+ scheme: bool = False
15
+ scheme_type: Optional[str] = None
16
+ sub_type: Optional[str] = None
17
+ field_name: Optional[str] = None
18
+
19
+ def get_field_name(self, default: str) -> str:
20
+ return self.field_name or default
21
+
22
+
23
+ @dataclass
24
+ class ParamMetadata:
25
+ serialization: Optional[str] = None
26
+ style: str = "simple"
27
+ explode: bool = False
28
+
29
+
30
+ @dataclass
31
+ class PathParamMetadata(ParamMetadata):
32
+ pass
33
+
34
+
35
+ @dataclass
36
+ class QueryParamMetadata(ParamMetadata):
37
+ style: str = "form"
38
+ explode: bool = True
39
+
40
+
41
+ @dataclass
42
+ class HeaderMetadata(ParamMetadata):
43
+ pass
44
+
45
+
46
+ @dataclass
47
+ class RequestMetadata:
48
+ media_type: str = "application/octet-stream"
49
+
50
+
51
+ @dataclass
52
+ class MultipartFormMetadata:
53
+ file: bool = False
54
+ content: bool = False
55
+ json: bool = False
56
+
57
+
58
+ @dataclass
59
+ class FormMetadata:
60
+ json: bool = False
61
+ style: str = "form"
62
+ explode: bool = True
63
+
64
+
65
+ class FieldMetadata:
66
+ security: Optional[SecurityMetadata] = None
67
+ path: Optional[PathParamMetadata] = None
68
+ query: Optional[QueryParamMetadata] = None
69
+ header: Optional[HeaderMetadata] = None
70
+ request: Optional[RequestMetadata] = None
71
+ form: Optional[FormMetadata] = None
72
+ multipart: Optional[MultipartFormMetadata] = None
73
+
74
+ def __init__(
75
+ self,
76
+ security: Optional[SecurityMetadata] = None,
77
+ path: Optional[Union[PathParamMetadata, bool]] = None,
78
+ query: Optional[Union[QueryParamMetadata, bool]] = None,
79
+ header: Optional[Union[HeaderMetadata, bool]] = None,
80
+ request: Optional[Union[RequestMetadata, bool]] = None,
81
+ form: Optional[Union[FormMetadata, bool]] = None,
82
+ multipart: Optional[Union[MultipartFormMetadata, bool]] = None,
83
+ ):
84
+ self.security = security
85
+ self.path = PathParamMetadata() if isinstance(path, bool) else path
86
+ self.query = QueryParamMetadata() if isinstance(query, bool) else query
87
+ self.header = HeaderMetadata() if isinstance(header, bool) else header
88
+ self.request = RequestMetadata() if isinstance(request, bool) else request
89
+ self.form = FormMetadata() if isinstance(form, bool) else form
90
+ self.multipart = (
91
+ MultipartFormMetadata() if isinstance(multipart, bool) else multipart
92
+ )
93
+
94
+
95
+ def find_field_metadata(field_info: FieldInfo, metadata_type: Type[T]) -> Optional[T]:
96
+ metadata = find_metadata(field_info, FieldMetadata)
97
+ if not metadata:
98
+ return None
99
+
100
+ fields = metadata.__dict__
101
+
102
+ for field in fields:
103
+ if isinstance(fields[field], metadata_type):
104
+ return fields[field]
105
+
106
+ return None
107
+
108
+
109
+ def find_metadata(field_info: FieldInfo, metadata_type: Type[T]) -> Optional[T]:
110
+ metadata = field_info.metadata
111
+ if not metadata:
112
+ return None
113
+
114
+ for md in metadata:
115
+ if isinstance(md, metadata_type):
116
+ return md
117
+
118
+ return None
@@ -0,0 +1,203 @@
1
+ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
2
+
3
+ from typing import (
4
+ Any,
5
+ Dict,
6
+ get_type_hints,
7
+ List,
8
+ Optional,
9
+ )
10
+
11
+ from pydantic import BaseModel
12
+ from pydantic.fields import FieldInfo
13
+
14
+ from .metadata import (
15
+ QueryParamMetadata,
16
+ find_field_metadata,
17
+ )
18
+ from .values import _get_serialized_params, _populate_from_globals, _val_to_string
19
+ from .forms import _populate_form
20
+
21
+
22
+ def get_query_params(
23
+ query_params: Any,
24
+ gbls: Optional[Any] = None,
25
+ ) -> Dict[str, List[str]]:
26
+ params: Dict[str, List[str]] = {}
27
+
28
+ globals_already_populated = _populate_query_params(query_params, gbls, params, [])
29
+ if gbls is not None:
30
+ _populate_query_params(gbls, None, params, globals_already_populated)
31
+
32
+ return params
33
+
34
+
35
+ def _populate_query_params(
36
+ query_params: Any,
37
+ gbls: Any,
38
+ query_param_values: Dict[str, List[str]],
39
+ skip_fields: List[str],
40
+ ) -> List[str]:
41
+ globals_already_populated: List[str] = []
42
+
43
+ if not isinstance(query_params, BaseModel):
44
+ return globals_already_populated
45
+
46
+ param_fields: Dict[str, FieldInfo] = query_params.__class__.model_fields
47
+ param_field_types = get_type_hints(query_params.__class__)
48
+ for name in param_fields:
49
+ if name in skip_fields:
50
+ continue
51
+
52
+ field = param_fields[name]
53
+
54
+ metadata = find_field_metadata(field, QueryParamMetadata)
55
+ if not metadata:
56
+ continue
57
+
58
+ value = getattr(query_params, name) if query_params is not None else None
59
+
60
+ value, global_found = _populate_from_globals(
61
+ name, value, QueryParamMetadata, gbls
62
+ )
63
+ if global_found:
64
+ globals_already_populated.append(name)
65
+
66
+ f_name = field.alias if field.alias is not None else name
67
+ serialization = metadata.serialization
68
+ if serialization is not None:
69
+ serialized_parms = _get_serialized_params(
70
+ metadata, f_name, value, param_field_types[name]
71
+ )
72
+ for key, value in serialized_parms.items():
73
+ if key in query_param_values:
74
+ query_param_values[key].extend(value)
75
+ else:
76
+ query_param_values[key] = [value]
77
+ else:
78
+ style = metadata.style
79
+ if style == "deepObject":
80
+ _populate_deep_object_query_params(f_name, value, query_param_values)
81
+ elif style == "form":
82
+ _populate_delimited_query_params(
83
+ metadata, f_name, value, ",", query_param_values
84
+ )
85
+ elif style == "pipeDelimited":
86
+ _populate_delimited_query_params(
87
+ metadata, f_name, value, "|", query_param_values
88
+ )
89
+ else:
90
+ raise NotImplementedError(
91
+ f"query param style {style} not yet supported"
92
+ )
93
+
94
+ return globals_already_populated
95
+
96
+
97
+ def _populate_deep_object_query_params(
98
+ field_name: str,
99
+ obj: Any,
100
+ params: Dict[str, List[str]],
101
+ ):
102
+ if obj is None:
103
+ return
104
+
105
+ if isinstance(obj, BaseModel):
106
+ _populate_deep_object_query_params_basemodel(field_name, obj, params)
107
+ elif isinstance(obj, Dict):
108
+ _populate_deep_object_query_params_dict(field_name, obj, params)
109
+
110
+
111
+ def _populate_deep_object_query_params_basemodel(
112
+ prior_params_key: str,
113
+ obj: Any,
114
+ params: Dict[str, List[str]],
115
+ ):
116
+ if obj is None:
117
+ return
118
+
119
+ if not isinstance(obj, BaseModel):
120
+ return
121
+
122
+ obj_fields: Dict[str, FieldInfo] = obj.__class__.model_fields
123
+ for name in obj_fields:
124
+ obj_field = obj_fields[name]
125
+
126
+ f_name = obj_field.alias if obj_field.alias is not None else name
127
+
128
+ params_key = f"{prior_params_key}[{f_name}]"
129
+
130
+ obj_param_metadata = find_field_metadata(obj_field, QueryParamMetadata)
131
+ if obj_param_metadata is None:
132
+ continue
133
+
134
+ obj_val = getattr(obj, name)
135
+ if obj_val is None:
136
+ continue
137
+
138
+ if isinstance(obj_val, BaseModel):
139
+ _populate_deep_object_query_params_basemodel(params_key, obj_val, params)
140
+ elif isinstance(obj_val, Dict):
141
+ _populate_deep_object_query_params_dict(params_key, obj_val, params)
142
+ elif isinstance(obj_val, List):
143
+ _populate_deep_object_query_params_list(params_key, obj_val, params)
144
+ else:
145
+ params[params_key] = [_val_to_string(obj_val)]
146
+
147
+
148
+ def _populate_deep_object_query_params_dict(
149
+ prior_params_key: str,
150
+ value: Dict,
151
+ params: Dict[str, List[str]],
152
+ ):
153
+ if value is None:
154
+ return
155
+
156
+ for key, val in value.items():
157
+ if val is None:
158
+ continue
159
+
160
+ params_key = f"{prior_params_key}[{key}]"
161
+
162
+ if isinstance(val, BaseModel):
163
+ _populate_deep_object_query_params_basemodel(params_key, val, params)
164
+ elif isinstance(val, Dict):
165
+ _populate_deep_object_query_params_dict(params_key, val, params)
166
+ elif isinstance(val, List):
167
+ _populate_deep_object_query_params_list(params_key, val, params)
168
+ else:
169
+ params[params_key] = [_val_to_string(val)]
170
+
171
+
172
+ def _populate_deep_object_query_params_list(
173
+ params_key: str,
174
+ value: List,
175
+ params: Dict[str, List[str]],
176
+ ):
177
+ if value is None:
178
+ return
179
+
180
+ for val in value:
181
+ if val is None:
182
+ continue
183
+
184
+ if params.get(params_key) is None:
185
+ params[params_key] = []
186
+
187
+ params[params_key].append(_val_to_string(val))
188
+
189
+
190
+ def _populate_delimited_query_params(
191
+ metadata: QueryParamMetadata,
192
+ field_name: str,
193
+ obj: Any,
194
+ delimiter: str,
195
+ query_param_values: Dict[str, List[str]],
196
+ ):
197
+ _populate_form(
198
+ field_name,
199
+ metadata.explode,
200
+ obj,
201
+ delimiter,
202
+ query_param_values,
203
+ )