agenta 0.48.9__py3-none-any.whl → 0.48.10__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.

Potentially problematic release.


This version of agenta might be problematic. Click here for more details.

Files changed (295) hide show
  1. agenta/__init__.py +3 -2
  2. agenta/client/Readme.md +258 -80
  3. agenta/client/__init__.py +205 -29
  4. agenta/client/backend/__init__.py +461 -0
  5. agenta/client/backend/access_control/__init__.py +2 -0
  6. agenta/client/backend/access_control/client.py +53 -73
  7. agenta/client/backend/access_control/raw_client.py +180 -0
  8. agenta/client/backend/admin/__init__.py +2 -0
  9. agenta/client/backend/admin/client.py +473 -268
  10. agenta/client/backend/admin/raw_client.py +1017 -0
  11. agenta/client/backend/api_keys/__init__.py +2 -0
  12. agenta/client/backend/api_keys/client.py +43 -276
  13. agenta/client/backend/api_keys/raw_client.py +364 -0
  14. agenta/client/backend/apps/__init__.py +2 -0
  15. agenta/client/backend/apps/client.py +132 -895
  16. agenta/client/backend/apps/raw_client.py +1516 -0
  17. agenta/client/backend/bases/__init__.py +2 -0
  18. agenta/client/backend/bases/client.py +33 -73
  19. agenta/client/backend/bases/raw_client.py +179 -0
  20. agenta/client/backend/billing/__init__.py +3 -0
  21. agenta/client/backend/billing/client.py +564 -0
  22. agenta/client/backend/billing/raw_client.py +805 -0
  23. agenta/client/backend/client.py +1268 -0
  24. agenta/client/backend/configs/__init__.py +2 -0
  25. agenta/client/backend/configs/client.py +49 -361
  26. agenta/client/backend/configs/raw_client.py +402 -0
  27. agenta/client/backend/containers/__init__.py +1 -3
  28. agenta/client/backend/containers/client.py +25 -548
  29. agenta/client/backend/containers/raw_client.py +112 -0
  30. agenta/client/backend/core/__init__.py +5 -0
  31. agenta/client/backend/core/api_error.py +12 -6
  32. agenta/client/backend/core/client_wrapper.py +4 -4
  33. agenta/client/backend/core/file.py +1 -3
  34. agenta/client/backend/core/force_multipart.py +16 -0
  35. agenta/client/backend/core/http_client.py +78 -34
  36. agenta/client/backend/core/http_response.py +55 -0
  37. agenta/client/backend/core/jsonable_encoder.py +0 -1
  38. agenta/client/backend/core/pydantic_utilities.py +88 -113
  39. agenta/client/backend/core/serialization.py +9 -3
  40. agenta/client/backend/environment.py +7 -0
  41. agenta/client/backend/environments/__init__.py +2 -0
  42. agenta/client/backend/environments/client.py +43 -79
  43. agenta/client/backend/environments/raw_client.py +193 -0
  44. agenta/client/backend/errors/__init__.py +2 -0
  45. agenta/client/backend/errors/unprocessable_entity_error.py +8 -2
  46. agenta/client/backend/evals/__init__.py +3 -0
  47. agenta/client/backend/evals/client.py +1042 -0
  48. agenta/client/backend/evals/raw_client.py +1549 -0
  49. agenta/client/backend/evaluations/__init__.py +2 -0
  50. agenta/client/backend/evaluations/client.py +106 -590
  51. agenta/client/backend/evaluations/raw_client.py +1344 -0
  52. agenta/client/backend/evaluators/__init__.py +2 -0
  53. agenta/client/backend/evaluators/client.py +99 -516
  54. agenta/client/backend/evaluators/raw_client.py +1182 -0
  55. agenta/client/backend/human_evaluations/__init__.py +2 -0
  56. agenta/client/backend/human_evaluations/client.py +120 -680
  57. agenta/client/backend/human_evaluations/raw_client.py +1577 -0
  58. agenta/client/backend/observability/__init__.py +14 -2
  59. agenta/client/backend/observability/client.py +185 -341
  60. agenta/client/backend/observability/raw_client.py +943 -0
  61. agenta/client/backend/observability/types/__init__.py +10 -2
  62. agenta/client/backend/observability/types/{format.py → fetch_trace_by_id_request_trace_id.py} +1 -1
  63. agenta/client/backend/observability/types/fetch_trace_by_id_response.py +15 -0
  64. agenta/client/backend/observability/types/query_analytics_response.py +2 -1
  65. agenta/client/backend/observability/types/query_traces_response.py +7 -3
  66. agenta/client/backend/organization/__init__.py +2 -0
  67. agenta/client/backend/organization/client.py +105 -361
  68. agenta/client/backend/organization/raw_client.py +774 -0
  69. agenta/client/backend/raw_client.py +1432 -0
  70. agenta/client/backend/scopes/__init__.py +2 -0
  71. agenta/client/backend/scopes/client.py +31 -45
  72. agenta/client/backend/scopes/raw_client.py +105 -0
  73. agenta/client/backend/testsets/__init__.py +14 -0
  74. agenta/client/backend/testsets/client.py +1098 -653
  75. agenta/client/backend/testsets/raw_client.py +2348 -0
  76. agenta/client/backend/testsets/types/__init__.py +17 -0
  77. agenta/client/backend/testsets/types/create_testset_from_file_request_file_type.py +7 -0
  78. agenta/client/backend/testsets/types/fetch_testset_to_file_request_file_type.py +7 -0
  79. agenta/client/backend/testsets/types/update_testset_from_file_request_file_type.py +7 -0
  80. agenta/client/backend/tracing/__init__.py +7 -0
  81. agenta/client/backend/tracing/client.py +782 -0
  82. agenta/client/backend/tracing/raw_client.py +1223 -0
  83. agenta/client/backend/tracing/types/__init__.py +8 -0
  84. agenta/client/backend/{types/variant_action_enum.py → tracing/types/fetch_trace_request_trace_id.py} +1 -1
  85. agenta/client/backend/tracing/types/remove_trace_request_trace_id.py +5 -0
  86. agenta/client/backend/types/__init__.py +153 -26
  87. agenta/client/backend/types/account_request.py +24 -0
  88. agenta/client/backend/types/account_response.py +5 -7
  89. agenta/client/backend/types/agenta_node_dto.py +13 -13
  90. agenta/client/backend/types/agenta_node_dto_nodes_value.py +1 -0
  91. agenta/client/backend/types/agenta_nodes_response.py +14 -8
  92. agenta/client/backend/types/agenta_root_dto.py +16 -8
  93. agenta/client/backend/types/agenta_roots_response.py +16 -8
  94. agenta/client/backend/types/agenta_tree_dto.py +16 -8
  95. agenta/client/backend/types/agenta_trees_response.py +16 -8
  96. agenta/client/backend/types/aggregated_result.py +5 -7
  97. agenta/client/backend/types/aggregated_result_evaluator_config.py +1 -0
  98. agenta/client/backend/types/analytics_response.py +4 -6
  99. agenta/client/backend/types/annotation.py +50 -0
  100. agenta/client/backend/types/annotation_create.py +39 -0
  101. agenta/client/backend/types/annotation_edit.py +31 -0
  102. agenta/client/backend/types/annotation_kind.py +5 -0
  103. agenta/client/backend/types/{uri.py → annotation_link.py} +6 -7
  104. agenta/client/backend/types/{provider_key_dto.py → annotation_link_response.py} +6 -7
  105. agenta/client/backend/types/annotation_query.py +40 -0
  106. agenta/client/backend/types/annotation_query_request.py +20 -0
  107. agenta/client/backend/types/annotation_reference.py +21 -0
  108. agenta/client/backend/types/annotation_references.py +22 -0
  109. agenta/client/backend/types/{docker_env_vars.py → annotation_response.py} +6 -7
  110. agenta/client/backend/types/annotation_source.py +5 -0
  111. agenta/client/backend/types/annotations_response.py +24 -0
  112. agenta/client/backend/types/app.py +3 -5
  113. agenta/client/backend/types/app_variant_response.py +3 -6
  114. agenta/client/backend/types/app_variant_revision.py +5 -6
  115. agenta/client/backend/types/artifact.py +44 -0
  116. agenta/client/backend/types/base_output.py +3 -5
  117. agenta/client/backend/types/body_fetch_workflow_revision.py +21 -0
  118. agenta/client/backend/types/body_import_testset.py +3 -5
  119. agenta/client/backend/types/bucket_dto.py +4 -6
  120. agenta/client/backend/types/collect_status_response.py +3 -5
  121. agenta/client/backend/types/config_db.py +3 -5
  122. agenta/client/backend/types/config_dto.py +5 -7
  123. agenta/client/backend/types/config_response_model.py +5 -7
  124. agenta/client/backend/types/correct_answer.py +3 -5
  125. agenta/client/backend/types/create_app_output.py +3 -5
  126. agenta/client/backend/types/custom_model_settings_dto.py +3 -5
  127. agenta/client/backend/types/custom_provider_dto.py +6 -9
  128. agenta/client/backend/types/custom_provider_kind.py +5 -5
  129. agenta/client/backend/types/custom_provider_settings_dto.py +3 -5
  130. agenta/client/backend/types/data.py +2 -1
  131. agenta/client/backend/types/delete_evaluation.py +3 -5
  132. agenta/client/backend/types/environment_output.py +3 -5
  133. agenta/client/backend/types/environment_output_extended.py +4 -6
  134. agenta/client/backend/types/environment_revision.py +5 -5
  135. agenta/client/backend/types/error.py +3 -5
  136. agenta/client/backend/types/evaluation.py +6 -8
  137. agenta/client/backend/types/evaluation_scenario.py +5 -7
  138. agenta/client/backend/types/evaluation_scenario_input.py +3 -5
  139. agenta/client/backend/types/evaluation_scenario_output.py +4 -6
  140. agenta/client/backend/types/evaluation_scenario_result.py +4 -6
  141. agenta/client/backend/types/evaluator.py +31 -12
  142. agenta/client/backend/types/evaluator_config.py +3 -5
  143. agenta/client/backend/types/evaluator_flags.py +21 -0
  144. agenta/client/backend/types/evaluator_mapping_output_interface.py +3 -5
  145. agenta/client/backend/types/evaluator_output_interface.py +3 -5
  146. agenta/client/backend/types/evaluator_query.py +32 -0
  147. agenta/client/backend/types/evaluator_query_request.py +30 -0
  148. agenta/client/backend/types/evaluator_request.py +20 -0
  149. agenta/client/backend/types/evaluator_response.py +21 -0
  150. agenta/client/backend/types/evaluators_response.py +21 -0
  151. agenta/client/backend/types/exception_dto.py +3 -5
  152. agenta/client/backend/types/{o_tel_spans_response.py → extended_o_tel_tracing_response.py} +5 -7
  153. agenta/client/backend/types/focus.py +5 -0
  154. agenta/client/backend/types/format.py +5 -0
  155. agenta/client/backend/types/full_json_input.py +34 -0
  156. agenta/client/backend/types/full_json_output.py +29 -0
  157. agenta/client/backend/types/get_config_response.py +3 -5
  158. agenta/client/backend/types/{header_dto.py → header.py} +4 -6
  159. agenta/client/backend/types/http_validation_error.py +4 -6
  160. agenta/client/backend/types/human_evaluation.py +3 -5
  161. agenta/client/backend/types/human_evaluation_scenario.py +4 -6
  162. agenta/client/backend/types/human_evaluation_scenario_input.py +3 -5
  163. agenta/client/backend/types/human_evaluation_scenario_output.py +3 -5
  164. agenta/client/backend/types/invite_request.py +4 -6
  165. agenta/client/backend/types/legacy_analytics_response.py +4 -6
  166. agenta/client/backend/types/legacy_data_point.py +3 -5
  167. agenta/client/backend/types/legacy_evaluator.py +26 -0
  168. agenta/client/backend/types/legacy_scope_request.py +4 -6
  169. agenta/client/backend/types/legacy_scopes_response.py +3 -5
  170. agenta/client/backend/types/legacy_subscription_request.py +19 -0
  171. agenta/client/backend/types/legacy_user_request.py +5 -7
  172. agenta/client/backend/types/legacy_user_response.py +3 -5
  173. agenta/client/backend/types/lifecycle_dto.py +3 -5
  174. agenta/client/backend/types/link_dto.py +4 -6
  175. agenta/client/backend/types/list_api_keys_response.py +3 -5
  176. agenta/client/backend/types/llm_run_rate_limit.py +3 -5
  177. agenta/client/backend/types/meta_request.py +30 -0
  178. agenta/client/backend/types/metrics_dto.py +3 -5
  179. agenta/client/backend/types/new_testset.py +3 -5
  180. agenta/client/backend/types/node_dto.py +4 -6
  181. agenta/client/backend/types/o_tel_context_dto.py +3 -5
  182. agenta/client/backend/types/o_tel_event.py +35 -0
  183. agenta/client/backend/types/o_tel_event_dto.py +3 -5
  184. agenta/client/backend/types/o_tel_extra_dto.py +4 -6
  185. agenta/client/backend/types/o_tel_flat_span.py +56 -0
  186. agenta/client/backend/types/o_tel_flat_span_input_end_time.py +6 -0
  187. agenta/client/backend/types/o_tel_flat_span_input_start_time.py +6 -0
  188. agenta/client/backend/types/o_tel_flat_span_output_end_time.py +6 -0
  189. agenta/client/backend/types/o_tel_flat_span_output_start_time.py +6 -0
  190. agenta/client/backend/types/o_tel_link.py +34 -0
  191. agenta/client/backend/types/o_tel_link_dto.py +4 -6
  192. agenta/client/backend/types/o_tel_links_response.py +22 -0
  193. agenta/client/backend/types/o_tel_span.py +58 -0
  194. agenta/client/backend/types/o_tel_span_dto.py +8 -10
  195. agenta/client/backend/types/o_tel_span_input_end_time.py +6 -0
  196. agenta/client/backend/types/o_tel_span_input_spans_value.py +7 -0
  197. agenta/client/backend/types/o_tel_span_input_start_time.py +6 -0
  198. agenta/client/backend/types/o_tel_span_output_end_time.py +6 -0
  199. agenta/client/backend/types/o_tel_span_output_spans_value.py +30 -0
  200. agenta/client/backend/types/o_tel_span_output_start_time.py +6 -0
  201. agenta/client/backend/types/o_tel_spans_tree.py +22 -0
  202. agenta/client/backend/types/o_tel_spans_tree_input_spans_value.py +7 -0
  203. agenta/client/backend/types/o_tel_spans_tree_output_spans_value.py +5 -0
  204. agenta/client/backend/types/o_tel_status_code.py +1 -1
  205. agenta/client/backend/types/o_tel_tracing_data_response.py +22 -0
  206. agenta/client/backend/types/o_tel_tracing_request.py +22 -0
  207. agenta/client/backend/types/o_tel_tracing_response.py +27 -0
  208. agenta/client/backend/types/organization.py +3 -5
  209. agenta/client/backend/types/organization_details.py +3 -5
  210. agenta/client/backend/types/organization_membership_request.py +5 -7
  211. agenta/client/backend/types/organization_output.py +3 -5
  212. agenta/client/backend/types/organization_request.py +3 -5
  213. agenta/client/backend/types/parent_dto.py +3 -5
  214. agenta/client/backend/types/permission.py +11 -0
  215. agenta/client/backend/types/plan.py +14 -0
  216. agenta/client/backend/types/project_membership_request.py +5 -7
  217. agenta/client/backend/types/project_request.py +4 -6
  218. agenta/client/backend/types/project_scope.py +5 -7
  219. agenta/client/backend/types/projects_response.py +3 -5
  220. agenta/client/backend/types/recursive_types.py +23 -0
  221. agenta/client/backend/types/reference.py +18 -5
  222. agenta/client/backend/types/reference_dto.py +4 -5
  223. agenta/client/backend/types/reference_request_model.py +4 -5
  224. agenta/client/backend/types/result.py +4 -6
  225. agenta/client/backend/types/root_dto.py +3 -5
  226. agenta/client/backend/types/scopes_response_model.py +4 -6
  227. agenta/client/backend/types/secret_dto.py +5 -7
  228. agenta/client/backend/types/secret_response_dto.py +11 -11
  229. agenta/client/backend/types/simple_evaluation_output.py +4 -6
  230. agenta/client/backend/types/span_dto.py +18 -14
  231. agenta/client/backend/types/span_dto_nodes_value.py +1 -1
  232. agenta/client/backend/types/standard_provider_dto.py +5 -7
  233. agenta/client/backend/types/standard_provider_settings_dto.py +3 -5
  234. agenta/client/backend/types/status_dto.py +4 -6
  235. agenta/client/backend/types/tags_request.py +30 -0
  236. agenta/client/backend/types/test_set_output_response.py +5 -7
  237. agenta/client/backend/types/test_set_simple_response.py +3 -5
  238. agenta/client/backend/types/testcase_response.py +33 -0
  239. agenta/client/backend/types/testset.py +46 -0
  240. agenta/client/backend/types/testset_request.py +20 -0
  241. agenta/client/backend/types/testset_response.py +21 -0
  242. agenta/client/backend/types/testsets_response.py +21 -0
  243. agenta/client/backend/types/time_dto.py +3 -5
  244. agenta/client/backend/types/timestamp.py +6 -0
  245. agenta/client/backend/types/tree_dto.py +4 -6
  246. agenta/client/backend/types/update_app_output.py +3 -5
  247. agenta/client/backend/types/user_request.py +3 -5
  248. agenta/client/backend/types/validation_error.py +4 -6
  249. agenta/client/backend/types/workflow_artifact.py +45 -0
  250. agenta/client/backend/types/workflow_data.py +20 -0
  251. agenta/client/backend/types/workflow_flags.py +21 -0
  252. agenta/client/backend/types/workflow_request.py +20 -0
  253. agenta/client/backend/types/workflow_response.py +21 -0
  254. agenta/client/backend/types/workflow_revision.py +57 -0
  255. agenta/client/backend/types/workflow_revision_request.py +20 -0
  256. agenta/client/backend/types/workflow_revision_response.py +21 -0
  257. agenta/client/backend/types/workflow_revisions_response.py +21 -0
  258. agenta/client/backend/types/workflow_variant.py +48 -0
  259. agenta/client/backend/types/workflow_variant_request.py +20 -0
  260. agenta/client/backend/types/workflow_variant_response.py +21 -0
  261. agenta/client/backend/types/workflow_variants_response.py +21 -0
  262. agenta/client/backend/types/workflows_response.py +21 -0
  263. agenta/client/backend/types/workspace.py +3 -5
  264. agenta/client/backend/types/workspace_member_response.py +4 -6
  265. agenta/client/backend/types/workspace_membership_request.py +5 -7
  266. agenta/client/backend/types/workspace_permission.py +5 -7
  267. agenta/client/backend/types/workspace_request.py +4 -6
  268. agenta/client/backend/types/workspace_response.py +4 -6
  269. agenta/client/backend/variants/__init__.py +2 -0
  270. agenta/client/backend/variants/client.py +306 -1651
  271. agenta/client/backend/variants/raw_client.py +2482 -0
  272. agenta/client/backend/variants/types/__init__.py +2 -0
  273. agenta/client/backend/variants/types/add_variant_from_base_and_config_response.py +1 -0
  274. agenta/client/backend/vault/__init__.py +2 -0
  275. agenta/client/backend/vault/client.py +69 -323
  276. agenta/client/backend/vault/raw_client.py +616 -0
  277. agenta/client/backend/workflows/__init__.py +3 -0
  278. agenta/client/backend/workflows/client.py +2398 -0
  279. agenta/client/backend/workflows/raw_client.py +3639 -0
  280. agenta/client/backend/workspace/__init__.py +2 -0
  281. agenta/client/backend/workspace/client.py +46 -147
  282. agenta/client/backend/workspace/raw_client.py +376 -0
  283. agenta/client/types.py +4 -0
  284. agenta/sdk/types.py +28 -1
  285. {agenta-0.48.9.dist-info → agenta-0.48.10.dist-info}/METADATA +1 -1
  286. agenta-0.48.10.dist-info/RECORD +362 -0
  287. agenta/client/backend/containers/types/__init__.py +0 -5
  288. agenta/client/backend/containers/types/container_templates_response.py +0 -6
  289. agenta/client/backend/types/image.py +0 -25
  290. agenta/client/backend/types/provider_kind.py +0 -21
  291. agenta/client/backend/types/template.py +0 -23
  292. agenta/client/backend/types/template_image_info.py +0 -29
  293. agenta/client/backend/types/variant_action.py +0 -22
  294. agenta-0.48.9.dist-info/RECORD +0 -255
  295. {agenta-0.48.9.dist-info → agenta-0.48.10.dist-info}/WHEEL +0 -0
