honeycomb-api 0.1.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.
- honeycomb/__init__.py +217 -0
- honeycomb/_generated/__init__.py +8 -0
- honeycomb/_generated/api/__init__.py +1 -0
- honeycomb/_generated/api/auth/__init__.py +0 -0
- honeycomb/_generated/api/auth/get_auth.py +172 -0
- honeycomb/_generated/api/auth/get_v2_auth.py +168 -0
- honeycomb/_generated/api/boards/__init__.py +0 -0
- honeycomb/_generated/api/boards/create_board.py +217 -0
- honeycomb/_generated/api/boards/create_board_view.py +237 -0
- honeycomb/_generated/api/boards/delete_board.py +191 -0
- honeycomb/_generated/api/boards/delete_board_view.py +210 -0
- honeycomb/_generated/api/boards/get_board.py +208 -0
- honeycomb/_generated/api/boards/get_board_view.py +214 -0
- honeycomb/_generated/api/boards/list_board_views.py +206 -0
- honeycomb/_generated/api/boards/list_boards.py +177 -0
- honeycomb/_generated/api/boards/update_board.py +238 -0
- honeycomb/_generated/api/boards/update_board_view.py +250 -0
- honeycomb/_generated/api/burn_alerts/__init__.py +0 -0
- honeycomb/_generated/api/burn_alerts/create_burn_alert.py +224 -0
- honeycomb/_generated/api/burn_alerts/delete_burn_alert.py +204 -0
- honeycomb/_generated/api/burn_alerts/get_burn_alert.py +208 -0
- honeycomb/_generated/api/burn_alerts/list_burn_alerts_by_slo.py +220 -0
- honeycomb/_generated/api/calculated_fields/__init__.py +0 -0
- honeycomb/_generated/api/calculated_fields/create_calculated_field.py +239 -0
- honeycomb/_generated/api/calculated_fields/delete_calculated_field.py +225 -0
- honeycomb/_generated/api/calculated_fields/get_calculated_field.py +207 -0
- honeycomb/_generated/api/calculated_fields/list_calculated_fields.py +252 -0
- honeycomb/_generated/api/calculated_fields/update_calculated_field.py +242 -0
- honeycomb/_generated/api/columns/__init__.py +0 -0
- honeycomb/_generated/api/columns/create_column.py +241 -0
- honeycomb/_generated/api/columns/delete_column.py +221 -0
- honeycomb/_generated/api/columns/get_column.py +206 -0
- honeycomb/_generated/api/columns/list_columns.py +256 -0
- honeycomb/_generated/api/columns/update_column.py +242 -0
- honeycomb/_generated/api/dataset_definitions/__init__.py +0 -0
- honeycomb/_generated/api/dataset_definitions/list_dataset_definitions.py +193 -0
- honeycomb/_generated/api/dataset_definitions/patch_dataset_definitions.py +235 -0
- honeycomb/_generated/api/datasets/__init__.py +0 -0
- honeycomb/_generated/api/datasets/create_dataset.py +227 -0
- honeycomb/_generated/api/datasets/delete_dataset.py +251 -0
- honeycomb/_generated/api/datasets/get_dataset.py +195 -0
- honeycomb/_generated/api/datasets/list_datasets.py +177 -0
- honeycomb/_generated/api/datasets/update_dataset.py +217 -0
- honeycomb/_generated/api/enhance/__init__.py +0 -0
- honeycomb/_generated/api/enhance/record_enhance_indexer_usage.py +231 -0
- honeycomb/_generated/api/environments/__init__.py +0 -0
- honeycomb/_generated/api/environments/create_environment.py +247 -0
- honeycomb/_generated/api/environments/delete_environment.py +245 -0
- honeycomb/_generated/api/environments/get_environment.py +213 -0
- honeycomb/_generated/api/environments/list_environments.py +245 -0
- honeycomb/_generated/api/environments/update_environment.py +254 -0
- honeycomb/_generated/api/events/__init__.py +0 -0
- honeycomb/_generated/api/events/create_event.py +269 -0
- honeycomb/_generated/api/events/create_events.py +314 -0
- honeycomb/_generated/api/key_management/__init__.py +0 -0
- honeycomb/_generated/api/key_management/create_api_key.py +286 -0
- honeycomb/_generated/api/key_management/delete_api_key.py +223 -0
- honeycomb/_generated/api/key_management/get_api_key.py +225 -0
- honeycomb/_generated/api/key_management/list_api_keys.py +281 -0
- honeycomb/_generated/api/key_management/update_api_key.py +270 -0
- honeycomb/_generated/api/kinesis_events/__init__.py +0 -0
- honeycomb/_generated/api/kinesis_events/create_kinesis_events.py +220 -0
- honeycomb/_generated/api/marker_settings/__init__.py +0 -0
- honeycomb/_generated/api/marker_settings/create_marker_setting.py +209 -0
- honeycomb/_generated/api/marker_settings/delete_marker_settings.py +194 -0
- honeycomb/_generated/api/marker_settings/list_marker_settings.py +186 -0
- honeycomb/_generated/api/marker_settings/update_marker_settings.py +230 -0
- honeycomb/_generated/api/markers/__init__.py +0 -0
- honeycomb/_generated/api/markers/create_marker.py +220 -0
- honeycomb/_generated/api/markers/create_marker_v2.py +253 -0
- honeycomb/_generated/api/markers/delete_marker.py +200 -0
- honeycomb/_generated/api/markers/get_marker.py +194 -0
- honeycomb/_generated/api/markers/update_marker.py +233 -0
- honeycomb/_generated/api/markers/update_marker_v2.py +262 -0
- honeycomb/_generated/api/pipelines/__init__.py +0 -0
- honeycomb/_generated/api/pipelines/get_pipeline_configuration.py +306 -0
- honeycomb/_generated/api/pipelines/record_pipeline_usage.py +244 -0
- honeycomb/_generated/api/pipelines/update_pipeline_configuration_rollout.py +261 -0
- honeycomb/_generated/api/queries/__init__.py +0 -0
- honeycomb/_generated/api/queries/create_query.py +224 -0
- honeycomb/_generated/api/queries/get_query.py +208 -0
- honeycomb/_generated/api/query_annotations/__init__.py +0 -0
- honeycomb/_generated/api/query_annotations/create_query_annotation.py +226 -0
- honeycomb/_generated/api/query_annotations/delete_query_annotation.py +198 -0
- honeycomb/_generated/api/query_annotations/get_query_annotation.py +202 -0
- honeycomb/_generated/api/query_annotations/list_query_annotations.py +217 -0
- honeycomb/_generated/api/query_annotations/update_query_annotation.py +237 -0
- honeycomb/_generated/api/query_data/__init__.py +0 -0
- honeycomb/_generated/api/query_data/create_query_result.py +247 -0
- honeycomb/_generated/api/query_data/get_query_result.py +208 -0
- honeycomb/_generated/api/recipients/__init__.py +0 -0
- honeycomb/_generated/api/recipients/create_recipient.py +317 -0
- honeycomb/_generated/api/recipients/delete_recipient.py +199 -0
- honeycomb/_generated/api/recipients/get_recipient.py +252 -0
- honeycomb/_generated/api/recipients/list_recipients.py +230 -0
- honeycomb/_generated/api/recipients/update_recipient.py +323 -0
- honeycomb/_generated/api/reporting/__init__.py +0 -0
- honeycomb/_generated/api/reporting/get_slo_history.py +218 -0
- honeycomb/_generated/api/service_maps/__init__.py +0 -0
- honeycomb/_generated/api/service_maps/create_map_dependency_request.py +252 -0
- honeycomb/_generated/api/service_maps/get_map_dependencies.py +265 -0
- honeycomb/_generated/api/sl_os/__init__.py +0 -0
- honeycomb/_generated/api/sl_os/create_slo.py +229 -0
- honeycomb/_generated/api/sl_os/delete_slo.py +210 -0
- honeycomb/_generated/api/sl_os/get_slo.py +256 -0
- honeycomb/_generated/api/sl_os/list_slos.py +210 -0
- honeycomb/_generated/api/sl_os/update_slo.py +242 -0
- honeycomb/_generated/api/triggers/__init__.py +0 -0
- honeycomb/_generated/api/triggers/create_trigger.py +250 -0
- honeycomb/_generated/api/triggers/delete_trigger.py +204 -0
- honeycomb/_generated/api/triggers/get_trigger.py +214 -0
- honeycomb/_generated/api/triggers/list_triggers.py +206 -0
- honeycomb/_generated/api/triggers/list_triggers_with_recipient.py +208 -0
- honeycomb/_generated/api/triggers/update_trigger.py +248 -0
- honeycomb/_generated/client.py +271 -0
- honeycomb/_generated/errors.py +14 -0
- honeycomb/_generated/models/__init__.py +561 -0
- honeycomb/_generated/models/api_key_create_request.py +78 -0
- honeycomb/_generated/models/api_key_create_request_data.py +130 -0
- honeycomb/_generated/models/api_key_create_request_data_relationships.py +78 -0
- honeycomb/_generated/models/api_key_create_request_data_type.py +7 -0
- honeycomb/_generated/models/api_key_list_response.py +112 -0
- honeycomb/_generated/models/api_key_object.py +189 -0
- honeycomb/_generated/models/api_key_object_links.py +74 -0
- honeycomb/_generated/models/api_key_object_relationships.py +150 -0
- honeycomb/_generated/models/api_key_object_type.py +7 -0
- honeycomb/_generated/models/api_key_response.py +78 -0
- honeycomb/_generated/models/api_key_update_request.py +104 -0
- honeycomb/_generated/models/auth.py +140 -0
- honeycomb/_generated/models/auth_api_key_access.py +154 -0
- honeycomb/_generated/models/auth_environment.py +82 -0
- honeycomb/_generated/models/auth_team.py +82 -0
- honeycomb/_generated/models/auth_type.py +8 -0
- honeycomb/_generated/models/auth_v2_response.py +108 -0
- honeycomb/_generated/models/auth_v2_response_data.py +122 -0
- honeycomb/_generated/models/auth_v2_response_data_attributes.py +141 -0
- honeycomb/_generated/models/auth_v2_response_data_attributes_key_type.py +7 -0
- honeycomb/_generated/models/auth_v2_response_data_attributes_timestamps.py +107 -0
- honeycomb/_generated/models/auth_v2_response_data_relationships.py +59 -0
- honeycomb/_generated/models/auth_v2_response_data_type.py +7 -0
- honeycomb/_generated/models/base_trigger.py +367 -0
- honeycomb/_generated/models/base_trigger_alert_type.py +8 -0
- honeycomb/_generated/models/base_trigger_baseline_details_type_0.py +92 -0
- honeycomb/_generated/models/base_trigger_baseline_details_type_0_offset_minutes.py +10 -0
- honeycomb/_generated/models/base_trigger_baseline_details_type_0_type.py +8 -0
- honeycomb/_generated/models/base_trigger_evaluation_schedule.py +83 -0
- honeycomb/_generated/models/base_trigger_evaluation_schedule_type.py +8 -0
- honeycomb/_generated/models/base_trigger_evaluation_schedule_window.py +103 -0
- honeycomb/_generated/models/base_trigger_evaluation_schedule_window_days_of_week_item.py +13 -0
- honeycomb/_generated/models/base_trigger_threshold.py +95 -0
- honeycomb/_generated/models/base_trigger_threshold_op.py +10 -0
- honeycomb/_generated/models/batch_event.py +110 -0
- honeycomb/_generated/models/board.py +276 -0
- honeycomb/_generated/models/board_layout_generation.py +8 -0
- honeycomb/_generated/models/board_links.py +74 -0
- honeycomb/_generated/models/board_panel_position.py +104 -0
- honeycomb/_generated/models/board_query_visualization_settings.py +141 -0
- honeycomb/_generated/models/board_query_visualization_settings_charts_item.py +113 -0
- honeycomb/_generated/models/board_query_visualization_settings_charts_item_chart_type.py +13 -0
- honeycomb/_generated/models/board_type.py +7 -0
- honeycomb/_generated/models/board_view_filter.py +93 -0
- honeycomb/_generated/models/board_view_filter_operation.py +22 -0
- honeycomb/_generated/models/board_view_response.py +111 -0
- honeycomb/_generated/models/budget_rate.py +189 -0
- honeycomb/_generated/models/budget_rate_alert_type.py +8 -0
- honeycomb/_generated/models/burn_alert_shared_params.py +136 -0
- honeycomb/_generated/models/calculated_field.py +117 -0
- honeycomb/_generated/models/configuration_key_attributes.py +140 -0
- honeycomb/_generated/models/configuration_key_attributes_key_type.py +7 -0
- honeycomb/_generated/models/configuration_key_attributes_timestamps.py +107 -0
- honeycomb/_generated/models/create_board_view_request.py +96 -0
- honeycomb/_generated/models/create_budget_rate_burn_alert_request.py +232 -0
- honeycomb/_generated/models/create_budget_rate_burn_alert_request_slo.py +74 -0
- honeycomb/_generated/models/create_column.py +149 -0
- honeycomb/_generated/models/create_column_type.py +11 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request.py +78 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data.py +90 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes.py +97 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data.py +88 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item.py +89 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item.py +89 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item.py +97 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum.py +102 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum_aggregation_temporality.py +7 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum_datapoints_item.py +105 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum_datapoints_item_attributes_item.py +87 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum_datapoints_item_attributes_item_value.py +73 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_type.py +7 -0
- honeycomb/_generated/models/create_environment_request.py +78 -0
- honeycomb/_generated/models/create_environment_request_data.py +90 -0
- honeycomb/_generated/models/create_environment_request_data_attributes.py +102 -0
- honeycomb/_generated/models/create_environment_request_data_type.py +7 -0
- honeycomb/_generated/models/create_events_content_encoding.py +8 -0
- honeycomb/_generated/models/create_events_response_200_item.py +82 -0
- honeycomb/_generated/models/create_exhaustion_time_burn_alert_request.py +217 -0
- honeycomb/_generated/models/create_exhaustion_time_burn_alert_request_slo.py +74 -0
- honeycomb/_generated/models/create_map_dependencies_request.py +128 -0
- honeycomb/_generated/models/create_map_dependencies_response.py +97 -0
- honeycomb/_generated/models/create_map_dependencies_response_status.py +9 -0
- honeycomb/_generated/models/create_pipeline_health_record_request.py +78 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data.py +98 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes.py +88 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data.py +88 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item.py +89 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item.py +89 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item.py +97 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum.py +102 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum_aggregation_temporality.py +7 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum_datapoints_item.py +105 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum_datapoints_item_attributes_item.py +87 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum_datapoints_item_attributes_item_value.py +73 -0
- honeycomb/_generated/models/create_pipeline_health_record_request_data_type.py +7 -0
- honeycomb/_generated/models/create_query_result_request.py +118 -0
- honeycomb/_generated/models/dataset.py +183 -0
- honeycomb/_generated/models/dataset_creation_payload.py +93 -0
- honeycomb/_generated/models/dataset_definition_type_1.py +96 -0
- honeycomb/_generated/models/dataset_definition_type_1_column_type.py +8 -0
- honeycomb/_generated/models/dataset_definitions.py +599 -0
- honeycomb/_generated/models/dataset_relationship.py +79 -0
- honeycomb/_generated/models/dataset_relationship_data.py +82 -0
- honeycomb/_generated/models/dataset_relationship_data_type.py +7 -0
- honeycomb/_generated/models/dataset_settings.py +73 -0
- honeycomb/_generated/models/dataset_update_payload.py +105 -0
- honeycomb/_generated/models/dataset_update_payload_settings.py +73 -0
- honeycomb/_generated/models/detailed_error.py +115 -0
- honeycomb/_generated/models/email_recipient.py +160 -0
- honeycomb/_generated/models/email_recipient_details.py +71 -0
- honeycomb/_generated/models/email_recipient_type.py +7 -0
- honeycomb/_generated/models/environment.py +112 -0
- honeycomb/_generated/models/environment_attributes.py +140 -0
- honeycomb/_generated/models/environment_attributes_color_type_1.py +7 -0
- honeycomb/_generated/models/environment_attributes_settings.py +70 -0
- honeycomb/_generated/models/environment_color.py +16 -0
- honeycomb/_generated/models/environment_links.py +70 -0
- honeycomb/_generated/models/environment_list_response.py +112 -0
- honeycomb/_generated/models/environment_relationship.py +79 -0
- honeycomb/_generated/models/environment_relationship_data.py +82 -0
- honeycomb/_generated/models/environment_relationship_data_type.py +7 -0
- honeycomb/_generated/models/environment_response.py +78 -0
- honeycomb/_generated/models/environment_type.py +7 -0
- honeycomb/_generated/models/error.py +74 -0
- honeycomb/_generated/models/event.py +71 -0
- honeycomb/_generated/models/exhaustion_time.py +174 -0
- honeycomb/_generated/models/exhaustion_time_alert_type.py +8 -0
- honeycomb/_generated/models/exhaustion_time_burn_alert_list_response.py +198 -0
- honeycomb/_generated/models/exhaustion_time_burn_alert_list_response_slo.py +77 -0
- honeycomb/_generated/models/filter_op.py +22 -0
- honeycomb/_generated/models/get_map_dependencies_response.py +169 -0
- honeycomb/_generated/models/get_map_dependencies_response_status.py +9 -0
- honeycomb/_generated/models/having_calculate_op.py +29 -0
- honeycomb/_generated/models/having_op.py +12 -0
- honeycomb/_generated/models/included_resource.py +106 -0
- honeycomb/_generated/models/included_resource_attributes.py +62 -0
- honeycomb/_generated/models/ingest_key_attributes.py +153 -0
- honeycomb/_generated/models/ingest_key_attributes_key_type.py +7 -0
- honeycomb/_generated/models/ingest_key_attributes_permissions.py +74 -0
- honeycomb/_generated/models/ingest_key_attributes_timestamps.py +107 -0
- honeycomb/_generated/models/ingest_key_type.py +90 -0
- honeycomb/_generated/models/ingest_key_type_key_type.py +7 -0
- honeycomb/_generated/models/jsonapi_error_source.py +92 -0
- honeycomb/_generated/models/kinesis_event.py +111 -0
- honeycomb/_generated/models/kinesis_event_record.py +73 -0
- honeycomb/_generated/models/kinesis_response.py +91 -0
- honeycomb/_generated/models/list_api_keys_filtertype.py +8 -0
- honeycomb/_generated/models/map_dependency.py +118 -0
- honeycomb/_generated/models/map_node.py +97 -0
- honeycomb/_generated/models/map_node_type.py +7 -0
- honeycomb/_generated/models/marker.py +151 -0
- honeycomb/_generated/models/marker_create_request.py +78 -0
- honeycomb/_generated/models/marker_create_request_data.py +104 -0
- honeycomb/_generated/models/marker_create_request_data_attributes.py +110 -0
- honeycomb/_generated/models/marker_create_request_data_relationships.py +92 -0
- honeycomb/_generated/models/marker_create_request_data_type.py +7 -0
- honeycomb/_generated/models/marker_object.py +136 -0
- honeycomb/_generated/models/marker_object_attributes.py +146 -0
- honeycomb/_generated/models/marker_object_attributes_timestamps.py +107 -0
- honeycomb/_generated/models/marker_object_links.py +74 -0
- honeycomb/_generated/models/marker_object_relationships.py +111 -0
- honeycomb/_generated/models/marker_object_relationships_dataset.py +104 -0
- honeycomb/_generated/models/marker_object_relationships_dataset_data_type_0.py +94 -0
- honeycomb/_generated/models/marker_object_relationships_dataset_data_type_0_type.py +7 -0
- honeycomb/_generated/models/marker_object_type.py +7 -0
- honeycomb/_generated/models/marker_response.py +78 -0
- honeycomb/_generated/models/marker_setting.py +125 -0
- honeycomb/_generated/models/marker_update_request.py +78 -0
- honeycomb/_generated/models/marker_update_request_data.py +104 -0
- honeycomb/_generated/models/marker_update_request_data_attributes.py +111 -0
- honeycomb/_generated/models/marker_update_request_data_relationships.py +92 -0
- honeycomb/_generated/models/marker_update_request_data_type.py +7 -0
- honeycomb/_generated/models/ms_teams_recipient.py +161 -0
- honeycomb/_generated/models/ms_teams_recipient_details.py +80 -0
- honeycomb/_generated/models/ms_teams_recipient_type.py +7 -0
- honeycomb/_generated/models/ms_teams_workflow_recipient.py +161 -0
- honeycomb/_generated/models/ms_teams_workflow_recipient_details.py +80 -0
- honeycomb/_generated/models/ms_teams_workflow_recipient_type.py +7 -0
- honeycomb/_generated/models/notification_recipient.py +131 -0
- honeycomb/_generated/models/notification_recipient_details.py +117 -0
- honeycomb/_generated/models/notification_recipient_details_pagerduty_severity.py +10 -0
- honeycomb/_generated/models/notification_recipient_details_variables_item.py +81 -0
- honeycomb/_generated/models/pager_duty_recipient.py +160 -0
- honeycomb/_generated/models/pager_duty_recipient_details.py +79 -0
- honeycomb/_generated/models/pager_duty_recipient_type.py +7 -0
- honeycomb/_generated/models/pagination_links.py +80 -0
- honeycomb/_generated/models/payload_template.py +73 -0
- honeycomb/_generated/models/pipeline_configuration_response.py +112 -0
- honeycomb/_generated/models/pipeline_configuration_response_attributes.py +101 -0
- honeycomb/_generated/models/pipeline_configuration_response_attributes_configs_item.py +85 -0
- honeycomb/_generated/models/pipeline_configuration_response_links.py +73 -0
- honeycomb/_generated/models/pipeline_configuration_response_type.py +7 -0
- honeycomb/_generated/models/pipeline_configuration_rollout.py +112 -0
- honeycomb/_generated/models/pipeline_configuration_rollout_attributes.py +75 -0
- honeycomb/_generated/models/pipeline_configuration_rollout_attributes_status.py +12 -0
- honeycomb/_generated/models/pipeline_configuration_rollout_links.py +73 -0
- honeycomb/_generated/models/pipeline_configuration_rollout_type.py +7 -0
- honeycomb/_generated/models/preset_filter.py +78 -0
- honeycomb/_generated/models/query.py +346 -0
- honeycomb/_generated/models/query_annotation.py +166 -0
- honeycomb/_generated/models/query_annotation_source.py +8 -0
- honeycomb/_generated/models/query_calculated_fields_item.py +80 -0
- honeycomb/_generated/models/query_calculations_item.py +98 -0
- honeycomb/_generated/models/query_compare_time_offset_seconds.py +14 -0
- honeycomb/_generated/models/query_filter_combination.py +8 -0
- honeycomb/_generated/models/query_filters_item.py +126 -0
- honeycomb/_generated/models/query_havings_item.py +128 -0
- honeycomb/_generated/models/query_op.py +30 -0
- honeycomb/_generated/models/query_orders_item.py +115 -0
- honeycomb/_generated/models/query_orders_item_order.py +8 -0
- honeycomb/_generated/models/query_panel.py +114 -0
- honeycomb/_generated/models/query_panel_query_panel.py +143 -0
- honeycomb/_generated/models/query_panel_query_panel_query_style.py +9 -0
- honeycomb/_generated/models/query_result.py +130 -0
- honeycomb/_generated/models/query_result_details.py +156 -0
- honeycomb/_generated/models/query_result_details_data.py +188 -0
- honeycomb/_generated/models/query_result_details_links.py +85 -0
- honeycomb/_generated/models/query_result_links.py +85 -0
- honeycomb/_generated/models/query_results_data.py +89 -0
- honeycomb/_generated/models/query_results_data_data.py +71 -0
- honeycomb/_generated/models/query_results_series.py +97 -0
- honeycomb/_generated/models/recipient_properties.py +137 -0
- honeycomb/_generated/models/recipient_type.py +12 -0
- honeycomb/_generated/models/slack_recipient.py +160 -0
- honeycomb/_generated/models/slack_recipient_details.py +71 -0
- honeycomb/_generated/models/slack_recipient_type.py +7 -0
- honeycomb/_generated/models/slo.py +245 -0
- honeycomb/_generated/models/slo_create.py +245 -0
- honeycomb/_generated/models/slo_create_sli.py +75 -0
- honeycomb/_generated/models/slo_detailed_response.py +312 -0
- honeycomb/_generated/models/slo_detailed_response_status.py +10 -0
- honeycomb/_generated/models/slo_history.py +94 -0
- honeycomb/_generated/models/slo_history_request.py +93 -0
- honeycomb/_generated/models/slo_history_response.py +91 -0
- honeycomb/_generated/models/slo_panel.py +114 -0
- honeycomb/_generated/models/slo_panel_slo_panel.py +75 -0
- honeycomb/_generated/models/slo_sli.py +74 -0
- honeycomb/_generated/models/tag.py +79 -0
- honeycomb/_generated/models/team_relationship.py +78 -0
- honeycomb/_generated/models/team_relationship_team.py +78 -0
- honeycomb/_generated/models/team_relationship_team_data.py +82 -0
- honeycomb/_generated/models/team_relationship_team_data_type.py +7 -0
- honeycomb/_generated/models/template_variable_definition.py +81 -0
- honeycomb/_generated/models/text_panel.py +114 -0
- honeycomb/_generated/models/text_panel_text_panel.py +71 -0
- honeycomb/_generated/models/trigger_response.py +399 -0
- honeycomb/_generated/models/trigger_with_inline_query.py +390 -0
- honeycomb/_generated/models/trigger_with_inline_query_query.py +60 -0
- honeycomb/_generated/models/trigger_with_query_reference.py +376 -0
- honeycomb/_generated/models/update_board_view_request.py +107 -0
- honeycomb/_generated/models/update_environment_request.py +78 -0
- honeycomb/_generated/models/update_environment_request_data.py +98 -0
- honeycomb/_generated/models/update_environment_request_data_attributes.py +118 -0
- honeycomb/_generated/models/update_environment_request_data_attributes_settings.py +73 -0
- honeycomb/_generated/models/update_environment_request_data_type.py +7 -0
- honeycomb/_generated/models/update_exhaustion_time_burn_alert_request.py +202 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout.py +98 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_attributes.py +75 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_attributes_status.py +12 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request.py +78 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request_data.py +98 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request_data_attributes.py +75 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request_data_attributes_status.py +12 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request_data_type.py +7 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_response.py +78 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_type.py +7 -0
- honeycomb/_generated/models/user_relationship.py +78 -0
- honeycomb/_generated/models/user_relationship_data.py +82 -0
- honeycomb/_generated/models/user_relationship_data_type.py +7 -0
- honeycomb/_generated/models/validation_error.py +145 -0
- honeycomb/_generated/models/validation_error_type_detail_item.py +103 -0
- honeycomb/_generated/models/validation_error_type_detail_item_code.py +10 -0
- honeycomb/_generated/models/webhook_header.py +81 -0
- honeycomb/_generated/models/webhook_recipient.py +160 -0
- honeycomb/_generated/models/webhook_recipient_details.py +142 -0
- honeycomb/_generated/models/webhook_recipient_details_webhook_payloads.py +117 -0
- honeycomb/_generated/models/webhook_recipient_details_webhook_payloads_payload_templates.py +126 -0
- honeycomb/_generated/models/webhook_recipient_type.py +7 -0
- honeycomb/_generated/py.typed +1 -0
- honeycomb/_generated/types.py +46 -0
- honeycomb/auth.py +152 -0
- honeycomb/client.py +736 -0
- honeycomb/exceptions.py +236 -0
- honeycomb/models/__init__.py +157 -0
- honeycomb/models/api_keys.py +81 -0
- honeycomb/models/board_builder.py +387 -0
- honeycomb/models/boards.py +86 -0
- honeycomb/models/burn_alerts.py +124 -0
- honeycomb/models/columns.py +59 -0
- honeycomb/models/datasets.py +51 -0
- honeycomb/models/derived_columns.py +107 -0
- honeycomb/models/environments.py +106 -0
- honeycomb/models/events.py +35 -0
- honeycomb/models/marker_builder.py +136 -0
- honeycomb/models/markers.py +73 -0
- honeycomb/models/queries.py +210 -0
- honeycomb/models/query_annotations.py +63 -0
- honeycomb/models/query_builder.py +840 -0
- honeycomb/models/recipient_builder.py +248 -0
- honeycomb/models/recipients.py +43 -0
- honeycomb/models/service_map_dependencies.py +126 -0
- honeycomb/models/slo_builder.py +463 -0
- honeycomb/models/slos.py +66 -0
- honeycomb/models/tags_mixin.py +79 -0
- honeycomb/models/trigger_builder.py +561 -0
- honeycomb/models/triggers.py +208 -0
- honeycomb/resources/__init__.py +35 -0
- honeycomb/resources/_recipient_utils.py +156 -0
- honeycomb/resources/api_keys.py +303 -0
- honeycomb/resources/base.py +142 -0
- honeycomb/resources/boards.py +350 -0
- honeycomb/resources/burn_alerts.py +205 -0
- honeycomb/resources/columns.py +185 -0
- honeycomb/resources/datasets.py +163 -0
- honeycomb/resources/derived_columns.py +233 -0
- honeycomb/resources/environments.py +295 -0
- honeycomb/resources/events.py +156 -0
- honeycomb/resources/markers.py +334 -0
- honeycomb/resources/queries.py +256 -0
- honeycomb/resources/query_annotations.py +207 -0
- honeycomb/resources/query_results.py +886 -0
- honeycomb/resources/recipients.py +202 -0
- honeycomb/resources/service_map_dependencies.py +389 -0
- honeycomb/resources/slos.py +353 -0
- honeycomb/resources/triggers.py +284 -0
- honeycomb/tools/__init__.py +85 -0
- honeycomb/tools/__main__.py +204 -0
- honeycomb/tools/builders.py +512 -0
- honeycomb/tools/descriptions.py +523 -0
- honeycomb/tools/executor.py +860 -0
- honeycomb/tools/generator.py +2386 -0
- honeycomb/tools/schemas.py +184 -0
- honeycomb_api-0.1.0.dist-info/METADATA +451 -0
- honeycomb_api-0.1.0.dist-info/RECORD +453 -0
- honeycomb_api-0.1.0.dist-info/WHEEL +4 -0
- honeycomb_api-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,840 @@
|
|
|
1
|
+
"""Query builder and shared query components for Honeycomb queries.
|
|
2
|
+
|
|
3
|
+
This module provides:
|
|
4
|
+
- Enums for query operations (CalcOp, FilterOp, OrderDirection, FilterCombination)
|
|
5
|
+
- Typed Pydantic models (Calculation, Filter, Order, Having)
|
|
6
|
+
- A fluent QueryBuilder for constructing queries
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from enum import Enum
|
|
12
|
+
from typing import TYPE_CHECKING, Any
|
|
13
|
+
|
|
14
|
+
from pydantic import BaseModel, Field
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from honeycomb.models.queries import QuerySpec
|
|
18
|
+
from honeycomb.models.triggers import TriggerQuery
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# =============================================================================
|
|
22
|
+
# Enums
|
|
23
|
+
# =============================================================================
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class CalcOp(str, Enum):
|
|
27
|
+
"""Calculation operations for Honeycomb queries."""
|
|
28
|
+
|
|
29
|
+
COUNT = "COUNT"
|
|
30
|
+
SUM = "SUM"
|
|
31
|
+
AVG = "AVG"
|
|
32
|
+
MIN = "MIN"
|
|
33
|
+
MAX = "MAX"
|
|
34
|
+
P001 = "P001"
|
|
35
|
+
P01 = "P01"
|
|
36
|
+
P05 = "P05"
|
|
37
|
+
P10 = "P10"
|
|
38
|
+
P25 = "P25"
|
|
39
|
+
P50 = "P50"
|
|
40
|
+
P75 = "P75"
|
|
41
|
+
P90 = "P90"
|
|
42
|
+
P95 = "P95"
|
|
43
|
+
P99 = "P99"
|
|
44
|
+
P999 = "P999"
|
|
45
|
+
COUNT_DISTINCT = "COUNT_DISTINCT"
|
|
46
|
+
CONCURRENCY = "CONCURRENCY"
|
|
47
|
+
HEATMAP = "HEATMAP"
|
|
48
|
+
RATE_AVG = "RATE_AVG"
|
|
49
|
+
RATE_SUM = "RATE_SUM"
|
|
50
|
+
RATE_MAX = "RATE_MAX"
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class FilterOp(str, Enum):
|
|
54
|
+
"""Filter operations for Honeycomb queries."""
|
|
55
|
+
|
|
56
|
+
EQUALS = "="
|
|
57
|
+
NOT_EQUALS = "!="
|
|
58
|
+
GREATER_THAN = ">"
|
|
59
|
+
GREATER_THAN_OR_EQUAL = ">="
|
|
60
|
+
LESS_THAN = "<"
|
|
61
|
+
LESS_THAN_OR_EQUAL = "<="
|
|
62
|
+
STARTS_WITH = "starts-with"
|
|
63
|
+
DOES_NOT_START_WITH = "does-not-start-with"
|
|
64
|
+
CONTAINS = "contains"
|
|
65
|
+
DOES_NOT_CONTAIN = "does-not-contain"
|
|
66
|
+
EXISTS = "exists"
|
|
67
|
+
DOES_NOT_EXIST = "does-not-exist"
|
|
68
|
+
IN = "in"
|
|
69
|
+
NOT_IN = "not-in"
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class OrderDirection(str, Enum):
|
|
73
|
+
"""Order directions for query results."""
|
|
74
|
+
|
|
75
|
+
ASCENDING = "ascending"
|
|
76
|
+
DESCENDING = "descending"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class FilterCombination(str, Enum):
|
|
80
|
+
"""How to combine multiple filters."""
|
|
81
|
+
|
|
82
|
+
AND = "AND"
|
|
83
|
+
OR = "OR"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# =============================================================================
|
|
87
|
+
# Typed Models
|
|
88
|
+
# =============================================================================
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class Calculation(BaseModel):
|
|
92
|
+
"""A calculation in a query.
|
|
93
|
+
|
|
94
|
+
Examples:
|
|
95
|
+
>>> Calculation(op=CalcOp.COUNT)
|
|
96
|
+
>>> Calculation(op=CalcOp.P99, column="duration_ms")
|
|
97
|
+
>>> Calculation(op="AVG", column="response_time", alias="avg_response")
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
op: CalcOp | str = Field(description="Calculation operation (COUNT, AVG, P99, etc.)")
|
|
101
|
+
column: str | None = Field(default=None, description="Column to calculate on")
|
|
102
|
+
alias: str | None = Field(default=None, description="Alias for the result column")
|
|
103
|
+
|
|
104
|
+
def to_dict(self) -> dict[str, Any]:
|
|
105
|
+
"""Convert to API dict format."""
|
|
106
|
+
op_value = self.op.value if isinstance(self.op, CalcOp) else self.op
|
|
107
|
+
result: dict[str, Any] = {"op": op_value}
|
|
108
|
+
if self.column is not None:
|
|
109
|
+
result["column"] = self.column
|
|
110
|
+
if self.alias is not None:
|
|
111
|
+
result["alias"] = self.alias
|
|
112
|
+
return result
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class Filter(BaseModel):
|
|
116
|
+
"""A filter in a query.
|
|
117
|
+
|
|
118
|
+
Examples:
|
|
119
|
+
>>> Filter(column="status", op=FilterOp.EQUALS, value=200)
|
|
120
|
+
>>> Filter(column="error", op=FilterOp.EXISTS, value=True)
|
|
121
|
+
>>> Filter(column="service", op="in", value=["api", "web"])
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
column: str = Field(description="Column to filter on")
|
|
125
|
+
op: FilterOp | str = Field(description="Filter operator (=, !=, >, <, contains, etc.)")
|
|
126
|
+
value: Any = Field(description="Filter value")
|
|
127
|
+
|
|
128
|
+
def to_dict(self) -> dict[str, Any]:
|
|
129
|
+
"""Convert to API dict format."""
|
|
130
|
+
op_value = self.op.value if isinstance(self.op, FilterOp) else self.op
|
|
131
|
+
return {"column": self.column, "op": op_value, "value": self.value}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class Order(BaseModel):
|
|
135
|
+
"""An ordering specification for query results.
|
|
136
|
+
|
|
137
|
+
Examples:
|
|
138
|
+
>>> Order(op=CalcOp.COUNT, order=OrderDirection.DESCENDING)
|
|
139
|
+
>>> Order(op=CalcOp.AVG, column="duration_ms", order=OrderDirection.ASCENDING)
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
op: CalcOp | str = Field(description="Calculation to order by")
|
|
143
|
+
column: str | None = Field(default=None, description="Column for the calculation")
|
|
144
|
+
order: OrderDirection | str = Field(
|
|
145
|
+
default=OrderDirection.DESCENDING, description="Sort direction"
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
def to_dict(self) -> dict[str, Any]:
|
|
149
|
+
"""Convert to API dict format."""
|
|
150
|
+
op_value = self.op.value if isinstance(self.op, CalcOp) else self.op
|
|
151
|
+
order_value = self.order.value if isinstance(self.order, OrderDirection) else self.order
|
|
152
|
+
result: dict[str, Any] = {"op": op_value, "order": order_value}
|
|
153
|
+
if self.column is not None:
|
|
154
|
+
result["column"] = self.column
|
|
155
|
+
return result
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class Having(BaseModel):
|
|
159
|
+
"""A having clause for post-aggregation filtering.
|
|
160
|
+
|
|
161
|
+
Examples:
|
|
162
|
+
>>> Having(calculate_op=CalcOp.COUNT, op=FilterOp.GREATER_THAN, value=100)
|
|
163
|
+
>>> Having(calculate_op=CalcOp.AVG, column="duration_ms", op=">", value=500.0)
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
calculate_op: CalcOp | str = Field(description="Calculation to filter on")
|
|
167
|
+
column: str | None = Field(default=None, description="Column for the calculation")
|
|
168
|
+
op: FilterOp | str = Field(description="Comparison operator")
|
|
169
|
+
value: float = Field(description="Threshold value")
|
|
170
|
+
|
|
171
|
+
def to_dict(self) -> dict[str, Any]:
|
|
172
|
+
"""Convert to API dict format."""
|
|
173
|
+
calc_op_value = (
|
|
174
|
+
self.calculate_op.value if isinstance(self.calculate_op, CalcOp) else self.calculate_op
|
|
175
|
+
)
|
|
176
|
+
op_value = self.op.value if isinstance(self.op, FilterOp) else self.op
|
|
177
|
+
result: dict[str, Any] = {
|
|
178
|
+
"calculate_op": calc_op_value,
|
|
179
|
+
"op": op_value,
|
|
180
|
+
"value": self.value,
|
|
181
|
+
}
|
|
182
|
+
if self.column is not None:
|
|
183
|
+
result["column"] = self.column
|
|
184
|
+
return result
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
# =============================================================================
|
|
188
|
+
# QueryBuilder
|
|
189
|
+
# =============================================================================
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class QueryBuilder:
|
|
193
|
+
"""Fluent builder for constructing QuerySpec objects.
|
|
194
|
+
|
|
195
|
+
The builder provides a chainable API for constructing queries. Each method
|
|
196
|
+
returns self, allowing method chaining. Call build() to get the final QuerySpec,
|
|
197
|
+
or build_for_trigger() to get a TriggerQuery with validation.
|
|
198
|
+
|
|
199
|
+
Examples:
|
|
200
|
+
>>> # Simple count query
|
|
201
|
+
>>> spec = QueryBuilder().last_1_hour().count().build()
|
|
202
|
+
|
|
203
|
+
>>> # Complex query with multiple calculations
|
|
204
|
+
>>> spec = (
|
|
205
|
+
... QueryBuilder()
|
|
206
|
+
... .last_24_hours()
|
|
207
|
+
... .count()
|
|
208
|
+
... .p99("duration_ms")
|
|
209
|
+
... .avg("duration_ms")
|
|
210
|
+
... .where("status", FilterOp.GREATER_THAN_OR_EQUAL, 500)
|
|
211
|
+
... .breakdown("service", "endpoint")
|
|
212
|
+
... .order_by_count()
|
|
213
|
+
... .build()
|
|
214
|
+
... )
|
|
215
|
+
|
|
216
|
+
>>> # Trigger query (validates time_range <= 3600)
|
|
217
|
+
>>> trigger_query = (
|
|
218
|
+
... QueryBuilder()
|
|
219
|
+
... .last_30_minutes()
|
|
220
|
+
... .p99("duration_ms")
|
|
221
|
+
... .build_for_trigger()
|
|
222
|
+
... )
|
|
223
|
+
"""
|
|
224
|
+
|
|
225
|
+
def __init__(self, name: str | None = None) -> None:
|
|
226
|
+
"""Initialize a query builder.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
name: Optional query name (required for board integration)
|
|
230
|
+
|
|
231
|
+
Examples:
|
|
232
|
+
>>> QueryBuilder() # No name (for standalone queries)
|
|
233
|
+
>>> QueryBuilder("Request Count") # With name (for board queries)
|
|
234
|
+
"""
|
|
235
|
+
self._time_range: int | None = None
|
|
236
|
+
self._start_time: int | None = None
|
|
237
|
+
self._end_time: int | None = None
|
|
238
|
+
self._granularity: int | None = None
|
|
239
|
+
self._calculations: list[Calculation] = []
|
|
240
|
+
self._filters: list[Filter] = []
|
|
241
|
+
self._breakdowns: list[str] = []
|
|
242
|
+
self._filter_combination: FilterCombination | None = None
|
|
243
|
+
self._orders: list[Order] = []
|
|
244
|
+
self._limit: int | None = None
|
|
245
|
+
self._havings: list[Having] = []
|
|
246
|
+
# Query metadata (for board integration)
|
|
247
|
+
self._dataset: str | None = None
|
|
248
|
+
self._query_name: str | None = name
|
|
249
|
+
self._query_description: str | None = None
|
|
250
|
+
|
|
251
|
+
# -------------------------------------------------------------------------
|
|
252
|
+
# Time Methods - Custom
|
|
253
|
+
# -------------------------------------------------------------------------
|
|
254
|
+
|
|
255
|
+
def time_range(self, seconds: int) -> QueryBuilder:
|
|
256
|
+
"""Set the query time range in seconds (relative time).
|
|
257
|
+
|
|
258
|
+
Note: Mutually exclusive with start_time()/end_time(). Setting this
|
|
259
|
+
clears any absolute time range.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
seconds: Time range in seconds (e.g., 3600 for 1 hour)
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
self for chaining
|
|
266
|
+
"""
|
|
267
|
+
self._time_range = seconds
|
|
268
|
+
self._start_time = None # Clear absolute time
|
|
269
|
+
self._end_time = None
|
|
270
|
+
return self
|
|
271
|
+
|
|
272
|
+
def start_time(self, timestamp: int) -> QueryBuilder:
|
|
273
|
+
"""Set absolute start time as Unix timestamp.
|
|
274
|
+
|
|
275
|
+
Note: Mutually exclusive with time_range(). Setting this clears any
|
|
276
|
+
relative time range. Must be used with end_time().
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
timestamp: Start time as Unix timestamp (seconds since epoch)
|
|
280
|
+
|
|
281
|
+
Returns:
|
|
282
|
+
self for chaining
|
|
283
|
+
"""
|
|
284
|
+
self._start_time = timestamp
|
|
285
|
+
self._time_range = None # Clear relative time
|
|
286
|
+
return self
|
|
287
|
+
|
|
288
|
+
def end_time(self, timestamp: int) -> QueryBuilder:
|
|
289
|
+
"""Set absolute end time as Unix timestamp.
|
|
290
|
+
|
|
291
|
+
Note: Mutually exclusive with time_range(). Setting this clears any
|
|
292
|
+
relative time range. Must be used with start_time().
|
|
293
|
+
|
|
294
|
+
Args:
|
|
295
|
+
timestamp: End time as Unix timestamp (seconds since epoch)
|
|
296
|
+
|
|
297
|
+
Returns:
|
|
298
|
+
self for chaining
|
|
299
|
+
"""
|
|
300
|
+
self._end_time = timestamp
|
|
301
|
+
self._time_range = None # Clear relative time
|
|
302
|
+
return self
|
|
303
|
+
|
|
304
|
+
def absolute_time(self, start: int, end: int) -> QueryBuilder:
|
|
305
|
+
"""Set absolute start and end times as Unix timestamps.
|
|
306
|
+
|
|
307
|
+
Convenience method equivalent to calling start_time(start).end_time(end).
|
|
308
|
+
|
|
309
|
+
Note: Mutually exclusive with time_range(). Setting this clears any
|
|
310
|
+
relative time range.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
start: Start time as Unix timestamp
|
|
314
|
+
end: End time as Unix timestamp
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
self for chaining
|
|
318
|
+
"""
|
|
319
|
+
self._start_time = start
|
|
320
|
+
self._end_time = end
|
|
321
|
+
self._time_range = None # Clear relative time range
|
|
322
|
+
return self
|
|
323
|
+
|
|
324
|
+
def granularity(self, seconds: int) -> QueryBuilder:
|
|
325
|
+
"""Set the time granularity for bucketing results.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
seconds: Granularity in seconds (e.g., 60 for 1-minute buckets)
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
self for chaining
|
|
332
|
+
"""
|
|
333
|
+
self._granularity = seconds
|
|
334
|
+
return self
|
|
335
|
+
|
|
336
|
+
# -------------------------------------------------------------------------
|
|
337
|
+
# Time Methods - Presets (matching Honeycomb UI)
|
|
338
|
+
# -------------------------------------------------------------------------
|
|
339
|
+
|
|
340
|
+
def last_10_minutes(self) -> QueryBuilder:
|
|
341
|
+
"""Set time range to last 10 minutes (600 seconds)."""
|
|
342
|
+
return self.time_range(600)
|
|
343
|
+
|
|
344
|
+
def last_30_minutes(self) -> QueryBuilder:
|
|
345
|
+
"""Set time range to last 30 minutes (1800 seconds)."""
|
|
346
|
+
return self.time_range(1800)
|
|
347
|
+
|
|
348
|
+
def last_1_hour(self) -> QueryBuilder:
|
|
349
|
+
"""Set time range to last 1 hour (3600 seconds)."""
|
|
350
|
+
return self.time_range(3600)
|
|
351
|
+
|
|
352
|
+
def last_2_hours(self) -> QueryBuilder:
|
|
353
|
+
"""Set time range to last 2 hours (7200 seconds)."""
|
|
354
|
+
return self.time_range(7200)
|
|
355
|
+
|
|
356
|
+
def last_8_hours(self) -> QueryBuilder:
|
|
357
|
+
"""Set time range to last 8 hours (28800 seconds)."""
|
|
358
|
+
return self.time_range(28800)
|
|
359
|
+
|
|
360
|
+
def last_24_hours(self) -> QueryBuilder:
|
|
361
|
+
"""Set time range to last 24 hours (86400 seconds)."""
|
|
362
|
+
return self.time_range(86400)
|
|
363
|
+
|
|
364
|
+
def last_1_day(self) -> QueryBuilder:
|
|
365
|
+
"""Set time range to last 1 day (86400 seconds). Alias for last_24_hours()."""
|
|
366
|
+
return self.time_range(86400)
|
|
367
|
+
|
|
368
|
+
def last_7_days(self) -> QueryBuilder:
|
|
369
|
+
"""Set time range to last 7 days (604800 seconds)."""
|
|
370
|
+
return self.time_range(604800)
|
|
371
|
+
|
|
372
|
+
def last_14_days(self) -> QueryBuilder:
|
|
373
|
+
"""Set time range to last 14 days (1209600 seconds)."""
|
|
374
|
+
return self.time_range(1209600)
|
|
375
|
+
|
|
376
|
+
def last_28_days(self) -> QueryBuilder:
|
|
377
|
+
"""Set time range to last 28 days (2419200 seconds)."""
|
|
378
|
+
return self.time_range(2419200)
|
|
379
|
+
|
|
380
|
+
# -------------------------------------------------------------------------
|
|
381
|
+
# Calculation Methods (additive - each call adds to the list)
|
|
382
|
+
# -------------------------------------------------------------------------
|
|
383
|
+
|
|
384
|
+
def calculate(
|
|
385
|
+
self, op: CalcOp | str, column: str | None = None, alias: str | None = None
|
|
386
|
+
) -> QueryBuilder:
|
|
387
|
+
"""Add a calculation to the query.
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
op: Calculation operation (e.g., CalcOp.COUNT, "AVG")
|
|
391
|
+
column: Column to calculate on (optional for COUNT)
|
|
392
|
+
alias: Alias for the result column
|
|
393
|
+
|
|
394
|
+
Returns:
|
|
395
|
+
self for chaining
|
|
396
|
+
"""
|
|
397
|
+
self._calculations.append(Calculation(op=op, column=column, alias=alias))
|
|
398
|
+
return self
|
|
399
|
+
|
|
400
|
+
def count(self, alias: str | None = None) -> QueryBuilder:
|
|
401
|
+
"""Add a COUNT calculation."""
|
|
402
|
+
return self.calculate(CalcOp.COUNT, alias=alias)
|
|
403
|
+
|
|
404
|
+
def sum(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
405
|
+
"""Add a SUM calculation on a column."""
|
|
406
|
+
return self.calculate(CalcOp.SUM, column=column, alias=alias)
|
|
407
|
+
|
|
408
|
+
def avg(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
409
|
+
"""Add an AVG calculation on a column."""
|
|
410
|
+
return self.calculate(CalcOp.AVG, column=column, alias=alias)
|
|
411
|
+
|
|
412
|
+
def min(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
413
|
+
"""Add a MIN calculation on a column."""
|
|
414
|
+
return self.calculate(CalcOp.MIN, column=column, alias=alias)
|
|
415
|
+
|
|
416
|
+
def max(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
417
|
+
"""Add a MAX calculation on a column."""
|
|
418
|
+
return self.calculate(CalcOp.MAX, column=column, alias=alias)
|
|
419
|
+
|
|
420
|
+
def count_distinct(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
421
|
+
"""Add a COUNT_DISTINCT calculation on a column."""
|
|
422
|
+
return self.calculate(CalcOp.COUNT_DISTINCT, column=column, alias=alias)
|
|
423
|
+
|
|
424
|
+
def p50(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
425
|
+
"""Add a P50 (median) calculation on a column."""
|
|
426
|
+
return self.calculate(CalcOp.P50, column=column, alias=alias)
|
|
427
|
+
|
|
428
|
+
def p90(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
429
|
+
"""Add a P90 calculation on a column."""
|
|
430
|
+
return self.calculate(CalcOp.P90, column=column, alias=alias)
|
|
431
|
+
|
|
432
|
+
def p95(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
433
|
+
"""Add a P95 calculation on a column."""
|
|
434
|
+
return self.calculate(CalcOp.P95, column=column, alias=alias)
|
|
435
|
+
|
|
436
|
+
def p99(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
437
|
+
"""Add a P99 calculation on a column."""
|
|
438
|
+
return self.calculate(CalcOp.P99, column=column, alias=alias)
|
|
439
|
+
|
|
440
|
+
def heatmap(self, column: str, alias: str | None = None) -> QueryBuilder:
|
|
441
|
+
"""Add a HEATMAP calculation on a column."""
|
|
442
|
+
return self.calculate(CalcOp.HEATMAP, column=column, alias=alias)
|
|
443
|
+
|
|
444
|
+
def concurrency(self, alias: str | None = None) -> QueryBuilder:
|
|
445
|
+
"""Add a CONCURRENCY calculation."""
|
|
446
|
+
return self.calculate(CalcOp.CONCURRENCY, alias=alias)
|
|
447
|
+
|
|
448
|
+
# -------------------------------------------------------------------------
|
|
449
|
+
# Filter Methods
|
|
450
|
+
# -------------------------------------------------------------------------
|
|
451
|
+
|
|
452
|
+
def filter(self, column: str, op: FilterOp | str, value: Any) -> QueryBuilder:
|
|
453
|
+
"""Add a filter to the query.
|
|
454
|
+
|
|
455
|
+
Args:
|
|
456
|
+
column: Column to filter on
|
|
457
|
+
op: Filter operator (e.g., FilterOp.EQUALS, ">=")
|
|
458
|
+
value: Filter value
|
|
459
|
+
|
|
460
|
+
Returns:
|
|
461
|
+
self for chaining
|
|
462
|
+
"""
|
|
463
|
+
self._filters.append(Filter(column=column, op=op, value=value))
|
|
464
|
+
return self
|
|
465
|
+
|
|
466
|
+
def where(self, column: str, op: FilterOp | str, value: Any) -> QueryBuilder:
|
|
467
|
+
"""Add a filter to the query. Alias for filter().
|
|
468
|
+
|
|
469
|
+
Args:
|
|
470
|
+
column: Column to filter on
|
|
471
|
+
op: Filter operator (e.g., FilterOp.EQUALS, ">=")
|
|
472
|
+
value: Filter value
|
|
473
|
+
|
|
474
|
+
Returns:
|
|
475
|
+
self for chaining
|
|
476
|
+
"""
|
|
477
|
+
return self.filter(column, op, value)
|
|
478
|
+
|
|
479
|
+
def where_equals(self, column: str, value: Any) -> QueryBuilder:
|
|
480
|
+
"""Add an equality filter.
|
|
481
|
+
|
|
482
|
+
Args:
|
|
483
|
+
column: Column to filter on
|
|
484
|
+
value: Value to match
|
|
485
|
+
|
|
486
|
+
Returns:
|
|
487
|
+
self for chaining
|
|
488
|
+
"""
|
|
489
|
+
return self.filter(column, FilterOp.EQUALS, value)
|
|
490
|
+
|
|
491
|
+
def where_exists(self, column: str) -> QueryBuilder:
|
|
492
|
+
"""Add a filter for column existence.
|
|
493
|
+
|
|
494
|
+
Args:
|
|
495
|
+
column: Column that must exist
|
|
496
|
+
|
|
497
|
+
Returns:
|
|
498
|
+
self for chaining
|
|
499
|
+
"""
|
|
500
|
+
return self.filter(column, FilterOp.EXISTS, True)
|
|
501
|
+
|
|
502
|
+
# -------------------------------------------------------------------------
|
|
503
|
+
# Filter Shortcuts (one method per operator)
|
|
504
|
+
# -------------------------------------------------------------------------
|
|
505
|
+
|
|
506
|
+
def eq(self, column: str, value: Any) -> QueryBuilder:
|
|
507
|
+
"""Filter where column equals value. Shortcut for where(column, FilterOp.EQUALS, value)."""
|
|
508
|
+
return self.filter(column, FilterOp.EQUALS, value)
|
|
509
|
+
|
|
510
|
+
def ne(self, column: str, value: Any) -> QueryBuilder:
|
|
511
|
+
"""Filter where column does not equal value. Shortcut for where(column, FilterOp.NOT_EQUALS, value)."""
|
|
512
|
+
return self.filter(column, FilterOp.NOT_EQUALS, value)
|
|
513
|
+
|
|
514
|
+
def gt(self, column: str, value: Any) -> QueryBuilder:
|
|
515
|
+
"""Filter where column > value. Shortcut for where(column, FilterOp.GREATER_THAN, value)."""
|
|
516
|
+
return self.filter(column, FilterOp.GREATER_THAN, value)
|
|
517
|
+
|
|
518
|
+
def gte(self, column: str, value: Any) -> QueryBuilder:
|
|
519
|
+
"""Filter where column >= value. Shortcut for where(column, FilterOp.GREATER_THAN_OR_EQUAL, value)."""
|
|
520
|
+
return self.filter(column, FilterOp.GREATER_THAN_OR_EQUAL, value)
|
|
521
|
+
|
|
522
|
+
def lt(self, column: str, value: Any) -> QueryBuilder:
|
|
523
|
+
"""Filter where column < value. Shortcut for where(column, FilterOp.LESS_THAN, value)."""
|
|
524
|
+
return self.filter(column, FilterOp.LESS_THAN, value)
|
|
525
|
+
|
|
526
|
+
def lte(self, column: str, value: Any) -> QueryBuilder:
|
|
527
|
+
"""Filter where column <= value. Shortcut for where(column, FilterOp.LESS_THAN_OR_EQUAL, value)."""
|
|
528
|
+
return self.filter(column, FilterOp.LESS_THAN_OR_EQUAL, value)
|
|
529
|
+
|
|
530
|
+
def starts_with(self, column: str, value: str) -> QueryBuilder:
|
|
531
|
+
"""Filter where column starts with value."""
|
|
532
|
+
return self.filter(column, FilterOp.STARTS_WITH, value)
|
|
533
|
+
|
|
534
|
+
def does_not_start_with(self, column: str, value: str) -> QueryBuilder:
|
|
535
|
+
"""Filter where column does not start with value."""
|
|
536
|
+
return self.filter(column, FilterOp.DOES_NOT_START_WITH, value)
|
|
537
|
+
|
|
538
|
+
def contains(self, column: str, value: str) -> QueryBuilder:
|
|
539
|
+
"""Filter where column contains value."""
|
|
540
|
+
return self.filter(column, FilterOp.CONTAINS, value)
|
|
541
|
+
|
|
542
|
+
def does_not_contain(self, column: str, value: str) -> QueryBuilder:
|
|
543
|
+
"""Filter where column does not contain value."""
|
|
544
|
+
return self.filter(column, FilterOp.DOES_NOT_CONTAIN, value)
|
|
545
|
+
|
|
546
|
+
def exists(self, column: str) -> QueryBuilder:
|
|
547
|
+
"""Filter where column exists."""
|
|
548
|
+
return self.filter(column, FilterOp.EXISTS, True)
|
|
549
|
+
|
|
550
|
+
def does_not_exist(self, column: str) -> QueryBuilder:
|
|
551
|
+
"""Filter where column does not exist."""
|
|
552
|
+
return self.filter(column, FilterOp.DOES_NOT_EXIST, True)
|
|
553
|
+
|
|
554
|
+
def is_in(self, column: str, values: list[Any]) -> QueryBuilder:
|
|
555
|
+
"""Filter where column is in a list of values."""
|
|
556
|
+
return self.filter(column, FilterOp.IN, values)
|
|
557
|
+
|
|
558
|
+
def not_in(self, column: str, values: list[Any]) -> QueryBuilder:
|
|
559
|
+
"""Filter where column is not in a list of values."""
|
|
560
|
+
return self.filter(column, FilterOp.NOT_IN, values)
|
|
561
|
+
|
|
562
|
+
def filter_with(self, combination: FilterCombination | str) -> QueryBuilder:
|
|
563
|
+
"""Set how multiple filters are combined.
|
|
564
|
+
|
|
565
|
+
Args:
|
|
566
|
+
combination: FilterCombination.AND or FilterCombination.OR
|
|
567
|
+
|
|
568
|
+
Returns:
|
|
569
|
+
self for chaining
|
|
570
|
+
"""
|
|
571
|
+
if isinstance(combination, str):
|
|
572
|
+
self._filter_combination = FilterCombination(combination)
|
|
573
|
+
else:
|
|
574
|
+
self._filter_combination = combination
|
|
575
|
+
return self
|
|
576
|
+
|
|
577
|
+
# -------------------------------------------------------------------------
|
|
578
|
+
# Grouping Methods
|
|
579
|
+
# -------------------------------------------------------------------------
|
|
580
|
+
|
|
581
|
+
def breakdown(self, *columns: str) -> QueryBuilder:
|
|
582
|
+
"""Add columns to group results by.
|
|
583
|
+
|
|
584
|
+
Args:
|
|
585
|
+
*columns: Column names to group by
|
|
586
|
+
|
|
587
|
+
Returns:
|
|
588
|
+
self for chaining
|
|
589
|
+
"""
|
|
590
|
+
self._breakdowns.extend(columns)
|
|
591
|
+
return self
|
|
592
|
+
|
|
593
|
+
def group_by(self, *columns: str) -> QueryBuilder:
|
|
594
|
+
"""Add columns to group results by. Alias for breakdown().
|
|
595
|
+
|
|
596
|
+
Args:
|
|
597
|
+
*columns: Column names to group by
|
|
598
|
+
|
|
599
|
+
Returns:
|
|
600
|
+
self for chaining
|
|
601
|
+
"""
|
|
602
|
+
return self.breakdown(*columns)
|
|
603
|
+
|
|
604
|
+
# -------------------------------------------------------------------------
|
|
605
|
+
# Ordering Methods
|
|
606
|
+
# -------------------------------------------------------------------------
|
|
607
|
+
|
|
608
|
+
def order_by(
|
|
609
|
+
self,
|
|
610
|
+
op: CalcOp | str,
|
|
611
|
+
direction: OrderDirection | str = OrderDirection.DESCENDING,
|
|
612
|
+
column: str | None = None,
|
|
613
|
+
) -> QueryBuilder:
|
|
614
|
+
"""Add an ordering specification.
|
|
615
|
+
|
|
616
|
+
Args:
|
|
617
|
+
op: Calculation to order by
|
|
618
|
+
direction: Sort direction (default: descending)
|
|
619
|
+
column: Column for the calculation (if applicable)
|
|
620
|
+
|
|
621
|
+
Returns:
|
|
622
|
+
self for chaining
|
|
623
|
+
"""
|
|
624
|
+
self._orders.append(Order(op=op, column=column, order=direction))
|
|
625
|
+
return self
|
|
626
|
+
|
|
627
|
+
def order_by_count(
|
|
628
|
+
self, direction: OrderDirection | str = OrderDirection.DESCENDING
|
|
629
|
+
) -> QueryBuilder:
|
|
630
|
+
"""Order results by COUNT.
|
|
631
|
+
|
|
632
|
+
Args:
|
|
633
|
+
direction: Sort direction (default: descending)
|
|
634
|
+
|
|
635
|
+
Returns:
|
|
636
|
+
self for chaining
|
|
637
|
+
"""
|
|
638
|
+
return self.order_by(CalcOp.COUNT, direction)
|
|
639
|
+
|
|
640
|
+
# -------------------------------------------------------------------------
|
|
641
|
+
# Result Limiting
|
|
642
|
+
# -------------------------------------------------------------------------
|
|
643
|
+
|
|
644
|
+
def limit(self, n: int) -> QueryBuilder:
|
|
645
|
+
"""Set the maximum number of results.
|
|
646
|
+
|
|
647
|
+
Args:
|
|
648
|
+
n: Maximum number of results (max 1000 for saved queries)
|
|
649
|
+
|
|
650
|
+
Returns:
|
|
651
|
+
self for chaining
|
|
652
|
+
"""
|
|
653
|
+
self._limit = n
|
|
654
|
+
return self
|
|
655
|
+
|
|
656
|
+
# -------------------------------------------------------------------------
|
|
657
|
+
# Having Methods
|
|
658
|
+
# -------------------------------------------------------------------------
|
|
659
|
+
|
|
660
|
+
def having(
|
|
661
|
+
self,
|
|
662
|
+
calculate_op: CalcOp | str,
|
|
663
|
+
op: FilterOp | str,
|
|
664
|
+
value: float,
|
|
665
|
+
column: str | None = None,
|
|
666
|
+
) -> QueryBuilder:
|
|
667
|
+
"""Add a having clause for post-aggregation filtering.
|
|
668
|
+
|
|
669
|
+
Args:
|
|
670
|
+
calculate_op: Calculation to filter on
|
|
671
|
+
op: Comparison operator
|
|
672
|
+
value: Threshold value
|
|
673
|
+
column: Column for the calculation (if applicable)
|
|
674
|
+
|
|
675
|
+
Returns:
|
|
676
|
+
self for chaining
|
|
677
|
+
"""
|
|
678
|
+
self._havings.append(Having(calculate_op=calculate_op, column=column, op=op, value=value))
|
|
679
|
+
return self
|
|
680
|
+
|
|
681
|
+
# -------------------------------------------------------------------------
|
|
682
|
+
# Dataset Scoping
|
|
683
|
+
# -------------------------------------------------------------------------
|
|
684
|
+
|
|
685
|
+
def dataset(self, dataset_slug: str) -> QueryBuilder:
|
|
686
|
+
"""Set dataset scope for this query.
|
|
687
|
+
|
|
688
|
+
Args:
|
|
689
|
+
dataset_slug: Dataset slug to query against
|
|
690
|
+
|
|
691
|
+
Returns:
|
|
692
|
+
self for chaining
|
|
693
|
+
|
|
694
|
+
Example:
|
|
695
|
+
>>> QueryBuilder().dataset("api-logs").last_1_hour().count()
|
|
696
|
+
"""
|
|
697
|
+
self._dataset = dataset_slug
|
|
698
|
+
return self
|
|
699
|
+
|
|
700
|
+
def environment_wide(self) -> QueryBuilder:
|
|
701
|
+
"""Mark query as environment-wide (all datasets).
|
|
702
|
+
|
|
703
|
+
Returns:
|
|
704
|
+
self for chaining
|
|
705
|
+
|
|
706
|
+
Example:
|
|
707
|
+
>>> QueryBuilder().environment_wide().last_1_hour().count()
|
|
708
|
+
"""
|
|
709
|
+
self._dataset = "__all__"
|
|
710
|
+
return self
|
|
711
|
+
|
|
712
|
+
def get_dataset(self) -> str:
|
|
713
|
+
"""Get dataset scope (defaults to \"__all__\" if not set).
|
|
714
|
+
|
|
715
|
+
Returns:
|
|
716
|
+
Dataset slug or \"__all__\" for environment-wide
|
|
717
|
+
"""
|
|
718
|
+
return self._dataset if self._dataset else "__all__"
|
|
719
|
+
|
|
720
|
+
# -------------------------------------------------------------------------
|
|
721
|
+
# Query Metadata (for board integration)
|
|
722
|
+
# -------------------------------------------------------------------------
|
|
723
|
+
|
|
724
|
+
def description(self, desc: str) -> QueryBuilder:
|
|
725
|
+
"""Set query description (optional).
|
|
726
|
+
|
|
727
|
+
For boards: This becomes the query annotation description.
|
|
728
|
+
|
|
729
|
+
Args:
|
|
730
|
+
desc: Query description (max 1023 chars)
|
|
731
|
+
|
|
732
|
+
Returns:
|
|
733
|
+
self for chaining
|
|
734
|
+
|
|
735
|
+
Example:
|
|
736
|
+
>>> (QueryBuilder("Request Count")
|
|
737
|
+
... .dataset("api-logs")
|
|
738
|
+
... .last_1_hour()
|
|
739
|
+
... .count()
|
|
740
|
+
... .description("Total requests over 24 hours"))
|
|
741
|
+
"""
|
|
742
|
+
self._query_description = desc
|
|
743
|
+
return self
|
|
744
|
+
|
|
745
|
+
def has_name(self) -> bool:
|
|
746
|
+
"""Check if query has name set.
|
|
747
|
+
|
|
748
|
+
Returns:
|
|
749
|
+
True if name is set
|
|
750
|
+
"""
|
|
751
|
+
return self._query_name is not None
|
|
752
|
+
|
|
753
|
+
def get_name(self) -> str | None:
|
|
754
|
+
"""Get query name.
|
|
755
|
+
|
|
756
|
+
Returns:
|
|
757
|
+
Query name or None
|
|
758
|
+
"""
|
|
759
|
+
return self._query_name
|
|
760
|
+
|
|
761
|
+
def get_description(self) -> str | None:
|
|
762
|
+
"""Get query description.
|
|
763
|
+
|
|
764
|
+
Returns:
|
|
765
|
+
Query description or None
|
|
766
|
+
"""
|
|
767
|
+
return self._query_description
|
|
768
|
+
|
|
769
|
+
# -------------------------------------------------------------------------
|
|
770
|
+
# Build Methods
|
|
771
|
+
# -------------------------------------------------------------------------
|
|
772
|
+
|
|
773
|
+
def build(self) -> QuerySpec:
|
|
774
|
+
"""Build a QuerySpec from the builder state.
|
|
775
|
+
|
|
776
|
+
Returns:
|
|
777
|
+
A QuerySpec configured with the builder's settings
|
|
778
|
+
|
|
779
|
+
Raises:
|
|
780
|
+
ValueError: If only one of start_time/end_time is set (must use both)
|
|
781
|
+
"""
|
|
782
|
+
# Import here to avoid circular imports
|
|
783
|
+
from honeycomb.models.queries import QuerySpec
|
|
784
|
+
|
|
785
|
+
# Validate absolute time: if either is set, both must be set
|
|
786
|
+
has_start = self._start_time is not None
|
|
787
|
+
has_end = self._end_time is not None
|
|
788
|
+
if has_start != has_end:
|
|
789
|
+
raise ValueError(
|
|
790
|
+
"Both start_time and end_time must be set together. "
|
|
791
|
+
"Use time_range() for relative time queries."
|
|
792
|
+
)
|
|
793
|
+
|
|
794
|
+
return QuerySpec(
|
|
795
|
+
time_range=self._time_range,
|
|
796
|
+
start_time=self._start_time,
|
|
797
|
+
end_time=self._end_time,
|
|
798
|
+
granularity=self._granularity,
|
|
799
|
+
calculations=self._calculations if self._calculations else None,
|
|
800
|
+
filters=self._filters if self._filters else None,
|
|
801
|
+
breakdowns=self._breakdowns if self._breakdowns else None,
|
|
802
|
+
filter_combination=self._filter_combination,
|
|
803
|
+
orders=self._orders if self._orders else None,
|
|
804
|
+
limit=self._limit,
|
|
805
|
+
havings=self._havings if self._havings else None,
|
|
806
|
+
)
|
|
807
|
+
|
|
808
|
+
def build_for_trigger(self) -> TriggerQuery:
|
|
809
|
+
"""Build a TriggerQuery from the builder state.
|
|
810
|
+
|
|
811
|
+
TriggerQuery has additional constraints:
|
|
812
|
+
- time_range must be <= 3600 seconds (1 hour)
|
|
813
|
+
- No absolute time support
|
|
814
|
+
- No orders, havings, or limit
|
|
815
|
+
|
|
816
|
+
Returns:
|
|
817
|
+
A TriggerQuery configured with the builder's settings
|
|
818
|
+
|
|
819
|
+
Raises:
|
|
820
|
+
ValueError: If time_range > 3600 or absolute time is set
|
|
821
|
+
"""
|
|
822
|
+
# Import here to avoid circular imports
|
|
823
|
+
from honeycomb.models.triggers import TriggerQuery
|
|
824
|
+
|
|
825
|
+
if self._start_time is not None or self._end_time is not None:
|
|
826
|
+
raise ValueError("TriggerQuery does not support absolute time ranges")
|
|
827
|
+
|
|
828
|
+
if self._time_range is not None and self._time_range > 3600:
|
|
829
|
+
raise ValueError(
|
|
830
|
+
f"TriggerQuery time_range must be <= 3600 seconds (1 hour), got {self._time_range}"
|
|
831
|
+
)
|
|
832
|
+
|
|
833
|
+
return TriggerQuery(
|
|
834
|
+
time_range=self._time_range if self._time_range is not None else 3600,
|
|
835
|
+
granularity=self._granularity,
|
|
836
|
+
calculations=self._calculations if self._calculations else None,
|
|
837
|
+
filters=self._filters if self._filters else None,
|
|
838
|
+
breakdowns=self._breakdowns if self._breakdowns else None,
|
|
839
|
+
filter_combination=self._filter_combination,
|
|
840
|
+
)
|