aeri-python 4.0.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 (391) hide show
  1. aeri/__init__.py +72 -0
  2. aeri/_client/_validation.py +204 -0
  3. aeri/_client/attributes.py +188 -0
  4. aeri/_client/client.py +3761 -0
  5. aeri/_client/constants.py +65 -0
  6. aeri/_client/datasets.py +302 -0
  7. aeri/_client/environment_variables.py +158 -0
  8. aeri/_client/get_client.py +149 -0
  9. aeri/_client/observe.py +661 -0
  10. aeri/_client/propagation.py +475 -0
  11. aeri/_client/resource_manager.py +510 -0
  12. aeri/_client/span.py +1519 -0
  13. aeri/_client/span_filter.py +76 -0
  14. aeri/_client/span_processor.py +206 -0
  15. aeri/_client/utils.py +132 -0
  16. aeri/_task_manager/media_manager.py +331 -0
  17. aeri/_task_manager/media_upload_consumer.py +44 -0
  18. aeri/_task_manager/media_upload_queue.py +12 -0
  19. aeri/_task_manager/score_ingestion_consumer.py +208 -0
  20. aeri/_task_manager/task_manager.py +475 -0
  21. aeri/_utils/__init__.py +19 -0
  22. aeri/_utils/environment.py +34 -0
  23. aeri/_utils/error_logging.py +47 -0
  24. aeri/_utils/parse_error.py +99 -0
  25. aeri/_utils/prompt_cache.py +188 -0
  26. aeri/_utils/request.py +137 -0
  27. aeri/_utils/serializer.py +205 -0
  28. aeri/api/.fern/metadata.json +14 -0
  29. aeri/api/__init__.py +836 -0
  30. aeri/api/annotation_queues/__init__.py +82 -0
  31. aeri/api/annotation_queues/client.py +1111 -0
  32. aeri/api/annotation_queues/raw_client.py +2288 -0
  33. aeri/api/annotation_queues/types/__init__.py +84 -0
  34. aeri/api/annotation_queues/types/annotation_queue.py +28 -0
  35. aeri/api/annotation_queues/types/annotation_queue_assignment_request.py +16 -0
  36. aeri/api/annotation_queues/types/annotation_queue_item.py +34 -0
  37. aeri/api/annotation_queues/types/annotation_queue_object_type.py +26 -0
  38. aeri/api/annotation_queues/types/annotation_queue_status.py +22 -0
  39. aeri/api/annotation_queues/types/create_annotation_queue_assignment_response.py +18 -0
  40. aeri/api/annotation_queues/types/create_annotation_queue_item_request.py +25 -0
  41. aeri/api/annotation_queues/types/create_annotation_queue_request.py +20 -0
  42. aeri/api/annotation_queues/types/delete_annotation_queue_assignment_response.py +14 -0
  43. aeri/api/annotation_queues/types/delete_annotation_queue_item_response.py +15 -0
  44. aeri/api/annotation_queues/types/paginated_annotation_queue_items.py +17 -0
  45. aeri/api/annotation_queues/types/paginated_annotation_queues.py +17 -0
  46. aeri/api/annotation_queues/types/update_annotation_queue_item_request.py +15 -0
  47. aeri/api/blob_storage_integrations/__init__.py +73 -0
  48. aeri/api/blob_storage_integrations/client.py +550 -0
  49. aeri/api/blob_storage_integrations/raw_client.py +976 -0
  50. aeri/api/blob_storage_integrations/types/__init__.py +77 -0
  51. aeri/api/blob_storage_integrations/types/blob_storage_export_frequency.py +26 -0
  52. aeri/api/blob_storage_integrations/types/blob_storage_export_mode.py +26 -0
  53. aeri/api/blob_storage_integrations/types/blob_storage_integration_deletion_response.py +14 -0
  54. aeri/api/blob_storage_integrations/types/blob_storage_integration_file_type.py +26 -0
  55. aeri/api/blob_storage_integrations/types/blob_storage_integration_response.py +64 -0
  56. aeri/api/blob_storage_integrations/types/blob_storage_integration_status_response.py +50 -0
  57. aeri/api/blob_storage_integrations/types/blob_storage_integration_type.py +26 -0
  58. aeri/api/blob_storage_integrations/types/blob_storage_integrations_response.py +15 -0
  59. aeri/api/blob_storage_integrations/types/blob_storage_sync_status.py +47 -0
  60. aeri/api/blob_storage_integrations/types/create_blob_storage_integration_request.py +91 -0
  61. aeri/api/client.py +679 -0
  62. aeri/api/comments/__init__.py +44 -0
  63. aeri/api/comments/client.py +407 -0
  64. aeri/api/comments/raw_client.py +750 -0
  65. aeri/api/comments/types/__init__.py +46 -0
  66. aeri/api/comments/types/create_comment_request.py +47 -0
  67. aeri/api/comments/types/create_comment_response.py +17 -0
  68. aeri/api/comments/types/get_comments_response.py +17 -0
  69. aeri/api/commons/__init__.py +210 -0
  70. aeri/api/commons/errors/__init__.py +56 -0
  71. aeri/api/commons/errors/access_denied_error.py +12 -0
  72. aeri/api/commons/errors/error.py +12 -0
  73. aeri/api/commons/errors/method_not_allowed_error.py +12 -0
  74. aeri/api/commons/errors/not_found_error.py +12 -0
  75. aeri/api/commons/errors/unauthorized_error.py +12 -0
  76. aeri/api/commons/types/__init__.py +190 -0
  77. aeri/api/commons/types/base_score.py +90 -0
  78. aeri/api/commons/types/base_score_v1.py +70 -0
  79. aeri/api/commons/types/boolean_score.py +26 -0
  80. aeri/api/commons/types/boolean_score_v1.py +26 -0
  81. aeri/api/commons/types/categorical_score.py +26 -0
  82. aeri/api/commons/types/categorical_score_v1.py +26 -0
  83. aeri/api/commons/types/comment.py +36 -0
  84. aeri/api/commons/types/comment_object_type.py +30 -0
  85. aeri/api/commons/types/config_category.py +15 -0
  86. aeri/api/commons/types/correction_score.py +26 -0
  87. aeri/api/commons/types/create_score_value.py +5 -0
  88. aeri/api/commons/types/dataset.py +49 -0
  89. aeri/api/commons/types/dataset_item.py +58 -0
  90. aeri/api/commons/types/dataset_run.py +63 -0
  91. aeri/api/commons/types/dataset_run_item.py +40 -0
  92. aeri/api/commons/types/dataset_run_with_items.py +19 -0
  93. aeri/api/commons/types/dataset_status.py +22 -0
  94. aeri/api/commons/types/map_value.py +11 -0
  95. aeri/api/commons/types/model.py +125 -0
  96. aeri/api/commons/types/model_price.py +14 -0
  97. aeri/api/commons/types/model_usage_unit.py +42 -0
  98. aeri/api/commons/types/numeric_score.py +17 -0
  99. aeri/api/commons/types/numeric_score_v1.py +17 -0
  100. aeri/api/commons/types/observation.py +142 -0
  101. aeri/api/commons/types/observation_level.py +30 -0
  102. aeri/api/commons/types/observation_v2.py +235 -0
  103. aeri/api/commons/types/observations_view.py +89 -0
  104. aeri/api/commons/types/pricing_tier.py +91 -0
  105. aeri/api/commons/types/pricing_tier_condition.py +68 -0
  106. aeri/api/commons/types/pricing_tier_input.py +76 -0
  107. aeri/api/commons/types/pricing_tier_operator.py +42 -0
  108. aeri/api/commons/types/score.py +201 -0
  109. aeri/api/commons/types/score_config.py +66 -0
  110. aeri/api/commons/types/score_config_data_type.py +26 -0
  111. aeri/api/commons/types/score_data_type.py +30 -0
  112. aeri/api/commons/types/score_source.py +26 -0
  113. aeri/api/commons/types/score_v1.py +131 -0
  114. aeri/api/commons/types/session.py +25 -0
  115. aeri/api/commons/types/session_with_traces.py +15 -0
  116. aeri/api/commons/types/trace.py +84 -0
  117. aeri/api/commons/types/trace_with_details.py +43 -0
  118. aeri/api/commons/types/trace_with_full_details.py +45 -0
  119. aeri/api/commons/types/usage.py +59 -0
  120. aeri/api/core/__init__.py +111 -0
  121. aeri/api/core/api_error.py +23 -0
  122. aeri/api/core/client_wrapper.py +141 -0
  123. aeri/api/core/datetime_utils.py +30 -0
  124. aeri/api/core/enum.py +20 -0
  125. aeri/api/core/file.py +70 -0
  126. aeri/api/core/force_multipart.py +18 -0
  127. aeri/api/core/http_client.py +711 -0
  128. aeri/api/core/http_response.py +55 -0
  129. aeri/api/core/http_sse/__init__.py +48 -0
  130. aeri/api/core/http_sse/_api.py +114 -0
  131. aeri/api/core/http_sse/_decoders.py +66 -0
  132. aeri/api/core/http_sse/_exceptions.py +7 -0
  133. aeri/api/core/http_sse/_models.py +17 -0
  134. aeri/api/core/jsonable_encoder.py +102 -0
  135. aeri/api/core/pydantic_utilities.py +310 -0
  136. aeri/api/core/query_encoder.py +60 -0
  137. aeri/api/core/remove_none_from_dict.py +11 -0
  138. aeri/api/core/request_options.py +35 -0
  139. aeri/api/core/serialization.py +282 -0
  140. aeri/api/dataset_items/__init__.py +52 -0
  141. aeri/api/dataset_items/client.py +499 -0
  142. aeri/api/dataset_items/raw_client.py +973 -0
  143. aeri/api/dataset_items/types/__init__.py +50 -0
  144. aeri/api/dataset_items/types/create_dataset_item_request.py +37 -0
  145. aeri/api/dataset_items/types/delete_dataset_item_response.py +17 -0
  146. aeri/api/dataset_items/types/paginated_dataset_items.py +17 -0
  147. aeri/api/dataset_run_items/__init__.py +43 -0
  148. aeri/api/dataset_run_items/client.py +323 -0
  149. aeri/api/dataset_run_items/raw_client.py +547 -0
  150. aeri/api/dataset_run_items/types/__init__.py +44 -0
  151. aeri/api/dataset_run_items/types/create_dataset_run_item_request.py +51 -0
  152. aeri/api/dataset_run_items/types/paginated_dataset_run_items.py +17 -0
  153. aeri/api/datasets/__init__.py +55 -0
  154. aeri/api/datasets/client.py +661 -0
  155. aeri/api/datasets/raw_client.py +1368 -0
  156. aeri/api/datasets/types/__init__.py +53 -0
  157. aeri/api/datasets/types/create_dataset_request.py +31 -0
  158. aeri/api/datasets/types/delete_dataset_run_response.py +14 -0
  159. aeri/api/datasets/types/paginated_dataset_runs.py +17 -0
  160. aeri/api/datasets/types/paginated_datasets.py +17 -0
  161. aeri/api/health/__init__.py +44 -0
  162. aeri/api/health/client.py +112 -0
  163. aeri/api/health/errors/__init__.py +42 -0
  164. aeri/api/health/errors/service_unavailable_error.py +13 -0
  165. aeri/api/health/raw_client.py +227 -0
  166. aeri/api/health/types/__init__.py +40 -0
  167. aeri/api/health/types/health_response.py +30 -0
  168. aeri/api/ingestion/__init__.py +169 -0
  169. aeri/api/ingestion/client.py +221 -0
  170. aeri/api/ingestion/raw_client.py +293 -0
  171. aeri/api/ingestion/types/__init__.py +169 -0
  172. aeri/api/ingestion/types/base_event.py +27 -0
  173. aeri/api/ingestion/types/create_event_body.py +14 -0
  174. aeri/api/ingestion/types/create_event_event.py +15 -0
  175. aeri/api/ingestion/types/create_generation_body.py +40 -0
  176. aeri/api/ingestion/types/create_generation_event.py +15 -0
  177. aeri/api/ingestion/types/create_observation_event.py +15 -0
  178. aeri/api/ingestion/types/create_span_body.py +19 -0
  179. aeri/api/ingestion/types/create_span_event.py +15 -0
  180. aeri/api/ingestion/types/ingestion_error.py +17 -0
  181. aeri/api/ingestion/types/ingestion_event.py +155 -0
  182. aeri/api/ingestion/types/ingestion_response.py +17 -0
  183. aeri/api/ingestion/types/ingestion_success.py +15 -0
  184. aeri/api/ingestion/types/ingestion_usage.py +8 -0
  185. aeri/api/ingestion/types/observation_body.py +53 -0
  186. aeri/api/ingestion/types/observation_type.py +54 -0
  187. aeri/api/ingestion/types/open_ai_completion_usage_schema.py +26 -0
  188. aeri/api/ingestion/types/open_ai_response_usage_schema.py +24 -0
  189. aeri/api/ingestion/types/open_ai_usage.py +28 -0
  190. aeri/api/ingestion/types/optional_observation_body.py +36 -0
  191. aeri/api/ingestion/types/score_body.py +75 -0
  192. aeri/api/ingestion/types/score_event.py +15 -0
  193. aeri/api/ingestion/types/sdk_log_body.py +14 -0
  194. aeri/api/ingestion/types/sdk_log_event.py +15 -0
  195. aeri/api/ingestion/types/trace_body.py +36 -0
  196. aeri/api/ingestion/types/trace_event.py +15 -0
  197. aeri/api/ingestion/types/update_event_body.py +14 -0
  198. aeri/api/ingestion/types/update_generation_body.py +40 -0
  199. aeri/api/ingestion/types/update_generation_event.py +15 -0
  200. aeri/api/ingestion/types/update_observation_event.py +15 -0
  201. aeri/api/ingestion/types/update_span_body.py +19 -0
  202. aeri/api/ingestion/types/update_span_event.py +15 -0
  203. aeri/api/ingestion/types/usage_details.py +10 -0
  204. aeri/api/legacy/__init__.py +61 -0
  205. aeri/api/legacy/client.py +105 -0
  206. aeri/api/legacy/metrics_v1/__init__.py +40 -0
  207. aeri/api/legacy/metrics_v1/client.py +214 -0
  208. aeri/api/legacy/metrics_v1/raw_client.py +322 -0
  209. aeri/api/legacy/metrics_v1/types/__init__.py +40 -0
  210. aeri/api/legacy/metrics_v1/types/metrics_response.py +19 -0
  211. aeri/api/legacy/observations_v1/__init__.py +43 -0
  212. aeri/api/legacy/observations_v1/client.py +523 -0
  213. aeri/api/legacy/observations_v1/raw_client.py +759 -0
  214. aeri/api/legacy/observations_v1/types/__init__.py +44 -0
  215. aeri/api/legacy/observations_v1/types/observations.py +17 -0
  216. aeri/api/legacy/observations_v1/types/observations_views.py +17 -0
  217. aeri/api/legacy/raw_client.py +13 -0
  218. aeri/api/legacy/score_v1/__init__.py +43 -0
  219. aeri/api/legacy/score_v1/client.py +329 -0
  220. aeri/api/legacy/score_v1/raw_client.py +545 -0
  221. aeri/api/legacy/score_v1/types/__init__.py +44 -0
  222. aeri/api/legacy/score_v1/types/create_score_request.py +75 -0
  223. aeri/api/legacy/score_v1/types/create_score_response.py +17 -0
  224. aeri/api/llm_connections/__init__.py +55 -0
  225. aeri/api/llm_connections/client.py +311 -0
  226. aeri/api/llm_connections/raw_client.py +541 -0
  227. aeri/api/llm_connections/types/__init__.py +53 -0
  228. aeri/api/llm_connections/types/llm_adapter.py +38 -0
  229. aeri/api/llm_connections/types/llm_connection.py +77 -0
  230. aeri/api/llm_connections/types/paginated_llm_connections.py +17 -0
  231. aeri/api/llm_connections/types/upsert_llm_connection_request.py +69 -0
  232. aeri/api/media/__init__.py +58 -0
  233. aeri/api/media/client.py +427 -0
  234. aeri/api/media/raw_client.py +739 -0
  235. aeri/api/media/types/__init__.py +56 -0
  236. aeri/api/media/types/get_media_response.py +55 -0
  237. aeri/api/media/types/get_media_upload_url_request.py +51 -0
  238. aeri/api/media/types/get_media_upload_url_response.py +28 -0
  239. aeri/api/media/types/media_content_type.py +232 -0
  240. aeri/api/media/types/patch_media_body.py +43 -0
  241. aeri/api/metrics/__init__.py +40 -0
  242. aeri/api/metrics/client.py +422 -0
  243. aeri/api/metrics/raw_client.py +530 -0
  244. aeri/api/metrics/types/__init__.py +40 -0
  245. aeri/api/metrics/types/metrics_v2response.py +19 -0
  246. aeri/api/models/__init__.py +43 -0
  247. aeri/api/models/client.py +523 -0
  248. aeri/api/models/raw_client.py +993 -0
  249. aeri/api/models/types/__init__.py +44 -0
  250. aeri/api/models/types/create_model_request.py +103 -0
  251. aeri/api/models/types/paginated_models.py +17 -0
  252. aeri/api/observations/__init__.py +43 -0
  253. aeri/api/observations/client.py +522 -0
  254. aeri/api/observations/raw_client.py +641 -0
  255. aeri/api/observations/types/__init__.py +44 -0
  256. aeri/api/observations/types/observations_v2meta.py +21 -0
  257. aeri/api/observations/types/observations_v2response.py +28 -0
  258. aeri/api/opentelemetry/__init__.py +67 -0
  259. aeri/api/opentelemetry/client.py +276 -0
  260. aeri/api/opentelemetry/raw_client.py +291 -0
  261. aeri/api/opentelemetry/types/__init__.py +65 -0
  262. aeri/api/opentelemetry/types/otel_attribute.py +27 -0
  263. aeri/api/opentelemetry/types/otel_attribute_value.py +46 -0
  264. aeri/api/opentelemetry/types/otel_resource.py +24 -0
  265. aeri/api/opentelemetry/types/otel_resource_span.py +32 -0
  266. aeri/api/opentelemetry/types/otel_scope.py +34 -0
  267. aeri/api/opentelemetry/types/otel_scope_span.py +28 -0
  268. aeri/api/opentelemetry/types/otel_span.py +76 -0
  269. aeri/api/opentelemetry/types/otel_trace_response.py +16 -0
  270. aeri/api/organizations/__init__.py +73 -0
  271. aeri/api/organizations/client.py +756 -0
  272. aeri/api/organizations/raw_client.py +1707 -0
  273. aeri/api/organizations/types/__init__.py +71 -0
  274. aeri/api/organizations/types/delete_membership_request.py +16 -0
  275. aeri/api/organizations/types/membership_deletion_response.py +17 -0
  276. aeri/api/organizations/types/membership_request.py +18 -0
  277. aeri/api/organizations/types/membership_response.py +20 -0
  278. aeri/api/organizations/types/membership_role.py +30 -0
  279. aeri/api/organizations/types/memberships_response.py +15 -0
  280. aeri/api/organizations/types/organization_api_key.py +31 -0
  281. aeri/api/organizations/types/organization_api_keys_response.py +19 -0
  282. aeri/api/organizations/types/organization_project.py +25 -0
  283. aeri/api/organizations/types/organization_projects_response.py +15 -0
  284. aeri/api/projects/__init__.py +67 -0
  285. aeri/api/projects/client.py +760 -0
  286. aeri/api/projects/raw_client.py +1577 -0
  287. aeri/api/projects/types/__init__.py +65 -0
  288. aeri/api/projects/types/api_key_deletion_response.py +18 -0
  289. aeri/api/projects/types/api_key_list.py +23 -0
  290. aeri/api/projects/types/api_key_response.py +30 -0
  291. aeri/api/projects/types/api_key_summary.py +35 -0
  292. aeri/api/projects/types/organization.py +22 -0
  293. aeri/api/projects/types/project.py +34 -0
  294. aeri/api/projects/types/project_deletion_response.py +15 -0
  295. aeri/api/projects/types/projects.py +15 -0
  296. aeri/api/prompt_version/__init__.py +4 -0
  297. aeri/api/prompt_version/client.py +157 -0
  298. aeri/api/prompt_version/raw_client.py +264 -0
  299. aeri/api/prompts/__init__.py +100 -0
  300. aeri/api/prompts/client.py +550 -0
  301. aeri/api/prompts/raw_client.py +987 -0
  302. aeri/api/prompts/types/__init__.py +96 -0
  303. aeri/api/prompts/types/base_prompt.py +42 -0
  304. aeri/api/prompts/types/chat_message.py +17 -0
  305. aeri/api/prompts/types/chat_message_type.py +15 -0
  306. aeri/api/prompts/types/chat_message_with_placeholders.py +8 -0
  307. aeri/api/prompts/types/chat_prompt.py +15 -0
  308. aeri/api/prompts/types/create_chat_prompt_request.py +37 -0
  309. aeri/api/prompts/types/create_chat_prompt_type.py +15 -0
  310. aeri/api/prompts/types/create_prompt_request.py +8 -0
  311. aeri/api/prompts/types/create_text_prompt_request.py +36 -0
  312. aeri/api/prompts/types/create_text_prompt_type.py +15 -0
  313. aeri/api/prompts/types/placeholder_message.py +16 -0
  314. aeri/api/prompts/types/placeholder_message_type.py +15 -0
  315. aeri/api/prompts/types/prompt.py +58 -0
  316. aeri/api/prompts/types/prompt_meta.py +35 -0
  317. aeri/api/prompts/types/prompt_meta_list_response.py +17 -0
  318. aeri/api/prompts/types/prompt_type.py +20 -0
  319. aeri/api/prompts/types/text_prompt.py +14 -0
  320. aeri/api/scim/__init__.py +94 -0
  321. aeri/api/scim/client.py +686 -0
  322. aeri/api/scim/raw_client.py +1528 -0
  323. aeri/api/scim/types/__init__.py +92 -0
  324. aeri/api/scim/types/authentication_scheme.py +20 -0
  325. aeri/api/scim/types/bulk_config.py +22 -0
  326. aeri/api/scim/types/empty_response.py +16 -0
  327. aeri/api/scim/types/filter_config.py +17 -0
  328. aeri/api/scim/types/resource_meta.py +17 -0
  329. aeri/api/scim/types/resource_type.py +27 -0
  330. aeri/api/scim/types/resource_types_response.py +21 -0
  331. aeri/api/scim/types/schema_extension.py +17 -0
  332. aeri/api/scim/types/schema_resource.py +19 -0
  333. aeri/api/scim/types/schemas_response.py +21 -0
  334. aeri/api/scim/types/scim_email.py +16 -0
  335. aeri/api/scim/types/scim_feature_support.py +14 -0
  336. aeri/api/scim/types/scim_name.py +14 -0
  337. aeri/api/scim/types/scim_user.py +24 -0
  338. aeri/api/scim/types/scim_users_list_response.py +25 -0
  339. aeri/api/scim/types/service_provider_config.py +36 -0
  340. aeri/api/scim/types/user_meta.py +20 -0
  341. aeri/api/score_configs/__init__.py +44 -0
  342. aeri/api/score_configs/client.py +526 -0
  343. aeri/api/score_configs/raw_client.py +1012 -0
  344. aeri/api/score_configs/types/__init__.py +46 -0
  345. aeri/api/score_configs/types/create_score_config_request.py +46 -0
  346. aeri/api/score_configs/types/score_configs.py +17 -0
  347. aeri/api/score_configs/types/update_score_config_request.py +53 -0
  348. aeri/api/scores/__init__.py +76 -0
  349. aeri/api/scores/client.py +420 -0
  350. aeri/api/scores/raw_client.py +656 -0
  351. aeri/api/scores/types/__init__.py +76 -0
  352. aeri/api/scores/types/get_scores_response.py +17 -0
  353. aeri/api/scores/types/get_scores_response_data.py +211 -0
  354. aeri/api/scores/types/get_scores_response_data_boolean.py +15 -0
  355. aeri/api/scores/types/get_scores_response_data_categorical.py +15 -0
  356. aeri/api/scores/types/get_scores_response_data_correction.py +15 -0
  357. aeri/api/scores/types/get_scores_response_data_numeric.py +15 -0
  358. aeri/api/scores/types/get_scores_response_trace_data.py +38 -0
  359. aeri/api/sessions/__init__.py +40 -0
  360. aeri/api/sessions/client.py +262 -0
  361. aeri/api/sessions/raw_client.py +500 -0
  362. aeri/api/sessions/types/__init__.py +40 -0
  363. aeri/api/sessions/types/paginated_sessions.py +17 -0
  364. aeri/api/trace/__init__.py +44 -0
  365. aeri/api/trace/client.py +728 -0
  366. aeri/api/trace/raw_client.py +1208 -0
  367. aeri/api/trace/types/__init__.py +46 -0
  368. aeri/api/trace/types/delete_trace_response.py +14 -0
  369. aeri/api/trace/types/sort.py +14 -0
  370. aeri/api/trace/types/traces.py +17 -0
  371. aeri/api/utils/__init__.py +44 -0
  372. aeri/api/utils/pagination/__init__.py +40 -0
  373. aeri/api/utils/pagination/types/__init__.py +40 -0
  374. aeri/api/utils/pagination/types/meta_response.py +38 -0
  375. aeri/batch_evaluation.py +1643 -0
  376. aeri/experiment.py +1044 -0
  377. aeri/langchain/CallbackHandler.py +1377 -0
  378. aeri/langchain/__init__.py +5 -0
  379. aeri/langchain/utils.py +212 -0
  380. aeri/logger.py +28 -0
  381. aeri/media.py +352 -0
  382. aeri/model.py +477 -0
  383. aeri/openai.py +1124 -0
  384. aeri/py.typed +0 -0
  385. aeri/span_filter.py +17 -0
  386. aeri/types.py +79 -0
  387. aeri/version.py +3 -0
  388. aeri_python-4.0.0.dist-info/METADATA +51 -0
  389. aeri_python-4.0.0.dist-info/RECORD +391 -0
  390. aeri_python-4.0.0.dist-info/WHEEL +4 -0
  391. aeri_python-4.0.0.dist-info/licenses/LICENSE +21 -0