@@ -0,0 +1,112 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from json.decoder import JSONDecodeError
5
+
6
+ from ..core.api_error import ApiError
7
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
+ from ..core.http_response import AsyncHttpResponse, HttpResponse
9
+ from ..core.pydantic_utilities import parse_obj_as
10
+ from ..core.request_options import RequestOptions
11
+
12
+
13
+ class RawContainersClient:
14
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
15
+ self._client_wrapper = client_wrapper
16
+
17
+ def container_templates(
18
+ self, *, request_options: typing.Optional[RequestOptions] = None
19
+ ) -> HttpResponse[typing.Optional[typing.Any]]:
20
+ """
21
+ Returns a list of templates available for creating new containers.
22
+
23
+ Parameters
24
+ ----------
25
+ request_options : typing.Optional[RequestOptions]
26
+ Request-specific configuration.
27
+
28
+ Returns
29
+ -------
30
+ HttpResponse[typing.Optional[typing.Any]]
31
+ Successful Response
32
+ """
33
+ _response = self._client_wrapper.httpx_client.request(
34
+ "containers/templates",
35
+ method="GET",
36
+ request_options=request_options,
37
+ )
38
+ try:
39
+ if _response is None or not _response.text.strip():
40
+ return HttpResponse(response=_response, data=None)
41
+ if 200 <= _response.status_code < 300:
42
+ _data = typing.cast(
43
+ typing.Optional[typing.Any],
44
+ parse_obj_as(
45
+ type_=typing.Optional[typing.Any], # type: ignore
46
+ object_=_response.json(),
47
+ ),
48
+ )
49
+ return HttpResponse(response=_response, data=_data)
50
+ _response_json = _response.json()
51
+ except JSONDecodeError:
52
+ raise ApiError(
53
+ status_code=_response.status_code,
54
+ headers=dict(_response.headers),
55
+ body=_response.text,
56
+ )
57
+ raise ApiError(
58
+ status_code=_response.status_code,
59
+ headers=dict(_response.headers),
60
+ body=_response_json,
61
+ )
62
+
63
+
64
+ class AsyncRawContainersClient:
65
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
66
+ self._client_wrapper = client_wrapper
67
+
68
+ async def container_templates(
69
+ self, *, request_options: typing.Optional[RequestOptions] = None
70
+ ) -> AsyncHttpResponse[typing.Optional[typing.Any]]:
71
+ """
72
+ Returns a list of templates available for creating new containers.
73
+
74
+ Parameters
75
+ ----------
76
+ request_options : typing.Optional[RequestOptions]
77
+ Request-specific configuration.
78
+
79
+ Returns
80
+ -------
81
+ AsyncHttpResponse[typing.Optional[typing.Any]]
82
+ Successful Response
83
+ """
84
+ _response = await self._client_wrapper.httpx_client.request(
85
+ "containers/templates",
86
+ method="GET",
87
+ request_options=request_options,
88
+ )
89
+ try:
90
+ if _response is None or not _response.text.strip():
91
+ return AsyncHttpResponse(response=_response, data=None)
92
+ if 200 <= _response.status_code < 300:
93
+ _data = typing.cast(
94
+ typing.Optional[typing.Any],
95
+ parse_obj_as(
96
+ type_=typing.Optional[typing.Any], # type: ignore
97
+ object_=_response.json(),
98
+ ),
99
+ )
100
+ return AsyncHttpResponse(response=_response, data=_data)
101
+ _response_json = _response.json()
102
+ except JSONDecodeError:
103
+ raise ApiError(
104
+ status_code=_response.status_code,
105
+ headers=dict(_response.headers),
106
+ body=_response.text,
107
+ )
108
+ raise ApiError(
109
+ status_code=_response.status_code,
110
+ headers=dict(_response.headers),
111
+ body=_response_json,
112
+ )
@@ -1,10 +1,13 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
+ # isort: skip_file
4
+
3
5
  from .api_error import ApiError
