opik 1.6.4__py3-none-any.whl → 1.9.71__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 (1021) hide show
  1. opik/__init__.py +33 -2
  2. opik/anonymizer/__init__.py +5 -0
  3. opik/anonymizer/anonymizer.py +12 -0
  4. opik/anonymizer/factory.py +80 -0
  5. opik/anonymizer/recursive_anonymizer.py +64 -0
  6. opik/anonymizer/rules.py +56 -0
  7. opik/anonymizer/rules_anonymizer.py +35 -0
  8. opik/api_objects/attachment/__init__.py +5 -0
  9. opik/api_objects/attachment/attachment.py +20 -0
  10. opik/api_objects/attachment/attachment_context.py +36 -0
  11. opik/api_objects/attachment/attachments_extractor.py +153 -0
  12. opik/api_objects/attachment/client.py +220 -0
  13. opik/api_objects/attachment/converters.py +51 -0
  14. opik/api_objects/attachment/decoder.py +18 -0
  15. opik/api_objects/attachment/decoder_base64.py +83 -0
  16. opik/api_objects/attachment/decoder_helpers.py +137 -0
  17. opik/api_objects/conversation/__init__.py +0 -0
  18. opik/api_objects/conversation/conversation_factory.py +43 -0
  19. opik/api_objects/conversation/conversation_thread.py +49 -0
  20. opik/api_objects/data_helpers.py +79 -0
  21. opik/api_objects/dataset/dataset.py +107 -45
  22. opik/api_objects/dataset/rest_operations.py +12 -3
  23. opik/api_objects/experiment/experiment.py +81 -45
  24. opik/api_objects/experiment/experiment_item.py +2 -1
  25. opik/api_objects/experiment/experiments_client.py +64 -0
  26. opik/api_objects/experiment/helpers.py +35 -11
  27. opik/api_objects/experiment/rest_operations.py +88 -19
  28. opik/api_objects/helpers.py +104 -7
  29. opik/api_objects/local_recording.py +81 -0
  30. opik/api_objects/opik_client.py +872 -174
  31. opik/api_objects/opik_query_language.py +136 -18
  32. opik/api_objects/optimization/__init__.py +3 -0
  33. opik/api_objects/optimization/optimization.py +39 -0
  34. opik/api_objects/prompt/__init__.py +13 -1
  35. opik/api_objects/prompt/base_prompt.py +69 -0
  36. opik/api_objects/prompt/base_prompt_template.py +29 -0
  37. opik/api_objects/prompt/chat/__init__.py +1 -0
  38. opik/api_objects/prompt/chat/chat_prompt.py +210 -0
  39. opik/api_objects/prompt/chat/chat_prompt_template.py +350 -0
  40. opik/api_objects/prompt/chat/content_renderer_registry.py +203 -0
  41. opik/api_objects/prompt/client.py +193 -41
  42. opik/api_objects/prompt/text/__init__.py +1 -0
  43. opik/api_objects/prompt/text/prompt.py +174 -0
  44. opik/api_objects/prompt/text/prompt_template.py +55 -0
  45. opik/api_objects/prompt/types.py +29 -0
  46. opik/api_objects/rest_stream_parser.py +98 -0
  47. opik/api_objects/search_helpers.py +89 -0
  48. opik/api_objects/span/span_client.py +165 -45
  49. opik/api_objects/span/span_data.py +136 -25
  50. opik/api_objects/threads/__init__.py +0 -0
  51. opik/api_objects/threads/threads_client.py +185 -0
  52. opik/api_objects/trace/trace_client.py +72 -36
  53. opik/api_objects/trace/trace_data.py +112 -26
  54. opik/api_objects/validation_helpers.py +3 -3
  55. opik/cli/__init__.py +5 -0
  56. opik/cli/__main__.py +6 -0
  57. opik/cli/configure.py +66 -0
  58. opik/cli/exports/__init__.py +131 -0
  59. opik/cli/exports/dataset.py +278 -0
  60. opik/cli/exports/experiment.py +784 -0
  61. opik/cli/exports/project.py +685 -0
  62. opik/cli/exports/prompt.py +578 -0
  63. opik/cli/exports/utils.py +406 -0
  64. opik/cli/harbor.py +39 -0
  65. opik/cli/healthcheck.py +21 -0
  66. opik/cli/imports/__init__.py +439 -0
  67. opik/cli/imports/dataset.py +143 -0
  68. opik/cli/imports/experiment.py +1192 -0
  69. opik/cli/imports/project.py +262 -0
  70. opik/cli/imports/prompt.py +177 -0
  71. opik/cli/imports/utils.py +280 -0
  72. opik/cli/main.py +49 -0
  73. opik/cli/proxy.py +93 -0
  74. opik/cli/usage_report/__init__.py +16 -0
  75. opik/cli/usage_report/charts.py +783 -0
  76. opik/cli/usage_report/cli.py +274 -0
  77. opik/cli/usage_report/constants.py +9 -0
  78. opik/cli/usage_report/extraction.py +749 -0
  79. opik/cli/usage_report/pdf.py +244 -0
  80. opik/cli/usage_report/statistics.py +78 -0
  81. opik/cli/usage_report/utils.py +235 -0
  82. opik/config.py +62 -4
  83. opik/configurator/configure.py +45 -6
  84. opik/configurator/opik_rest_helpers.py +4 -1
  85. opik/context_storage.py +164 -65
  86. opik/datetime_helpers.py +12 -0
  87. opik/decorator/arguments_helpers.py +9 -1
  88. opik/decorator/base_track_decorator.py +298 -146
  89. opik/decorator/context_manager/__init__.py +0 -0
  90. opik/decorator/context_manager/span_context_manager.py +123 -0
  91. opik/decorator/context_manager/trace_context_manager.py +84 -0
  92. opik/decorator/generator_wrappers.py +3 -2
  93. opik/decorator/inspect_helpers.py +11 -0
  94. opik/decorator/opik_args/__init__.py +13 -0
  95. opik/decorator/opik_args/api_classes.py +71 -0
  96. opik/decorator/opik_args/helpers.py +120 -0
  97. opik/decorator/span_creation_handler.py +49 -21
  98. opik/decorator/tracker.py +9 -1
  99. opik/dict_utils.py +3 -3
  100. opik/environment.py +13 -1
  101. opik/error_tracking/api.py +1 -1
  102. opik/error_tracking/before_send.py +6 -5
  103. opik/error_tracking/environment_details.py +29 -7
  104. opik/error_tracking/error_filtering/filter_by_response_status_code.py +42 -0
  105. opik/error_tracking/error_filtering/filter_chain_builder.py +14 -3
  106. opik/evaluation/__init__.py +14 -2
  107. opik/evaluation/engine/engine.py +280 -82
  108. opik/evaluation/engine/evaluation_tasks_executor.py +15 -10
  109. opik/evaluation/engine/helpers.py +34 -9
  110. opik/evaluation/engine/metrics_evaluator.py +237 -0
  111. opik/evaluation/engine/types.py +5 -4
  112. opik/evaluation/evaluation_result.py +169 -2
  113. opik/evaluation/evaluator.py +659 -58
  114. opik/evaluation/metrics/__init__.py +121 -6
  115. opik/evaluation/metrics/aggregated_metric.py +92 -0
  116. opik/evaluation/metrics/arguments_helpers.py +15 -21
  117. opik/evaluation/metrics/arguments_validator.py +38 -0
  118. opik/evaluation/metrics/base_metric.py +20 -10
  119. opik/evaluation/metrics/conversation/__init__.py +48 -0
  120. opik/evaluation/metrics/conversation/conversation_thread_metric.py +79 -0
  121. opik/evaluation/metrics/conversation/conversation_turns_factory.py +39 -0
  122. opik/evaluation/metrics/conversation/g_eval_wrappers.py +19 -0
  123. opik/evaluation/metrics/conversation/helpers.py +84 -0
  124. opik/evaluation/metrics/conversation/heuristics/__init__.py +14 -0
  125. opik/evaluation/metrics/conversation/heuristics/degeneration/__init__.py +3 -0
  126. opik/evaluation/metrics/conversation/heuristics/degeneration/metric.py +189 -0
  127. opik/evaluation/metrics/conversation/heuristics/degeneration/phrases.py +12 -0
  128. opik/evaluation/metrics/conversation/heuristics/knowledge_retention/__init__.py +3 -0
  129. opik/evaluation/metrics/conversation/heuristics/knowledge_retention/metric.py +172 -0
  130. opik/evaluation/metrics/conversation/llm_judges/__init__.py +32 -0
  131. opik/evaluation/metrics/conversation/llm_judges/conversational_coherence/__init__.py +0 -0
  132. opik/evaluation/metrics/conversation/llm_judges/conversational_coherence/metric.py +274 -0
  133. opik/evaluation/metrics/conversation/llm_judges/conversational_coherence/schema.py +16 -0
  134. opik/evaluation/metrics/conversation/llm_judges/conversational_coherence/templates.py +95 -0
  135. opik/evaluation/metrics/conversation/llm_judges/g_eval_wrappers.py +442 -0
  136. opik/evaluation/metrics/conversation/llm_judges/session_completeness/__init__.py +0 -0
  137. opik/evaluation/metrics/conversation/llm_judges/session_completeness/metric.py +295 -0
  138. opik/evaluation/metrics/conversation/llm_judges/session_completeness/schema.py +22 -0
  139. opik/evaluation/metrics/conversation/llm_judges/session_completeness/templates.py +139 -0
  140. opik/evaluation/metrics/conversation/llm_judges/user_frustration/__init__.py +0 -0
  141. opik/evaluation/metrics/conversation/llm_judges/user_frustration/metric.py +277 -0
  142. opik/evaluation/metrics/conversation/llm_judges/user_frustration/schema.py +16 -0
  143. opik/evaluation/metrics/conversation/llm_judges/user_frustration/templates.py +135 -0
  144. opik/evaluation/metrics/conversation/types.py +34 -0
  145. opik/evaluation/metrics/conversation_types.py +9 -0
  146. opik/evaluation/metrics/heuristics/bertscore.py +107 -0
  147. opik/evaluation/metrics/heuristics/bleu.py +43 -16
  148. opik/evaluation/metrics/heuristics/chrf.py +127 -0
  149. opik/evaluation/metrics/heuristics/contains.py +50 -11
  150. opik/evaluation/metrics/heuristics/distribution_metrics.py +331 -0
  151. opik/evaluation/metrics/heuristics/equals.py +4 -1
  152. opik/evaluation/metrics/heuristics/gleu.py +113 -0
  153. opik/evaluation/metrics/heuristics/is_json.py +9 -3
  154. opik/evaluation/metrics/heuristics/language_adherence.py +123 -0
  155. opik/evaluation/metrics/heuristics/levenshtein_ratio.py +6 -5
  156. opik/evaluation/metrics/heuristics/meteor.py +119 -0
  157. opik/evaluation/metrics/heuristics/prompt_injection.py +150 -0
  158. opik/evaluation/metrics/heuristics/readability.py +129 -0
  159. opik/evaluation/metrics/heuristics/regex_match.py +4 -1
  160. opik/evaluation/metrics/heuristics/rouge.py +148 -0
  161. opik/evaluation/metrics/heuristics/sentiment.py +98 -0
  162. opik/evaluation/metrics/heuristics/spearman.py +88 -0
  163. opik/evaluation/metrics/heuristics/tone.py +155 -0
  164. opik/evaluation/metrics/heuristics/vader_sentiment.py +77 -0
  165. opik/evaluation/metrics/llm_judges/answer_relevance/metric.py +27 -30
  166. opik/evaluation/metrics/llm_judges/answer_relevance/parser.py +27 -0
  167. opik/evaluation/metrics/llm_judges/answer_relevance/templates.py +10 -10
  168. opik/evaluation/metrics/llm_judges/context_precision/metric.py +28 -31
  169. opik/evaluation/metrics/llm_judges/context_precision/parser.py +27 -0
  170. opik/evaluation/metrics/llm_judges/context_precision/template.py +7 -7
  171. opik/evaluation/metrics/llm_judges/context_recall/metric.py +27 -31
  172. opik/evaluation/metrics/llm_judges/context_recall/parser.py +27 -0
  173. opik/evaluation/metrics/llm_judges/context_recall/template.py +7 -7
  174. opik/evaluation/metrics/llm_judges/factuality/metric.py +7 -26
  175. opik/evaluation/metrics/llm_judges/factuality/parser.py +35 -0
  176. opik/evaluation/metrics/llm_judges/factuality/template.py +1 -1
  177. opik/evaluation/metrics/llm_judges/g_eval/__init__.py +5 -0
  178. opik/evaluation/metrics/llm_judges/g_eval/metric.py +244 -113
  179. opik/evaluation/metrics/llm_judges/g_eval/parser.py +161 -0
  180. opik/evaluation/metrics/llm_judges/g_eval/presets.py +209 -0
  181. opik/evaluation/metrics/llm_judges/g_eval_presets/__init__.py +36 -0
  182. opik/evaluation/metrics/llm_judges/g_eval_presets/agent_assessment.py +77 -0
  183. opik/evaluation/metrics/llm_judges/g_eval_presets/bias_classifier.py +181 -0
  184. opik/evaluation/metrics/llm_judges/g_eval_presets/compliance_risk.py +41 -0
  185. opik/evaluation/metrics/llm_judges/g_eval_presets/prompt_uncertainty.py +41 -0
  186. opik/evaluation/metrics/llm_judges/g_eval_presets/qa_suite.py +146 -0
  187. opik/evaluation/metrics/llm_judges/hallucination/metric.py +23 -27
  188. opik/evaluation/metrics/llm_judges/hallucination/parser.py +29 -0
  189. opik/evaluation/metrics/llm_judges/hallucination/template.py +2 -4
  190. opik/evaluation/metrics/llm_judges/llm_juries/__init__.py +3 -0
  191. opik/evaluation/metrics/llm_judges/llm_juries/metric.py +76 -0
  192. opik/evaluation/metrics/llm_judges/moderation/metric.py +23 -28
  193. opik/evaluation/metrics/llm_judges/moderation/parser.py +27 -0
  194. opik/evaluation/metrics/llm_judges/moderation/template.py +2 -2
  195. opik/evaluation/metrics/llm_judges/parsing_helpers.py +26 -0
  196. opik/evaluation/metrics/llm_judges/structure_output_compliance/__init__.py +0 -0
  197. opik/evaluation/metrics/llm_judges/structure_output_compliance/metric.py +144 -0
  198. opik/evaluation/metrics/llm_judges/structure_output_compliance/parser.py +79 -0
  199. opik/evaluation/metrics/llm_judges/structure_output_compliance/schema.py +15 -0
  200. opik/evaluation/metrics/llm_judges/structure_output_compliance/template.py +50 -0
  201. opik/evaluation/metrics/llm_judges/syc_eval/__init__.py +0 -0
  202. opik/evaluation/metrics/llm_judges/syc_eval/metric.py +252 -0
  203. opik/evaluation/metrics/llm_judges/syc_eval/parser.py +82 -0
  204. opik/evaluation/metrics/llm_judges/syc_eval/template.py +155 -0
  205. opik/evaluation/metrics/llm_judges/trajectory_accuracy/__init__.py +3 -0
  206. opik/evaluation/metrics/llm_judges/trajectory_accuracy/metric.py +171 -0
  207. opik/evaluation/metrics/llm_judges/trajectory_accuracy/parser.py +38 -0
  208. opik/evaluation/metrics/llm_judges/trajectory_accuracy/templates.py +65 -0
  209. opik/evaluation/metrics/llm_judges/usefulness/metric.py +23 -32
  210. opik/evaluation/metrics/llm_judges/usefulness/parser.py +28 -0
  211. opik/evaluation/metrics/ragas_metric.py +112 -0
  212. opik/evaluation/models/__init__.py +10 -0
  213. opik/evaluation/models/base_model.py +140 -18
  214. opik/evaluation/models/langchain/__init__.py +3 -0
  215. opik/evaluation/models/langchain/langchain_chat_model.py +166 -0
  216. opik/evaluation/models/langchain/message_converters.py +106 -0
  217. opik/evaluation/models/langchain/opik_monitoring.py +23 -0
  218. opik/evaluation/models/litellm/litellm_chat_model.py +186 -40
  219. opik/evaluation/models/litellm/opik_monitor.py +24 -21
  220. opik/evaluation/models/litellm/util.py +125 -0
  221. opik/evaluation/models/litellm/warning_filters.py +16 -4
  222. opik/evaluation/models/model_capabilities.py +187 -0
  223. opik/evaluation/models/models_factory.py +25 -3
  224. opik/evaluation/preprocessing.py +92 -0
  225. opik/evaluation/report.py +70 -12
  226. opik/evaluation/rest_operations.py +49 -45
  227. opik/evaluation/samplers/__init__.py +4 -0
  228. opik/evaluation/samplers/base_dataset_sampler.py +40 -0
  229. opik/evaluation/samplers/random_dataset_sampler.py +48 -0
  230. opik/evaluation/score_statistics.py +66 -0
  231. opik/evaluation/scorers/__init__.py +4 -0
  232. opik/evaluation/scorers/scorer_function.py +55 -0
  233. opik/evaluation/scorers/scorer_wrapper_metric.py +130 -0
  234. opik/evaluation/test_case.py +3 -2
  235. opik/evaluation/test_result.py +1 -0
  236. opik/evaluation/threads/__init__.py +0 -0
  237. opik/evaluation/threads/context_helper.py +32 -0
  238. opik/evaluation/threads/evaluation_engine.py +181 -0
  239. opik/evaluation/threads/evaluation_result.py +18 -0
  240. opik/evaluation/threads/evaluator.py +120 -0
  241. opik/evaluation/threads/helpers.py +51 -0
  242. opik/evaluation/types.py +9 -1
  243. opik/exceptions.py +116 -3
  244. opik/file_upload/__init__.py +0 -0
  245. opik/file_upload/base_upload_manager.py +39 -0
  246. opik/file_upload/file_upload_monitor.py +14 -0
  247. opik/file_upload/file_uploader.py +141 -0
  248. opik/file_upload/mime_type.py +9 -0
  249. opik/file_upload/s3_multipart_upload/__init__.py +0 -0
  250. opik/file_upload/s3_multipart_upload/file_parts_strategy.py +89 -0
  251. opik/file_upload/s3_multipart_upload/s3_file_uploader.py +86 -0
  252. opik/file_upload/s3_multipart_upload/s3_upload_error.py +29 -0
  253. opik/file_upload/thread_pool.py +17 -0
  254. opik/file_upload/upload_client.py +114 -0
  255. opik/file_upload/upload_manager.py +255 -0
  256. opik/file_upload/upload_options.py +37 -0
  257. opik/format_helpers.py +17 -0
  258. opik/guardrails/__init__.py +4 -0
  259. opik/guardrails/guardrail.py +157 -0
  260. opik/guardrails/guards/__init__.py +5 -0
  261. opik/guardrails/guards/guard.py +17 -0
  262. opik/guardrails/guards/pii.py +47 -0
  263. opik/guardrails/guards/topic.py +76 -0
  264. opik/guardrails/rest_api_client.py +34 -0
  265. opik/guardrails/schemas.py +24 -0
  266. opik/guardrails/tracing.py +61 -0
  267. opik/healthcheck/__init__.py +2 -1
  268. opik/healthcheck/checks.py +2 -2
  269. opik/healthcheck/rich_representation.py +1 -1
  270. opik/hooks/__init__.py +23 -0
  271. opik/hooks/anonymizer_hook.py +36 -0
  272. opik/hooks/httpx_client_hook.py +112 -0
  273. opik/httpx_client.py +75 -4
  274. opik/id_helpers.py +18 -0
  275. opik/integrations/adk/__init__.py +14 -0
  276. opik/integrations/adk/callback_context_info_extractors.py +32 -0
  277. opik/integrations/adk/graph/__init__.py +0 -0
  278. opik/integrations/adk/graph/mermaid_graph_builder.py +128 -0
  279. opik/integrations/adk/graph/nodes.py +101 -0
  280. opik/integrations/adk/graph/subgraph_edges_builders.py +41 -0
  281. opik/integrations/adk/helpers.py +48 -0
  282. opik/integrations/adk/legacy_opik_tracer.py +381 -0
  283. opik/integrations/adk/opik_tracer.py +370 -0
  284. opik/integrations/adk/patchers/__init__.py +4 -0
  285. opik/integrations/adk/patchers/adk_otel_tracer/__init__.py +0 -0
  286. opik/integrations/adk/patchers/adk_otel_tracer/llm_span_helpers.py +30 -0
  287. opik/integrations/adk/patchers/adk_otel_tracer/opik_adk_otel_tracer.py +201 -0
  288. opik/integrations/adk/patchers/litellm_wrappers.py +91 -0
  289. opik/integrations/adk/patchers/llm_response_wrapper.py +105 -0
  290. opik/integrations/adk/patchers/patchers.py +64 -0
  291. opik/integrations/adk/recursive_callback_injector.py +126 -0
  292. opik/integrations/aisuite/aisuite_decorator.py +8 -3
  293. opik/integrations/aisuite/opik_tracker.py +1 -0
  294. opik/integrations/anthropic/messages_create_decorator.py +8 -3
  295. opik/integrations/anthropic/opik_tracker.py +0 -1
  296. opik/integrations/bedrock/converse/__init__.py +0 -0
  297. opik/integrations/bedrock/converse/chunks_aggregator.py +188 -0
  298. opik/integrations/bedrock/{converse_decorator.py → converse/converse_decorator.py} +18 -8
  299. opik/integrations/bedrock/invoke_agent_decorator.py +12 -7
  300. opik/integrations/bedrock/invoke_model/__init__.py +0 -0
  301. opik/integrations/bedrock/invoke_model/chunks_aggregator/__init__.py +78 -0
  302. opik/integrations/bedrock/invoke_model/chunks_aggregator/api.py +45 -0
  303. opik/integrations/bedrock/invoke_model/chunks_aggregator/base.py +23 -0
  304. opik/integrations/bedrock/invoke_model/chunks_aggregator/claude.py +121 -0
  305. opik/integrations/bedrock/invoke_model/chunks_aggregator/format_detector.py +107 -0
  306. opik/integrations/bedrock/invoke_model/chunks_aggregator/llama.py +108 -0
  307. opik/integrations/bedrock/invoke_model/chunks_aggregator/mistral.py +118 -0
  308. opik/integrations/bedrock/invoke_model/chunks_aggregator/nova.py +99 -0
  309. opik/integrations/bedrock/invoke_model/invoke_model_decorator.py +178 -0
  310. opik/integrations/bedrock/invoke_model/response_types.py +34 -0
  311. opik/integrations/bedrock/invoke_model/stream_wrappers.py +122 -0
  312. opik/integrations/bedrock/invoke_model/usage_converters.py +87 -0
  313. opik/integrations/bedrock/invoke_model/usage_extraction.py +108 -0
  314. opik/integrations/bedrock/opik_tracker.py +43 -4
  315. opik/integrations/bedrock/types.py +19 -0
  316. opik/integrations/crewai/crewai_decorator.py +34 -56
  317. opik/integrations/crewai/opik_tracker.py +31 -10
  318. opik/integrations/crewai/patchers/__init__.py +5 -0
  319. opik/integrations/crewai/patchers/flow.py +118 -0
  320. opik/integrations/crewai/patchers/litellm_completion.py +30 -0
  321. opik/integrations/crewai/patchers/llm_client.py +207 -0
  322. opik/integrations/dspy/callback.py +246 -84
  323. opik/integrations/dspy/graph.py +88 -0
  324. opik/integrations/dspy/parsers.py +168 -0
  325. opik/integrations/genai/encoder_extension.py +2 -6
  326. opik/integrations/genai/generate_content_decorator.py +20 -13
  327. opik/integrations/guardrails/guardrails_decorator.py +4 -0
  328. opik/integrations/harbor/__init__.py +17 -0
  329. opik/integrations/harbor/experiment_service.py +269 -0
  330. opik/integrations/harbor/opik_tracker.py +528 -0
  331. opik/integrations/haystack/constants.py +35 -0
  332. opik/integrations/haystack/converters.py +1 -2
  333. opik/integrations/haystack/opik_connector.py +28 -6
  334. opik/integrations/haystack/opik_span_bridge.py +284 -0
  335. opik/integrations/haystack/opik_tracer.py +124 -222
  336. opik/integrations/langchain/__init__.py +3 -1
  337. opik/integrations/langchain/helpers.py +96 -0
  338. opik/integrations/langchain/langgraph_async_context_bridge.py +131 -0
  339. opik/integrations/langchain/langgraph_tracer_injector.py +88 -0
  340. opik/integrations/langchain/opik_encoder_extension.py +2 -2
  341. opik/integrations/langchain/opik_tracer.py +641 -206
  342. opik/integrations/langchain/provider_usage_extractors/__init__.py +5 -0
  343. opik/integrations/langchain/provider_usage_extractors/anthropic_usage_extractor.py +101 -0
  344. opik/integrations/langchain/provider_usage_extractors/anthropic_vertexai_usage_extractor.py +67 -0
  345. opik/integrations/langchain/provider_usage_extractors/bedrock_usage_extractor.py +94 -0
  346. opik/integrations/langchain/provider_usage_extractors/google_generative_ai_usage_extractor.py +109 -0
  347. opik/integrations/langchain/provider_usage_extractors/groq_usage_extractor.py +92 -0
  348. opik/integrations/langchain/provider_usage_extractors/langchain_run_helpers/__init__.py +15 -0
  349. opik/integrations/langchain/provider_usage_extractors/langchain_run_helpers/helpers.py +134 -0
  350. opik/integrations/langchain/provider_usage_extractors/langchain_run_helpers/langchain_usage.py +163 -0
  351. opik/integrations/langchain/provider_usage_extractors/openai_usage_extractor.py +124 -0
  352. opik/integrations/langchain/provider_usage_extractors/provider_usage_extractor_protocol.py +29 -0
  353. opik/integrations/langchain/provider_usage_extractors/usage_extractor.py +48 -0
  354. opik/integrations/langchain/provider_usage_extractors/vertexai_usage_extractor.py +109 -0
  355. opik/integrations/litellm/__init__.py +5 -0
  356. opik/integrations/litellm/completion_chunks_aggregator.py +115 -0
  357. opik/integrations/litellm/litellm_completion_decorator.py +242 -0
  358. opik/integrations/litellm/opik_tracker.py +43 -0
  359. opik/integrations/litellm/stream_patchers.py +151 -0
  360. opik/integrations/llama_index/callback.py +179 -78
  361. opik/integrations/llama_index/event_parsing_utils.py +29 -9
  362. opik/integrations/openai/agents/opik_tracing_processor.py +204 -32
  363. opik/integrations/openai/agents/span_data_parsers.py +15 -6
  364. opik/integrations/openai/chat_completion_chunks_aggregator.py +1 -1
  365. opik/integrations/openai/{openai_decorator.py → openai_chat_completions_decorator.py} +45 -35
  366. opik/integrations/openai/openai_responses_decorator.py +158 -0
  367. opik/integrations/openai/opik_tracker.py +94 -13
  368. opik/integrations/openai/response_events_aggregator.py +36 -0
  369. opik/integrations/openai/stream_patchers.py +125 -15
  370. opik/integrations/sagemaker/auth.py +5 -1
  371. opik/jsonable_encoder.py +29 -1
  372. opik/llm_usage/base_original_provider_usage.py +15 -8
  373. opik/llm_usage/bedrock_usage.py +8 -2
  374. opik/llm_usage/google_usage.py +6 -1
  375. opik/llm_usage/llm_usage_info.py +6 -0
  376. opik/llm_usage/{openai_usage.py → openai_chat_completions_usage.py} +2 -12
  377. opik/llm_usage/{openai_agent_usage.py → openai_responses_usage.py} +7 -15
  378. opik/llm_usage/opik_usage.py +36 -10
  379. opik/llm_usage/opik_usage_factory.py +35 -19
  380. opik/logging_messages.py +19 -7
  381. opik/message_processing/arguments_utils.py +22 -0
  382. opik/message_processing/batching/base_batcher.py +45 -17
  383. opik/message_processing/batching/batch_manager.py +22 -10
  384. opik/message_processing/batching/batch_manager_constuctors.py +36 -11
  385. opik/message_processing/batching/batchers.py +167 -44
  386. opik/message_processing/batching/flushing_thread.py +0 -3
  387. opik/message_processing/batching/sequence_splitter.py +50 -5
  388. opik/message_processing/emulation/__init__.py +0 -0
  389. opik/message_processing/emulation/emulator_message_processor.py +578 -0
  390. opik/message_processing/emulation/local_emulator_message_processor.py +140 -0
  391. opik/message_processing/emulation/models.py +162 -0
  392. opik/message_processing/encoder_helpers.py +79 -0
  393. opik/message_processing/message_queue.py +79 -0
  394. opik/message_processing/messages.py +154 -12
  395. opik/message_processing/preprocessing/__init__.py +0 -0
  396. opik/message_processing/preprocessing/attachments_preprocessor.py +70 -0
  397. opik/message_processing/preprocessing/batching_preprocessor.py +53 -0
  398. opik/message_processing/preprocessing/constants.py +1 -0
  399. opik/message_processing/preprocessing/file_upload_preprocessor.py +38 -0
  400. opik/message_processing/preprocessing/preprocessor.py +36 -0
  401. opik/message_processing/processors/__init__.py +0 -0
  402. opik/message_processing/processors/attachments_extraction_processor.py +146 -0
  403. opik/message_processing/processors/message_processors.py +92 -0
  404. opik/message_processing/processors/message_processors_chain.py +96 -0
  405. opik/message_processing/processors/online_message_processor.py +324 -0
  406. opik/message_processing/queue_consumer.py +61 -13
  407. opik/message_processing/streamer.py +102 -31
  408. opik/message_processing/streamer_constructors.py +67 -12
  409. opik/opik_context.py +103 -11
  410. opik/plugins/pytest/decorator.py +2 -2
  411. opik/plugins/pytest/experiment_runner.py +3 -2
  412. opik/plugins/pytest/hooks.py +6 -4
  413. opik/rate_limit/__init__.py +0 -0
  414. opik/rate_limit/rate_limit.py +25 -0
  415. opik/rest_api/__init__.py +643 -11
  416. opik/rest_api/alerts/__init__.py +7 -0
  417. opik/rest_api/alerts/client.py +667 -0
  418. opik/rest_api/alerts/raw_client.py +1015 -0
  419. opik/rest_api/alerts/types/__init__.py +7 -0
  420. opik/rest_api/alerts/types/get_webhook_examples_request_alert_type.py +5 -0
  421. opik/rest_api/annotation_queues/__init__.py +4 -0
  422. opik/rest_api/annotation_queues/client.py +668 -0
  423. opik/rest_api/annotation_queues/raw_client.py +1019 -0
  424. opik/rest_api/attachments/__init__.py +17 -0
  425. opik/rest_api/attachments/client.py +752 -0
  426. opik/rest_api/attachments/raw_client.py +1125 -0
  427. opik/rest_api/attachments/types/__init__.py +15 -0
  428. opik/rest_api/attachments/types/attachment_list_request_entity_type.py +5 -0
  429. opik/rest_api/attachments/types/download_attachment_request_entity_type.py +5 -0
  430. opik/rest_api/attachments/types/start_multipart_upload_request_entity_type.py +5 -0
  431. opik/rest_api/attachments/types/upload_attachment_request_entity_type.py +5 -0
  432. opik/rest_api/automation_rule_evaluators/__init__.py +2 -0
  433. opik/rest_api/automation_rule_evaluators/client.py +182 -1162
  434. opik/rest_api/automation_rule_evaluators/raw_client.py +598 -0
  435. opik/rest_api/chat_completions/__init__.py +2 -0
  436. opik/rest_api/chat_completions/client.py +115 -149
  437. opik/rest_api/chat_completions/raw_client.py +339 -0
  438. opik/rest_api/check/__init__.py +2 -0
  439. opik/rest_api/check/client.py +88 -106
  440. opik/rest_api/check/raw_client.py +258 -0
  441. opik/rest_api/client.py +112 -212
  442. opik/rest_api/core/__init__.py +5 -0
  443. opik/rest_api/core/api_error.py +12 -6
  444. opik/rest_api/core/client_wrapper.py +4 -14
  445. opik/rest_api/core/datetime_utils.py +1 -3
  446. opik/rest_api/core/file.py +2 -5
  447. opik/rest_api/core/http_client.py +42 -120
  448. opik/rest_api/core/http_response.py +55 -0
  449. opik/rest_api/core/jsonable_encoder.py +1 -4
  450. opik/rest_api/core/pydantic_utilities.py +79 -147
  451. opik/rest_api/core/query_encoder.py +1 -3
  452. opik/rest_api/core/serialization.py +10 -10
  453. opik/rest_api/dashboards/__init__.py +4 -0
  454. opik/rest_api/dashboards/client.py +462 -0
  455. opik/rest_api/dashboards/raw_client.py +648 -0
  456. opik/rest_api/datasets/__init__.py +5 -0
  457. opik/rest_api/datasets/client.py +1638 -1091
  458. opik/rest_api/datasets/raw_client.py +3389 -0
  459. opik/rest_api/datasets/types/__init__.py +8 -0
  460. opik/rest_api/datasets/types/dataset_update_visibility.py +5 -0
  461. opik/rest_api/datasets/types/dataset_write_visibility.py +5 -0
  462. opik/rest_api/errors/__init__.py +2 -0
  463. opik/rest_api/errors/bad_request_error.py +4 -3
  464. opik/rest_api/errors/conflict_error.py +4 -3
  465. opik/rest_api/errors/forbidden_error.py +4 -2
  466. opik/rest_api/errors/not_found_error.py +4 -3
  467. opik/rest_api/errors/not_implemented_error.py +4 -3
  468. opik/rest_api/errors/unauthorized_error.py +4 -3
  469. opik/rest_api/errors/unprocessable_entity_error.py +4 -3
  470. opik/rest_api/experiments/__init__.py +5 -0
  471. opik/rest_api/experiments/client.py +676 -752
  472. opik/rest_api/experiments/raw_client.py +1872 -0
  473. opik/rest_api/experiments/types/__init__.py +10 -0
  474. opik/rest_api/experiments/types/experiment_update_status.py +5 -0
  475. opik/rest_api/experiments/types/experiment_update_type.py +5 -0
  476. opik/rest_api/experiments/types/experiment_write_status.py +5 -0
  477. opik/rest_api/experiments/types/experiment_write_type.py +5 -0
  478. opik/rest_api/feedback_definitions/__init__.py +2 -0
  479. opik/rest_api/feedback_definitions/client.py +96 -370
  480. opik/rest_api/feedback_definitions/raw_client.py +541 -0
  481. opik/rest_api/feedback_definitions/types/__init__.py +2 -0
  482. opik/rest_api/feedback_definitions/types/find_feedback_definitions_request_type.py +1 -3
  483. opik/rest_api/guardrails/__init__.py +4 -0
  484. opik/rest_api/guardrails/client.py +104 -0
  485. opik/rest_api/guardrails/raw_client.py +102 -0
  486. opik/rest_api/llm_provider_key/__init__.py +2 -0
  487. opik/rest_api/llm_provider_key/client.py +166 -440
  488. opik/rest_api/llm_provider_key/raw_client.py +643 -0
  489. opik/rest_api/llm_provider_key/types/__init__.py +2 -0
  490. opik/rest_api/llm_provider_key/types/provider_api_key_write_provider.py +1 -1
  491. opik/rest_api/manual_evaluation/__init__.py +4 -0
  492. opik/rest_api/manual_evaluation/client.py +347 -0
  493. opik/rest_api/manual_evaluation/raw_client.py +543 -0
  494. opik/rest_api/open_telemetry_ingestion/__init__.py +2 -0
  495. opik/rest_api/open_telemetry_ingestion/client.py +38 -63
  496. opik/rest_api/open_telemetry_ingestion/raw_client.py +88 -0
  497. opik/rest_api/optimizations/__init__.py +7 -0
  498. opik/rest_api/optimizations/client.py +704 -0
  499. opik/rest_api/optimizations/raw_client.py +920 -0
  500. opik/rest_api/optimizations/types/__init__.py +7 -0
  501. opik/rest_api/optimizations/types/optimization_update_status.py +7 -0
  502. opik/rest_api/projects/__init__.py +10 -1
  503. opik/rest_api/projects/client.py +180 -855
  504. opik/rest_api/projects/raw_client.py +1216 -0
  505. opik/rest_api/projects/types/__init__.py +11 -4
  506. opik/rest_api/projects/types/project_metric_request_public_interval.py +1 -3
  507. opik/rest_api/projects/types/project_metric_request_public_metric_type.py +11 -1
  508. opik/rest_api/projects/types/project_update_visibility.py +5 -0
  509. opik/rest_api/projects/types/project_write_visibility.py +5 -0
  510. opik/rest_api/prompts/__init__.py +4 -2
  511. opik/rest_api/prompts/client.py +381 -970
  512. opik/rest_api/prompts/raw_client.py +1634 -0
  513. opik/rest_api/prompts/types/__init__.py +5 -1
  514. opik/rest_api/prompts/types/create_prompt_version_detail_template_structure.py +5 -0
  515. opik/rest_api/prompts/types/prompt_write_template_structure.py +5 -0
  516. opik/rest_api/raw_client.py +156 -0
  517. opik/rest_api/redirect/__init__.py +4 -0
  518. opik/rest_api/redirect/client.py +375 -0
  519. opik/rest_api/redirect/raw_client.py +566 -0
  520. opik/rest_api/service_toggles/__init__.py +4 -0
  521. opik/rest_api/service_toggles/client.py +91 -0
  522. opik/rest_api/service_toggles/raw_client.py +93 -0
  523. opik/rest_api/spans/__init__.py +2 -0
  524. opik/rest_api/spans/client.py +659 -1354
  525. opik/rest_api/spans/raw_client.py +2383 -0
  526. opik/rest_api/spans/types/__init__.py +2 -0
  527. opik/rest_api/spans/types/find_feedback_score_names_1_request_type.py +1 -3
  528. opik/rest_api/spans/types/get_span_stats_request_type.py +1 -3
  529. opik/rest_api/spans/types/get_spans_by_project_request_type.py +1 -3
  530. opik/rest_api/spans/types/span_search_stream_request_public_type.py +1 -3
  531. opik/rest_api/system_usage/__init__.py +2 -0
  532. opik/rest_api/system_usage/client.py +157 -216
  533. opik/rest_api/system_usage/raw_client.py +455 -0
  534. opik/rest_api/traces/__init__.py +2 -0
  535. opik/rest_api/traces/client.py +2102 -1625
  536. opik/rest_api/traces/raw_client.py +4144 -0
  537. opik/rest_api/types/__init__.py +629 -24
  538. opik/rest_api/types/aggregation_data.py +27 -0
  539. opik/rest_api/types/alert.py +33 -0
  540. opik/rest_api/types/alert_alert_type.py +5 -0
  541. opik/rest_api/types/alert_page_public.py +24 -0
  542. opik/rest_api/types/alert_public.py +33 -0
  543. opik/rest_api/types/alert_public_alert_type.py +5 -0
  544. opik/rest_api/types/alert_trigger.py +27 -0
  545. opik/rest_api/types/alert_trigger_config.py +28 -0
  546. opik/rest_api/types/alert_trigger_config_public.py +28 -0
  547. opik/rest_api/types/alert_trigger_config_public_type.py +10 -0
  548. opik/rest_api/types/alert_trigger_config_type.py +10 -0
  549. opik/rest_api/types/alert_trigger_config_write.py +22 -0
  550. opik/rest_api/types/alert_trigger_config_write_type.py +10 -0
  551. opik/rest_api/types/alert_trigger_event_type.py +19 -0
  552. opik/rest_api/types/alert_trigger_public.py +27 -0
  553. opik/rest_api/types/alert_trigger_public_event_type.py +19 -0
  554. opik/rest_api/types/alert_trigger_write.py +23 -0
  555. opik/rest_api/types/alert_trigger_write_event_type.py +19 -0
  556. opik/rest_api/types/alert_write.py +28 -0
  557. opik/rest_api/types/alert_write_alert_type.py +5 -0
  558. opik/rest_api/types/annotation_queue.py +42 -0
  559. opik/rest_api/types/annotation_queue_batch.py +27 -0
  560. opik/rest_api/types/{json_schema_element.py → annotation_queue_item_ids.py} +5 -7
  561. opik/rest_api/types/annotation_queue_page_public.py +28 -0
  562. opik/rest_api/types/annotation_queue_public.py +38 -0
  563. opik/rest_api/types/annotation_queue_public_scope.py +5 -0
  564. opik/rest_api/types/{workspace_metadata.py → annotation_queue_reviewer.py} +6 -7
  565. opik/rest_api/types/annotation_queue_reviewer_public.py +20 -0
  566. opik/rest_api/types/annotation_queue_scope.py +5 -0
  567. opik/rest_api/types/annotation_queue_write.py +31 -0
  568. opik/rest_api/types/annotation_queue_write_scope.py +5 -0
  569. opik/rest_api/types/assistant_message.py +7 -8
  570. opik/rest_api/types/assistant_message_role.py +1 -3
  571. opik/rest_api/types/attachment.py +22 -0
  572. opik/rest_api/types/attachment_page.py +28 -0
  573. opik/rest_api/types/audio_url.py +19 -0
  574. opik/rest_api/types/audio_url_public.py +19 -0
  575. opik/rest_api/types/audio_url_write.py +19 -0
  576. opik/rest_api/types/automation_rule_evaluator.py +160 -0
  577. opik/rest_api/types/automation_rule_evaluator_llm_as_judge.py +6 -6
  578. opik/rest_api/types/automation_rule_evaluator_llm_as_judge_public.py +6 -6
  579. opik/rest_api/types/automation_rule_evaluator_llm_as_judge_write.py +6 -6
  580. opik/rest_api/types/automation_rule_evaluator_object_object_public.py +155 -0
  581. opik/rest_api/types/automation_rule_evaluator_page_public.py +6 -6
  582. opik/rest_api/types/automation_rule_evaluator_public.py +155 -0
  583. opik/rest_api/types/automation_rule_evaluator_span_llm_as_judge.py +22 -0
  584. opik/rest_api/types/automation_rule_evaluator_span_llm_as_judge_public.py +22 -0
  585. opik/rest_api/types/automation_rule_evaluator_span_llm_as_judge_write.py +22 -0
  586. opik/rest_api/types/automation_rule_evaluator_span_user_defined_metric_python.py +22 -0
  587. opik/rest_api/types/automation_rule_evaluator_span_user_defined_metric_python_public.py +22 -0
  588. opik/rest_api/types/automation_rule_evaluator_span_user_defined_metric_python_write.py +22 -0
  589. opik/rest_api/types/automation_rule_evaluator_trace_thread_llm_as_judge.py +22 -0
  590. opik/rest_api/types/automation_rule_evaluator_trace_thread_llm_as_judge_public.py +22 -0
  591. opik/rest_api/types/automation_rule_evaluator_trace_thread_llm_as_judge_write.py +22 -0
  592. opik/rest_api/types/automation_rule_evaluator_trace_thread_user_defined_metric_python.py +22 -0
  593. opik/rest_api/types/automation_rule_evaluator_trace_thread_user_defined_metric_python_public.py +22 -0
  594. opik/rest_api/types/automation_rule_evaluator_trace_thread_user_defined_metric_python_write.py +22 -0
  595. opik/rest_api/types/automation_rule_evaluator_update.py +143 -0
  596. opik/rest_api/types/automation_rule_evaluator_update_llm_as_judge.py +6 -6
  597. opik/rest_api/types/automation_rule_evaluator_update_span_llm_as_judge.py +22 -0
  598. opik/rest_api/types/automation_rule_evaluator_update_span_user_defined_metric_python.py +22 -0
  599. opik/rest_api/types/automation_rule_evaluator_update_trace_thread_llm_as_judge.py +22 -0
  600. opik/rest_api/types/automation_rule_evaluator_update_trace_thread_user_defined_metric_python.py +22 -0
  601. opik/rest_api/types/automation_rule_evaluator_update_user_defined_metric_python.py +6 -6
  602. opik/rest_api/types/automation_rule_evaluator_user_defined_metric_python.py +6 -6
  603. opik/rest_api/types/automation_rule_evaluator_user_defined_metric_python_public.py +6 -6
  604. opik/rest_api/types/automation_rule_evaluator_user_defined_metric_python_write.py +6 -6
  605. opik/rest_api/types/automation_rule_evaluator_write.py +143 -0
  606. opik/rest_api/types/avg_value_stat_public.py +3 -5
  607. opik/rest_api/types/batch_delete.py +3 -5
  608. opik/rest_api/types/batch_delete_by_project.py +20 -0
  609. opik/rest_api/types/bi_information.py +3 -5
  610. opik/rest_api/types/bi_information_response.py +4 -6
  611. opik/rest_api/types/boolean_feedback_definition.py +25 -0
  612. opik/rest_api/types/boolean_feedback_definition_create.py +20 -0
  613. opik/rest_api/types/boolean_feedback_definition_public.py +25 -0
  614. opik/rest_api/types/boolean_feedback_definition_update.py +20 -0
  615. opik/rest_api/types/boolean_feedback_detail.py +29 -0
  616. opik/rest_api/types/boolean_feedback_detail_create.py +29 -0
  617. opik/rest_api/types/boolean_feedback_detail_public.py +29 -0
  618. opik/rest_api/types/boolean_feedback_detail_update.py +29 -0
  619. opik/rest_api/types/categorical_feedback_definition.py +5 -7
  620. opik/rest_api/types/categorical_feedback_definition_create.py +4 -6
  621. opik/rest_api/types/categorical_feedback_definition_public.py +5 -7
  622. opik/rest_api/types/categorical_feedback_definition_update.py +4 -6
  623. opik/rest_api/types/categorical_feedback_detail.py +3 -5
  624. opik/rest_api/types/categorical_feedback_detail_create.py +3 -5
  625. opik/rest_api/types/categorical_feedback_detail_public.py +3 -5
  626. opik/rest_api/types/categorical_feedback_detail_update.py +3 -5
  627. opik/rest_api/types/chat_completion_choice.py +4 -6
  628. opik/rest_api/types/chat_completion_response.py +5 -6
  629. opik/rest_api/types/check.py +22 -0
  630. opik/rest_api/types/{json_node_compare.py → check_name.py} +1 -1
  631. opik/rest_api/types/check_public.py +22 -0
  632. opik/rest_api/types/check_public_name.py +5 -0
  633. opik/rest_api/types/check_public_result.py +5 -0
  634. opik/rest_api/types/check_result.py +5 -0
  635. opik/rest_api/types/chunked_output_json_node.py +4 -6
  636. opik/rest_api/types/chunked_output_json_node_public.py +4 -6
  637. opik/rest_api/types/chunked_output_json_node_public_type.py +6 -10
  638. opik/rest_api/types/chunked_output_json_node_type.py +6 -10
  639. opik/rest_api/types/column.py +8 -10
  640. opik/rest_api/types/column_compare.py +8 -10
  641. opik/rest_api/types/column_public.py +8 -10
  642. opik/rest_api/types/column_types_item.py +1 -3
  643. opik/rest_api/types/comment.py +4 -6
  644. opik/rest_api/types/comment_compare.py +4 -6
  645. opik/rest_api/types/comment_public.py +4 -6
  646. opik/rest_api/types/complete_multipart_upload_request.py +33 -0
  647. opik/rest_api/types/complete_multipart_upload_request_entity_type.py +5 -0
  648. opik/rest_api/types/completion_tokens_details.py +3 -5
  649. opik/rest_api/types/count_value_stat_public.py +3 -5
  650. opik/rest_api/types/dashboard_page_public.py +24 -0
  651. opik/rest_api/types/dashboard_public.py +30 -0
  652. opik/rest_api/types/data_point_double.py +21 -0
  653. opik/rest_api/types/data_point_number_public.py +3 -5
  654. opik/rest_api/types/dataset.py +14 -6
  655. opik/rest_api/types/dataset_expansion.py +42 -0
  656. opik/rest_api/types/dataset_expansion_response.py +39 -0
  657. opik/rest_api/types/dataset_item.py +9 -8
  658. opik/rest_api/types/dataset_item_batch.py +3 -5
  659. opik/rest_api/types/dataset_item_changes_public.py +5 -0
  660. opik/rest_api/types/dataset_item_compare.py +9 -8
  661. opik/rest_api/types/dataset_item_compare_source.py +1 -3
  662. opik/rest_api/types/dataset_item_filter.py +27 -0
  663. opik/rest_api/types/dataset_item_filter_operator.py +21 -0
  664. opik/rest_api/types/dataset_item_page_compare.py +10 -7
  665. opik/rest_api/types/dataset_item_page_public.py +10 -7
  666. opik/rest_api/types/dataset_item_public.py +9 -8
  667. opik/rest_api/types/dataset_item_public_source.py +1 -3
  668. opik/rest_api/types/dataset_item_source.py +1 -3
  669. opik/rest_api/types/dataset_item_update.py +39 -0
  670. opik/rest_api/types/dataset_item_write.py +5 -6
  671. opik/rest_api/types/dataset_item_write_source.py +1 -3
  672. opik/rest_api/types/dataset_page_public.py +9 -6
  673. opik/rest_api/types/dataset_public.py +14 -6
  674. opik/rest_api/types/dataset_public_status.py +5 -0
  675. opik/rest_api/types/dataset_public_visibility.py +5 -0
  676. opik/rest_api/types/dataset_status.py +5 -0
  677. opik/rest_api/types/dataset_version_diff.py +22 -0
  678. opik/rest_api/types/dataset_version_diff_stats.py +24 -0
  679. opik/rest_api/types/dataset_version_page_public.py +23 -0
  680. opik/rest_api/types/dataset_version_public.py +59 -0
  681. opik/rest_api/types/dataset_version_summary.py +46 -0
  682. opik/rest_api/types/dataset_version_summary_public.py +46 -0
  683. opik/rest_api/types/dataset_visibility.py +5 -0
  684. opik/rest_api/types/delete_attachments_request.py +23 -0
  685. opik/rest_api/types/delete_attachments_request_entity_type.py +5 -0
  686. opik/rest_api/types/delete_feedback_score.py +4 -5
  687. opik/rest_api/types/delete_ids_holder.py +19 -0
  688. opik/rest_api/types/delta.py +7 -9
  689. opik/rest_api/types/error_count_with_deviation.py +21 -0
  690. opik/rest_api/types/error_count_with_deviation_detailed.py +21 -0
  691. opik/rest_api/types/error_info.py +3 -5
  692. opik/rest_api/types/error_info_experiment_item_bulk_write_view.py +21 -0
  693. opik/rest_api/types/error_info_public.py +3 -5
  694. opik/rest_api/types/error_info_write.py +3 -5
  695. opik/rest_api/types/error_message.py +3 -5
  696. opik/rest_api/types/error_message_detail.py +3 -5
  697. opik/rest_api/types/error_message_detailed.py +3 -5
  698. opik/rest_api/types/error_message_public.py +3 -5
  699. opik/rest_api/types/experiment.py +21 -10
  700. opik/rest_api/types/experiment_group_aggregations_response.py +20 -0
  701. opik/rest_api/types/experiment_group_response.py +22 -0
  702. opik/rest_api/types/experiment_item.py +14 -11
  703. opik/rest_api/types/experiment_item_bulk_record.py +27 -0
  704. opik/rest_api/types/experiment_item_bulk_record_experiment_item_bulk_write_view.py +27 -0
  705. opik/rest_api/types/experiment_item_bulk_upload.py +27 -0
  706. opik/rest_api/types/experiment_item_compare.py +14 -11
  707. opik/rest_api/types/experiment_item_compare_trace_visibility_mode.py +5 -0
  708. opik/rest_api/types/experiment_item_public.py +6 -6
  709. opik/rest_api/types/experiment_item_public_trace_visibility_mode.py +5 -0
  710. opik/rest_api/types/experiment_item_trace_visibility_mode.py +5 -0
  711. opik/rest_api/types/experiment_page_public.py +9 -6
  712. opik/rest_api/types/experiment_public.py +21 -10
  713. opik/rest_api/types/experiment_public_status.py +5 -0
  714. opik/rest_api/types/experiment_public_type.py +5 -0
  715. opik/rest_api/types/experiment_score.py +20 -0
  716. opik/rest_api/types/experiment_score_public.py +20 -0
  717. opik/rest_api/types/experiment_score_write.py +20 -0
  718. opik/rest_api/types/experiment_status.py +5 -0
  719. opik/rest_api/types/experiment_type.py +5 -0
  720. opik/rest_api/types/export_trace_service_request.py +5 -0
  721. opik/rest_api/types/feedback.py +40 -27
  722. opik/rest_api/types/feedback_create.py +27 -13
  723. opik/rest_api/types/feedback_definition_page_public.py +4 -6
  724. opik/rest_api/types/feedback_object_public.py +40 -27
  725. opik/rest_api/types/feedback_public.py +40 -27
  726. opik/rest_api/types/feedback_score.py +7 -7
  727. opik/rest_api/types/feedback_score_average.py +3 -5
  728. opik/rest_api/types/feedback_score_average_detailed.py +3 -5
  729. opik/rest_api/types/feedback_score_average_public.py +3 -5
  730. opik/rest_api/types/feedback_score_batch.py +4 -6
  731. opik/rest_api/types/feedback_score_batch_item.py +6 -6
  732. opik/rest_api/types/feedback_score_batch_item_source.py +1 -3
  733. opik/rest_api/types/feedback_score_batch_item_thread.py +32 -0
  734. opik/rest_api/types/feedback_score_batch_item_thread_source.py +5 -0
  735. opik/rest_api/types/feedback_score_compare.py +7 -7
  736. opik/rest_api/types/feedback_score_compare_source.py +1 -3
  737. opik/rest_api/types/feedback_score_experiment_item_bulk_write_view.py +31 -0
  738. opik/rest_api/types/feedback_score_experiment_item_bulk_write_view_source.py +5 -0
  739. opik/rest_api/types/feedback_score_names.py +4 -6
  740. opik/rest_api/types/feedback_score_public.py +11 -7
  741. opik/rest_api/types/feedback_score_public_source.py +1 -3
  742. opik/rest_api/types/feedback_score_source.py +1 -3
  743. opik/rest_api/types/feedback_update.py +27 -13
  744. opik/rest_api/types/function.py +4 -7
  745. opik/rest_api/types/function_call.py +3 -5
  746. opik/rest_api/types/group_content.py +19 -0
  747. opik/rest_api/types/group_content_with_aggregations.py +21 -0
  748. opik/rest_api/types/group_detail.py +19 -0
  749. opik/rest_api/types/group_details.py +20 -0
  750. opik/rest_api/types/guardrail.py +34 -0
  751. opik/rest_api/types/guardrail_batch.py +20 -0
  752. opik/rest_api/types/guardrail_name.py +5 -0
  753. opik/rest_api/types/guardrail_result.py +5 -0
  754. opik/rest_api/types/guardrail_write.py +33 -0
  755. opik/rest_api/types/guardrail_write_name.py +5 -0
  756. opik/rest_api/types/guardrail_write_result.py +5 -0
  757. opik/rest_api/types/guardrails_validation.py +21 -0
  758. opik/rest_api/types/guardrails_validation_public.py +21 -0
  759. opik/rest_api/types/ids_holder.py +19 -0
  760. opik/rest_api/types/image_url.py +20 -0
  761. opik/rest_api/types/image_url_public.py +20 -0
  762. opik/rest_api/types/image_url_write.py +20 -0
  763. opik/rest_api/types/json_list_string.py +7 -0
  764. opik/rest_api/types/json_list_string_compare.py +7 -0
  765. opik/rest_api/types/json_list_string_experiment_item_bulk_write_view.py +7 -0
  766. opik/rest_api/types/json_list_string_public.py +7 -0
  767. opik/rest_api/types/json_list_string_write.py +7 -0
  768. opik/rest_api/types/json_schema.py +5 -8
  769. opik/rest_api/types/llm_as_judge_code.py +8 -12
  770. opik/rest_api/types/llm_as_judge_code_public.py +8 -12
  771. opik/rest_api/types/llm_as_judge_code_write.py +8 -12
  772. opik/rest_api/types/llm_as_judge_message.py +9 -7
  773. opik/rest_api/types/llm_as_judge_message_content.py +26 -0
  774. opik/rest_api/types/llm_as_judge_message_content_public.py +26 -0
  775. opik/rest_api/types/llm_as_judge_message_content_write.py +26 -0
  776. opik/rest_api/types/llm_as_judge_message_public.py +9 -7
  777. opik/rest_api/types/llm_as_judge_message_public_role.py +1 -1
  778. opik/rest_api/types/llm_as_judge_message_role.py +1 -1
  779. opik/rest_api/types/llm_as_judge_message_write.py +9 -7
  780. opik/rest_api/types/llm_as_judge_message_write_role.py +1 -1
  781. opik/rest_api/types/llm_as_judge_model_parameters.py +6 -5
  782. opik/rest_api/types/llm_as_judge_model_parameters_public.py +6 -5
  783. opik/rest_api/types/llm_as_judge_model_parameters_write.py +6 -5
  784. opik/rest_api/types/llm_as_judge_output_schema.py +4 -6
  785. opik/rest_api/types/llm_as_judge_output_schema_public.py +4 -6
  786. opik/rest_api/types/llm_as_judge_output_schema_public_type.py +1 -3
  787. opik/rest_api/types/llm_as_judge_output_schema_type.py +1 -3
  788. opik/rest_api/types/llm_as_judge_output_schema_write.py +4 -6
  789. opik/rest_api/types/llm_as_judge_output_schema_write_type.py +1 -3
  790. opik/rest_api/types/log_item.py +5 -7
  791. opik/rest_api/types/log_item_level.py +1 -3
  792. opik/rest_api/types/log_page.py +4 -6
  793. opik/rest_api/types/manual_evaluation_request.py +38 -0
  794. opik/rest_api/types/manual_evaluation_request_entity_type.py +5 -0
  795. opik/rest_api/types/manual_evaluation_response.py +27 -0
  796. opik/rest_api/types/multipart_upload_part.py +20 -0
  797. opik/rest_api/types/numerical_feedback_definition.py +5 -7
  798. opik/rest_api/types/numerical_feedback_definition_create.py +4 -6
  799. opik/rest_api/types/numerical_feedback_definition_public.py +5 -7
  800. opik/rest_api/types/numerical_feedback_definition_update.py +4 -6
  801. opik/rest_api/types/numerical_feedback_detail.py +3 -5
  802. opik/rest_api/types/numerical_feedback_detail_create.py +3 -5
  803. opik/rest_api/types/numerical_feedback_detail_public.py +3 -5
  804. opik/rest_api/types/numerical_feedback_detail_update.py +3 -5
  805. opik/rest_api/types/optimization.py +37 -0
  806. opik/rest_api/types/optimization_page_public.py +28 -0
  807. opik/rest_api/types/optimization_public.py +37 -0
  808. opik/rest_api/types/optimization_public_status.py +7 -0
  809. opik/rest_api/types/optimization_status.py +7 -0
  810. opik/rest_api/types/optimization_studio_config.py +27 -0
  811. opik/rest_api/types/optimization_studio_config_public.py +27 -0
  812. opik/rest_api/types/optimization_studio_config_write.py +27 -0
  813. opik/rest_api/types/optimization_studio_log.py +22 -0
  814. opik/rest_api/types/optimization_write.py +30 -0
  815. opik/rest_api/types/optimization_write_status.py +7 -0
  816. opik/rest_api/types/page_columns.py +4 -6
  817. opik/rest_api/types/percentage_value_stat_public.py +4 -6
  818. opik/rest_api/types/percentage_values.py +8 -16
  819. opik/rest_api/types/percentage_values_detailed.py +8 -16
  820. opik/rest_api/types/percentage_values_public.py +8 -16
  821. opik/rest_api/types/project.py +12 -7
  822. opik/rest_api/types/project_detailed.py +12 -7
  823. opik/rest_api/types/project_detailed_visibility.py +5 -0
  824. opik/rest_api/types/project_metric_response_public.py +5 -9
  825. opik/rest_api/types/project_metric_response_public_interval.py +1 -3
  826. opik/rest_api/types/project_metric_response_public_metric_type.py +11 -1
  827. opik/rest_api/types/project_page_public.py +8 -10
  828. opik/rest_api/types/project_public.py +6 -6
  829. opik/rest_api/types/project_public_visibility.py +5 -0
  830. opik/rest_api/types/project_reference.py +31 -0
  831. opik/rest_api/types/project_reference_public.py +31 -0
  832. opik/rest_api/types/project_stat_item_object_public.py +8 -17
  833. opik/rest_api/types/project_stats_public.py +4 -6
  834. opik/rest_api/types/project_stats_summary.py +4 -6
  835. opik/rest_api/types/project_stats_summary_item.py +9 -6
  836. opik/rest_api/types/project_visibility.py +5 -0
  837. opik/rest_api/types/prompt.py +12 -7
  838. opik/rest_api/types/prompt_detail.py +12 -7
  839. opik/rest_api/types/prompt_detail_template_structure.py +5 -0
  840. opik/rest_api/types/prompt_page_public.py +9 -6
  841. opik/rest_api/types/prompt_public.py +11 -6
  842. opik/rest_api/types/prompt_public_template_structure.py +5 -0
  843. opik/rest_api/types/prompt_template_structure.py +5 -0
  844. opik/rest_api/types/prompt_tokens_details.py +19 -0
  845. opik/rest_api/types/prompt_version.py +7 -6
  846. opik/rest_api/types/prompt_version_detail.py +7 -6
  847. opik/rest_api/types/prompt_version_detail_template_structure.py +5 -0
  848. opik/rest_api/types/prompt_version_link.py +4 -5
  849. opik/rest_api/types/prompt_version_link_public.py +4 -5
  850. opik/rest_api/types/prompt_version_link_write.py +3 -5
  851. opik/rest_api/types/prompt_version_page_public.py +9 -6
  852. opik/rest_api/types/prompt_version_public.py +7 -6
  853. opik/rest_api/types/prompt_version_public_template_structure.py +5 -0
  854. opik/rest_api/types/prompt_version_template_structure.py +5 -0
  855. opik/rest_api/types/prompt_version_update.py +33 -0
  856. opik/rest_api/types/provider_api_key.py +18 -8
  857. opik/rest_api/types/provider_api_key_page_public.py +27 -0
  858. opik/rest_api/types/provider_api_key_provider.py +1 -1
  859. opik/rest_api/types/provider_api_key_public.py +18 -8
  860. opik/rest_api/types/provider_api_key_public_provider.py +1 -1
  861. opik/rest_api/types/response_format.py +5 -7
  862. opik/rest_api/types/response_format_type.py +1 -3
  863. opik/rest_api/types/result.py +21 -0
  864. opik/rest_api/types/results_number_public.py +4 -6
  865. opik/rest_api/types/score_name.py +4 -5
  866. opik/rest_api/types/service_toggles_config.py +44 -0
  867. opik/rest_api/types/span.py +13 -15
  868. opik/rest_api/types/span_batch.py +4 -6
  869. opik/rest_api/types/span_enrichment_options.py +31 -0
  870. opik/rest_api/types/span_experiment_item_bulk_write_view.py +39 -0
  871. opik/rest_api/types/span_experiment_item_bulk_write_view_type.py +5 -0
  872. opik/rest_api/types/span_filter.py +23 -0
  873. opik/rest_api/types/span_filter_operator.py +21 -0
  874. opik/rest_api/types/span_filter_public.py +4 -6
  875. opik/rest_api/types/span_filter_public_operator.py +2 -0
  876. opik/rest_api/types/span_filter_write.py +23 -0
  877. opik/rest_api/types/span_filter_write_operator.py +21 -0
  878. opik/rest_api/types/span_llm_as_judge_code.py +27 -0
  879. opik/rest_api/types/span_llm_as_judge_code_public.py +27 -0
  880. opik/rest_api/types/span_llm_as_judge_code_write.py +27 -0
  881. opik/rest_api/types/span_page_public.py +9 -6
  882. opik/rest_api/types/span_public.py +19 -16
  883. opik/rest_api/types/span_public_type.py +1 -1
  884. opik/rest_api/types/span_type.py +1 -1
  885. opik/rest_api/types/span_update.py +46 -0
  886. opik/rest_api/types/span_update_type.py +5 -0
  887. opik/rest_api/types/span_user_defined_metric_python_code.py +20 -0
  888. opik/rest_api/types/span_user_defined_metric_python_code_public.py +20 -0
  889. opik/rest_api/types/span_user_defined_metric_python_code_write.py +20 -0
  890. opik/rest_api/types/span_write.py +13 -14
  891. opik/rest_api/types/span_write_type.py +1 -1
  892. opik/rest_api/types/spans_count_response.py +20 -0
  893. opik/rest_api/types/start_multipart_upload_response.py +20 -0
  894. opik/rest_api/types/stream_options.py +3 -5
  895. opik/rest_api/types/studio_evaluation.py +20 -0
  896. opik/rest_api/types/studio_evaluation_public.py +20 -0
  897. opik/rest_api/types/studio_evaluation_write.py +20 -0
  898. opik/rest_api/types/studio_llm_model.py +21 -0
  899. opik/rest_api/types/studio_llm_model_public.py +21 -0
  900. opik/rest_api/types/studio_llm_model_write.py +21 -0
  901. opik/rest_api/types/studio_message.py +20 -0
  902. opik/rest_api/types/studio_message_public.py +20 -0
  903. opik/rest_api/types/studio_message_write.py +20 -0
  904. opik/rest_api/types/studio_metric.py +21 -0
  905. opik/rest_api/types/studio_metric_public.py +21 -0
  906. opik/rest_api/types/studio_metric_write.py +21 -0
  907. opik/rest_api/types/studio_optimizer.py +21 -0
  908. opik/rest_api/types/studio_optimizer_public.py +21 -0
  909. opik/rest_api/types/studio_optimizer_write.py +21 -0
  910. opik/rest_api/types/studio_prompt.py +20 -0
  911. opik/rest_api/types/studio_prompt_public.py +20 -0
  912. opik/rest_api/types/studio_prompt_write.py +20 -0
  913. opik/rest_api/types/tool.py +4 -6
  914. opik/rest_api/types/tool_call.py +4 -6
  915. opik/rest_api/types/trace.py +26 -12
  916. opik/rest_api/types/trace_batch.py +4 -6
  917. opik/rest_api/types/trace_count_response.py +4 -6
  918. opik/rest_api/types/trace_enrichment_options.py +32 -0
  919. opik/rest_api/types/trace_experiment_item_bulk_write_view.py +41 -0
  920. opik/rest_api/types/trace_filter.py +23 -0
  921. opik/rest_api/types/trace_filter_operator.py +21 -0
  922. opik/rest_api/types/trace_filter_public.py +23 -0
  923. opik/rest_api/types/trace_filter_public_operator.py +21 -0
  924. opik/rest_api/types/trace_filter_write.py +23 -0
  925. opik/rest_api/types/trace_filter_write_operator.py +21 -0
  926. opik/rest_api/types/trace_page_public.py +8 -10
  927. opik/rest_api/types/trace_public.py +27 -13
  928. opik/rest_api/types/trace_public_visibility_mode.py +5 -0
  929. opik/rest_api/types/trace_thread.py +18 -9
  930. opik/rest_api/types/trace_thread_filter.py +23 -0
  931. opik/rest_api/types/trace_thread_filter_operator.py +21 -0
  932. opik/rest_api/types/trace_thread_filter_public.py +23 -0
  933. opik/rest_api/types/trace_thread_filter_public_operator.py +21 -0
  934. opik/rest_api/types/trace_thread_filter_write.py +23 -0
  935. opik/rest_api/types/trace_thread_filter_write_operator.py +21 -0
  936. opik/rest_api/types/trace_thread_identifier.py +22 -0
  937. opik/rest_api/types/trace_thread_llm_as_judge_code.py +26 -0
  938. opik/rest_api/types/trace_thread_llm_as_judge_code_public.py +26 -0
  939. opik/rest_api/types/trace_thread_llm_as_judge_code_write.py +26 -0
  940. opik/rest_api/types/trace_thread_page.py +9 -6
  941. opik/rest_api/types/trace_thread_status.py +5 -0
  942. opik/rest_api/types/trace_thread_update.py +19 -0
  943. opik/rest_api/types/trace_thread_user_defined_metric_python_code.py +19 -0
  944. opik/rest_api/types/trace_thread_user_defined_metric_python_code_public.py +19 -0
  945. opik/rest_api/types/trace_thread_user_defined_metric_python_code_write.py +19 -0
  946. opik/rest_api/types/trace_update.py +39 -0
  947. opik/rest_api/types/trace_visibility_mode.py +5 -0
  948. opik/rest_api/types/trace_write.py +10 -11
  949. opik/rest_api/types/usage.py +6 -6
  950. opik/rest_api/types/user_defined_metric_python_code.py +3 -5
  951. opik/rest_api/types/user_defined_metric_python_code_public.py +3 -5
  952. opik/rest_api/types/user_defined_metric_python_code_write.py +3 -5
  953. opik/rest_api/types/value_entry.py +27 -0
  954. opik/rest_api/types/value_entry_compare.py +27 -0
  955. opik/rest_api/types/value_entry_compare_source.py +5 -0
  956. opik/rest_api/types/value_entry_experiment_item_bulk_write_view.py +27 -0
  957. opik/rest_api/types/value_entry_experiment_item_bulk_write_view_source.py +5 -0
  958. opik/rest_api/types/value_entry_public.py +27 -0
  959. opik/rest_api/types/value_entry_public_source.py +5 -0
  960. opik/rest_api/types/value_entry_source.py +5 -0
  961. opik/rest_api/types/video_url.py +19 -0
  962. opik/rest_api/types/video_url_public.py +19 -0
  963. opik/rest_api/types/video_url_write.py +19 -0
  964. opik/rest_api/types/webhook.py +28 -0
  965. opik/rest_api/types/webhook_examples.py +19 -0
  966. opik/rest_api/types/webhook_public.py +28 -0
  967. opik/rest_api/types/webhook_test_result.py +23 -0
  968. opik/rest_api/types/webhook_test_result_status.py +5 -0
  969. opik/rest_api/types/webhook_write.py +23 -0
  970. opik/rest_api/types/welcome_wizard_tracking.py +22 -0
  971. opik/rest_api/types/workspace_configuration.py +27 -0
  972. opik/rest_api/types/workspace_metric_request.py +24 -0
  973. opik/rest_api/types/workspace_metric_response.py +20 -0
  974. opik/rest_api/types/workspace_metrics_summary_request.py +23 -0
  975. opik/rest_api/types/workspace_metrics_summary_response.py +20 -0
  976. opik/rest_api/types/workspace_name_holder.py +19 -0
  977. opik/rest_api/types/workspace_spans_count.py +20 -0
  978. opik/rest_api/types/workspace_trace_count.py +3 -5
  979. opik/rest_api/welcome_wizard/__init__.py +4 -0
  980. opik/rest_api/welcome_wizard/client.py +195 -0
  981. opik/rest_api/welcome_wizard/raw_client.py +208 -0
  982. opik/rest_api/workspaces/__init__.py +2 -0
  983. opik/rest_api/workspaces/client.py +550 -77
  984. opik/rest_api/workspaces/raw_client.py +923 -0
  985. opik/rest_client_configurator/api.py +1 -0
  986. opik/rest_client_configurator/retry_decorator.py +1 -0
  987. opik/s3_httpx_client.py +67 -0
  988. opik/simulation/__init__.py +6 -0
  989. opik/simulation/simulated_user.py +99 -0
  990. opik/simulation/simulator.py +108 -0
  991. opik/synchronization.py +11 -24
  992. opik/tracing_runtime_config.py +48 -0
  993. opik/types.py +48 -2
  994. opik/url_helpers.py +13 -3
  995. opik/validation/chat_prompt_messages.py +241 -0
  996. opik/validation/feedback_score.py +4 -5
  997. opik/validation/parameter.py +122 -0
  998. opik/validation/parameters_validator.py +175 -0
  999. opik/validation/validator.py +30 -2
  1000. opik/validation/validator_helpers.py +147 -0
  1001. opik-1.9.71.dist-info/METADATA +370 -0
  1002. opik-1.9.71.dist-info/RECORD +1110 -0
  1003. {opik-1.6.4.dist-info → opik-1.9.71.dist-info}/WHEEL +1 -1
  1004. opik-1.9.71.dist-info/licenses/LICENSE +203 -0
  1005. opik/api_objects/prompt/prompt.py +0 -107
  1006. opik/api_objects/prompt/prompt_template.py +0 -35
  1007. opik/cli.py +0 -193
  1008. opik/evaluation/metrics/models.py +0 -8
  1009. opik/hooks.py +0 -13
  1010. opik/integrations/bedrock/chunks_aggregator.py +0 -55
  1011. opik/integrations/bedrock/helpers.py +0 -8
  1012. opik/integrations/langchain/google_run_helpers.py +0 -75
  1013. opik/integrations/langchain/openai_run_helpers.py +0 -122
  1014. opik/message_processing/message_processors.py +0 -203
  1015. opik/rest_api/types/delta_role.py +0 -7
  1016. opik/rest_api/types/json_object_schema.py +0 -34
  1017. opik-1.6.4.dist-info/METADATA +0 -270
  1018. opik-1.6.4.dist-info/RECORD +0 -507
  1019. /opik/integrations/bedrock/{stream_wrappers.py → converse/stream_wrappers.py} +0 -0
  1020. {opik-1.6.4.dist-info → opik-1.9.71.dist-info}/entry_points.txt +0 -0
  1021. {opik-1.6.4.dist-info → opik-1.9.71.dist-info}/top_level.txt +0 -0
