aeri-python 4.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aeri/__init__.py +72 -0
- aeri/_client/_validation.py +204 -0
- aeri/_client/attributes.py +188 -0
- aeri/_client/client.py +3761 -0
- aeri/_client/constants.py +65 -0
- aeri/_client/datasets.py +302 -0
- aeri/_client/environment_variables.py +158 -0
- aeri/_client/get_client.py +149 -0
- aeri/_client/observe.py +661 -0
- aeri/_client/propagation.py +475 -0
- aeri/_client/resource_manager.py +510 -0
- aeri/_client/span.py +1519 -0
- aeri/_client/span_filter.py +76 -0
- aeri/_client/span_processor.py +206 -0
- aeri/_client/utils.py +132 -0
- aeri/_task_manager/media_manager.py +331 -0
- aeri/_task_manager/media_upload_consumer.py +44 -0
- aeri/_task_manager/media_upload_queue.py +12 -0
- aeri/_task_manager/score_ingestion_consumer.py +208 -0
- aeri/_task_manager/task_manager.py +475 -0
- aeri/_utils/__init__.py +19 -0
- aeri/_utils/environment.py +34 -0
- aeri/_utils/error_logging.py +47 -0
- aeri/_utils/parse_error.py +99 -0
- aeri/_utils/prompt_cache.py +188 -0
- aeri/_utils/request.py +137 -0
- aeri/_utils/serializer.py +205 -0
- aeri/api/.fern/metadata.json +14 -0
- aeri/api/__init__.py +836 -0
- aeri/api/annotation_queues/__init__.py +82 -0
- aeri/api/annotation_queues/client.py +1111 -0
- aeri/api/annotation_queues/raw_client.py +2288 -0
- aeri/api/annotation_queues/types/__init__.py +84 -0
- aeri/api/annotation_queues/types/annotation_queue.py +28 -0
- aeri/api/annotation_queues/types/annotation_queue_assignment_request.py +16 -0
- aeri/api/annotation_queues/types/annotation_queue_item.py +34 -0
- aeri/api/annotation_queues/types/annotation_queue_object_type.py +26 -0
- aeri/api/annotation_queues/types/annotation_queue_status.py +22 -0
- aeri/api/annotation_queues/types/create_annotation_queue_assignment_response.py +18 -0
- aeri/api/annotation_queues/types/create_annotation_queue_item_request.py +25 -0
- aeri/api/annotation_queues/types/create_annotation_queue_request.py +20 -0
- aeri/api/annotation_queues/types/delete_annotation_queue_assignment_response.py +14 -0
- aeri/api/annotation_queues/types/delete_annotation_queue_item_response.py +15 -0
- aeri/api/annotation_queues/types/paginated_annotation_queue_items.py +17 -0
- aeri/api/annotation_queues/types/paginated_annotation_queues.py +17 -0
- aeri/api/annotation_queues/types/update_annotation_queue_item_request.py +15 -0
- aeri/api/blob_storage_integrations/__init__.py +73 -0
- aeri/api/blob_storage_integrations/client.py +550 -0
- aeri/api/blob_storage_integrations/raw_client.py +976 -0
- aeri/api/blob_storage_integrations/types/__init__.py +77 -0
- aeri/api/blob_storage_integrations/types/blob_storage_export_frequency.py +26 -0
- aeri/api/blob_storage_integrations/types/blob_storage_export_mode.py +26 -0
- aeri/api/blob_storage_integrations/types/blob_storage_integration_deletion_response.py +14 -0
- aeri/api/blob_storage_integrations/types/blob_storage_integration_file_type.py +26 -0
- aeri/api/blob_storage_integrations/types/blob_storage_integration_response.py +64 -0
- aeri/api/blob_storage_integrations/types/blob_storage_integration_status_response.py +50 -0
- aeri/api/blob_storage_integrations/types/blob_storage_integration_type.py +26 -0
- aeri/api/blob_storage_integrations/types/blob_storage_integrations_response.py +15 -0
- aeri/api/blob_storage_integrations/types/blob_storage_sync_status.py +47 -0
- aeri/api/blob_storage_integrations/types/create_blob_storage_integration_request.py +91 -0
- aeri/api/client.py +679 -0
- aeri/api/comments/__init__.py +44 -0
- aeri/api/comments/client.py +407 -0
- aeri/api/comments/raw_client.py +750 -0
- aeri/api/comments/types/__init__.py +46 -0
- aeri/api/comments/types/create_comment_request.py +47 -0
- aeri/api/comments/types/create_comment_response.py +17 -0
- aeri/api/comments/types/get_comments_response.py +17 -0
- aeri/api/commons/__init__.py +210 -0
- aeri/api/commons/errors/__init__.py +56 -0
- aeri/api/commons/errors/access_denied_error.py +12 -0
- aeri/api/commons/errors/error.py +12 -0
- aeri/api/commons/errors/method_not_allowed_error.py +12 -0
- aeri/api/commons/errors/not_found_error.py +12 -0
- aeri/api/commons/errors/unauthorized_error.py +12 -0
- aeri/api/commons/types/__init__.py +190 -0
- aeri/api/commons/types/base_score.py +90 -0
- aeri/api/commons/types/base_score_v1.py +70 -0
- aeri/api/commons/types/boolean_score.py +26 -0
- aeri/api/commons/types/boolean_score_v1.py +26 -0
- aeri/api/commons/types/categorical_score.py +26 -0
- aeri/api/commons/types/categorical_score_v1.py +26 -0
- aeri/api/commons/types/comment.py +36 -0
- aeri/api/commons/types/comment_object_type.py +30 -0
- aeri/api/commons/types/config_category.py +15 -0
- aeri/api/commons/types/correction_score.py +26 -0
- aeri/api/commons/types/create_score_value.py +5 -0
- aeri/api/commons/types/dataset.py +49 -0
- aeri/api/commons/types/dataset_item.py +58 -0
- aeri/api/commons/types/dataset_run.py +63 -0
- aeri/api/commons/types/dataset_run_item.py +40 -0
- aeri/api/commons/types/dataset_run_with_items.py +19 -0
- aeri/api/commons/types/dataset_status.py +22 -0
- aeri/api/commons/types/map_value.py +11 -0
- aeri/api/commons/types/model.py +125 -0
- aeri/api/commons/types/model_price.py +14 -0
- aeri/api/commons/types/model_usage_unit.py +42 -0
- aeri/api/commons/types/numeric_score.py +17 -0
- aeri/api/commons/types/numeric_score_v1.py +17 -0
- aeri/api/commons/types/observation.py +142 -0
- aeri/api/commons/types/observation_level.py +30 -0
- aeri/api/commons/types/observation_v2.py +235 -0
- aeri/api/commons/types/observations_view.py +89 -0
- aeri/api/commons/types/pricing_tier.py +91 -0
- aeri/api/commons/types/pricing_tier_condition.py +68 -0
- aeri/api/commons/types/pricing_tier_input.py +76 -0
- aeri/api/commons/types/pricing_tier_operator.py +42 -0
- aeri/api/commons/types/score.py +201 -0
- aeri/api/commons/types/score_config.py +66 -0
- aeri/api/commons/types/score_config_data_type.py +26 -0
- aeri/api/commons/types/score_data_type.py +30 -0
- aeri/api/commons/types/score_source.py +26 -0
- aeri/api/commons/types/score_v1.py +131 -0
- aeri/api/commons/types/session.py +25 -0
- aeri/api/commons/types/session_with_traces.py +15 -0
- aeri/api/commons/types/trace.py +84 -0
- aeri/api/commons/types/trace_with_details.py +43 -0
- aeri/api/commons/types/trace_with_full_details.py +45 -0
- aeri/api/commons/types/usage.py +59 -0
- aeri/api/core/__init__.py +111 -0
- aeri/api/core/api_error.py +23 -0
- aeri/api/core/client_wrapper.py +141 -0
- aeri/api/core/datetime_utils.py +30 -0
- aeri/api/core/enum.py +20 -0
- aeri/api/core/file.py +70 -0
- aeri/api/core/force_multipart.py +18 -0
- aeri/api/core/http_client.py +711 -0
- aeri/api/core/http_response.py +55 -0
- aeri/api/core/http_sse/__init__.py +48 -0
- aeri/api/core/http_sse/_api.py +114 -0
- aeri/api/core/http_sse/_decoders.py +66 -0
- aeri/api/core/http_sse/_exceptions.py +7 -0
- aeri/api/core/http_sse/_models.py +17 -0
- aeri/api/core/jsonable_encoder.py +102 -0
- aeri/api/core/pydantic_utilities.py +310 -0
- aeri/api/core/query_encoder.py +60 -0
- aeri/api/core/remove_none_from_dict.py +11 -0
- aeri/api/core/request_options.py +35 -0
- aeri/api/core/serialization.py +282 -0
- aeri/api/dataset_items/__init__.py +52 -0
- aeri/api/dataset_items/client.py +499 -0
- aeri/api/dataset_items/raw_client.py +973 -0
- aeri/api/dataset_items/types/__init__.py +50 -0
- aeri/api/dataset_items/types/create_dataset_item_request.py +37 -0
- aeri/api/dataset_items/types/delete_dataset_item_response.py +17 -0
- aeri/api/dataset_items/types/paginated_dataset_items.py +17 -0
- aeri/api/dataset_run_items/__init__.py +43 -0
- aeri/api/dataset_run_items/client.py +323 -0
- aeri/api/dataset_run_items/raw_client.py +547 -0
- aeri/api/dataset_run_items/types/__init__.py +44 -0
- aeri/api/dataset_run_items/types/create_dataset_run_item_request.py +51 -0
- aeri/api/dataset_run_items/types/paginated_dataset_run_items.py +17 -0
- aeri/api/datasets/__init__.py +55 -0
- aeri/api/datasets/client.py +661 -0
- aeri/api/datasets/raw_client.py +1368 -0
- aeri/api/datasets/types/__init__.py +53 -0
- aeri/api/datasets/types/create_dataset_request.py +31 -0
- aeri/api/datasets/types/delete_dataset_run_response.py +14 -0
- aeri/api/datasets/types/paginated_dataset_runs.py +17 -0
- aeri/api/datasets/types/paginated_datasets.py +17 -0
- aeri/api/health/__init__.py +44 -0
- aeri/api/health/client.py +112 -0
- aeri/api/health/errors/__init__.py +42 -0
- aeri/api/health/errors/service_unavailable_error.py +13 -0
- aeri/api/health/raw_client.py +227 -0
- aeri/api/health/types/__init__.py +40 -0
- aeri/api/health/types/health_response.py +30 -0
- aeri/api/ingestion/__init__.py +169 -0
- aeri/api/ingestion/client.py +221 -0
- aeri/api/ingestion/raw_client.py +293 -0
- aeri/api/ingestion/types/__init__.py +169 -0
- aeri/api/ingestion/types/base_event.py +27 -0
- aeri/api/ingestion/types/create_event_body.py +14 -0
- aeri/api/ingestion/types/create_event_event.py +15 -0
- aeri/api/ingestion/types/create_generation_body.py +40 -0
- aeri/api/ingestion/types/create_generation_event.py +15 -0
- aeri/api/ingestion/types/create_observation_event.py +15 -0
- aeri/api/ingestion/types/create_span_body.py +19 -0
- aeri/api/ingestion/types/create_span_event.py +15 -0
- aeri/api/ingestion/types/ingestion_error.py +17 -0
- aeri/api/ingestion/types/ingestion_event.py +155 -0
- aeri/api/ingestion/types/ingestion_response.py +17 -0
- aeri/api/ingestion/types/ingestion_success.py +15 -0
- aeri/api/ingestion/types/ingestion_usage.py +8 -0
- aeri/api/ingestion/types/observation_body.py +53 -0
- aeri/api/ingestion/types/observation_type.py +54 -0
- aeri/api/ingestion/types/open_ai_completion_usage_schema.py +26 -0
- aeri/api/ingestion/types/open_ai_response_usage_schema.py +24 -0
- aeri/api/ingestion/types/open_ai_usage.py +28 -0
- aeri/api/ingestion/types/optional_observation_body.py +36 -0
- aeri/api/ingestion/types/score_body.py +75 -0
- aeri/api/ingestion/types/score_event.py +15 -0
- aeri/api/ingestion/types/sdk_log_body.py +14 -0
- aeri/api/ingestion/types/sdk_log_event.py +15 -0
- aeri/api/ingestion/types/trace_body.py +36 -0
- aeri/api/ingestion/types/trace_event.py +15 -0
- aeri/api/ingestion/types/update_event_body.py +14 -0
- aeri/api/ingestion/types/update_generation_body.py +40 -0
- aeri/api/ingestion/types/update_generation_event.py +15 -0
- aeri/api/ingestion/types/update_observation_event.py +15 -0
- aeri/api/ingestion/types/update_span_body.py +19 -0
- aeri/api/ingestion/types/update_span_event.py +15 -0
- aeri/api/ingestion/types/usage_details.py +10 -0
- aeri/api/legacy/__init__.py +61 -0
- aeri/api/legacy/client.py +105 -0
- aeri/api/legacy/metrics_v1/__init__.py +40 -0
- aeri/api/legacy/metrics_v1/client.py +214 -0
- aeri/api/legacy/metrics_v1/raw_client.py +322 -0
- aeri/api/legacy/metrics_v1/types/__init__.py +40 -0
- aeri/api/legacy/metrics_v1/types/metrics_response.py +19 -0
- aeri/api/legacy/observations_v1/__init__.py +43 -0
- aeri/api/legacy/observations_v1/client.py +523 -0
- aeri/api/legacy/observations_v1/raw_client.py +759 -0
- aeri/api/legacy/observations_v1/types/__init__.py +44 -0
- aeri/api/legacy/observations_v1/types/observations.py +17 -0
- aeri/api/legacy/observations_v1/types/observations_views.py +17 -0
- aeri/api/legacy/raw_client.py +13 -0
- aeri/api/legacy/score_v1/__init__.py +43 -0
- aeri/api/legacy/score_v1/client.py +329 -0
- aeri/api/legacy/score_v1/raw_client.py +545 -0
- aeri/api/legacy/score_v1/types/__init__.py +44 -0
- aeri/api/legacy/score_v1/types/create_score_request.py +75 -0
- aeri/api/legacy/score_v1/types/create_score_response.py +17 -0
- aeri/api/llm_connections/__init__.py +55 -0
- aeri/api/llm_connections/client.py +311 -0
- aeri/api/llm_connections/raw_client.py +541 -0
- aeri/api/llm_connections/types/__init__.py +53 -0
- aeri/api/llm_connections/types/llm_adapter.py +38 -0
- aeri/api/llm_connections/types/llm_connection.py +77 -0
- aeri/api/llm_connections/types/paginated_llm_connections.py +17 -0
- aeri/api/llm_connections/types/upsert_llm_connection_request.py +69 -0
- aeri/api/media/__init__.py +58 -0
- aeri/api/media/client.py +427 -0
- aeri/api/media/raw_client.py +739 -0
- aeri/api/media/types/__init__.py +56 -0
- aeri/api/media/types/get_media_response.py +55 -0
- aeri/api/media/types/get_media_upload_url_request.py +51 -0
- aeri/api/media/types/get_media_upload_url_response.py +28 -0
- aeri/api/media/types/media_content_type.py +232 -0
- aeri/api/media/types/patch_media_body.py +43 -0
- aeri/api/metrics/__init__.py +40 -0
- aeri/api/metrics/client.py +422 -0
- aeri/api/metrics/raw_client.py +530 -0
- aeri/api/metrics/types/__init__.py +40 -0
- aeri/api/metrics/types/metrics_v2response.py +19 -0
- aeri/api/models/__init__.py +43 -0
- aeri/api/models/client.py +523 -0
- aeri/api/models/raw_client.py +993 -0
- aeri/api/models/types/__init__.py +44 -0
- aeri/api/models/types/create_model_request.py +103 -0
- aeri/api/models/types/paginated_models.py +17 -0
- aeri/api/observations/__init__.py +43 -0
- aeri/api/observations/client.py +522 -0
- aeri/api/observations/raw_client.py +641 -0
- aeri/api/observations/types/__init__.py +44 -0
- aeri/api/observations/types/observations_v2meta.py +21 -0
- aeri/api/observations/types/observations_v2response.py +28 -0
- aeri/api/opentelemetry/__init__.py +67 -0
- aeri/api/opentelemetry/client.py +276 -0
- aeri/api/opentelemetry/raw_client.py +291 -0
- aeri/api/opentelemetry/types/__init__.py +65 -0
- aeri/api/opentelemetry/types/otel_attribute.py +27 -0
- aeri/api/opentelemetry/types/otel_attribute_value.py +46 -0
- aeri/api/opentelemetry/types/otel_resource.py +24 -0
- aeri/api/opentelemetry/types/otel_resource_span.py +32 -0
- aeri/api/opentelemetry/types/otel_scope.py +34 -0
- aeri/api/opentelemetry/types/otel_scope_span.py +28 -0
- aeri/api/opentelemetry/types/otel_span.py +76 -0
- aeri/api/opentelemetry/types/otel_trace_response.py +16 -0
- aeri/api/organizations/__init__.py +73 -0
- aeri/api/organizations/client.py +756 -0
- aeri/api/organizations/raw_client.py +1707 -0
- aeri/api/organizations/types/__init__.py +71 -0
- aeri/api/organizations/types/delete_membership_request.py +16 -0
- aeri/api/organizations/types/membership_deletion_response.py +17 -0
- aeri/api/organizations/types/membership_request.py +18 -0
- aeri/api/organizations/types/membership_response.py +20 -0
- aeri/api/organizations/types/membership_role.py +30 -0
- aeri/api/organizations/types/memberships_response.py +15 -0
- aeri/api/organizations/types/organization_api_key.py +31 -0
- aeri/api/organizations/types/organization_api_keys_response.py +19 -0
- aeri/api/organizations/types/organization_project.py +25 -0
- aeri/api/organizations/types/organization_projects_response.py +15 -0
- aeri/api/projects/__init__.py +67 -0
- aeri/api/projects/client.py +760 -0
- aeri/api/projects/raw_client.py +1577 -0
- aeri/api/projects/types/__init__.py +65 -0
- aeri/api/projects/types/api_key_deletion_response.py +18 -0
- aeri/api/projects/types/api_key_list.py +23 -0
- aeri/api/projects/types/api_key_response.py +30 -0
- aeri/api/projects/types/api_key_summary.py +35 -0
- aeri/api/projects/types/organization.py +22 -0
- aeri/api/projects/types/project.py +34 -0
- aeri/api/projects/types/project_deletion_response.py +15 -0
- aeri/api/projects/types/projects.py +15 -0
- aeri/api/prompt_version/__init__.py +4 -0
- aeri/api/prompt_version/client.py +157 -0
- aeri/api/prompt_version/raw_client.py +264 -0
- aeri/api/prompts/__init__.py +100 -0
- aeri/api/prompts/client.py +550 -0
- aeri/api/prompts/raw_client.py +987 -0
- aeri/api/prompts/types/__init__.py +96 -0
- aeri/api/prompts/types/base_prompt.py +42 -0
- aeri/api/prompts/types/chat_message.py +17 -0
- aeri/api/prompts/types/chat_message_type.py +15 -0
- aeri/api/prompts/types/chat_message_with_placeholders.py +8 -0
- aeri/api/prompts/types/chat_prompt.py +15 -0
- aeri/api/prompts/types/create_chat_prompt_request.py +37 -0
- aeri/api/prompts/types/create_chat_prompt_type.py +15 -0
- aeri/api/prompts/types/create_prompt_request.py +8 -0
- aeri/api/prompts/types/create_text_prompt_request.py +36 -0
- aeri/api/prompts/types/create_text_prompt_type.py +15 -0
- aeri/api/prompts/types/placeholder_message.py +16 -0
- aeri/api/prompts/types/placeholder_message_type.py +15 -0
- aeri/api/prompts/types/prompt.py +58 -0
- aeri/api/prompts/types/prompt_meta.py +35 -0
- aeri/api/prompts/types/prompt_meta_list_response.py +17 -0
- aeri/api/prompts/types/prompt_type.py +20 -0
- aeri/api/prompts/types/text_prompt.py +14 -0
- aeri/api/scim/__init__.py +94 -0
- aeri/api/scim/client.py +686 -0
- aeri/api/scim/raw_client.py +1528 -0
- aeri/api/scim/types/__init__.py +92 -0
- aeri/api/scim/types/authentication_scheme.py +20 -0
- aeri/api/scim/types/bulk_config.py +22 -0
- aeri/api/scim/types/empty_response.py +16 -0
- aeri/api/scim/types/filter_config.py +17 -0
- aeri/api/scim/types/resource_meta.py +17 -0
- aeri/api/scim/types/resource_type.py +27 -0
- aeri/api/scim/types/resource_types_response.py +21 -0
- aeri/api/scim/types/schema_extension.py +17 -0
- aeri/api/scim/types/schema_resource.py +19 -0
- aeri/api/scim/types/schemas_response.py +21 -0
- aeri/api/scim/types/scim_email.py +16 -0
- aeri/api/scim/types/scim_feature_support.py +14 -0
- aeri/api/scim/types/scim_name.py +14 -0
- aeri/api/scim/types/scim_user.py +24 -0
- aeri/api/scim/types/scim_users_list_response.py +25 -0
- aeri/api/scim/types/service_provider_config.py +36 -0
- aeri/api/scim/types/user_meta.py +20 -0
- aeri/api/score_configs/__init__.py +44 -0
- aeri/api/score_configs/client.py +526 -0
- aeri/api/score_configs/raw_client.py +1012 -0
- aeri/api/score_configs/types/__init__.py +46 -0
- aeri/api/score_configs/types/create_score_config_request.py +46 -0
- aeri/api/score_configs/types/score_configs.py +17 -0
- aeri/api/score_configs/types/update_score_config_request.py +53 -0
- aeri/api/scores/__init__.py +76 -0
- aeri/api/scores/client.py +420 -0
- aeri/api/scores/raw_client.py +656 -0
- aeri/api/scores/types/__init__.py +76 -0
- aeri/api/scores/types/get_scores_response.py +17 -0
- aeri/api/scores/types/get_scores_response_data.py +211 -0
- aeri/api/scores/types/get_scores_response_data_boolean.py +15 -0
- aeri/api/scores/types/get_scores_response_data_categorical.py +15 -0
- aeri/api/scores/types/get_scores_response_data_correction.py +15 -0
- aeri/api/scores/types/get_scores_response_data_numeric.py +15 -0
- aeri/api/scores/types/get_scores_response_trace_data.py +38 -0
- aeri/api/sessions/__init__.py +40 -0
- aeri/api/sessions/client.py +262 -0
- aeri/api/sessions/raw_client.py +500 -0
- aeri/api/sessions/types/__init__.py +40 -0
- aeri/api/sessions/types/paginated_sessions.py +17 -0
- aeri/api/trace/__init__.py +44 -0
- aeri/api/trace/client.py +728 -0
- aeri/api/trace/raw_client.py +1208 -0
- aeri/api/trace/types/__init__.py +46 -0
- aeri/api/trace/types/delete_trace_response.py +14 -0
- aeri/api/trace/types/sort.py +14 -0
- aeri/api/trace/types/traces.py +17 -0
- aeri/api/utils/__init__.py +44 -0
- aeri/api/utils/pagination/__init__.py +40 -0
- aeri/api/utils/pagination/types/__init__.py +40 -0
- aeri/api/utils/pagination/types/meta_response.py +38 -0
- aeri/batch_evaluation.py +1643 -0
- aeri/experiment.py +1044 -0
- aeri/langchain/CallbackHandler.py +1377 -0
- aeri/langchain/__init__.py +5 -0
- aeri/langchain/utils.py +212 -0
- aeri/logger.py +28 -0
- aeri/media.py +352 -0
- aeri/model.py +477 -0
- aeri/openai.py +1124 -0
- aeri/py.typed +0 -0
- aeri/span_filter.py +17 -0
- aeri/types.py +79 -0
- aeri/version.py +3 -0
- aeri_python-4.0.0.dist-info/METADATA +51 -0
- aeri_python-4.0.0.dist-info/RECORD +391 -0
- aeri_python-4.0.0.dist-info/WHEEL +4 -0
- aeri_python-4.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,759 @@
|
|
|
1
|
+
# This file was auto-generated by Fern from our API Definition.
|
|
2
|
+
|
|
3
|
+
import datetime as dt
|
|
4
|
+
import typing
|
|
5
|
+
from json.decoder import JSONDecodeError
|
|
6
|
+
|
|
7
|
+
from ...commons.errors.access_denied_error import AccessDeniedError
|
|
8
|
+
from ...commons.errors.error import Error
|
|
9
|
+
from ...commons.errors.method_not_allowed_error import MethodNotAllowedError
|
|
10
|
+
from ...commons.errors.not_found_error import NotFoundError
|
|
11
|
+
from ...commons.errors.unauthorized_error import UnauthorizedError
|
|
12
|
+
from ...commons.types.observation_level import ObservationLevel
|
|
13
|
+
from ...commons.types.observations_view import ObservationsView
|
|
14
|
+
from ...core.api_error import ApiError
|
|
15
|
+
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
|
|
16
|
+
from ...core.datetime_utils import serialize_datetime
|
|
17
|
+
from ...core.http_response import AsyncHttpResponse, HttpResponse
|
|
18
|
+
from ...core.jsonable_encoder import jsonable_encoder
|
|
19
|
+
from ...core.pydantic_utilities import parse_obj_as
|
|
20
|
+
from ...core.request_options import RequestOptions
|
|
21
|
+
from .types.observations_views import ObservationsViews
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class RawObservationsV1Client:
|
|
25
|
+
def __init__(self, *, client_wrapper: SyncClientWrapper):
|
|
26
|
+
self._client_wrapper = client_wrapper
|
|
27
|
+
|
|
28
|
+
def get(
|
|
29
|
+
self,
|
|
30
|
+
observation_id: str,
|
|
31
|
+
*,
|
|
32
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
33
|
+
) -> HttpResponse[ObservationsView]:
|
|
34
|
+
"""
|
|
35
|
+
Get a observation
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
observation_id : str
|
|
40
|
+
The unique aeri identifier of an observation, can be an event, span or generation
|
|
41
|
+
|
|
42
|
+
request_options : typing.Optional[RequestOptions]
|
|
43
|
+
Request-specific configuration.
|
|
44
|
+
|
|
45
|
+
Returns
|
|
46
|
+
-------
|
|
47
|
+
HttpResponse[ObservationsView]
|
|
48
|
+
"""
|
|
49
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
50
|
+
f"api/public/observations/{jsonable_encoder(observation_id)}",
|
|
51
|
+
method="GET",
|
|
52
|
+
request_options=request_options,
|
|
53
|
+
)
|
|
54
|
+
try:
|
|
55
|
+
if 200 <= _response.status_code < 300:
|
|
56
|
+
_data = typing.cast(
|
|
57
|
+
ObservationsView,
|
|
58
|
+
parse_obj_as(
|
|
59
|
+
type_=ObservationsView, # type: ignore
|
|
60
|
+
object_=_response.json(),
|
|
61
|
+
),
|
|
62
|
+
)
|
|
63
|
+
return HttpResponse(response=_response, data=_data)
|
|
64
|
+
if _response.status_code == 400:
|
|
65
|
+
raise Error(
|
|
66
|
+
headers=dict(_response.headers),
|
|
67
|
+
body=typing.cast(
|
|
68
|
+
typing.Any,
|
|
69
|
+
parse_obj_as(
|
|
70
|
+
type_=typing.Any, # type: ignore
|
|
71
|
+
object_=_response.json(),
|
|
72
|
+
),
|
|
73
|
+
),
|
|
74
|
+
)
|
|
75
|
+
if _response.status_code == 401:
|
|
76
|
+
raise UnauthorizedError(
|
|
77
|
+
headers=dict(_response.headers),
|
|
78
|
+
body=typing.cast(
|
|
79
|
+
typing.Any,
|
|
80
|
+
parse_obj_as(
|
|
81
|
+
type_=typing.Any, # type: ignore
|
|
82
|
+
object_=_response.json(),
|
|
83
|
+
),
|
|
84
|
+
),
|
|
85
|
+
)
|
|
86
|
+
if _response.status_code == 403:
|
|
87
|
+
raise AccessDeniedError(
|
|
88
|
+
headers=dict(_response.headers),
|
|
89
|
+
body=typing.cast(
|
|
90
|
+
typing.Any,
|
|
91
|
+
parse_obj_as(
|
|
92
|
+
type_=typing.Any, # type: ignore
|
|
93
|
+
object_=_response.json(),
|
|
94
|
+
),
|
|
95
|
+
),
|
|
96
|
+
)
|
|
97
|
+
if _response.status_code == 405:
|
|
98
|
+
raise MethodNotAllowedError(
|
|
99
|
+
headers=dict(_response.headers),
|
|
100
|
+
body=typing.cast(
|
|
101
|
+
typing.Any,
|
|
102
|
+
parse_obj_as(
|
|
103
|
+
type_=typing.Any, # type: ignore
|
|
104
|
+
object_=_response.json(),
|
|
105
|
+
),
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
if _response.status_code == 404:
|
|
109
|
+
raise NotFoundError(
|
|
110
|
+
headers=dict(_response.headers),
|
|
111
|
+
body=typing.cast(
|
|
112
|
+
typing.Any,
|
|
113
|
+
parse_obj_as(
|
|
114
|
+
type_=typing.Any, # type: ignore
|
|
115
|
+
object_=_response.json(),
|
|
116
|
+
),
|
|
117
|
+
),
|
|
118
|
+
)
|
|
119
|
+
_response_json = _response.json()
|
|
120
|
+
except JSONDecodeError:
|
|
121
|
+
raise ApiError(
|
|
122
|
+
status_code=_response.status_code,
|
|
123
|
+
headers=dict(_response.headers),
|
|
124
|
+
body=_response.text,
|
|
125
|
+
)
|
|
126
|
+
raise ApiError(
|
|
127
|
+
status_code=_response.status_code,
|
|
128
|
+
headers=dict(_response.headers),
|
|
129
|
+
body=_response_json,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def get_many(
|
|
133
|
+
self,
|
|
134
|
+
*,
|
|
135
|
+
page: typing.Optional[int] = None,
|
|
136
|
+
limit: typing.Optional[int] = None,
|
|
137
|
+
name: typing.Optional[str] = None,
|
|
138
|
+
user_id: typing.Optional[str] = None,
|
|
139
|
+
type: typing.Optional[str] = None,
|
|
140
|
+
trace_id: typing.Optional[str] = None,
|
|
141
|
+
level: typing.Optional[ObservationLevel] = None,
|
|
142
|
+
parent_observation_id: typing.Optional[str] = None,
|
|
143
|
+
environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
|
|
144
|
+
from_start_time: typing.Optional[dt.datetime] = None,
|
|
145
|
+
to_start_time: typing.Optional[dt.datetime] = None,
|
|
146
|
+
version: typing.Optional[str] = None,
|
|
147
|
+
filter: typing.Optional[str] = None,
|
|
148
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
149
|
+
) -> HttpResponse[ObservationsViews]:
|
|
150
|
+
"""
|
|
151
|
+
Get a list of observations.
|
|
152
|
+
|
|
153
|
+
Consider using the [v2 observations endpoint](/api-reference#tag/observationsv2/GET/api/public/v2/observations) for cursor-based pagination and field selection.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
page : typing.Optional[int]
|
|
158
|
+
Page number, starts at 1.
|
|
159
|
+
|
|
160
|
+
limit : typing.Optional[int]
|
|
161
|
+
Limit of items per page. If you encounter api issues due to too large page sizes, try to reduce the limit.
|
|
162
|
+
|
|
163
|
+
name : typing.Optional[str]
|
|
164
|
+
|
|
165
|
+
user_id : typing.Optional[str]
|
|
166
|
+
|
|
167
|
+
type : typing.Optional[str]
|
|
168
|
+
|
|
169
|
+
trace_id : typing.Optional[str]
|
|
170
|
+
|
|
171
|
+
level : typing.Optional[ObservationLevel]
|
|
172
|
+
Optional filter for observations with a specific level (e.g. "DEBUG", "DEFAULT", "WARNING", "ERROR").
|
|
173
|
+
|
|
174
|
+
parent_observation_id : typing.Optional[str]
|
|
175
|
+
|
|
176
|
+
environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
|
|
177
|
+
Optional filter for observations where the environment is one of the provided values.
|
|
178
|
+
|
|
179
|
+
from_start_time : typing.Optional[dt.datetime]
|
|
180
|
+
Retrieve only observations with a start_time on or after this datetime (ISO 8601).
|
|
181
|
+
|
|
182
|
+
to_start_time : typing.Optional[dt.datetime]
|
|
183
|
+
Retrieve only observations with a start_time before this datetime (ISO 8601).
|
|
184
|
+
|
|
185
|
+
version : typing.Optional[str]
|
|
186
|
+
Optional filter to only include observations with a certain version.
|
|
187
|
+
|
|
188
|
+
filter : typing.Optional[str]
|
|
189
|
+
JSON string containing an array of filter conditions. When provided, this takes precedence over query parameter filters (userId, name, type, level, environment, fromStartTime, ...).
|
|
190
|
+
|
|
191
|
+
## Filter Structure
|
|
192
|
+
Each filter condition has the following structure:
|
|
193
|
+
```json
|
|
194
|
+
[
|
|
195
|
+
{
|
|
196
|
+
"type": string, // Required. One of: "datetime", "string", "number", "stringOptions", "categoryOptions", "arrayOptions", "stringObject", "numberObject", "boolean", "null"
|
|
197
|
+
"column": string, // Required. Column to filter on (see available columns below)
|
|
198
|
+
"operator": string, // Required. Operator based on type:
|
|
199
|
+
// - datetime: ">", "<", ">=", "<="
|
|
200
|
+
// - string: "=", "contains", "does not contain", "starts with", "ends with"
|
|
201
|
+
// - stringOptions: "any of", "none of"
|
|
202
|
+
// - categoryOptions: "any of", "none of"
|
|
203
|
+
// - arrayOptions: "any of", "none of", "all of"
|
|
204
|
+
// - number: "=", ">", "<", ">=", "<="
|
|
205
|
+
// - stringObject: "=", "contains", "does not contain", "starts with", "ends with"
|
|
206
|
+
// - numberObject: "=", ">", "<", ">=", "<="
|
|
207
|
+
// - boolean: "=", "<>"
|
|
208
|
+
// - null: "is null", "is not null"
|
|
209
|
+
"value": any, // Required (except for null type). Value to compare against. Type depends on filter type
|
|
210
|
+
"key": string // Required only for stringObject, numberObject, and categoryOptions types when filtering on nested fields like metadata
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Available Columns
|
|
216
|
+
|
|
217
|
+
### Core Observation Fields
|
|
218
|
+
- `id` (string) - Observation ID
|
|
219
|
+
- `type` (string) - Observation type (SPAN, GENERATION, EVENT)
|
|
220
|
+
- `name` (string) - Observation name
|
|
221
|
+
- `traceId` (string) - Associated trace ID
|
|
222
|
+
- `startTime` (datetime) - Observation start time
|
|
223
|
+
- `endTime` (datetime) - Observation end time
|
|
224
|
+
- `environment` (string) - Environment tag
|
|
225
|
+
- `level` (string) - Log level (DEBUG, DEFAULT, WARNING, ERROR)
|
|
226
|
+
- `statusMessage` (string) - Status message
|
|
227
|
+
- `version` (string) - Version tag
|
|
228
|
+
|
|
229
|
+
### Performance Metrics
|
|
230
|
+
- `latency` (number) - Latency in seconds (calculated: end_time - start_time)
|
|
231
|
+
- `timeToFirstToken` (number) - Time to first token in seconds
|
|
232
|
+
- `tokensPerSecond` (number) - Output tokens per second
|
|
233
|
+
|
|
234
|
+
### Token Usage
|
|
235
|
+
- `inputTokens` (number) - Number of input tokens
|
|
236
|
+
- `outputTokens` (number) - Number of output tokens
|
|
237
|
+
- `totalTokens` (number) - Total tokens (alias: `tokens`)
|
|
238
|
+
|
|
239
|
+
### Cost Metrics
|
|
240
|
+
- `inputCost` (number) - Input cost in USD
|
|
241
|
+
- `outputCost` (number) - Output cost in USD
|
|
242
|
+
- `totalCost` (number) - Total cost in USD
|
|
243
|
+
|
|
244
|
+
### Model Information
|
|
245
|
+
- `model` (string) - Provided model name
|
|
246
|
+
- `promptName` (string) - Associated prompt name
|
|
247
|
+
- `promptVersion` (number) - Associated prompt version
|
|
248
|
+
|
|
249
|
+
### Structured Data
|
|
250
|
+
- `metadata` (stringObject/numberObject/categoryOptions) - Metadata key-value pairs. Use `key` parameter to filter on specific metadata keys.
|
|
251
|
+
|
|
252
|
+
### Associated Trace Fields (requires join with traces table)
|
|
253
|
+
- `userId` (string) - User ID from associated trace
|
|
254
|
+
- `traceName` (string) - Name from associated trace
|
|
255
|
+
- `traceEnvironment` (string) - Environment from associated trace
|
|
256
|
+
- `traceTags` (arrayOptions) - Tags from associated trace
|
|
257
|
+
|
|
258
|
+
## Filter Examples
|
|
259
|
+
```json
|
|
260
|
+
[
|
|
261
|
+
{
|
|
262
|
+
"type": "string",
|
|
263
|
+
"column": "type",
|
|
264
|
+
"operator": "=",
|
|
265
|
+
"value": "GENERATION"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"type": "number",
|
|
269
|
+
"column": "latency",
|
|
270
|
+
"operator": ">=",
|
|
271
|
+
"value": 2.5
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"type": "stringObject",
|
|
275
|
+
"column": "metadata",
|
|
276
|
+
"key": "environment",
|
|
277
|
+
"operator": "=",
|
|
278
|
+
"value": "production"
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
request_options : typing.Optional[RequestOptions]
|
|
284
|
+
Request-specific configuration.
|
|
285
|
+
|
|
286
|
+
Returns
|
|
287
|
+
-------
|
|
288
|
+
HttpResponse[ObservationsViews]
|
|
289
|
+
"""
|
|
290
|
+
_response = self._client_wrapper.httpx_client.request(
|
|
291
|
+
"api/public/observations",
|
|
292
|
+
method="GET",
|
|
293
|
+
params={
|
|
294
|
+
"page": page,
|
|
295
|
+
"limit": limit,
|
|
296
|
+
"name": name,
|
|
297
|
+
"userId": user_id,
|
|
298
|
+
"type": type,
|
|
299
|
+
"traceId": trace_id,
|
|
300
|
+
"level": level,
|
|
301
|
+
"parentObservationId": parent_observation_id,
|
|
302
|
+
"environment": environment,
|
|
303
|
+
"fromStartTime": serialize_datetime(from_start_time)
|
|
304
|
+
if from_start_time is not None
|
|
305
|
+
else None,
|
|
306
|
+
"toStartTime": serialize_datetime(to_start_time)
|
|
307
|
+
if to_start_time is not None
|
|
308
|
+
else None,
|
|
309
|
+
"version": version,
|
|
310
|
+
"filter": filter,
|
|
311
|
+
},
|
|
312
|
+
request_options=request_options,
|
|
313
|
+
)
|
|
314
|
+
try:
|
|
315
|
+
if 200 <= _response.status_code < 300:
|
|
316
|
+
_data = typing.cast(
|
|
317
|
+
ObservationsViews,
|
|
318
|
+
parse_obj_as(
|
|
319
|
+
type_=ObservationsViews, # type: ignore
|
|
320
|
+
object_=_response.json(),
|
|
321
|
+
),
|
|
322
|
+
)
|
|
323
|
+
return HttpResponse(response=_response, data=_data)
|
|
324
|
+
if _response.status_code == 400:
|
|
325
|
+
raise Error(
|
|
326
|
+
headers=dict(_response.headers),
|
|
327
|
+
body=typing.cast(
|
|
328
|
+
typing.Any,
|
|
329
|
+
parse_obj_as(
|
|
330
|
+
type_=typing.Any, # type: ignore
|
|
331
|
+
object_=_response.json(),
|
|
332
|
+
),
|
|
333
|
+
),
|
|
334
|
+
)
|
|
335
|
+
if _response.status_code == 401:
|
|
336
|
+
raise UnauthorizedError(
|
|
337
|
+
headers=dict(_response.headers),
|
|
338
|
+
body=typing.cast(
|
|
339
|
+
typing.Any,
|
|
340
|
+
parse_obj_as(
|
|
341
|
+
type_=typing.Any, # type: ignore
|
|
342
|
+
object_=_response.json(),
|
|
343
|
+
),
|
|
344
|
+
),
|
|
345
|
+
)
|
|
346
|
+
if _response.status_code == 403:
|
|
347
|
+
raise AccessDeniedError(
|
|
348
|
+
headers=dict(_response.headers),
|
|
349
|
+
body=typing.cast(
|
|
350
|
+
typing.Any,
|
|
351
|
+
parse_obj_as(
|
|
352
|
+
type_=typing.Any, # type: ignore
|
|
353
|
+
object_=_response.json(),
|
|
354
|
+
),
|
|
355
|
+
),
|
|
356
|
+
)
|
|
357
|
+
if _response.status_code == 405:
|
|
358
|
+
raise MethodNotAllowedError(
|
|
359
|
+
headers=dict(_response.headers),
|
|
360
|
+
body=typing.cast(
|
|
361
|
+
typing.Any,
|
|
362
|
+
parse_obj_as(
|
|
363
|
+
type_=typing.Any, # type: ignore
|
|
364
|
+
object_=_response.json(),
|
|
365
|
+
),
|
|
366
|
+
),
|
|
367
|
+
)
|
|
368
|
+
if _response.status_code == 404:
|
|
369
|
+
raise NotFoundError(
|
|
370
|
+
headers=dict(_response.headers),
|
|
371
|
+
body=typing.cast(
|
|
372
|
+
typing.Any,
|
|
373
|
+
parse_obj_as(
|
|
374
|
+
type_=typing.Any, # type: ignore
|
|
375
|
+
object_=_response.json(),
|
|
376
|
+
),
|
|
377
|
+
),
|
|
378
|
+
)
|
|
379
|
+
_response_json = _response.json()
|
|
380
|
+
except JSONDecodeError:
|
|
381
|
+
raise ApiError(
|
|
382
|
+
status_code=_response.status_code,
|
|
383
|
+
headers=dict(_response.headers),
|
|
384
|
+
body=_response.text,
|
|
385
|
+
)
|
|
386
|
+
raise ApiError(
|
|
387
|
+
status_code=_response.status_code,
|
|
388
|
+
headers=dict(_response.headers),
|
|
389
|
+
body=_response_json,
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
class AsyncRawObservationsV1Client:
|
|
394
|
+
def __init__(self, *, client_wrapper: AsyncClientWrapper):
|
|
395
|
+
self._client_wrapper = client_wrapper
|
|
396
|
+
|
|
397
|
+
async def get(
|
|
398
|
+
self,
|
|
399
|
+
observation_id: str,
|
|
400
|
+
*,
|
|
401
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
402
|
+
) -> AsyncHttpResponse[ObservationsView]:
|
|
403
|
+
"""
|
|
404
|
+
Get a observation
|
|
405
|
+
|
|
406
|
+
Parameters
|
|
407
|
+
----------
|
|
408
|
+
observation_id : str
|
|
409
|
+
The unique aeri identifier of an observation, can be an event, span or generation
|
|
410
|
+
|
|
411
|
+
request_options : typing.Optional[RequestOptions]
|
|
412
|
+
Request-specific configuration.
|
|
413
|
+
|
|
414
|
+
Returns
|
|
415
|
+
-------
|
|
416
|
+
AsyncHttpResponse[ObservationsView]
|
|
417
|
+
"""
|
|
418
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
419
|
+
f"api/public/observations/{jsonable_encoder(observation_id)}",
|
|
420
|
+
method="GET",
|
|
421
|
+
request_options=request_options,
|
|
422
|
+
)
|
|
423
|
+
try:
|
|
424
|
+
if 200 <= _response.status_code < 300:
|
|
425
|
+
_data = typing.cast(
|
|
426
|
+
ObservationsView,
|
|
427
|
+
parse_obj_as(
|
|
428
|
+
type_=ObservationsView, # type: ignore
|
|
429
|
+
object_=_response.json(),
|
|
430
|
+
),
|
|
431
|
+
)
|
|
432
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
433
|
+
if _response.status_code == 400:
|
|
434
|
+
raise Error(
|
|
435
|
+
headers=dict(_response.headers),
|
|
436
|
+
body=typing.cast(
|
|
437
|
+
typing.Any,
|
|
438
|
+
parse_obj_as(
|
|
439
|
+
type_=typing.Any, # type: ignore
|
|
440
|
+
object_=_response.json(),
|
|
441
|
+
),
|
|
442
|
+
),
|
|
443
|
+
)
|
|
444
|
+
if _response.status_code == 401:
|
|
445
|
+
raise UnauthorizedError(
|
|
446
|
+
headers=dict(_response.headers),
|
|
447
|
+
body=typing.cast(
|
|
448
|
+
typing.Any,
|
|
449
|
+
parse_obj_as(
|
|
450
|
+
type_=typing.Any, # type: ignore
|
|
451
|
+
object_=_response.json(),
|
|
452
|
+
),
|
|
453
|
+
),
|
|
454
|
+
)
|
|
455
|
+
if _response.status_code == 403:
|
|
456
|
+
raise AccessDeniedError(
|
|
457
|
+
headers=dict(_response.headers),
|
|
458
|
+
body=typing.cast(
|
|
459
|
+
typing.Any,
|
|
460
|
+
parse_obj_as(
|
|
461
|
+
type_=typing.Any, # type: ignore
|
|
462
|
+
object_=_response.json(),
|
|
463
|
+
),
|
|
464
|
+
),
|
|
465
|
+
)
|
|
466
|
+
if _response.status_code == 405:
|
|
467
|
+
raise MethodNotAllowedError(
|
|
468
|
+
headers=dict(_response.headers),
|
|
469
|
+
body=typing.cast(
|
|
470
|
+
typing.Any,
|
|
471
|
+
parse_obj_as(
|
|
472
|
+
type_=typing.Any, # type: ignore
|
|
473
|
+
object_=_response.json(),
|
|
474
|
+
),
|
|
475
|
+
),
|
|
476
|
+
)
|
|
477
|
+
if _response.status_code == 404:
|
|
478
|
+
raise NotFoundError(
|
|
479
|
+
headers=dict(_response.headers),
|
|
480
|
+
body=typing.cast(
|
|
481
|
+
typing.Any,
|
|
482
|
+
parse_obj_as(
|
|
483
|
+
type_=typing.Any, # type: ignore
|
|
484
|
+
object_=_response.json(),
|
|
485
|
+
),
|
|
486
|
+
),
|
|
487
|
+
)
|
|
488
|
+
_response_json = _response.json()
|
|
489
|
+
except JSONDecodeError:
|
|
490
|
+
raise ApiError(
|
|
491
|
+
status_code=_response.status_code,
|
|
492
|
+
headers=dict(_response.headers),
|
|
493
|
+
body=_response.text,
|
|
494
|
+
)
|
|
495
|
+
raise ApiError(
|
|
496
|
+
status_code=_response.status_code,
|
|
497
|
+
headers=dict(_response.headers),
|
|
498
|
+
body=_response_json,
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
async def get_many(
|
|
502
|
+
self,
|
|
503
|
+
*,
|
|
504
|
+
page: typing.Optional[int] = None,
|
|
505
|
+
limit: typing.Optional[int] = None,
|
|
506
|
+
name: typing.Optional[str] = None,
|
|
507
|
+
user_id: typing.Optional[str] = None,
|
|
508
|
+
type: typing.Optional[str] = None,
|
|
509
|
+
trace_id: typing.Optional[str] = None,
|
|
510
|
+
level: typing.Optional[ObservationLevel] = None,
|
|
511
|
+
parent_observation_id: typing.Optional[str] = None,
|
|
512
|
+
environment: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
|
|
513
|
+
from_start_time: typing.Optional[dt.datetime] = None,
|
|
514
|
+
to_start_time: typing.Optional[dt.datetime] = None,
|
|
515
|
+
version: typing.Optional[str] = None,
|
|
516
|
+
filter: typing.Optional[str] = None,
|
|
517
|
+
request_options: typing.Optional[RequestOptions] = None,
|
|
518
|
+
) -> AsyncHttpResponse[ObservationsViews]:
|
|
519
|
+
"""
|
|
520
|
+
Get a list of observations.
|
|
521
|
+
|
|
522
|
+
Consider using the [v2 observations endpoint](/api-reference#tag/observationsv2/GET/api/public/v2/observations) for cursor-based pagination and field selection.
|
|
523
|
+
|
|
524
|
+
Parameters
|
|
525
|
+
----------
|
|
526
|
+
page : typing.Optional[int]
|
|
527
|
+
Page number, starts at 1.
|
|
528
|
+
|
|
529
|
+
limit : typing.Optional[int]
|
|
530
|
+
Limit of items per page. If you encounter api issues due to too large page sizes, try to reduce the limit.
|
|
531
|
+
|
|
532
|
+
name : typing.Optional[str]
|
|
533
|
+
|
|
534
|
+
user_id : typing.Optional[str]
|
|
535
|
+
|
|
536
|
+
type : typing.Optional[str]
|
|
537
|
+
|
|
538
|
+
trace_id : typing.Optional[str]
|
|
539
|
+
|
|
540
|
+
level : typing.Optional[ObservationLevel]
|
|
541
|
+
Optional filter for observations with a specific level (e.g. "DEBUG", "DEFAULT", "WARNING", "ERROR").
|
|
542
|
+
|
|
543
|
+
parent_observation_id : typing.Optional[str]
|
|
544
|
+
|
|
545
|
+
environment : typing.Optional[typing.Union[str, typing.Sequence[str]]]
|
|
546
|
+
Optional filter for observations where the environment is one of the provided values.
|
|
547
|
+
|
|
548
|
+
from_start_time : typing.Optional[dt.datetime]
|
|
549
|
+
Retrieve only observations with a start_time on or after this datetime (ISO 8601).
|
|
550
|
+
|
|
551
|
+
to_start_time : typing.Optional[dt.datetime]
|
|
552
|
+
Retrieve only observations with a start_time before this datetime (ISO 8601).
|
|
553
|
+
|
|
554
|
+
version : typing.Optional[str]
|
|
555
|
+
Optional filter to only include observations with a certain version.
|
|
556
|
+
|
|
557
|
+
filter : typing.Optional[str]
|
|
558
|
+
JSON string containing an array of filter conditions. When provided, this takes precedence over query parameter filters (userId, name, type, level, environment, fromStartTime, ...).
|
|
559
|
+
|
|
560
|
+
## Filter Structure
|
|
561
|
+
Each filter condition has the following structure:
|
|
562
|
+
```json
|
|
563
|
+
[
|
|
564
|
+
{
|
|
565
|
+
"type": string, // Required. One of: "datetime", "string", "number", "stringOptions", "categoryOptions", "arrayOptions", "stringObject", "numberObject", "boolean", "null"
|
|
566
|
+
"column": string, // Required. Column to filter on (see available columns below)
|
|
567
|
+
"operator": string, // Required. Operator based on type:
|
|
568
|
+
// - datetime: ">", "<", ">=", "<="
|
|
569
|
+
// - string: "=", "contains", "does not contain", "starts with", "ends with"
|
|
570
|
+
// - stringOptions: "any of", "none of"
|
|
571
|
+
// - categoryOptions: "any of", "none of"
|
|
572
|
+
// - arrayOptions: "any of", "none of", "all of"
|
|
573
|
+
// - number: "=", ">", "<", ">=", "<="
|
|
574
|
+
// - stringObject: "=", "contains", "does not contain", "starts with", "ends with"
|
|
575
|
+
// - numberObject: "=", ">", "<", ">=", "<="
|
|
576
|
+
// - boolean: "=", "<>"
|
|
577
|
+
// - null: "is null", "is not null"
|
|
578
|
+
"value": any, // Required (except for null type). Value to compare against. Type depends on filter type
|
|
579
|
+
"key": string // Required only for stringObject, numberObject, and categoryOptions types when filtering on nested fields like metadata
|
|
580
|
+
}
|
|
581
|
+
]
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
## Available Columns
|
|
585
|
+
|
|
586
|
+
### Core Observation Fields
|
|
587
|
+
- `id` (string) - Observation ID
|
|
588
|
+
- `type` (string) - Observation type (SPAN, GENERATION, EVENT)
|
|
589
|
+
- `name` (string) - Observation name
|
|
590
|
+
- `traceId` (string) - Associated trace ID
|
|
591
|
+
- `startTime` (datetime) - Observation start time
|
|
592
|
+
- `endTime` (datetime) - Observation end time
|
|
593
|
+
- `environment` (string) - Environment tag
|
|
594
|
+
- `level` (string) - Log level (DEBUG, DEFAULT, WARNING, ERROR)
|
|
595
|
+
- `statusMessage` (string) - Status message
|
|
596
|
+
- `version` (string) - Version tag
|
|
597
|
+
|
|
598
|
+
### Performance Metrics
|
|
599
|
+
- `latency` (number) - Latency in seconds (calculated: end_time - start_time)
|
|
600
|
+
- `timeToFirstToken` (number) - Time to first token in seconds
|
|
601
|
+
- `tokensPerSecond` (number) - Output tokens per second
|
|
602
|
+
|
|
603
|
+
### Token Usage
|
|
604
|
+
- `inputTokens` (number) - Number of input tokens
|
|
605
|
+
- `outputTokens` (number) - Number of output tokens
|
|
606
|
+
- `totalTokens` (number) - Total tokens (alias: `tokens`)
|
|
607
|
+
|
|
608
|
+
### Cost Metrics
|
|
609
|
+
- `inputCost` (number) - Input cost in USD
|
|
610
|
+
- `outputCost` (number) - Output cost in USD
|
|
611
|
+
- `totalCost` (number) - Total cost in USD
|
|
612
|
+
|
|
613
|
+
### Model Information
|
|
614
|
+
- `model` (string) - Provided model name
|
|
615
|
+
- `promptName` (string) - Associated prompt name
|
|
616
|
+
- `promptVersion` (number) - Associated prompt version
|
|
617
|
+
|
|
618
|
+
### Structured Data
|
|
619
|
+
- `metadata` (stringObject/numberObject/categoryOptions) - Metadata key-value pairs. Use `key` parameter to filter on specific metadata keys.
|
|
620
|
+
|
|
621
|
+
### Associated Trace Fields (requires join with traces table)
|
|
622
|
+
- `userId` (string) - User ID from associated trace
|
|
623
|
+
- `traceName` (string) - Name from associated trace
|
|
624
|
+
- `traceEnvironment` (string) - Environment from associated trace
|
|
625
|
+
- `traceTags` (arrayOptions) - Tags from associated trace
|
|
626
|
+
|
|
627
|
+
## Filter Examples
|
|
628
|
+
```json
|
|
629
|
+
[
|
|
630
|
+
{
|
|
631
|
+
"type": "string",
|
|
632
|
+
"column": "type",
|
|
633
|
+
"operator": "=",
|
|
634
|
+
"value": "GENERATION"
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
"type": "number",
|
|
638
|
+
"column": "latency",
|
|
639
|
+
"operator": ">=",
|
|
640
|
+
"value": 2.5
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
"type": "stringObject",
|
|
644
|
+
"column": "metadata",
|
|
645
|
+
"key": "environment",
|
|
646
|
+
"operator": "=",
|
|
647
|
+
"value": "production"
|
|
648
|
+
}
|
|
649
|
+
]
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
request_options : typing.Optional[RequestOptions]
|
|
653
|
+
Request-specific configuration.
|
|
654
|
+
|
|
655
|
+
Returns
|
|
656
|
+
-------
|
|
657
|
+
AsyncHttpResponse[ObservationsViews]
|
|
658
|
+
"""
|
|
659
|
+
_response = await self._client_wrapper.httpx_client.request(
|
|
660
|
+
"api/public/observations",
|
|
661
|
+
method="GET",
|
|
662
|
+
params={
|
|
663
|
+
"page": page,
|
|
664
|
+
"limit": limit,
|
|
665
|
+
"name": name,
|
|
666
|
+
"userId": user_id,
|
|
667
|
+
"type": type,
|
|
668
|
+
"traceId": trace_id,
|
|
669
|
+
"level": level,
|
|
670
|
+
"parentObservationId": parent_observation_id,
|
|
671
|
+
"environment": environment,
|
|
672
|
+
"fromStartTime": serialize_datetime(from_start_time)
|
|
673
|
+
if from_start_time is not None
|
|
674
|
+
else None,
|
|
675
|
+
"toStartTime": serialize_datetime(to_start_time)
|
|
676
|
+
if to_start_time is not None
|
|
677
|
+
else None,
|
|
678
|
+
"version": version,
|
|
679
|
+
"filter": filter,
|
|
680
|
+
},
|
|
681
|
+
request_options=request_options,
|
|
682
|
+
)
|
|
683
|
+
try:
|
|
684
|
+
if 200 <= _response.status_code < 300:
|
|
685
|
+
_data = typing.cast(
|
|
686
|
+
ObservationsViews,
|
|
687
|
+
parse_obj_as(
|
|
688
|
+
type_=ObservationsViews, # type: ignore
|
|
689
|
+
object_=_response.json(),
|
|
690
|
+
),
|
|
691
|
+
)
|
|
692
|
+
return AsyncHttpResponse(response=_response, data=_data)
|
|
693
|
+
if _response.status_code == 400:
|
|
694
|
+
raise Error(
|
|
695
|
+
headers=dict(_response.headers),
|
|
696
|
+
body=typing.cast(
|
|
697
|
+
typing.Any,
|
|
698
|
+
parse_obj_as(
|
|
699
|
+
type_=typing.Any, # type: ignore
|
|
700
|
+
object_=_response.json(),
|
|
701
|
+
),
|
|
702
|
+
),
|
|
703
|
+
)
|
|
704
|
+
if _response.status_code == 401:
|
|
705
|
+
raise UnauthorizedError(
|
|
706
|
+
headers=dict(_response.headers),
|
|
707
|
+
body=typing.cast(
|
|
708
|
+
typing.Any,
|
|
709
|
+
parse_obj_as(
|
|
710
|
+
type_=typing.Any, # type: ignore
|
|
711
|
+
object_=_response.json(),
|
|
712
|
+
),
|
|
713
|
+
),
|
|
714
|
+
)
|
|
715
|
+
if _response.status_code == 403:
|
|
716
|
+
raise AccessDeniedError(
|
|
717
|
+
headers=dict(_response.headers),
|
|
718
|
+
body=typing.cast(
|
|
719
|
+
typing.Any,
|
|
720
|
+
parse_obj_as(
|
|
721
|
+
type_=typing.Any, # type: ignore
|
|
722
|
+
object_=_response.json(),
|
|
723
|
+
),
|
|
724
|
+
),
|
|
725
|
+
)
|
|
726
|
+
if _response.status_code == 405:
|
|
727
|
+
raise MethodNotAllowedError(
|
|
728
|
+
headers=dict(_response.headers),
|
|
729
|
+
body=typing.cast(
|
|
730
|
+
typing.Any,
|
|
731
|
+
parse_obj_as(
|
|
732
|
+
type_=typing.Any, # type: ignore
|
|
733
|
+
object_=_response.json(),
|
|
734
|
+
),
|
|
735
|
+
),
|
|
736
|
+
)
|
|
737
|
+
if _response.status_code == 404:
|
|
738
|
+
raise NotFoundError(
|
|
739
|
+
headers=dict(_response.headers),
|
|
740
|
+
body=typing.cast(
|
|
741
|
+
typing.Any,
|
|
742
|
+
parse_obj_as(
|
|
743
|
+
type_=typing.Any, # type: ignore
|
|
744
|
+
object_=_response.json(),
|
|
745
|
+
),
|
|
746
|
+
),
|
|
747
|
+
)
|
|
748
|
+
_response_json = _response.json()
|
|
749
|
+
except JSONDecodeError:
|
|
750
|
+
raise ApiError(
|
|
751
|
+
status_code=_response.status_code,
|
|
752
|
+
headers=dict(_response.headers),
|
|
753
|
+
body=_response.text,
|
|
754
|
+
)
|
|
755
|
+
raise ApiError(
|
|
756
|
+
status_code=_response.status_code,
|
|
757
|
+
headers=dict(_response.headers),
|
|
758
|
+
body=_response_json,
|
|
759
|
+
)
|