4
6
  from .client_wrapper import AsyncClientWrapper, BaseClientWrapper, SyncClientWrapper
5
7
  from .datetime_utils import serialize_datetime
6
8
  from .file import File, convert_file_dict_to_httpx_tuples, with_content_type
7
9
  from .http_client import AsyncHttpClient, HttpClient
10
+ from .http_response import AsyncHttpResponse, HttpResponse
8
11
  from .jsonable_encoder import jsonable_encoder
9
12
  from .pydantic_utilities import (
10
13
  IS_PYDANTIC_V2,
@@ -24,10 +27,12 @@ __all__ = [
24
27
  "ApiError",
25
28
  "AsyncClientWrapper",
26
29
  "AsyncHttpClient",
30
+ "AsyncHttpResponse",
27
31
  "BaseClientWrapper",
28
32
  "FieldMetadata",
29
33
  "File",
30
34
  "HttpClient",
35
+ "HttpResponse",
31
36
  "IS_PYDANTIC_V2",
32
37
  "RequestOptions",
33
38
  "SyncClientWrapper",
@@ -1,17 +1,23 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
- import typing
3
+ from typing import Any, Dict, Optional
4
4
 
5
5
 
6
6
  class ApiError(Exception):
7
- status_code: typing.Optional[int]
8
- body: typing.Any
7
+ headers: Optional[Dict[str, str]]
8
+ status_code: Optional[int]
9
+ body: Any
9
10
 
10
11
  def __init__(
11
- self, *, status_code: typing.Optional[int] = None, body: typing.Any = None
12
- ):
12
+ self,
13
+ *,
14
+ headers: Optional[Dict[str, str]] = None,
15
+ status_code: Optional[int] = None,
16
+ body: Any = None,
17
+ ) -> None:
18
+ self.headers = headers
13
19
  self.status_code = status_code
14
20
  self.body = body
15
21
 
16
22
  def __str__(self) -> str:
17
- return f"status_code: {self.status_code}, body: {self.body}"
23
+ return f"headers: {self.headers}, status_code: {self.status_code}, body: {self.body}"
@@ -1,9 +1,9 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  import typing
4
+
4
5
  import httpx
5
- from .http_client import HttpClient
6
- from .http_client import AsyncHttpClient
6
+ from .http_client import AsyncHttpClient, HttpClient
7
7
 
8
8
 
9
9
  class BaseClientWrapper:
@@ -35,7 +35,7 @@ class SyncClientWrapper(BaseClientWrapper):
35
35
  api_key: str,
36
36
  base_url: str,
37
37
  timeout: typing.Optional[float] = None,
38
- httpx_client: httpx.Client,
38
+ httpx_client: httpx.Client
39
39
  ):