@@ -1,21 +1,28 @@
1
1
  # This file was auto-generated by Fern from our API Definition.
2
2
 
3
3
  import typing
4
- from ..core.client_wrapper import SyncClientWrapper
4
+
5
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
5
6
  from ..core.request_options import RequestOptions
6
- from ..types.experiment_page_public import ExperimentPagePublic
7
- from ..core.pydantic_utilities import parse_obj_as
8
- from json.decoder import JSONDecodeError
9
- from ..core.api_error import ApiError
10
- from ..types.json_node_write import JsonNodeWrite
11
- from ..types.prompt_version_link_write import PromptVersionLinkWrite
12
- from ..core.serialization import convert_and_respect_annotation_metadata
7
+ from ..types.experiment_group_aggregations_response import ExperimentGroupAggregationsResponse
8
+ from ..types.experiment_group_response import ExperimentGroupResponse
13
9
  from ..types.experiment_item import ExperimentItem
14
- from ..types.experiment_public import ExperimentPublic
15
- from ..core.jsonable_encoder import jsonable_encoder
16
- from ..errors.not_found_error import NotFoundError
10
+ from ..types.experiment_item_bulk_record_experiment_item_bulk_write_view import (
11
+ ExperimentItemBulkRecordExperimentItemBulkWriteView,
12
+ )
17
13
  from ..types.experiment_item_public import ExperimentItemPublic