aeri/__init__.py ADDED
@@ -0,0 +1,72 @@
1
+ """.. include:: ../README.md"""
2
+
3
+ from aeri.batch_evaluation import (
4
+ BatchEvaluationResult,
5
+ BatchEvaluationResumeToken,
6
+ CompositeEvaluatorFunction,
7
+ EvaluatorInputs,
8
+ EvaluatorStats,
9
+ MapperFunction,
10
+ )
11
+ from aeri.experiment import Evaluation
12
+
13
+ from ._client import client as _client_module
14
+ from ._client.attributes import AeriOtelSpanAttributes
15
+ from ._client.constants import ObservationTypeLiteral
16
+ from ._client.get_client import get_client
17
+ from ._client.observe import observe
18
+ from ._client.propagation import propagate_attributes
19
+ from ._client.span import (
20
+ AeriAgent,
21
+ AeriChain,
22
+ AeriEmbedding,
23
+ AeriEvaluator,
24
+ AeriEvent,
25
+ AeriGeneration,
26
+ AeriGuardrail,
27
+ AeriRetriever,
28
+ AeriSpan,
29
+ AeriTool,
30
+ )
31
+ from .span_filter import (
32
+ KNOWN_LLM_INSTRUMENTATION_SCOPE_PREFIXES,
33
+ is_default_export_span,
34
+ is_genai_span,
35
+ is_known_llm_instrumentor,
36
+ is_aeri_span,
37
+ )
38
+
39
+ Aeri = _client_module.Aeri
40
+
41
+ __all__ = [
42
+ "Aeri",
43
+ "get_client",
44
+ "observe",
45
+ "propagate_attributes",
46
+ "ObservationTypeLiteral",
47
+ "AeriSpan",
48
+ "AeriGeneration",
49
+ "AeriEvent",
50
+ "AeriOtelSpanAttributes",
51
+ "AeriAgent",
52
+ "AeriTool",
53
+ "AeriChain",
54
+ "AeriEmbedding",
55
+ "AeriEvaluator",
56
+ "AeriRetriever",
57
+ "AeriGuardrail",
58
+ "Evaluation",
59
+ "EvaluatorInputs",
60
+ "MapperFunction",
61
+ "CompositeEvaluatorFunction",
62
+ "EvaluatorStats",
63
+ "BatchEvaluationResumeToken",
64
+ "BatchEvaluationResult",
65
+ "is_default_export_span",
66
+ "is_aeri_span",
67
+ "is_genai_span",
68
+ "is_known_llm_instrumentor",
69
+ "KNOWN_LLM_INSTRUMENTATION_SCOPE_PREFIXES",
70
+ "experiment",
71
+ "api",
72
+ ]
@@ -0,0 +1,204 @@
1
+ """Pydantic V2 strict validation models for all public Aeri client entry-points.
2
+
3
+ Every payload that a caller passes to ``Aeri.start_observation``,
4
+ ``Aeri.create_score``, or any other public method is validated through one of
5
+ these models *before* being passed deeper into the SDK.
6
+
7
+ Design choices
8
+ ──────────────
9
+ • ``model_config = ConfigDict(strict=True)`` — rejects silent coercions (e.g.
10
+ "1" → 1) that can hide bugs in caller code.
11
+ • ``extra="forbid"`` — fails fast on unknown/misspelled fields.
12
+ • All fields that map to API concepts reuse the auto-generated Fern types (e.g.
13
+ ``MapValue``, ``ScoreBody``) so there's a single source of truth.
14
+ • Validators use Annotated + Field constraints rather than ``@validator`` /
15
+ ``@root_validator`` (Pydantic V1 patterns) for cleaner V2 semantics.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from datetime import datetime
21
+ from typing import Annotated, Any, Dict, Literal, Optional, Union
22
+
23
+ from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
24
+
25
+ from aeri._client.constants import (
26
+ ObservationTypeGenerationLike,
27
+ ObservationTypeLiteralNoEvent,
28
+ get_observation_types_list,
29
+ )
30
+ from aeri.api import MapValue, ScoreBody
31
+ from aeri.types import ScoreDataType, SpanLevel
32
+
33
+ # ─── Shared constraints ───────────────────────────────────────────────────────
34
+
35
+ _NonEmptyStr = Annotated[str, Field(min_length=1)]
36
+
37
+
38
+ # ─── Observation (span / generation / agent / tool …) ────────────────────────
39
+
40
+ class _GenerationFields(BaseModel):
41
+ """Extra fields that only apply to generation-like observations."""
42
+
43
+ model_config = ConfigDict(strict=True, extra="forbid")
44
+
45
+ completion_start_time: Optional[datetime] = None
46
+ model: Optional[str] = None
47
+ model_parameters: Optional[Dict[str, MapValue]] = None
48
+ usage_details: Optional[Dict[str, int]] = None
49
+ cost_details: Optional[Dict[str, float]] = None
50
+ prompt: Optional[Any] = None # PromptClient — avoid circular import
51
+
52
+
53
+ class ObservationInput(BaseModel):
54
+ """Validated payload for ``Aeri.start_observation`` /
55
+ ``Aeri.start_as_current_observation``."""
56
+
57
+ model_config = ConfigDict(strict=True, extra="forbid", populate_by_name=True)
58
+
59
+ name: _NonEmptyStr
60
+ as_type: ObservationTypeLiteralNoEvent = "span"
61
+ input: Optional[Any] = None
62
+ output: Optional[Any] = None
63
+ metadata: Optional[Any] = None
64
+ version: Optional[str] = None
65
+ level: Optional[SpanLevel] = None
66
+ status_message: Optional[str] = None
67
+
68
+ # Generation-only fields — allowed on any type but only forwarded when
69
+ # as_type is in ObservationTypeGenerationLike
70
+ completion_start_time: Optional[datetime] = None
71
+ model: Optional[str] = None
72
+ model_parameters: Optional[Dict[str, MapValue]] = None
73
+ usage_details: Optional[Dict[str, int]] = None
74
+ cost_details: Optional[Dict[str, float]] = None
75
+ prompt: Optional[Any] = None
76
+
77
+ @model_validator(mode="after")
78
+ def _warn_generation_fields_on_non_generation(self) -> "ObservationInput":
79
+ generation_types = get_observation_types_list(ObservationTypeGenerationLike)
80
+ if self.as_type not in generation_types:
81
+ gen_only = [
82
+ f
83
+ for f in ("completion_start_time", "model", "model_parameters",
84
+ "usage_details", "cost_details", "prompt")
85
+ if getattr(self, f) is not None
86
+ ]
87
+ if gen_only:
88
+ import warnings
89
+ warnings.warn(
90
+ f"Fields {gen_only} are only meaningful for generation-like "
91
+ f"observations (as_type in {generation_types}), but "
92
+ f"as_type={self.as_type!r} was given. They will be ignored.",
93
+ stacklevel=4,
94
+ )
95
+ return self
96
+
97
+
98
+ # ─── Score creation ───────────────────────────────────────────────────────────
99
+
100
+ class ScoreInput(BaseModel):
101
+ """Validated payload for ``Aeri.create_score`` and the span ``.score()`` helpers."""
102
+
103
+ model_config = ConfigDict(strict=True, extra="forbid")
104
+
105
+ name: _NonEmptyStr
106
+ value: Union[float, int, bool, str]
107
+ data_type: Optional[ScoreDataType] = None
108
+ comment: Optional[str] = None
109
+ config_id: Optional[str] = None
110
+ trace_id: Optional[str] = None
111
+ observation_id: Optional[str] = None
112
+
113
+ @field_validator("value")
114
+ @classmethod
115
+ def _coerce_bool_to_int(cls, v: Any) -> Any:
116
+ # Preserve bool as-is; API handles BOOLEAN data_type separately
117
+ return v
118
+
119
+ @model_validator(mode="after")
120
+ def _validate_data_type_matches_value(self) -> "ScoreInput":
121
+ if self.data_type is None:
122
+ return self
123
+ # Numeric
124
+ if self.data_type == "NUMERIC" and not isinstance(self.value, (int, float)):
125
+ value_repr = repr(self.value)
126
+ msg = f"data_type='NUMERIC' requires a numeric value; got {value_repr!r}"
127
+ raise ValueError(msg)
128
+ # Boolean
129
+ if self.data_type == "BOOLEAN" and not isinstance(self.value, (bool, int)):
130
+ value_repr = repr(self.value)
131
+ msg = f"data_type='BOOLEAN' requires a bool/int value (0 or 1); got {value_repr!r}"
132
+ raise ValueError(msg)
133
+ # Categorical
134
+ if self.data_type == "CATEGORICAL" and not isinstance(self.value, str):
135
+ value_repr = repr(self.value)
136
+ msg = f"data_type='CATEGORICAL' requires a string value; got {value_repr!r}"
137
+ raise ValueError(msg)
138
+ return self
139
+
140
+
141
+ # ─── Client constructor config ────────────────────────────────────────────────
142
+
143
+ class AeriClientConfig(BaseModel):
144
+ """Validates all constructor parameters for the ``Aeri`` client.
145
+
146
+ This is applied in ``Aeri.__init__`` after environment variable resolution
147
+ so that misconfigured callers get a clear error immediately.
148
+ """
149
+
150
+ model_config = ConfigDict(strict=False, extra="forbid") # lenient: coerce env strs
151
+
152
+ public_key: Optional[str] = None
153
+ secret_key: Optional[str] = None
154
+ base_url: str = "https://api.aeri.com"
155
+ timeout: int = Field(default=5, ge=1, le=300)
156
+ debug: bool = False
157
+ tracing_enabled: bool = True
158
+ flush_at: int = Field(default=15, ge=1, le=10_000)
159
+ flush_interval: float = Field(default=1.0, ge=0.1, le=3600.0)
160
+ environment: Optional[str] = None
161
+ release: Optional[str] = None
162
+ media_upload_thread_count: int = Field(default=1, ge=1, le=32)
163
+ sample_rate: float = Field(default=1.0, ge=0.0, le=1.0)
164
+
165
+ @field_validator("environment")
166
+ @classmethod
167
+ def _validate_environment_name(cls, v: Optional[str]) -> Optional[str]:
168
+ if v is None:
169
+ return v
170
+ if v.lower().startswith("aeri"):
171
+ msg = "environment name must not start with 'aeri'"
172
+ raise ValueError(msg)
173
+ import re
174
+ if not re.fullmatch(r"[a-z0-9_\-]+", v):
175
+ msg = (
176
+ f"environment must be lowercase alphanumeric with hyphens/underscores; "
177
+ f"got {v!r}"
178
+ )
179
+ raise ValueError(msg)
180
+ return v
181
+
182
+
183
+ # ─── Trace context ────────────────────────────────────────────────────────────
184
+
185
+ class TraceContextInput(BaseModel):
186
+ """Validates the ``trace_context`` dict passed to ``start_observation``."""
187
+
188
+ model_config = ConfigDict(strict=True, extra="forbid")
189
+
190
+ trace_id: Optional[str] = None
191
+ parent_span_id: Optional[str] = None
192
+
193
+ @field_validator("trace_id", "parent_span_id")
194
+ @classmethod
195
+ def _must_be_hex(cls, v: Optional[str], info: Any) -> Optional[str]:
196
+ if v is None:
197
+ return v
198
+ try:
199
+ int(v, 16)
200
+ except ValueError:
201
+ field_repr = repr(info.field_name)
202
+ msg = f"{field_repr} must be a hexadecimal string; got {v!r}"
203
+ raise ValueError(msg)
204
+ return v
@@ -0,0 +1,188 @@
1
+ """Span attribute management for Aeri OpenTelemetry integration.
2
+
3
+ This module defines constants and functions for managing OpenTelemetry span attributes
4
+ used by Aeri. It provides a structured approach to creating and manipulating
5
+ attributes for different span types (trace, span, generation) while ensuring consistency.
6
+
7
+ The module includes:
8
+ - Attribute name constants organized by category
9
+ - Functions to create attribute dictionaries for different entity types
10
+ - Utilities for serializing and processing attribute values
11
+ """
12
+
13
+ import json
14
+ from datetime import datetime
15
+ from typing import Any, Dict, Literal, Optional, Union
16
+
17
+ from aeri._client.constants import (
18
+ ObservationTypeGenerationLike,
19
+ ObservationTypeSpanLike,
20
+ )
21
+ from aeri._utils.serializer import EventSerializer
22
+ from aeri.api import MapValue
23
+ from aeri.model import PromptClient
24
+ from aeri.types import SpanLevel
25
+
26
+
27
+ class AeriOtelSpanAttributes:
28
+ # Aeri-Trace attributes
29
+ TRACE_NAME = "aeri.trace.name"
30
+ TRACE_USER_ID = "user.id"
31
+ TRACE_SESSION_ID = "session.id"
32
+ TRACE_TAGS = "aeri.trace.tags"
33
+ TRACE_PUBLIC = "aeri.trace.public"
34
+ TRACE_METADATA = "aeri.trace.metadata"
35
+ TRACE_INPUT = "aeri.trace.input"
36
+ TRACE_OUTPUT = "aeri.trace.output"
37
+
38
+ # Aeri-observation attributes
39
+ OBSERVATION_TYPE = "aeri.observation.type"
40
+ OBSERVATION_METADATA = "aeri.observation.metadata"
41
+ OBSERVATION_LEVEL = "aeri.observation.level"
42
+ OBSERVATION_STATUS_MESSAGE = "aeri.observation.status_message"
43
+ OBSERVATION_INPUT = "aeri.observation.input"
44
+ OBSERVATION_OUTPUT = "aeri.observation.output"
45
+
46
+ # Aeri-observation of type Generation attributes
47
+ OBSERVATION_COMPLETION_START_TIME = "aeri.observation.completion_start_time"
48
+ OBSERVATION_MODEL = "aeri.observation.model.name"
49
+ OBSERVATION_MODEL_PARAMETERS = "aeri.observation.model.parameters"
50
+ OBSERVATION_USAGE_DETAILS = "aeri.observation.usage_details"
51
+ OBSERVATION_COST_DETAILS = "aeri.observation.cost_details"
52
+ OBSERVATION_PROMPT_NAME = "aeri.observation.prompt.name"
53
+ OBSERVATION_PROMPT_VERSION = "aeri.observation.prompt.version"
54
+
55
+ # General
56
+ ENVIRONMENT = "aeri.environment"
57
+ RELEASE = "aeri.release"
58
+ VERSION = "aeri.version"
59
+
60
+ # Internal
61
+ AS_ROOT = "aeri.internal.as_root"
62
+
63
+ # Experiments
64
+ EXPERIMENT_ID = "aeri.experiment.id"
65
+ EXPERIMENT_NAME = "aeri.experiment.name"
66
+ EXPERIMENT_DESCRIPTION = "aeri.experiment.description"
67
+ EXPERIMENT_METADATA = "aeri.experiment.metadata"
68
+ EXPERIMENT_DATASET_ID = "aeri.experiment.dataset.id"
69
+ EXPERIMENT_ITEM_ID = "aeri.experiment.item.id"
70
+ EXPERIMENT_ITEM_EXPECTED_OUTPUT = "aeri.experiment.item.expected_output"
71
+ EXPERIMENT_ITEM_METADATA = "aeri.experiment.item.metadata"
72
+ EXPERIMENT_ITEM_ROOT_OBSERVATION_ID = "aeri.experiment.item.root_observation_id"
73
+
74
+
75
+ def create_trace_attributes(
76
+ *,
77
+ input: Optional[Any] = None,
78
+ output: Optional[Any] = None,
79
+ public: Optional[bool] = None,
80
+ ) -> dict:
81
+ attributes = {
82
+ AeriOtelSpanAttributes.TRACE_INPUT: _serialize(input),
83
+ AeriOtelSpanAttributes.TRACE_OUTPUT: _serialize(output),
84
+ AeriOtelSpanAttributes.TRACE_PUBLIC: public,
85
+ }
86
+
87
+ return {k: v for k, v in attributes.items() if v is not None}
88
+
89
+
90
+ def create_span_attributes(
91
+ *,
92
+ metadata: Optional[Any] = None,
93
+ input: Optional[Any] = None,
94
+ output: Optional[Any] = None,
95
+ level: Optional[SpanLevel] = None,
96
+ status_message: Optional[str] = None,
97
+ version: Optional[str] = None,
98
+ observation_type: Optional[
99
+ Union[ObservationTypeSpanLike, Literal["event"]]
100
+ ] = "span",
101
+ ) -> dict:
102
+ attributes = {
103
+ AeriOtelSpanAttributes.OBSERVATION_TYPE: observation_type,
104
+ AeriOtelSpanAttributes.OBSERVATION_LEVEL: level,
105
+ AeriOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE: status_message,
106
+ AeriOtelSpanAttributes.VERSION: version,
107
+ AeriOtelSpanAttributes.OBSERVATION_INPUT: _serialize(input),
108
+ AeriOtelSpanAttributes.OBSERVATION_OUTPUT: _serialize(output),
109
+ **_flatten_and_serialize_metadata(metadata, "observation"),
110
+ }
111
+
112
+ return {k: v for k, v in attributes.items() if v is not None}
113
+
114
+
115
+ def create_generation_attributes(
116
+ *,
117
+ name: Optional[str] = None,
118
+ completion_start_time: Optional[datetime] = None,
119
+ metadata: Optional[Any] = None,
120
+ level: Optional[SpanLevel] = None,
121
+ status_message: Optional[str] = None,
122
+ version: Optional[str] = None,
123
+ model: Optional[str] = None,
124
+ model_parameters: Optional[Dict[str, MapValue]] = None,
125
+ input: Optional[Any] = None,
126
+ output: Optional[Any] = None,
127
+ usage_details: Optional[Dict[str, int]] = None,
128
+ cost_details: Optional[Dict[str, float]] = None,
129
+ prompt: Optional[PromptClient] = None,
130
+ observation_type: Optional[ObservationTypeGenerationLike] = "generation",
131
+ ) -> dict:
132
+ attributes = {
133
+ AeriOtelSpanAttributes.OBSERVATION_TYPE: observation_type,
134
+ AeriOtelSpanAttributes.OBSERVATION_LEVEL: level,
135
+ AeriOtelSpanAttributes.OBSERVATION_STATUS_MESSAGE: status_message,
136
+ AeriOtelSpanAttributes.VERSION: version,
137
+ AeriOtelSpanAttributes.OBSERVATION_INPUT: _serialize(input),
138
+ AeriOtelSpanAttributes.OBSERVATION_OUTPUT: _serialize(output),
139
+ AeriOtelSpanAttributes.OBSERVATION_MODEL: model,
140
+ AeriOtelSpanAttributes.OBSERVATION_PROMPT_NAME: prompt.name
141
+ if prompt and not prompt.is_fallback
142
+ else None,
143
+ AeriOtelSpanAttributes.OBSERVATION_PROMPT_VERSION: prompt.version
144
+ if prompt and not prompt.is_fallback
145
+ else None,
146
+ AeriOtelSpanAttributes.OBSERVATION_USAGE_DETAILS: _serialize(usage_details),
147
+ AeriOtelSpanAttributes.OBSERVATION_COST_DETAILS: _serialize(cost_details),
148
+ AeriOtelSpanAttributes.OBSERVATION_COMPLETION_START_TIME: _serialize(
149
+ completion_start_time
150
+ ),
151
+ AeriOtelSpanAttributes.OBSERVATION_MODEL_PARAMETERS: _serialize(
152
+ model_parameters
153
+ ),
154
+ **_flatten_and_serialize_metadata(metadata, "observation"),
155
+ }
156
+
157
+ return {k: v for k, v in attributes.items() if v is not None}
158
+
159
+
160
+ def _serialize(obj: Any) -> Optional[str]:
161
+ if obj is None or isinstance(obj, str):
162
+ return obj
163
+
164
+ return json.dumps(obj, cls=EventSerializer)
165
+
166
+
167
+ def _flatten_and_serialize_metadata(
168
+ metadata: Any, type: Literal["observation", "trace"]
169
+ ) -> dict:
170
+ prefix = (
171
+ AeriOtelSpanAttributes.OBSERVATION_METADATA
172
+ if type == "observation"
173
+ else AeriOtelSpanAttributes.TRACE_METADATA
174
+ )
175
+
176
+ metadata_attributes: Dict[str, Union[str, int, None]] = {}
177
+
178
+ if not isinstance(metadata, dict):
179
+ metadata_attributes[prefix] = _serialize(metadata)
180
+ else:
181
+ for key, value in metadata.items():
182
+ metadata_attributes[f"{prefix}.{key}"] = (
183
+ value
184
+ if isinstance(value, str) or isinstance(value, int)
185
+ else _serialize(value)
186
+ )
187
+
188
+ return metadata_attributes