40
40
  super().__init__(api_key=api_key, base_url=base_url, timeout=timeout)
41
41
  self.httpx_client = HttpClient(
@@ -53,7 +53,7 @@ class AsyncClientWrapper(BaseClientWrapper):
53
53
  api_key: str,
54
54
  base_url: str,
55
55
  timeout: typing.Optional[float] = None,
56
- httpx_client: httpx.AsyncClient,
56
+ httpx_client: httpx.AsyncClient
57
57
  ):
58
58
  super().__init__(api_key=api_key, base_url=base_url, timeout=timeout)
59
59
  self.httpx_client = AsyncHttpClient(
@@ -53,9 +53,7 @@ def with_content_type(*, file: File, default_content_type: str) -> File:
53
53
  filename, content = cast(Tuple[Optional[str], FileContent], file) # type: ignore
54
54
  return (filename, content, default_content_type)
55
55
  elif len(file) == 3:
56
- filename, content, file_content_type = cast(
57
- Tuple[Optional[str], FileContent, Optional[str]], file
58
- ) # type: ignore
56
+ filename, content, file_content_type = cast(Tuple[Optional[str], FileContent, Optional[str]], file) # type: ignore
59
57
  out_content_type = file_content_type or default_content_type
60
58
  return (filename, content, out_content_type)
61
59
  elif len(file) == 4:
@@ -0,0 +1,16 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+
4
+ class ForceMultipartDict(dict):
5
+ """
6
+ A dictionary subclass that always evaluates to True in boolean contexts.
7
+
8
+ This is used to force multipart/form-data encoding in HTTP requests even when
9
+ the dictionary is empty, which would normally evaluate to False.
10
+ """
11
+
12
+ def __bool__(self):
13
+ return True
14
+
15
+
16
+ FORCE_MULTIPART = ForceMultipartDict()
@@ -2,7 +2,6 @@
2
2
 
3
3
  import asyncio
4
4
  import email.utils
5
- import json
6
5
  import re
7
6
  import time
8
7
  import typing
@@ -11,12 +10,13 @@ from contextlib import asynccontextmanager, contextmanager
11
10
  from random import random
12
11
 
13
12
  import httpx
14
-
15
13
  from .file import File, convert_file_dict_to_httpx_tuples
14
+ from .force_multipart import FORCE_MULTIPART
16
15
  from .jsonable_encoder import jsonable_encoder
17
16
  from .query_encoder import encode_query
18
17
  from .remove_none_from_dict import remove_none_from_dict
19
18
  from .request_options import RequestOptions
19
+ from httpx._types import RequestFiles
20
20
 
21
21
  INITIAL_RETRY_DELAY_SECONDS = 0.5
22
22
  MAX_RETRY_DELAY_SECONDS = 10
@@ -191,12 +191,18 @@ class HttpClient:
191
191
  typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]