18
- from ..core.client_wrapper import AsyncClientWrapper
14
+ from ..types.experiment_page_public import ExperimentPagePublic
15
+ from ..types.experiment_public import ExperimentPublic
16
+ from ..types.experiment_score import ExperimentScore
17
+ from ..types.experiment_score_write import ExperimentScoreWrite
18
+ from ..types.json_list_string_write import JsonListStringWrite
19
+ from ..types.json_node import JsonNode
20
+ from ..types.prompt_version_link_write import PromptVersionLinkWrite
21
+ from .raw_client import AsyncRawExperimentsClient, RawExperimentsClient
22
+ from .types.experiment_update_status import ExperimentUpdateStatus
23
+ from .types.experiment_update_type import ExperimentUpdateType
24
+ from .types.experiment_write_status import ExperimentWriteStatus
25
+ from .types.experiment_write_type import ExperimentWriteType
19
26
 
20
27
  # this is used as the default value for optional parameters
21
28
  OMIT = typing.cast(typing.Any, ...)
@@ -23,7 +30,18 @@ OMIT = typing.cast(typing.Any, ...)
23
30
 
24
31
  class ExperimentsClient:
25
32
  def __init__(self, *, client_wrapper: SyncClientWrapper):
26
- self._client_wrapper = client_wrapper
33
+ self._raw_client = RawExperimentsClient(client_wrapper=client_wrapper)
34
+
35
+ @property
36
+ def with_raw_response(self) -> RawExperimentsClient:
37
+ """
38
+ Retrieves a raw implementation of this client that returns raw responses.
39
+
40
+ Returns
41
+ -------
42
+ RawExperimentsClient
43
+ """
44
+ return self._raw_client
27
45
 