192
192
  ] = None,
193
193
  files: typing.Optional[
194
- typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]]
194
+ typing.Union[
195
+ typing.Dict[
196
+ str, typing.Optional[typing.Union[File, typing.List[File]]]
197
+ ],
198
+ typing.List[typing.Tuple[str, File]],
199
+ ]
195
200
  ] = None,
196
201
  headers: typing.Optional[typing.Dict[str, typing.Any]] = None,
197
202
  request_options: typing.Optional[RequestOptions] = None,
198
203
  retries: int = 2,
199
204
  omit: typing.Optional[typing.Any] = None,
205
+ force_multipart: typing.Optional[bool] = None,
200
206
  ) -> httpx.Response:
201
207
  base_url = self.get_base_url(base_url)
202
208
  timeout = (
@@ -210,6 +216,17 @@ class HttpClient:
210
216
  json=json, data=data, request_options=request_options, omit=omit
211
217
  )
212
218
 
219
+ request_files: typing.Optional[RequestFiles] = (
220
+ convert_file_dict_to_httpx_tuples(
221
+ remove_omit_from_dict(remove_none_from_dict(files), omit)
222
+ )
223
+ if (files is not None and files is not omit and isinstance(files, dict))
224
+ else None
225
+ )
226
+
227
+ if (request_files is None or len(request_files) == 0) and force_multipart:
228
+ request_files = FORCE_MULTIPART
229
+
213
230
  response = self.httpx_client.request(
214
231
  method=method,
215
232
  url=urllib.parse.urljoin(f"{base_url}/", path),
@@ -249,13 +266,7 @@ class HttpClient:
249
266
  json=json_body,
250
267
  data=data_body,
251
268
  content=content,
252
- files=(
253
- convert_file_dict_to_httpx_tuples(
254
- remove_omit_from_dict(remove_none_from_dict(files), omit)
255
- )
256
- if (files is not None and files is not omit)
257
- else None
258
- ),
269
+ files=request_files,
259
270
  timeout=timeout,
260
271
  )