28
46
  def find_experiments(
29
47
  self,
@@ -31,9 +49,13 @@ class ExperimentsClient:
31
49
  page: typing.Optional[int] = None,
32
50
  size: typing.Optional[int] = None,
33
51
  dataset_id: typing.Optional[str] = None,
52
+ optimization_id: typing.Optional[str] = None,
53
+ types: typing.Optional[str] = None,
34
54
  name: typing.Optional[str] = None,
35
55
  dataset_deleted: typing.Optional[bool] = None,
36
56
  prompt_id: typing.Optional[str] = None,
57
+ sorting: typing.Optional[str] = None,
58
+ filters: typing.Optional[str] = None,
37
59
  request_options: typing.Optional[RequestOptions] = None,
38
60
  ) -> ExperimentPagePublic:
39
61
  """
@@ -47,12 +69,20 @@ class ExperimentsClient:
47
69
 
48
70
  dataset_id : typing.Optional[str]
49
71
 
72
+ optimization_id : typing.Optional[str]
73
+
74
+ types : typing.Optional[str]
75
+
50
76
  name : typing.Optional[str]
51
77
 
52
78
  dataset_deleted : typing.Optional[bool]
53
79
 
54
80
  prompt_id : typing.Optional[str]
55
81
 
82
+ sorting : typing.Optional[str]
83
+
84
+ filters : typing.Optional[str]
85
+
56
86
  request_options : typing.Optional[RequestOptions]
57
87
  Request-specific configuration.
58
88
 
@@ -64,39 +94,23 @@ class ExperimentsClient:
64
94
  Examples
65
95
  --------
66
96
  from Opik import OpikApi
67
-
68
- client = OpikApi(
69
- api_key="YOUR_API_KEY",
70
- workspace_name="YOUR_WORKSPACE_NAME",
71
- )
97
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
72
98
  client.experiments.find_experiments()
73
99
  """
74
- _response = self._client_wrapper.httpx_client.request(
75
- "v1/private/experiments",
76
- method="GET",
77
- params={
78
- "page": page,
79
- "size": size,
80
- "datasetId": dataset_id,
81
- "name": name,
82
- "dataset_deleted": dataset_deleted,
83
- "prompt_id": prompt_id,
84
- },
100
+ _response = self._raw_client.find_experiments(
101
+ page=page,
102
+ size=size,
103
+ dataset_id=dataset_id,
104
+ optimization_id=optimization_id,
105
+ types=types,
106
+ name=name,
107
+ dataset_deleted=dataset_deleted,
108
+ prompt_id=prompt_id,
109
+ sorting=sorting,
110
+ filters=filters,
85
111
  request_options=request_options,
86
112
  )
87
- try:
88
- if 200 <= _response.status_code < 300:
89
- return typing.cast(
90
- ExperimentPagePublic,
91
- parse_obj_as(
92
- type_=ExperimentPagePublic, # type: ignore
93
- object_=_response.json(),
94
- ),
95
- )
96
- _response_json = _response.json()
97
- except JSONDecodeError:
98
- raise ApiError(status_code=_response.status_code, body=_response.text)
99
- raise ApiError(status_code=_response.status_code, body=_response_json)
113
+ return _response.data
100
114
 
101
115
  def create_experiment(
102
116
  self,
@@ -104,11 +118,13 @@ class ExperimentsClient:
104
118
  dataset_name: str,
105
119
  id: typing.Optional[str] = OMIT,
106
120
  name: typing.Optional[str] = OMIT,
107
- metadata: typing.Optional[JsonNodeWrite] = OMIT,
121
+ metadata: typing.Optional[JsonListStringWrite] = OMIT,
122
+ type: typing.Optional[ExperimentWriteType] = OMIT,
123
+ optimization_id: typing.Optional[str] = OMIT,
124
+ status: typing.Optional[ExperimentWriteStatus] = OMIT,
125
+ experiment_scores: typing.Optional[typing.Sequence[ExperimentScoreWrite]] = OMIT,
108
126
  prompt_version: typing.Optional[PromptVersionLinkWrite] = OMIT,
109
- prompt_versions: typing.Optional[
110
- typing.Sequence[PromptVersionLinkWrite]
111
- ] = OMIT,
127
+ prompt_versions: typing.Optional[typing.Sequence[PromptVersionLinkWrite]] = OMIT,
112
128
  request_options: typing.Optional[RequestOptions] = None,
113
129
  ) -> None:
114
130
  """
@@ -122,7 +138,15 @@ class ExperimentsClient:
122
138
 
123
139
  name : typing.Optional[str]
124
140
 
125
- metadata : typing.Optional[JsonNodeWrite]
141
+ metadata : typing.Optional[JsonListStringWrite]
142
+
143
+ type : typing.Optional[ExperimentWriteType]
144
+
145
+ optimization_id : typing.Optional[str]
146
+
147
+ status : typing.Optional[ExperimentWriteStatus]
148
+
149
+ experiment_scores : typing.Optional[typing.Sequence[ExperimentScoreWrite]]
126
150
 
127
151
  prompt_version : typing.Optional[PromptVersionLinkWrite]
128
152
 
@@ -138,47 +162,23 @@ class ExperimentsClient:
138
162
  Examples
139
163
  --------
140
164
  from Opik import OpikApi
141
-
142
- client = OpikApi(
143
- api_key="YOUR_API_KEY",
144
- workspace_name="YOUR_WORKSPACE_NAME",
145
- )
146
- client.experiments.create_experiment(
147
- dataset_name="dataset_name",
148
- )
165
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
166
+ client.experiments.create_experiment(dataset_name='dataset_name', )
149
167
  """
150
- _response = self._client_wrapper.httpx_client.request(
151
- "v1/private/experiments",
152
- method="POST",
153
- json={
154
- "id": id,
155
- "dataset_name": dataset_name,
156
- "name": name,
157
- "metadata": metadata,
158
- "prompt_version": convert_and_respect_annotation_metadata(
159
- object_=prompt_version,
160
- annotation=PromptVersionLinkWrite,
161
- direction="write",
162
- ),
163
- "prompt_versions": convert_and_respect_annotation_metadata(
164
- object_=prompt_versions,
165
- annotation=typing.Sequence[PromptVersionLinkWrite],
166
- direction="write",
167
- ),
168
- },
169
- headers={
170
- "content-type": "application/json",
171
- },
168
+ _response = self._raw_client.create_experiment(
169
+ dataset_name=dataset_name,
170
+ id=id,
171
+ name=name,
172
+ metadata=metadata,
173
+ type=type,
174
+ optimization_id=optimization_id,
175
+ status=status,
176
+ experiment_scores=experiment_scores,
177
+ prompt_version=prompt_version,
178
+ prompt_versions=prompt_versions,
172
179
  request_options=request_options,
173
- omit=OMIT,
174
180
  )
175
- try:
176
- if 200 <= _response.status_code < 300:
177
- return
178
- _response_json = _response.json()
179
- except JSONDecodeError:
180
- raise ApiError(status_code=_response.status_code, body=_response.text)
181
- raise ApiError(status_code=_response.status_code, body=_response_json)
181
+ return _response.data
182
182
 
183
183
  def create_experiment_items(
184
184
  self,
@@ -202,51 +202,18 @@ class ExperimentsClient:
202
202
 
203
203
  Examples
204
204
  --------
205
- from Opik import ExperimentItem, OpikApi
206
-
207
- client = OpikApi(
208
- api_key="YOUR_API_KEY",
209
- workspace_name="YOUR_WORKSPACE_NAME",
210
- )
211
- client.experiments.create_experiment_items(
212
- experiment_items=[
213
- ExperimentItem(
214
- experiment_id="experiment_id",
215
- dataset_item_id="dataset_item_id",
216
- trace_id="trace_id",
217
- )
218
- ],
219
- )
205
+ from Opik import OpikApi
206
+ from Opik import ExperimentItem
207
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
208
+ client.experiments.create_experiment_items(experiment_items=[ExperimentItem(experiment_id='experiment_id', dataset_item_id='dataset_item_id', trace_id='trace_id', )], )
220
209
  """
221
- _response = self._client_wrapper.httpx_client.request(
222
- "v1/private/experiments/items",
223
- method="POST",
224
- json={
225
- "experiment_items": convert_and_respect_annotation_metadata(
226
- object_=experiment_items,
227
- annotation=typing.Sequence[ExperimentItem],
228
- direction="write",
229
- ),
230
- },
231
- headers={
232
- "content-type": "application/json",
233
- },
234
- request_options=request_options,
235
- omit=OMIT,
210
+ _response = self._raw_client.create_experiment_items(
211
+ experiment_items=experiment_items, request_options=request_options
236
212
  )
237
- try:
238
- if 200 <= _response.status_code < 300:
239
- return
240
- _response_json = _response.json()
241
- except JSONDecodeError:
242
- raise ApiError(status_code=_response.status_code, body=_response.text)
243
- raise ApiError(status_code=_response.status_code, body=_response_json)
213
+ return _response.data
244
214
 
245
215
  def delete_experiment_items(
246
- self,
247
- *,
248
- ids: typing.Sequence[str],
249
- request_options: typing.Optional[RequestOptions] = None,
216
+ self, *, ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
250
217
  ) -> None:
251
218
  """
252
219
  Delete experiment items
@@ -265,40 +232,14 @@ class ExperimentsClient:
265
232
  Examples
266
233
  --------
267
234
  from Opik import OpikApi
268
-
269
- client = OpikApi(
270
- api_key="YOUR_API_KEY",
271
- workspace_name="YOUR_WORKSPACE_NAME",
272
- )
273
- client.experiments.delete_experiment_items(
274
- ids=["ids"],
275
- )
235
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
236
+ client.experiments.delete_experiment_items(ids=['ids'], )
276
237
  """
277
- _response = self._client_wrapper.httpx_client.request(
278
- "v1/private/experiments/items/delete",
279
- method="POST",
280
- json={
281
- "ids": ids,
282
- },
283
- headers={
284
- "content-type": "application/json",
285
- },
286
- request_options=request_options,
287
- omit=OMIT,
288
- )
289
- try:
290
- if 200 <= _response.status_code < 300:
291
- return
292
- _response_json = _response.json()
293
- except JSONDecodeError:
294
- raise ApiError(status_code=_response.status_code, body=_response.text)
295
- raise ApiError(status_code=_response.status_code, body=_response_json)
238
+ _response = self._raw_client.delete_experiment_items(ids=ids, request_options=request_options)
239
+ return _response.data
296
240
 
297
241
  def delete_experiments_by_id(
298
- self,
299
- *,
300
- ids: typing.Sequence[str],
301
- request_options: typing.Optional[RequestOptions] = None,
242
+ self, *, ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
302
243
  ) -> None:
303
244
  """
304
245
  Delete experiments by id
@@ -317,40 +258,60 @@ class ExperimentsClient:
317
258
  Examples
318
259
  --------
319
260
  from Opik import OpikApi
261
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
262
+ client.experiments.delete_experiments_by_id(ids=['ids'], )
263
+ """
264
+ _response = self._raw_client.delete_experiments_by_id(ids=ids, request_options=request_options)
265
+ return _response.data
320
266
 
321
- client = OpikApi(
322
- api_key="YOUR_API_KEY",
323
- workspace_name="YOUR_WORKSPACE_NAME",
324
- )
325
- client.experiments.delete_experiments_by_id(
326
- ids=["ids"],
327
- )
267
+ def experiment_items_bulk(
268
+ self,
269
+ *,
270
+ experiment_name: str,
271
+ dataset_name: str,
272
+ items: typing.Sequence[ExperimentItemBulkRecordExperimentItemBulkWriteView],
273
+ experiment_id: typing.Optional[str] = OMIT,
274
+ request_options: typing.Optional[RequestOptions] = None,
275
+ ) -> None:
276
+ """
277
+ Record experiment items in bulk with traces, spans, and feedback scores. Maximum request size is 4MB.
278
+
279
+ Parameters
280
+ ----------
281
+ experiment_name : str
282
+
283
+ dataset_name : str
284
+
285
+ items : typing.Sequence[ExperimentItemBulkRecordExperimentItemBulkWriteView]
286
+
287
+ experiment_id : typing.Optional[str]
288
+ Optional experiment ID. If provided, items will be added to the existing experiment and experimentName will be ignored. If not provided or experiment with that ID doesn't exist, a new experiment will be created with the given experimentName
289
+
290
+ request_options : typing.Optional[RequestOptions]
291
+ Request-specific configuration.
292
+
293
+ Returns
294
+ -------
295
+ None
296
+
297
+ Examples
298
+ --------
299
+ from Opik import OpikApi
300
+ from Opik import ExperimentItemBulkRecordExperimentItemBulkWriteView
301
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
302
+ client.experiments.experiment_items_bulk(experiment_name='experiment_name', dataset_name='dataset_name', items=[ExperimentItemBulkRecordExperimentItemBulkWriteView(dataset_item_id='dataset_item_id', )], )
328
303
  """
329
- _response = self._client_wrapper.httpx_client.request(
330
- "v1/private/experiments/delete",
331
- method="POST",
332
- json={
333
- "ids": ids,
334
- },
335
- headers={
336
- "content-type": "application/json",
337
- },
304
+ _response = self._raw_client.experiment_items_bulk(
305
+ experiment_name=experiment_name,
306
+ dataset_name=dataset_name,
307
+ items=items,
308
+ experiment_id=experiment_id,
338
309
  request_options=request_options,
339
- omit=OMIT,
340
310
  )
341
- try:
342
- if 200 <= _response.status_code < 300:
343
- return
344
- _response_json = _response.json()
345
- except JSONDecodeError:
346
- raise ApiError(status_code=_response.status_code, body=_response.text)
347
- raise ApiError(status_code=_response.status_code, body=_response_json)
311
+ return _response.data
348
312
 
349
313
  def find_feedback_score_names(
350
- self,
351
- *,
352
- experiment_ids: typing.Optional[str] = None,
353
- request_options: typing.Optional[RequestOptions] = None,
314
+ self, *, experiment_ids: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
354
315
  ) -> typing.List[str]:
355
316
  """
356
317
  Find Feedback Score names
@@ -370,34 +331,121 @@ class ExperimentsClient:
370
331
  Examples
371
332
  --------
372
333
  from Opik import OpikApi
334
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
335
+ client.experiments.find_feedback_score_names()
336
+ """
337
+ _response = self._raw_client.find_feedback_score_names(
338
+ experiment_ids=experiment_ids, request_options=request_options
339
+ )
340
+ return _response.data
341
+
342
+ def find_experiment_groups(
343
+ self,
344
+ *,
345
+ groups: typing.Optional[str] = None,
346
+ types: typing.Optional[str] = None,
347
+ name: typing.Optional[str] = None,
348
+ filters: typing.Optional[str] = None,
349
+ request_options: typing.Optional[RequestOptions] = None,
350
+ ) -> ExperimentGroupResponse:
351
+ """
352
+ Find experiments grouped by specified fields
373
353
 
374
- client = OpikApi(
375
- api_key="YOUR_API_KEY",
376
- workspace_name="YOUR_WORKSPACE_NAME",
354
+ Parameters
355
+ ----------
356
+ groups : typing.Optional[str]
357
+
358
+ types : typing.Optional[str]
359
+
360
+ name : typing.Optional[str]
361
+
362
+ filters : typing.Optional[str]
363
+
364
+ request_options : typing.Optional[RequestOptions]
365
+ Request-specific configuration.
366
+
367
+ Returns
368
+ -------
369
+ ExperimentGroupResponse
370
+ Experiment groups
371
+
372
+ Examples
373
+ --------
374
+ from Opik import OpikApi
375
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
376
+ client.experiments.find_experiment_groups()
377
+ """
378
+ _response = self._raw_client.find_experiment_groups(
379
+ groups=groups, types=types, name=name, filters=filters, request_options=request_options
377
380
  )
378
- client.experiments.find_feedback_score_names()
381
+ return _response.data
382
+
383
+ def find_experiment_groups_aggregations(
384
+ self,
385
+ *,
386
+ groups: typing.Optional[str] = None,
387
+ types: typing.Optional[str] = None,
388
+ name: typing.Optional[str] = None,
389
+ filters: typing.Optional[str] = None,
390
+ request_options: typing.Optional[RequestOptions] = None,
391
+ ) -> ExperimentGroupAggregationsResponse:
379
392
  """
380
- _response = self._client_wrapper.httpx_client.request(
381
- "v1/private/experiments/feedback-scores/names",
382
- method="GET",
383
- params={
384
- "experiment_ids": experiment_ids,
385
- },
386
- request_options=request_options,
393
+ Find experiments grouped by specified fields with aggregation metrics
394
+
395
+ Parameters
396
+ ----------
397
+ groups : typing.Optional[str]
398
+
399
+ types : typing.Optional[str]
400
+
401
+ name : typing.Optional[str]
402
+
403
+ filters : typing.Optional[str]
404
+
405
+ request_options : typing.Optional[RequestOptions]
406
+ Request-specific configuration.
407
+
408
+ Returns
409
+ -------
410
+ ExperimentGroupAggregationsResponse
411
+ Experiment groups with aggregations
412
+
413
+ Examples
414
+ --------
415
+ from Opik import OpikApi
416
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
417
+ client.experiments.find_experiment_groups_aggregations()
418
+ """
419
+ _response = self._raw_client.find_experiment_groups_aggregations(
420
+ groups=groups, types=types, name=name, filters=filters, request_options=request_options
387
421
  )
388
- try:
389
- if 200 <= _response.status_code < 300:
390
- return typing.cast(
391
- typing.List[str],
392
- parse_obj_as(
393
- type_=typing.List[str], # type: ignore
394
- object_=_response.json(),
395
- ),
396
- )
397
- _response_json = _response.json()
398
- except JSONDecodeError:
399
- raise ApiError(status_code=_response.status_code, body=_response.text)
400
- raise ApiError(status_code=_response.status_code, body=_response_json)
422
+ return _response.data
423
+
424
+ def finish_experiments(
425
+ self, *, ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
426
+ ) -> None:
427
+ """
428
+ Finish experiments and trigger alert events
429
+
430
+ Parameters
431
+ ----------
432
+ ids : typing.Sequence[str]
433
+
434
+ request_options : typing.Optional[RequestOptions]
435
+ Request-specific configuration.
436
+
437
+ Returns
438
+ -------
439
+ None
440
+
441
+ Examples
442
+ --------
443
+ from Opik import OpikApi
444
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
445
+ client.experiments.finish_experiments(ids=['ids'], )
446
+ """
447
+ _response = self._raw_client.finish_experiments(ids=ids, request_options=request_options)
448
+ return _response.data
401
449
 
402
450
  def get_experiment_by_id(
403
451
  self, id: str, *, request_options: typing.Optional[RequestOptions] = None
@@ -420,109 +468,64 @@ class ExperimentsClient:
420
468
  Examples
421
469
  --------
422
470
  from Opik import OpikApi
423
-
424
- client = OpikApi(
425
- api_key="YOUR_API_KEY",
426
- workspace_name="YOUR_WORKSPACE_NAME",
427
- )
428
- client.experiments.get_experiment_by_id(
429
- id="id",
430
- )
471
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
472
+ client.experiments.get_experiment_by_id(id='id', )
431
473
  """
432
- _response = self._client_wrapper.httpx_client.request(
433
- f"v1/private/experiments/{jsonable_encoder(id)}",
434
- method="GET",
435
- request_options=request_options,
436
- )
437
- try:
438
- if 200 <= _response.status_code < 300:
439
- return typing.cast(
440
- ExperimentPublic,
441
- parse_obj_as(
442
- type_=ExperimentPublic, # type: ignore
443
- object_=_response.json(),
444
- ),
445
- )
446
- if _response.status_code == 404:
447
- raise NotFoundError(
448
- typing.cast(
449
- typing.Optional[typing.Any],
450
- parse_obj_as(
451
- type_=typing.Optional[typing.Any], # type: ignore
452
- object_=_response.json(),
453
- ),
454
- )
455
- )
456
- _response_json = _response.json()
457
- except JSONDecodeError:
458
- raise ApiError(status_code=_response.status_code, body=_response.text)
459
- raise ApiError(status_code=_response.status_code, body=_response_json)
460
-
461
- def get_experiment_by_name(
462
- self, *, name: str, request_options: typing.Optional[RequestOptions] = None
463
- ) -> ExperimentPublic:
474
+ _response = self._raw_client.get_experiment_by_id(id, request_options=request_options)
475
+ return _response.data
476
+
477
+ def update_experiment(
478
+ self,
479
+ id: str,
480
+ *,
481
+ name: typing.Optional[str] = OMIT,
482
+ metadata: typing.Optional[JsonNode] = OMIT,
483
+ type: typing.Optional[ExperimentUpdateType] = OMIT,
484
+ status: typing.Optional[ExperimentUpdateStatus] = OMIT,
485
+ experiment_scores: typing.Optional[typing.Sequence[ExperimentScore]] = OMIT,
486
+ request_options: typing.Optional[RequestOptions] = None,
487
+ ) -> None:
464
488
  """
465
- Get experiment by name
489
+ Update experiment by id
466
490
 
467
491
  Parameters
468
492
  ----------
469
- name : str
493
+ id : str
494
+
495
+ name : typing.Optional[str]
496
+
497
+ metadata : typing.Optional[JsonNode]
498
+
499
+ type : typing.Optional[ExperimentUpdateType]
500
+
501
+ status : typing.Optional[ExperimentUpdateStatus]
502
+ The status of the experiment
503
+
504
+ experiment_scores : typing.Optional[typing.Sequence[ExperimentScore]]
470
505
 
471
506
  request_options : typing.Optional[RequestOptions]
472
507
  Request-specific configuration.
473
508
 
474
509
  Returns
475
510
  -------
476
- ExperimentPublic
477
- Experiments resource
511
+ None
478
512
 
479
513
  Examples
480
514
  --------
481
515
  from Opik import OpikApi
482
-
483
- client = OpikApi(
484
- api_key="YOUR_API_KEY",
485
- workspace_name="YOUR_WORKSPACE_NAME",
486
- )
487
- client.experiments.get_experiment_by_name(
488
- name="name",
489
- )
516
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
517
+ client.experiments.update_experiment(id='id', )
490
518
  """
491
- _response = self._client_wrapper.httpx_client.request(
492
- "v1/private/experiments/retrieve",
493
- method="POST",
494
- json={
495
- "name": name,
496
- },
497
- headers={
498
- "content-type": "application/json",
499
- },
519
+ _response = self._raw_client.update_experiment(
520
+ id,
521
+ name=name,
522
+ metadata=metadata,
523
+ type=type,
524
+ status=status,
525
+ experiment_scores=experiment_scores,
500
526
  request_options=request_options,
501
- omit=OMIT,
502
527
  )
503
- try:
504
- if 200 <= _response.status_code < 300:
505
- return typing.cast(
506
- ExperimentPublic,
507
- parse_obj_as(
508
- type_=ExperimentPublic, # type: ignore
509
- object_=_response.json(),
510
- ),
511
- )
512
- if _response.status_code == 404:
513
- raise NotFoundError(
514
- typing.cast(
515
- typing.Optional[typing.Any],
516
- parse_obj_as(
517
- type_=typing.Optional[typing.Any], # type: ignore
518
- object_=_response.json(),
519
- ),
520
- )
521
- )
522
- _response_json = _response.json()
523
- except JSONDecodeError:
524
- raise ApiError(status_code=_response.status_code, body=_response.text)
525
- raise ApiError(status_code=_response.status_code, body=_response_json)
528
+ return _response.data
526
529
 
527
530
  def get_experiment_item_by_id(
528
531
  self, id: str, *, request_options: typing.Optional[RequestOptions] = None
@@ -545,43 +548,11 @@ class ExperimentsClient:
545
548
  Examples
546
549
  --------
547
550
  from Opik import OpikApi
548
-
549
- client = OpikApi(
550
- api_key="YOUR_API_KEY",
551
- workspace_name="YOUR_WORKSPACE_NAME",
552
- )
553
- client.experiments.get_experiment_item_by_id(
554
- id="id",
555
- )
551
+ client = OpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
552
+ client.experiments.get_experiment_item_by_id(id='id', )
556
553
  """
557
- _response = self._client_wrapper.httpx_client.request(
558
- f"v1/private/experiments/items/{jsonable_encoder(id)}",
559
- method="GET",
560
- request_options=request_options,
561
- )
562
- try:
563
- if 200 <= _response.status_code < 300:
564
- return typing.cast(
565
- ExperimentItemPublic,
566
- parse_obj_as(
567
- type_=ExperimentItemPublic, # type: ignore
568
- object_=_response.json(),
569
- ),
570
- )
571
- if _response.status_code == 404:
572
- raise NotFoundError(
573
- typing.cast(
574
- typing.Optional[typing.Any],
575
- parse_obj_as(
576
- type_=typing.Optional[typing.Any], # type: ignore
577
- object_=_response.json(),
578
- ),
579
- )
580
- )
581
- _response_json = _response.json()
582
- except JSONDecodeError:
583
- raise ApiError(status_code=_response.status_code, body=_response.text)
584
- raise ApiError(status_code=_response.status_code, body=_response_json)
554
+ _response = self._raw_client.get_experiment_item_by_id(id, request_options=request_options)
555
+ return _response.data
585
556
 
586
557
  def stream_experiment_items(
587
558
  self,
@@ -609,46 +580,67 @@ class ExperimentsClient:
609
580
  request_options : typing.Optional[RequestOptions]
610
581
  Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
611
582
 
612
- Yields
613
- ------
583
+ Returns
584
+ -------
614
585
  typing.Iterator[bytes]
615
586
  Experiment items stream or error during process
616
587
  """
617
- with self._client_wrapper.httpx_client.stream(
618
- "v1/private/experiments/items/stream",
619
- method="POST",
620
- json={
621
- "experiment_name": experiment_name,
622
- "limit": limit,
623
- "last_retrieved_id": last_retrieved_id,
624
- "truncate": truncate,
625
- },
626
- headers={
627
- "content-type": "application/json",
628
- },
588
+ with self._raw_client.stream_experiment_items(
589
+ experiment_name=experiment_name,
590
+ limit=limit,
591
+ last_retrieved_id=last_retrieved_id,
592
+ truncate=truncate,
629
593
  request_options=request_options,
630
- omit=OMIT,
631
- ) as _response:
632
- try:
633
- if 200 <= _response.status_code < 300:
634
- _chunk_size = (
635
- request_options.get("chunk_size", None)
636
- if request_options is not None
637
- else None
638
- )
639
- for _chunk in _response.iter_bytes(chunk_size=_chunk_size):
640
- yield _chunk
641
- return
642
- _response.read()
643
- _response_json = _response.json()
644
- except JSONDecodeError:
645
- raise ApiError(status_code=_response.status_code, body=_response.text)
646
- raise ApiError(status_code=_response.status_code, body=_response_json)
594
+ ) as r:
595
+ yield from r.data
596
+
597
+ def stream_experiments(
598
+ self,
599
+ *,
600
+ name: str,
601
+ limit: typing.Optional[int] = OMIT,
602
+ last_retrieved_id: typing.Optional[str] = OMIT,
603
+ request_options: typing.Optional[RequestOptions] = None,
604
+ ) -> typing.Iterator[bytes]:
605
+ """
606
+ Stream experiments
607
+
608
+ Parameters
609
+ ----------
610
+ name : str
611
+
612
+ limit : typing.Optional[int]
613
+
614
+ last_retrieved_id : typing.Optional[str]
615
+
616
+ request_options : typing.Optional[RequestOptions]
617
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
618
+
619
+ Returns
620
+ -------
621
+ typing.Iterator[bytes]
622
+ Experiments stream or error during process
623
+ """
624
+ with self._raw_client.stream_experiments(
625
+ name=name, limit=limit, last_retrieved_id=last_retrieved_id, request_options=request_options
626
+ ) as r:
627
+ yield from r.data
647
628
 
648
629
 
649
630
  class AsyncExperimentsClient:
650
631
  def __init__(self, *, client_wrapper: AsyncClientWrapper):
651
- self._client_wrapper = client_wrapper
632
+ self._raw_client = AsyncRawExperimentsClient(client_wrapper=client_wrapper)
633
+
634
+ @property
635
+ def with_raw_response(self) -> AsyncRawExperimentsClient:
636
+ """
637
+ Retrieves a raw implementation of this client that returns raw responses.
638
+
639
+ Returns
640
+ -------
641
+ AsyncRawExperimentsClient
642
+ """
643
+ return self._raw_client
652
644
 
653
645
  async def find_experiments(
654
646
  self,
@@ -656,9 +648,13 @@ class AsyncExperimentsClient:
656
648
  page: typing.Optional[int] = None,
657
649
  size: typing.Optional[int] = None,
658
650
  dataset_id: typing.Optional[str] = None,
651
+ optimization_id: typing.Optional[str] = None,
652
+ types: typing.Optional[str] = None,
659
653
  name: typing.Optional[str] = None,
660
654
  dataset_deleted: typing.Optional[bool] = None,
661
655
  prompt_id: typing.Optional[str] = None,
656
+ sorting: typing.Optional[str] = None,
657
+ filters: typing.Optional[str] = None,
662
658
  request_options: typing.Optional[RequestOptions] = None,
663
659
  ) -> ExperimentPagePublic:
664
660
  """
@@ -672,12 +668,20 @@ class AsyncExperimentsClient:
672
668
 
673
669
  dataset_id : typing.Optional[str]
674
670
 
671
+ optimization_id : typing.Optional[str]
672
+
673
+ types : typing.Optional[str]
674
+
675
675
  name : typing.Optional[str]
676
676
 
677
677
  dataset_deleted : typing.Optional[bool]
678
678
 
679
679
  prompt_id : typing.Optional[str]
680
680
 
681
+ sorting : typing.Optional[str]
682
+
683
+ filters : typing.Optional[str]
684
+
681
685
  request_options : typing.Optional[RequestOptions]
682
686
  Request-specific configuration.
683
687
 
@@ -688,48 +692,27 @@ class AsyncExperimentsClient:
688
692
 
689
693
  Examples
690
694
  --------
691
- import asyncio
692
-
693
695
  from Opik import AsyncOpikApi
694
-
695
- client = AsyncOpikApi(
696
- api_key="YOUR_API_KEY",
697
- workspace_name="YOUR_WORKSPACE_NAME",
698
- )
699
-
700
-
696
+ import asyncio
697
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
701
698
  async def main() -> None:
702
699
  await client.experiments.find_experiments()
703
-
704
-
705
700
  asyncio.run(main())
706
701
  """
707
- _response = await self._client_wrapper.httpx_client.request(
708
- "v1/private/experiments",
709
- method="GET",
710
- params={
711
- "page": page,
712
- "size": size,
713
- "datasetId": dataset_id,
714
- "name": name,
715
- "dataset_deleted": dataset_deleted,
716
- "prompt_id": prompt_id,
717
- },
702
+ _response = await self._raw_client.find_experiments(
703
+ page=page,
704
+ size=size,
705
+ dataset_id=dataset_id,
706
+ optimization_id=optimization_id,
707
+ types=types,
708
+ name=name,
709
+ dataset_deleted=dataset_deleted,
710
+ prompt_id=prompt_id,
711
+ sorting=sorting,
712
+ filters=filters,
718
713
  request_options=request_options,
719
714
  )
720
- try:
721
- if 200 <= _response.status_code < 300:
722
- return typing.cast(
723
- ExperimentPagePublic,
724
- parse_obj_as(
725
- type_=ExperimentPagePublic, # type: ignore
726
- object_=_response.json(),
727
- ),
728
- )
729
- _response_json = _response.json()
730
- except JSONDecodeError:
731
- raise ApiError(status_code=_response.status_code, body=_response.text)
732
- raise ApiError(status_code=_response.status_code, body=_response_json)
715
+ return _response.data
733
716
 
734
717
  async def create_experiment(
735
718
  self,
@@ -737,11 +720,13 @@ class AsyncExperimentsClient:
737
720
  dataset_name: str,
738
721
  id: typing.Optional[str] = OMIT,
739
722
  name: typing.Optional[str] = OMIT,
740
- metadata: typing.Optional[JsonNodeWrite] = OMIT,
723
+ metadata: typing.Optional[JsonListStringWrite] = OMIT,
724
+ type: typing.Optional[ExperimentWriteType] = OMIT,
725
+ optimization_id: typing.Optional[str] = OMIT,
726
+ status: typing.Optional[ExperimentWriteStatus] = OMIT,
727
+ experiment_scores: typing.Optional[typing.Sequence[ExperimentScoreWrite]] = OMIT,
741
728
  prompt_version: typing.Optional[PromptVersionLinkWrite] = OMIT,
742
- prompt_versions: typing.Optional[
743
- typing.Sequence[PromptVersionLinkWrite]
744
- ] = OMIT,
729
+ prompt_versions: typing.Optional[typing.Sequence[PromptVersionLinkWrite]] = OMIT,
745
730
  request_options: typing.Optional[RequestOptions] = None,
746
731
  ) -> None:
747
732
  """
@@ -755,7 +740,15 @@ class AsyncExperimentsClient:
755
740
 
756
741
  name : typing.Optional[str]
757
742
 
758
- metadata : typing.Optional[JsonNodeWrite]
743
+ metadata : typing.Optional[JsonListStringWrite]
744
+
745
+ type : typing.Optional[ExperimentWriteType]
746
+
747
+ optimization_id : typing.Optional[str]
748
+
749
+ status : typing.Optional[ExperimentWriteStatus]
750
+
751
+ experiment_scores : typing.Optional[typing.Sequence[ExperimentScoreWrite]]
759
752
 
760
753
  prompt_version : typing.Optional[PromptVersionLinkWrite]
761
754
 
@@ -770,56 +763,27 @@ class AsyncExperimentsClient:
770
763
 
771
764
  Examples
772
765
  --------
773
- import asyncio
774
-
775
766
  from Opik import AsyncOpikApi
776
-
777
- client = AsyncOpikApi(
778
- api_key="YOUR_API_KEY",
779
- workspace_name="YOUR_WORKSPACE_NAME",
780
- )
781
-
782
-
767
+ import asyncio
768
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
783
769
  async def main() -> None:
784
- await client.experiments.create_experiment(
785
- dataset_name="dataset_name",
786
- )
787
-
788
-
770
+ await client.experiments.create_experiment(dataset_name='dataset_name', )
789
771
  asyncio.run(main())
790
772
  """
791
- _response = await self._client_wrapper.httpx_client.request(
792
- "v1/private/experiments",
793
- method="POST",
794
- json={
795
- "id": id,
796
- "dataset_name": dataset_name,
797
- "name": name,
798
- "metadata": metadata,
799
- "prompt_version": convert_and_respect_annotation_metadata(
800
- object_=prompt_version,
801
- annotation=PromptVersionLinkWrite,
802
- direction="write",
803
- ),
804
- "prompt_versions": convert_and_respect_annotation_metadata(
805
- object_=prompt_versions,
806
- annotation=typing.Sequence[PromptVersionLinkWrite],
807
- direction="write",
808
- ),
809
- },
810
- headers={
811
- "content-type": "application/json",
812
- },
773
+ _response = await self._raw_client.create_experiment(
774
+ dataset_name=dataset_name,
775
+ id=id,
776
+ name=name,
777
+ metadata=metadata,
778
+ type=type,
779
+ optimization_id=optimization_id,
780
+ status=status,
781
+ experiment_scores=experiment_scores,
782
+ prompt_version=prompt_version,
783
+ prompt_versions=prompt_versions,
813
784
  request_options=request_options,
814
- omit=OMIT,
815
785
  )
816
- try:
817
- if 200 <= _response.status_code < 300:
818
- return
819
- _response_json = _response.json()
820
- except JSONDecodeError:
821
- raise ApiError(status_code=_response.status_code, body=_response.text)
822
- raise ApiError(status_code=_response.status_code, body=_response_json)
786
+ return _response.data
823
787
 
824
788
  async def create_experiment_items(
825
789
  self,
@@ -843,59 +807,21 @@ class AsyncExperimentsClient:
843
807
 
844
808
  Examples
845
809
  --------
810
+ from Opik import AsyncOpikApi
811
+ from Opik import ExperimentItem
846
812
  import asyncio
847
-
848
- from Opik import AsyncOpikApi, ExperimentItem
849
-
850
- client = AsyncOpikApi(
851
- api_key="YOUR_API_KEY",
852
- workspace_name="YOUR_WORKSPACE_NAME",
853
- )
854
-
855
-
813
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
856
814
  async def main() -> None:
857
- await client.experiments.create_experiment_items(
858
- experiment_items=[
859
- ExperimentItem(
860
- experiment_id="experiment_id",
861
- dataset_item_id="dataset_item_id",
862
- trace_id="trace_id",
863
- )
864
- ],
865
- )
866
-
867
-
815
+ await client.experiments.create_experiment_items(experiment_items=[ExperimentItem(experiment_id='experiment_id', dataset_item_id='dataset_item_id', trace_id='trace_id', )], )
868
816
  asyncio.run(main())
869
817
  """
870
- _response = await self._client_wrapper.httpx_client.request(
871
- "v1/private/experiments/items",
872
- method="POST",
873
- json={
874
- "experiment_items": convert_and_respect_annotation_metadata(
875
- object_=experiment_items,
876
- annotation=typing.Sequence[ExperimentItem],
877
- direction="write",
878
- ),
879
- },
880
- headers={
881
- "content-type": "application/json",
882
- },
883
- request_options=request_options,
884
- omit=OMIT,
818
+ _response = await self._raw_client.create_experiment_items(
819
+ experiment_items=experiment_items, request_options=request_options
885
820
  )
886
- try:
887
- if 200 <= _response.status_code < 300:
888
- return
889
- _response_json = _response.json()
890
- except JSONDecodeError:
891
- raise ApiError(status_code=_response.status_code, body=_response.text)
892
- raise ApiError(status_code=_response.status_code, body=_response_json)
821
+ return _response.data
893
822
 
894
823
  async def delete_experiment_items(
895
- self,
896
- *,
897
- ids: typing.Sequence[str],
898
- request_options: typing.Optional[RequestOptions] = None,
824
+ self, *, ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
899
825
  ) -> None:
900
826
  """
901
827
  Delete experiment items
@@ -913,49 +839,18 @@ class AsyncExperimentsClient:
913
839
 
914
840
  Examples
915
841
  --------
916
- import asyncio
917
-
918
842
  from Opik import AsyncOpikApi
919
-
920
- client = AsyncOpikApi(
921
- api_key="YOUR_API_KEY",
922
- workspace_name="YOUR_WORKSPACE_NAME",
923
- )
924
-
925
-
843
+ import asyncio
844
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
926
845
  async def main() -> None:
927
- await client.experiments.delete_experiment_items(
928
- ids=["ids"],
929
- )
930
-
931
-
846
+ await client.experiments.delete_experiment_items(ids=['ids'], )
932
847
  asyncio.run(main())
933
848
  """
934
- _response = await self._client_wrapper.httpx_client.request(
935
- "v1/private/experiments/items/delete",
936
- method="POST",
937
- json={
938
- "ids": ids,
939
- },
940
- headers={
941
- "content-type": "application/json",
942
- },
943
- request_options=request_options,
944
- omit=OMIT,
945
- )
946
- try:
947
- if 200 <= _response.status_code < 300:
948
- return
949
- _response_json = _response.json()
950
- except JSONDecodeError:
951
- raise ApiError(status_code=_response.status_code, body=_response.text)
952
- raise ApiError(status_code=_response.status_code, body=_response_json)
849
+ _response = await self._raw_client.delete_experiment_items(ids=ids, request_options=request_options)
850
+ return _response.data
953
851
 
954
852
  async def delete_experiments_by_id(
955
- self,
956
- *,
957
- ids: typing.Sequence[str],
958
- request_options: typing.Optional[RequestOptions] = None,
853
+ self, *, ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
959
854
  ) -> None:
960
855
  """
961
856
  Delete experiments by id
@@ -973,49 +868,67 @@ class AsyncExperimentsClient:
973
868
 
974
869
  Examples
975
870
  --------
871
+ from Opik import AsyncOpikApi
976
872
  import asyncio
873
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
874
+ async def main() -> None:
875
+ await client.experiments.delete_experiments_by_id(ids=['ids'], )
876
+ asyncio.run(main())
877
+ """
878
+ _response = await self._raw_client.delete_experiments_by_id(ids=ids, request_options=request_options)
879
+ return _response.data
977
880
 
978
- from Opik import AsyncOpikApi
881
+ async def experiment_items_bulk(
882
+ self,
883
+ *,
884
+ experiment_name: str,
885
+ dataset_name: str,
886
+ items: typing.Sequence[ExperimentItemBulkRecordExperimentItemBulkWriteView],
887
+ experiment_id: typing.Optional[str] = OMIT,
888
+ request_options: typing.Optional[RequestOptions] = None,
889
+ ) -> None:
890
+ """
891
+ Record experiment items in bulk with traces, spans, and feedback scores. Maximum request size is 4MB.
979
892
 
980
- client = AsyncOpikApi(
981
- api_key="YOUR_API_KEY",
982
- workspace_name="YOUR_WORKSPACE_NAME",
983
- )
893
+ Parameters
894
+ ----------
895
+ experiment_name : str
984
896
 
897
+ dataset_name : str
985
898
 
986
- async def main() -> None:
987
- await client.experiments.delete_experiments_by_id(
988
- ids=["ids"],
989
- )
899
+ items : typing.Sequence[ExperimentItemBulkRecordExperimentItemBulkWriteView]
990
900
 
901
+ experiment_id : typing.Optional[str]
902
+ Optional experiment ID. If provided, items will be added to the existing experiment and experimentName will be ignored. If not provided or experiment with that ID doesn't exist, a new experiment will be created with the given experimentName
903
+
904
+ request_options : typing.Optional[RequestOptions]
905
+ Request-specific configuration.
906
+
907
+ Returns
908
+ -------
909
+ None
991
910
 
911
+ Examples
912
+ --------
913
+ from Opik import AsyncOpikApi
914
+ from Opik import ExperimentItemBulkRecordExperimentItemBulkWriteView
915
+ import asyncio
916
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
917
+ async def main() -> None:
918
+ await client.experiments.experiment_items_bulk(experiment_name='experiment_name', dataset_name='dataset_name', items=[ExperimentItemBulkRecordExperimentItemBulkWriteView(dataset_item_id='dataset_item_id', )], )
992
919
  asyncio.run(main())
993
920
  """
994
- _response = await self._client_wrapper.httpx_client.request(
995
- "v1/private/experiments/delete",
996
- method="POST",
997
- json={
998
- "ids": ids,
999
- },
1000
- headers={
1001
- "content-type": "application/json",
1002
- },
921
+ _response = await self._raw_client.experiment_items_bulk(
922
+ experiment_name=experiment_name,
923
+ dataset_name=dataset_name,
924
+ items=items,
925
+ experiment_id=experiment_id,
1003
926
  request_options=request_options,
1004
- omit=OMIT,
1005
927
  )
1006
- try:
1007
- if 200 <= _response.status_code < 300:
1008
- return
1009
- _response_json = _response.json()
1010
- except JSONDecodeError:
1011
- raise ApiError(status_code=_response.status_code, body=_response.text)
1012
- raise ApiError(status_code=_response.status_code, body=_response_json)
928
+ return _response.data
1013
929
 
1014
930
  async def find_feedback_score_names(
1015
- self,
1016
- *,
1017
- experiment_ids: typing.Optional[str] = None,
1018
- request_options: typing.Optional[RequestOptions] = None,
931
+ self, *, experiment_ids: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None
1019
932
  ) -> typing.List[str]:
1020
933
  """
1021
934
  Find Feedback Score names
@@ -1034,120 +947,144 @@ class AsyncExperimentsClient:
1034
947
 
1035
948
  Examples
1036
949
  --------
950
+ from Opik import AsyncOpikApi
1037
951
  import asyncio
952
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
953
+ async def main() -> None:
954
+ await client.experiments.find_feedback_score_names()
955
+ asyncio.run(main())
956
+ """
957
+ _response = await self._raw_client.find_feedback_score_names(
958
+ experiment_ids=experiment_ids, request_options=request_options
959
+ )
960
+ return _response.data
1038
961
 
1039
- from Opik import AsyncOpikApi
962
+ async def find_experiment_groups(
963
+ self,
964
+ *,
965
+ groups: typing.Optional[str] = None,
966
+ types: typing.Optional[str] = None,
967
+ name: typing.Optional[str] = None,
968
+ filters: typing.Optional[str] = None,
969
+ request_options: typing.Optional[RequestOptions] = None,
970
+ ) -> ExperimentGroupResponse:
971
+ """
972
+ Find experiments grouped by specified fields
1040
973
 
1041
- client = AsyncOpikApi(
1042
- api_key="YOUR_API_KEY",
1043
- workspace_name="YOUR_WORKSPACE_NAME",
1044
- )
974
+ Parameters
975
+ ----------
976
+ groups : typing.Optional[str]
1045
977
 
978
+ types : typing.Optional[str]
1046
979
 
1047
- async def main() -> None:
1048
- await client.experiments.find_feedback_score_names()
980
+ name : typing.Optional[str]
1049
981
 
982
+ filters : typing.Optional[str]
1050
983
 
984
+ request_options : typing.Optional[RequestOptions]
985
+ Request-specific configuration.
986
+
987
+ Returns
988
+ -------
989
+ ExperimentGroupResponse
990
+ Experiment groups
991
+
992
+ Examples
993
+ --------
994
+ from Opik import AsyncOpikApi
995
+ import asyncio
996
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
997
+ async def main() -> None:
998
+ await client.experiments.find_experiment_groups()
1051
999
  asyncio.run(main())
1052
1000
  """
1053
- _response = await self._client_wrapper.httpx_client.request(
1054
- "v1/private/experiments/feedback-scores/names",
1055
- method="GET",
1056
- params={
1057
- "experiment_ids": experiment_ids,
1058
- },
1059
- request_options=request_options,
1001
+ _response = await self._raw_client.find_experiment_groups(
1002
+ groups=groups, types=types, name=name, filters=filters, request_options=request_options
1060
1003
  )
1061
- try:
1062
- if 200 <= _response.status_code < 300:
1063
- return typing.cast(
1064
- typing.List[str],
1065
- parse_obj_as(
1066
- type_=typing.List[str], # type: ignore
1067
- object_=_response.json(),
1068
- ),
1069
- )
1070
- _response_json = _response.json()
1071
- except JSONDecodeError:
1072
- raise ApiError(status_code=_response.status_code, body=_response.text)
1073
- raise ApiError(status_code=_response.status_code, body=_response_json)
1004
+ return _response.data
1074
1005
 
1075
- async def get_experiment_by_id(
1076
- self, id: str, *, request_options: typing.Optional[RequestOptions] = None
1077
- ) -> ExperimentPublic:
1006
+ async def find_experiment_groups_aggregations(
1007
+ self,
1008
+ *,
1009
+ groups: typing.Optional[str] = None,
1010
+ types: typing.Optional[str] = None,
1011
+ name: typing.Optional[str] = None,
1012
+ filters: typing.Optional[str] = None,
1013
+ request_options: typing.Optional[RequestOptions] = None,
1014
+ ) -> ExperimentGroupAggregationsResponse:
1078
1015
  """
1079
- Get experiment by id
1016
+ Find experiments grouped by specified fields with aggregation metrics
1080
1017
 
1081
1018
  Parameters
1082
1019
  ----------
1083
- id : str
1020
+ groups : typing.Optional[str]
1021
+
1022
+ types : typing.Optional[str]
1023
+
1024
+ name : typing.Optional[str]
1025
+
1026
+ filters : typing.Optional[str]
1084
1027
 
1085
1028
  request_options : typing.Optional[RequestOptions]
1086
1029
  Request-specific configuration.
1087
1030
 
1088
1031
  Returns
1089
1032
  -------
1090
- ExperimentPublic
1091
- Experiment resource
1033
+ ExperimentGroupAggregationsResponse
1034
+ Experiment groups with aggregations
1092
1035
 
1093
1036
  Examples
1094
1037
  --------
1095
- import asyncio
1096
-
1097
1038
  from Opik import AsyncOpikApi
1098
-
1099
- client = AsyncOpikApi(
1100
- api_key="YOUR_API_KEY",
1101
- workspace_name="YOUR_WORKSPACE_NAME",
1039
+ import asyncio
1040
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
1041
+ async def main() -> None:
1042
+ await client.experiments.find_experiment_groups_aggregations()
1043
+ asyncio.run(main())
1044
+ """
1045
+ _response = await self._raw_client.find_experiment_groups_aggregations(
1046
+ groups=groups, types=types, name=name, filters=filters, request_options=request_options
1102
1047
  )
1048
+ return _response.data
1103
1049
 
1050
+ async def finish_experiments(
1051
+ self, *, ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None
1052
+ ) -> None:
1053
+ """
1054
+ Finish experiments and trigger alert events
1104
1055
 
1105
- async def main() -> None:
1106
- await client.experiments.get_experiment_by_id(
1107
- id="id",
1108
- )
1056
+ Parameters
1057
+ ----------
1058
+ ids : typing.Sequence[str]
1059
+
1060
+ request_options : typing.Optional[RequestOptions]
1061
+ Request-specific configuration.
1109
1062
 
1063
+ Returns
1064
+ -------
1065
+ None
1110
1066
 
1067
+ Examples
1068
+ --------
1069
+ from Opik import AsyncOpikApi
1070
+ import asyncio
1071
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
1072
+ async def main() -> None:
1073
+ await client.experiments.finish_experiments(ids=['ids'], )
1111
1074
  asyncio.run(main())
1112
1075
  """
1113
- _response = await self._client_wrapper.httpx_client.request(
1114
- f"v1/private/experiments/{jsonable_encoder(id)}",
1115
- method="GET",
1116
- request_options=request_options,
1117
- )
1118
- try:
1119
- if 200 <= _response.status_code < 300:
1120
- return typing.cast(
1121
- ExperimentPublic,
1122
- parse_obj_as(
1123
- type_=ExperimentPublic, # type: ignore
1124
- object_=_response.json(),
1125
- ),
1126
- )
1127
- if _response.status_code == 404:
1128
- raise NotFoundError(
1129
- typing.cast(
1130
- typing.Optional[typing.Any],
1131
- parse_obj_as(
1132
- type_=typing.Optional[typing.Any], # type: ignore
1133
- object_=_response.json(),
1134
- ),
1135
- )
1136
- )
1137
- _response_json = _response.json()
1138
- except JSONDecodeError:
1139
- raise ApiError(status_code=_response.status_code, body=_response.text)
1140
- raise ApiError(status_code=_response.status_code, body=_response_json)
1141
-
1142
- async def get_experiment_by_name(
1143
- self, *, name: str, request_options: typing.Optional[RequestOptions] = None
1076
+ _response = await self._raw_client.finish_experiments(ids=ids, request_options=request_options)
1077
+ return _response.data
1078
+
1079
+ async def get_experiment_by_id(
1080
+ self, id: str, *, request_options: typing.Optional[RequestOptions] = None
1144
1081
  ) -> ExperimentPublic:
1145
1082
  """
1146
- Get experiment by name
1083
+ Get experiment by id
1147
1084
 
1148
1085
  Parameters
1149
1086
  ----------
1150
- name : str
1087
+ id : str
1151
1088
 
1152
1089
  request_options : typing.Optional[RequestOptions]
1153
1090
  Request-specific configuration.
@@ -1155,63 +1092,75 @@ class AsyncExperimentsClient:
1155
1092
  Returns
1156
1093
  -------
1157
1094
  ExperimentPublic
1158
- Experiments resource
1095
+ Experiment resource
1159
1096
 
1160
1097
  Examples
1161
1098
  --------
1099
+ from Opik import AsyncOpikApi
1162
1100
  import asyncio
1101
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
1102
+ async def main() -> None:
1103
+ await client.experiments.get_experiment_by_id(id='id', )
1104
+ asyncio.run(main())
1105
+ """
1106
+ _response = await self._raw_client.get_experiment_by_id(id, request_options=request_options)
1107
+ return _response.data
1163
1108
 
1164
- from Opik import AsyncOpikApi
1109
+ async def update_experiment(
1110
+ self,
1111
+ id: str,
1112
+ *,
1113
+ name: typing.Optional[str] = OMIT,
1114
+ metadata: typing.Optional[JsonNode] = OMIT,
1115
+ type: typing.Optional[ExperimentUpdateType] = OMIT,
1116
+ status: typing.Optional[ExperimentUpdateStatus] = OMIT,
1117
+ experiment_scores: typing.Optional[typing.Sequence[ExperimentScore]] = OMIT,
1118
+ request_options: typing.Optional[RequestOptions] = None,
1119
+ ) -> None:
1120
+ """
1121
+ Update experiment by id
1165
1122
 
1166
- client = AsyncOpikApi(
1167
- api_key="YOUR_API_KEY",
1168
- workspace_name="YOUR_WORKSPACE_NAME",
1169
- )
1123
+ Parameters
1124
+ ----------
1125
+ id : str
1126
+
1127
+ name : typing.Optional[str]
1170
1128
 
1129
+ metadata : typing.Optional[JsonNode]
1171
1130
 
1172
- async def main() -> None:
1173
- await client.experiments.get_experiment_by_name(
1174
- name="name",
1175
- )
1131
+ type : typing.Optional[ExperimentUpdateType]
1132
+
1133
+ status : typing.Optional[ExperimentUpdateStatus]
1134
+ The status of the experiment
1135
+
1136
+ experiment_scores : typing.Optional[typing.Sequence[ExperimentScore]]
1137
+
1138
+ request_options : typing.Optional[RequestOptions]
1139
+ Request-specific configuration.
1176
1140
 
1141
+ Returns
1142
+ -------
1143
+ None
1177
1144
 
1145
+ Examples
1146
+ --------
1147
+ from Opik import AsyncOpikApi
1148
+ import asyncio
1149
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
1150
+ async def main() -> None:
1151
+ await client.experiments.update_experiment(id='id', )
1178
1152
  asyncio.run(main())
1179
1153
  """
1180
- _response = await self._client_wrapper.httpx_client.request(
1181
- "v1/private/experiments/retrieve",
1182
- method="POST",
1183
- json={
1184
- "name": name,
1185
- },
1186
- headers={
1187
- "content-type": "application/json",
1188
- },
1154
+ _response = await self._raw_client.update_experiment(
1155
+ id,
1156
+ name=name,
1157
+ metadata=metadata,
1158
+ type=type,
1159
+ status=status,
1160
+ experiment_scores=experiment_scores,
1189
1161
  request_options=request_options,
1190
- omit=OMIT,
1191
1162
  )
1192
- try:
1193
- if 200 <= _response.status_code < 300:
1194
- return typing.cast(
1195
- ExperimentPublic,
1196
- parse_obj_as(
1197
- type_=ExperimentPublic, # type: ignore
1198
- object_=_response.json(),
1199
- ),
1200
- )
1201
- if _response.status_code == 404:
1202
- raise NotFoundError(
1203
- typing.cast(
1204
- typing.Optional[typing.Any],
1205
- parse_obj_as(
1206
- type_=typing.Optional[typing.Any], # type: ignore
1207
- object_=_response.json(),
1208
- ),
1209
- )
1210
- )
1211
- _response_json = _response.json()
1212
- except JSONDecodeError:
1213
- raise ApiError(status_code=_response.status_code, body=_response.text)
1214
- raise ApiError(status_code=_response.status_code, body=_response_json)
1163
+ return _response.data
1215
1164
 
1216
1165
  async def get_experiment_item_by_id(
1217
1166
  self, id: str, *, request_options: typing.Optional[RequestOptions] = None
@@ -1233,52 +1182,15 @@ class AsyncExperimentsClient:
1233
1182
 
1234
1183
  Examples
1235
1184
  --------
1236
- import asyncio
1237
-
1238
1185
  from Opik import AsyncOpikApi
1239
-
1240
- client = AsyncOpikApi(
1241
- api_key="YOUR_API_KEY",
1242
- workspace_name="YOUR_WORKSPACE_NAME",
1243
- )
1244
-
1245
-
1186
+ import asyncio
1187
+ client = AsyncOpikApi(api_key="YOUR_API_KEY", workspace_name="YOUR_WORKSPACE_NAME", )
1246
1188
  async def main() -> None:
1247
- await client.experiments.get_experiment_item_by_id(
1248
- id="id",
1249
- )
1250
-
1251
-
1189
+ await client.experiments.get_experiment_item_by_id(id='id', )
1252
1190
  asyncio.run(main())
1253
1191
  """
1254
- _response = await self._client_wrapper.httpx_client.request(
1255
- f"v1/private/experiments/items/{jsonable_encoder(id)}",
1256
- method="GET",
1257
- request_options=request_options,
1258
- )
1259
- try:
1260
- if 200 <= _response.status_code < 300:
1261
- return typing.cast(
1262
- ExperimentItemPublic,
1263
- parse_obj_as(
1264
- type_=ExperimentItemPublic, # type: ignore
1265
- object_=_response.json(),
1266
- ),
1267
- )
1268
- if _response.status_code == 404:
1269
- raise NotFoundError(
1270
- typing.cast(
1271
- typing.Optional[typing.Any],
1272
- parse_obj_as(
1273
- type_=typing.Optional[typing.Any], # type: ignore
1274
- object_=_response.json(),
1275
- ),
1276
- )
1277
- )
1278
- _response_json = _response.json()
1279
- except JSONDecodeError:
1280
- raise ApiError(status_code=_response.status_code, body=_response.text)
1281
- raise ApiError(status_code=_response.status_code, body=_response_json)
1192
+ _response = await self._raw_client.get_experiment_item_by_id(id, request_options=request_options)
1193
+ return _response.data
1282
1194
 
1283
1195
  async def stream_experiment_items(
1284
1196
  self,
@@ -1306,38 +1218,50 @@ class AsyncExperimentsClient:
1306
1218
  request_options : typing.Optional[RequestOptions]
1307
1219
  Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
1308
1220
 
1309
- Yields
1310
- ------
1221
+ Returns
1222
+ -------
1311
1223
  typing.AsyncIterator[bytes]
1312
1224
  Experiment items stream or error during process
1313
1225
  """
1314
- async with self._client_wrapper.httpx_client.stream(
1315
- "v1/private/experiments/items/stream",
1316
- method="POST",
1317
- json={
1318
- "experiment_name": experiment_name,
1319
- "limit": limit,
1320
- "last_retrieved_id": last_retrieved_id,
1321
- "truncate": truncate,
1322
- },
1323
- headers={
1324
- "content-type": "application/json",
1325
- },
1226
+ async with self._raw_client.stream_experiment_items(
1227
+ experiment_name=experiment_name,
1228
+ limit=limit,
1229
+ last_retrieved_id=last_retrieved_id,
1230
+ truncate=truncate,
1326
1231
  request_options=request_options,
1327
- omit=OMIT,
1328
- ) as _response:
1329
- try:
1330
- if 200 <= _response.status_code < 300:
1331
- _chunk_size = (
1332
- request_options.get("chunk_size", None)
1333
- if request_options is not None
1334
- else None
1335
- )
1336
- async for _chunk in _response.aiter_bytes(chunk_size=_chunk_size):
1337
- yield _chunk
1338
- return
1339
- await _response.aread()
1340
- _response_json = _response.json()
1341
- except JSONDecodeError:
1342
- raise ApiError(status_code=_response.status_code, body=_response.text)
1343
- raise ApiError(status_code=_response.status_code, body=_response_json)
1232
+ ) as r:
1233
+ async for data in r.data:
1234
+ yield data
1235
+
1236
+ async def stream_experiments(
1237
+ self,
1238
+ *,
1239
+ name: str,
1240
+ limit: typing.Optional[int] = OMIT,
1241
+ last_retrieved_id: typing.Optional[str] = OMIT,
1242
+ request_options: typing.Optional[RequestOptions] = None,
1243
+ ) -> typing.AsyncIterator[bytes]:
1244
+ """
1245
+ Stream experiments
1246
+
1247
+ Parameters
1248
+ ----------
1249
+ name : str
1250
+
1251
+ limit : typing.Optional[int]
1252
+
1253
+ last_retrieved_id : typing.Optional[str]
1254
+
1255
+ request_options : typing.Optional[RequestOptions]
1256
+ Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.
1257
+
1258
+ Returns
1259
+ -------
1260
+ typing.AsyncIterator[bytes]
1261
+ Experiments stream or error during process
1262
+ """
1263
+ async with self._raw_client.stream_experiments(
1264
+ name=name, limit=limit, last_retrieved_id=last_retrieved_id, request_options=request_options
1265
+ ) as r:
1266
+ async for data in r.data:
1267
+ yield data