261
272
 
@@ -295,12 +306,18 @@ class HttpClient:
295
306
  typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]
296
307
  ] = None,
297
308
  files: typing.Optional[
298
- typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]]
309
+ typing.Union[
310
+ typing.Dict[
311
+ str, typing.Optional[typing.Union[File, typing.List[File]]]
312
+ ],
313
+ typing.List[typing.Tuple[str, File]],
314
+ ]
299
315
  ] = None,
300
316
  headers: typing.Optional[typing.Dict[str, typing.Any]] = None,
301
317
  request_options: typing.Optional[RequestOptions] = None,
302
318
  retries: int = 2,
303
319
  omit: typing.Optional[typing.Any] = None,
320
+ force_multipart: typing.Optional[bool] = None,
304
321
  ) -> typing.Iterator[httpx.Response]:
305
322
  base_url = self.get_base_url(base_url)
306
323
  timeout = (
@@ -310,6 +327,17 @@ class HttpClient:
310
327
  else self.base_timeout()
311
328
  )
312
329
 
330
+ request_files: typing.Optional[RequestFiles] = (
331
+ convert_file_dict_to_httpx_tuples(
332
+ remove_omit_from_dict(remove_none_from_dict(files), omit)
333
+ )
334
+ if (files is not None and files is not omit and isinstance(files, dict))
335
+ else None
336
+ )
337
+
338
+ if (request_files is None or len(request_files) == 0) and force_multipart:
339
+ request_files = FORCE_MULTIPART
340
+
313
341
  json_body, data_body = get_request_body(
314
342
  json=json, data=data, request_options=request_options, omit=omit
315
343
  )
@@ -352,13 +380,7 @@ class HttpClient:
352
380
  json=json_body,
353
381
  data=data_body,
354
382
  content=content,
355
- files=(
356
- convert_file_dict_to_httpx_tuples(
357
- remove_omit_from_dict(remove_none_from_dict(files), omit)
358
- )
359
- if (files is not None and files is not omit)
360
- else None
361
- ),
383
+ files=request_files,
362
384
  timeout=timeout,
363
385
  ) as stream:
364
386
  yield stream
@@ -402,12 +424,18 @@ class AsyncHttpClient:
402
424
  typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]
403
425
  ] = None,
404
426
  files: typing.Optional[
405
- typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]]
427
+ typing.Union[
428
+ typing.Dict[
429
+ str, typing.Optional[typing.Union[File, typing.List[File]]]
430
+ ],
431
+ typing.List[typing.Tuple[str, File]],
432
+ ]
406
433
  ] = None,
407
434
  headers: typing.Optional[typing.Dict[str, typing.Any]] = None,
408
435
  request_options: typing.Optional[RequestOptions] = None,
409
436
  retries: int = 2,
410
437
  omit: typing.Optional[typing.Any] = None,
438
+ force_multipart: typing.Optional[bool] = None,
411
439
  ) -> httpx.Response:
412
440
  base_url = self.get_base_url(base_url)
413
441
  timeout = (
@@ -417,6 +445,17 @@ class AsyncHttpClient:
417
445
  else self.base_timeout()
418
446
  )
419
447
 
448
+ request_files: typing.Optional[RequestFiles] = (
449
+ convert_file_dict_to_httpx_tuples(
450
+ remove_omit_from_dict(remove_none_from_dict(files), omit)
451
+ )
452
+ if (files is not None and files is not omit and isinstance(files, dict))
453
+ else None
454
+ )
455
+
456
+ if (request_files is None or len(request_files) == 0) and force_multipart:
457
+ request_files = FORCE_MULTIPART
458
+
420
459
  json_body, data_body = get_request_body(
421
460
  json=json, data=data, request_options=request_options, omit=omit
422
461
  )
@@ -461,13 +500,7 @@ class AsyncHttpClient:
461
500
  json=json_body,
462
501
  data=data_body,
463
502
  content=content,
464
- files=(
465
- convert_file_dict_to_httpx_tuples(
466
- remove_omit_from_dict(remove_none_from_dict(files), omit)
467
- )
468
- if files is not None
469
- else None
470
- ),
503
+ files=request_files,
471
504
  timeout=timeout,
472
505
  )
473
506
 
@@ -506,12 +539,18 @@ class AsyncHttpClient:
506
539
  typing.Union[bytes, typing.Iterator[bytes], typing.AsyncIterator[bytes]]
507
540
  ] = None,
508
541
  files: typing.Optional[
509
- typing.Dict[str, typing.Optional[typing.Union[File, typing.List[File]]]]
542
+ typing.Union[
543
+ typing.Dict[
544
+ str, typing.Optional[typing.Union[File, typing.List[File]]]
545
+ ],
546
+ typing.List[typing.Tuple[str, File]],
547
+ ]
510
548
  ] = None,
511
549
  headers: typing.Optional[typing.Dict[str, typing.Any]] = None,
512
550
  request_options: typing.Optional[RequestOptions] = None,
513
551
  retries: int = 2,
514
552
  omit: typing.Optional[typing.Any] = None,
553
+ force_multipart: typing.Optional[bool] = None,
515
554
  ) -> typing.AsyncIterator[httpx.Response]:
516
555
  base_url = self.get_base_url(base_url)
517
556
  timeout = (
@@ -521,6 +560,17 @@ class AsyncHttpClient:
521
560
  else self.base_timeout()
522
561
  )
523
562
 
563
+ request_files: typing.Optional[RequestFiles] = (
564
+ convert_file_dict_to_httpx_tuples(
565
+ remove_omit_from_dict(remove_none_from_dict(files), omit)
566
+ )
567
+ if (files is not None and files is not omit and isinstance(files, dict))
568
+ else None
569
+ )
570
+
571
+ if (request_files is None or len(request_files) == 0) and force_multipart:
572
+ request_files = FORCE_MULTIPART
573
+
524
574
  json_body, data_body = get_request_body(
525
575
  json=json, data=data, request_options=request_options, omit=omit
526
576
  )
@@ -563,13 +613,7 @@ class AsyncHttpClient:
563
613
  json=json_body,
564
614
  data=data_body,
565
615
  content=content,
566
- files=(
567
- convert_file_dict_to_httpx_tuples(
568
- remove_omit_from_dict(remove_none_from_dict(files), omit)
569
- )
570
- if files is not None
571
- else None
572
- ),
616
+ files=request_files,
573
617
  timeout=timeout,
574
618
  ) as stream:
575
619
  yield stream
@@ -0,0 +1,55 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ from typing import Dict, Generic, TypeVar
4
+
5
+ import httpx
6
+
7
+ T = TypeVar("T")
8
+ """Generic to represent the underlying type of the data wrapped by the HTTP response."""
9
+
10
+
11
+ class BaseHttpResponse:
12
+ """Minimalist HTTP response wrapper that exposes response headers."""
13
+
14
+ _response: httpx.Response
15
+
16
+ def __init__(self, response: httpx.Response):
17
+ self._response = response
18
+
19
+ @property
20
+ def headers(self) -> Dict[str, str]:
21
+ return dict(self._response.headers)
22
+
23
+
24
+ class HttpResponse(Generic[T], BaseHttpResponse):
25
+ """HTTP response wrapper that exposes response headers and data."""
26
+
27
+ _data: T
28
+
29
+ def __init__(self, response: httpx.Response, data: T):
30
+ super().__init__(response)
31
+ self._data = data
32
+
33
+ @property
34
+ def data(self) -> T:
35
+ return self._data
36
+
37
+ def close(self) -> None:
38
+ self._response.close()
39
+
40
+
41
+ class AsyncHttpResponse(Generic[T], BaseHttpResponse):
42
+ """HTTP response wrapper that exposes response headers and data."""
43
+
44
+ _data: T
45
+
46
+ def __init__(self, response: httpx.Response, data: T):
47
+ super().__init__(response)
48
+ self._data = data
49
+
50
+ @property
51
+ def data(self) -> T:
52
+ return self._data
53
+
54
+ async def close(self) -> None:
55
+ await self._response.aclose()
@@ -17,7 +17,6 @@ from types import GeneratorType
17
17
  from typing import Any, Callable, Dict, List, Optional, Set, Union
18
18
 
19
19
  import pydantic
20
-
21
20
  from .datetime_utils import serialize_datetime
22
21
  from .pydantic_utilities import (
23
22
  IS_PYDANTIC_V2,