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,353 @@
|
|
|
1
|
+
"""SLOs resource for Honeycomb API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from ..models.burn_alerts import BurnAlertCreate, BurnAlertRecipient
|
|
8
|
+
from ..models.slos import SLO, SLOCreate
|
|
9
|
+
from .base import BaseResource
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..client import HoneycombClient
|
|
13
|
+
from ..models.slo_builder import SLOBundle
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SLOsResource(BaseResource):
|
|
17
|
+
"""Resource for managing Honeycomb SLOs (Service Level Objectives).
|
|
18
|
+
|
|
19
|
+
SLOs allow you to define and track service level objectives
|
|
20
|
+
based on your data.
|
|
21
|
+
|
|
22
|
+
Example (async):
|
|
23
|
+
>>> async with HoneycombClient(api_key="...") as client:
|
|
24
|
+
... slos = await client.slos.list(dataset="my-dataset")
|
|
25
|
+
... slo = await client.slos.get(dataset="my-dataset", slo_id="abc123")
|
|
26
|
+
|
|
27
|
+
Example (sync):
|
|
28
|
+
>>> with HoneycombClient(api_key="...", sync=True) as client:
|
|
29
|
+
... slos = client.slos.list(dataset="my-dataset")
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, client: HoneycombClient) -> None:
|
|
33
|
+
super().__init__(client)
|
|
34
|
+
|
|
35
|
+
def _build_path(self, dataset: str, slo_id: str | None = None) -> str:
|
|
36
|
+
"""Build API path for SLOs."""
|
|
37
|
+
base = f"/1/slos/{dataset}"
|
|
38
|
+
if slo_id:
|
|
39
|
+
return f"{base}/{slo_id}"
|
|
40
|
+
return base
|
|
41
|
+
|
|
42
|
+
# -------------------------------------------------------------------------
|
|
43
|
+
# Async methods
|
|
44
|
+
# -------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
async def list_async(self, dataset: str) -> list[SLO]:
|
|
47
|
+
"""List all SLOs for a dataset (async).
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
dataset: Dataset slug.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
List of SLO objects.
|
|
54
|
+
"""
|
|
55
|
+
data = await self._get_async(self._build_path(dataset))
|
|
56
|
+
return self._parse_model_list(SLO, data)
|
|
57
|
+
|
|
58
|
+
async def get_async(self, dataset: str, slo_id: str) -> SLO:
|
|
59
|
+
"""Get a specific SLO (async).
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
dataset: Dataset slug.
|
|
63
|
+
slo_id: SLO ID.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
SLO object.
|
|
67
|
+
"""
|
|
68
|
+
data = await self._get_async(self._build_path(dataset, slo_id))
|
|
69
|
+
return self._parse_model(SLO, data)
|
|
70
|
+
|
|
71
|
+
async def create_async(self, dataset: str, slo: SLOCreate) -> SLO:
|
|
72
|
+
"""Create a new SLO (async).
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
dataset: Dataset slug.
|
|
76
|
+
slo: SLO configuration.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Created SLO object.
|
|
80
|
+
"""
|
|
81
|
+
data = await self._post_async(self._build_path(dataset), json=slo.model_dump_for_api())
|
|
82
|
+
return self._parse_model(SLO, data)
|
|
83
|
+
|
|
84
|
+
async def update_async(self, dataset: str, slo_id: str, slo: SLOCreate) -> SLO:
|
|
85
|
+
"""Update an existing SLO (async).
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
dataset: Dataset slug.
|
|
89
|
+
slo_id: SLO ID.
|
|
90
|
+
slo: Updated SLO configuration.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Updated SLO object.
|
|
94
|
+
"""
|
|
95
|
+
data = await self._put_async(
|
|
96
|
+
self._build_path(dataset, slo_id), json=slo.model_dump_for_api()
|
|
97
|
+
)
|
|
98
|
+
return self._parse_model(SLO, data)
|
|
99
|
+
|
|
100
|
+
async def delete_async(self, dataset: str, slo_id: str) -> None:
|
|
101
|
+
"""Delete an SLO (async).
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
dataset: Dataset slug.
|
|
105
|
+
slo_id: SLO ID.
|
|
106
|
+
"""
|
|
107
|
+
await self._delete_async(self._build_path(dataset, slo_id))
|
|
108
|
+
|
|
109
|
+
# -------------------------------------------------------------------------
|
|
110
|
+
# SLO Bundle creation helpers (async)
|
|
111
|
+
# -------------------------------------------------------------------------
|
|
112
|
+
|
|
113
|
+
async def create_from_bundle_async(self, bundle: SLOBundle) -> dict[str, SLO]:
|
|
114
|
+
"""Create SLO(s) from an SLOBundle with automatic orchestration (async).
|
|
115
|
+
|
|
116
|
+
This method handles the full orchestration of creating an SLO bundle:
|
|
117
|
+
1. Creates derived column if needed (environment-wide or dataset-scoped)
|
|
118
|
+
2. Creates SLO in each specified dataset
|
|
119
|
+
3. Creates burn alerts for each SLO (if configured)
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
bundle: SLOBundle from SLOBuilder.build()
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Dictionary mapping dataset slugs to created SLO objects
|
|
126
|
+
|
|
127
|
+
Example:
|
|
128
|
+
>>> bundle = (
|
|
129
|
+
... SLOBuilder("API Availability")
|
|
130
|
+
... .dataset("api-logs")
|
|
131
|
+
... .target_nines(3)
|
|
132
|
+
... .sli(alias="success_rate", expression="IF(LT($status, 400), 1, 0)")
|
|
133
|
+
... .exhaustion_alert(
|
|
134
|
+
... BurnAlertBuilder(BurnAlertType.EXHAUSTION_TIME)
|
|
135
|
+
... .exhaustion_minutes(60)
|
|
136
|
+
... .email("oncall@example.com")
|
|
137
|
+
... )
|
|
138
|
+
... .build()
|
|
139
|
+
... )
|
|
140
|
+
>>> slos = await client.slos.create_from_bundle_async(bundle)
|
|
141
|
+
>>> api_slo = slos["api-logs"]
|
|
142
|
+
"""
|
|
143
|
+
created_slos: dict[str, SLO] = {}
|
|
144
|
+
|
|
145
|
+
# Step 1: Create derived column if needed
|
|
146
|
+
if bundle.derived_column:
|
|
147
|
+
if bundle.derived_column_environment_wide:
|
|
148
|
+
# Create as environment-wide derived column (use "__all__" dataset)
|
|
149
|
+
await self._client.derived_columns.create_async("__all__", bundle.derived_column)
|
|
150
|
+
else:
|
|
151
|
+
# Create in first dataset (single-dataset SLO)
|
|
152
|
+
await self._client.derived_columns.create_async(
|
|
153
|
+
bundle.datasets[0], bundle.derived_column
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# Step 2: Create SLO in each dataset
|
|
157
|
+
for dataset in bundle.datasets:
|
|
158
|
+
slo = await self.create_async(dataset, bundle.slo)
|
|
159
|
+
created_slos[dataset] = slo
|
|
160
|
+
|
|
161
|
+
# Step 3: Create burn alerts for this SLO
|
|
162
|
+
for alert_def in bundle.burn_alerts:
|
|
163
|
+
# Process inline recipients with idempotent handling
|
|
164
|
+
from ._recipient_utils import process_inline_recipients
|
|
165
|
+
|
|
166
|
+
processed_recipients = await process_inline_recipients(
|
|
167
|
+
self._client, alert_def.recipients.copy()
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
# Convert recipients to BurnAlertRecipient format
|
|
171
|
+
recipients = [BurnAlertRecipient(**recipient) for recipient in processed_recipients]
|
|
172
|
+
|
|
173
|
+
# Convert budget rate percent to per-million if needed
|
|
174
|
+
budget_rate_threshold = None
|
|
175
|
+
if alert_def.budget_rate_decrease_percent is not None:
|
|
176
|
+
budget_rate_threshold = int(alert_def.budget_rate_decrease_percent * 10000)
|
|
177
|
+
|
|
178
|
+
burn_alert = BurnAlertCreate(
|
|
179
|
+
alert_type=alert_def.alert_type,
|
|
180
|
+
slo_id=slo.id,
|
|
181
|
+
description=alert_def.description,
|
|
182
|
+
exhaustion_minutes=alert_def.exhaustion_minutes,
|
|
183
|
+
budget_rate_window_minutes=alert_def.budget_rate_window_minutes,
|
|
184
|
+
budget_rate_decrease_threshold_per_million=budget_rate_threshold,
|
|
185
|
+
recipients=recipients if recipients else [],
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
await self._client.burn_alerts.create_async(dataset, burn_alert)
|
|
189
|
+
|
|
190
|
+
return created_slos
|
|
191
|
+
|
|
192
|
+
# -------------------------------------------------------------------------
|
|
193
|
+
# Sync methods
|
|
194
|
+
# -------------------------------------------------------------------------
|
|
195
|
+
|
|
196
|
+
def list(self, dataset: str) -> list[SLO]:
|
|
197
|
+
"""List all SLOs for a dataset.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
dataset: Dataset slug.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
List of SLO objects.
|
|
204
|
+
"""
|
|
205
|
+
if not self._client.is_sync:
|
|
206
|
+
raise RuntimeError("Use list_async() for async mode, or pass sync=True to client")
|
|
207
|
+
data = self._get_sync(self._build_path(dataset))
|
|
208
|
+
return self._parse_model_list(SLO, data)
|
|
209
|
+
|
|
210
|
+
def get(self, dataset: str, slo_id: str) -> SLO:
|
|
211
|
+
"""Get a specific SLO.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
dataset: Dataset slug.
|
|
215
|
+
slo_id: SLO ID.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
SLO object.
|
|
219
|
+
"""
|
|
220
|
+
if not self._client.is_sync:
|
|
221
|
+
raise RuntimeError("Use get_async() for async mode, or pass sync=True to client")
|
|
222
|
+
data = self._get_sync(self._build_path(dataset, slo_id))
|
|
223
|
+
return self._parse_model(SLO, data)
|
|
224
|
+
|
|
225
|
+
def create(self, dataset: str, slo: SLOCreate) -> SLO:
|
|
226
|
+
"""Create a new SLO.
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
dataset: Dataset slug.
|
|
230
|
+
slo: SLO configuration.
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
Created SLO object.
|
|
234
|
+
"""
|
|
235
|
+
if not self._client.is_sync:
|
|
236
|
+
raise RuntimeError("Use create_async() for async mode, or pass sync=True to client")
|
|
237
|
+
data = self._post_sync(self._build_path(dataset), json=slo.model_dump_for_api())
|
|
238
|
+
return self._parse_model(SLO, data)
|
|
239
|
+
|
|
240
|
+
def update(self, dataset: str, slo_id: str, slo: SLOCreate) -> SLO:
|
|
241
|
+
"""Update an existing SLO.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
dataset: Dataset slug.
|
|
245
|
+
slo_id: SLO ID.
|
|
246
|
+
slo: Updated SLO configuration.
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
Updated SLO object.
|
|
250
|
+
"""
|
|
251
|
+
if not self._client.is_sync:
|
|
252
|
+
raise RuntimeError("Use update_async() for async mode, or pass sync=True to client")
|
|
253
|
+
data = self._put_sync(self._build_path(dataset, slo_id), json=slo.model_dump_for_api())
|
|
254
|
+
return self._parse_model(SLO, data)
|
|
255
|
+
|
|
256
|
+
def delete(self, dataset: str, slo_id: str) -> None:
|
|
257
|
+
"""Delete an SLO.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
dataset: Dataset slug.
|
|
261
|
+
slo_id: SLO ID.
|
|
262
|
+
"""
|
|
263
|
+
if not self._client.is_sync:
|
|
264
|
+
raise RuntimeError("Use delete_async() for async mode, or pass sync=True to client")
|
|
265
|
+
self._delete_sync(self._build_path(dataset, slo_id))
|
|
266
|
+
|
|
267
|
+
# -------------------------------------------------------------------------
|
|
268
|
+
# SLO Bundle creation helpers (sync)
|
|
269
|
+
# -------------------------------------------------------------------------
|
|
270
|
+
|
|
271
|
+
def create_from_bundle(self, bundle: SLOBundle) -> dict[str, SLO]:
|
|
272
|
+
"""Create SLO(s) from an SLOBundle with automatic orchestration.
|
|
273
|
+
|
|
274
|
+
This method handles the full orchestration of creating an SLO bundle:
|
|
275
|
+
1. Creates derived column if needed (environment-wide or dataset-scoped)
|
|
276
|
+
2. Creates SLO in each specified dataset
|
|
277
|
+
3. Creates burn alerts for each SLO (if configured)
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
bundle: SLOBundle from SLOBuilder.build()
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
Dictionary mapping dataset slugs to created SLO objects
|
|
284
|
+
|
|
285
|
+
Example:
|
|
286
|
+
>>> bundle = (
|
|
287
|
+
... SLOBuilder("API Availability")
|
|
288
|
+
... .dataset("api-logs")
|
|
289
|
+
... .target_nines(3)
|
|
290
|
+
... .sli(alias="success_rate", expression="IF(LT($status, 400), 1, 0)")
|
|
291
|
+
... .exhaustion_alert(
|
|
292
|
+
... BurnAlertBuilder(BurnAlertType.EXHAUSTION_TIME)
|
|
293
|
+
... .exhaustion_minutes(60)
|
|
294
|
+
... .email("oncall@example.com")
|
|
295
|
+
... )
|
|
296
|
+
... .build()
|
|
297
|
+
... )
|
|
298
|
+
>>> slos = client.slos.create_from_bundle(bundle)
|
|
299
|
+
>>> api_slo = slos["api-logs"]
|
|
300
|
+
"""
|
|
301
|
+
if not self._client.is_sync:
|
|
302
|
+
raise RuntimeError(
|
|
303
|
+
"Use create_from_bundle_async() for async mode, or pass sync=True to client"
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
created_slos: dict[str, SLO] = {}
|
|
307
|
+
|
|
308
|
+
# Step 1: Create derived column if needed
|
|
309
|
+
if bundle.derived_column:
|
|
310
|
+
if bundle.derived_column_environment_wide:
|
|
311
|
+
# Create as environment-wide derived column (use "__all__" dataset)
|
|
312
|
+
self._client.derived_columns.create("__all__", bundle.derived_column)
|
|
313
|
+
else:
|
|
314
|
+
# Create in first dataset (single-dataset SLO)
|
|
315
|
+
self._client.derived_columns.create(bundle.datasets[0], bundle.derived_column)
|
|
316
|
+
|
|
317
|
+
# Step 2: Create SLO in each dataset
|
|
318
|
+
for dataset in bundle.datasets:
|
|
319
|
+
slo = self.create(dataset, bundle.slo)
|
|
320
|
+
created_slos[dataset] = slo
|
|
321
|
+
|
|
322
|
+
# Step 3: Create burn alerts for this SLO
|
|
323
|
+
for alert_def in bundle.burn_alerts:
|
|
324
|
+
# Process inline recipients with idempotent handling
|
|
325
|
+
import asyncio
|
|
326
|
+
|
|
327
|
+
from ._recipient_utils import process_inline_recipients
|
|
328
|
+
|
|
329
|
+
processed_recipients = asyncio.run(
|
|
330
|
+
process_inline_recipients(self._client, alert_def.recipients.copy())
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
# Convert recipients to BurnAlertRecipient format
|
|
334
|
+
recipients = [BurnAlertRecipient(**recipient) for recipient in processed_recipients]
|
|
335
|
+
|
|
336
|
+
# Convert budget rate percent to per-million if needed
|
|
337
|
+
budget_rate_threshold = None
|
|
338
|
+
if alert_def.budget_rate_decrease_percent is not None:
|
|
339
|
+
budget_rate_threshold = int(alert_def.budget_rate_decrease_percent * 10000)
|
|
340
|
+
|
|
341
|
+
burn_alert = BurnAlertCreate(
|
|
342
|
+
alert_type=alert_def.alert_type,
|
|
343
|
+
slo_id=slo.id,
|
|
344
|
+
description=alert_def.description,
|
|
345
|
+
exhaustion_minutes=alert_def.exhaustion_minutes,
|
|
346
|
+
budget_rate_window_minutes=alert_def.budget_rate_window_minutes,
|
|
347
|
+
budget_rate_decrease_threshold_per_million=budget_rate_threshold,
|
|
348
|
+
recipients=recipients if recipients else [],
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
self._client.burn_alerts.create(dataset, burn_alert)
|
|
352
|
+
|
|
353
|
+
return created_slos
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"""Triggers resource for Honeycomb API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
from ..models.triggers import Trigger, TriggerCreate
|
|
9
|
+
from .base import BaseResource
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..client import HoneycombClient
|
|
13
|
+
from ..models.trigger_builder import TriggerBundle
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TriggersResource(BaseResource):
|
|
17
|
+
"""Resource for managing Honeycomb triggers.
|
|
18
|
+
|
|
19
|
+
Triggers allow you to define alert conditions on your data
|
|
20
|
+
and receive notifications when those conditions are met.
|
|
21
|
+
|
|
22
|
+
Example (async):
|
|
23
|
+
>>> async with HoneycombClient(api_key="...") as client:
|
|
24
|
+
... triggers = await client.triggers.list(dataset="my-dataset")
|
|
25
|
+
... trigger = await client.triggers.get(dataset="my-dataset", trigger_id="abc123")
|
|
26
|
+
|
|
27
|
+
Example (sync):
|
|
28
|
+
>>> with HoneycombClient(api_key="...", sync=True) as client:
|
|
29
|
+
... triggers = client.triggers.list(dataset="my-dataset")
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, client: HoneycombClient) -> None:
|
|
33
|
+
super().__init__(client)
|
|
34
|
+
|
|
35
|
+
def _build_path(self, dataset: str, trigger_id: str | None = None) -> str:
|
|
36
|
+
"""Build API path for triggers."""
|
|
37
|
+
base = f"/1/triggers/{dataset}"
|
|
38
|
+
if trigger_id:
|
|
39
|
+
return f"{base}/{trigger_id}"
|
|
40
|
+
return base
|
|
41
|
+
|
|
42
|
+
# -------------------------------------------------------------------------
|
|
43
|
+
# Async methods
|
|
44
|
+
# -------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
async def list_async(self, dataset: str) -> list[Trigger]:
|
|
47
|
+
"""List all triggers for a dataset (async).
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
dataset: Dataset slug.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
List of Trigger objects.
|
|
54
|
+
"""
|
|
55
|
+
data = await self._get_async(self._build_path(dataset))
|
|
56
|
+
return self._parse_model_list(Trigger, data)
|
|
57
|
+
|
|
58
|
+
async def get_async(self, dataset: str, trigger_id: str) -> Trigger:
|
|
59
|
+
"""Get a specific trigger (async).
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
dataset: Dataset slug.
|
|
63
|
+
trigger_id: Trigger ID.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
Trigger object.
|
|
67
|
+
"""
|
|
68
|
+
data = await self._get_async(self._build_path(dataset, trigger_id))
|
|
69
|
+
return self._parse_model(Trigger, data)
|
|
70
|
+
|
|
71
|
+
async def create_async(self, dataset: str, trigger: TriggerCreate) -> Trigger:
|
|
72
|
+
"""Create a new trigger (async).
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
dataset: Dataset slug.
|
|
76
|
+
trigger: Trigger configuration.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Created Trigger object.
|
|
80
|
+
"""
|
|
81
|
+
data = await self._post_async(self._build_path(dataset), json=trigger.model_dump_for_api())
|
|
82
|
+
return self._parse_model(Trigger, data)
|
|
83
|
+
|
|
84
|
+
async def update_async(self, dataset: str, trigger_id: str, trigger: TriggerCreate) -> Trigger:
|
|
85
|
+
"""Update an existing trigger (async).
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
dataset: Dataset slug.
|
|
89
|
+
trigger_id: Trigger ID.
|
|
90
|
+
trigger: Updated trigger configuration.
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
Updated Trigger object.
|
|
94
|
+
"""
|
|
95
|
+
data = await self._put_async(
|
|
96
|
+
self._build_path(dataset, trigger_id), json=trigger.model_dump_for_api()
|
|
97
|
+
)
|
|
98
|
+
return self._parse_model(Trigger, data)
|
|
99
|
+
|
|
100
|
+
async def delete_async(self, dataset: str, trigger_id: str) -> None:
|
|
101
|
+
"""Delete a trigger (async).
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
dataset: Dataset slug.
|
|
105
|
+
trigger_id: Trigger ID.
|
|
106
|
+
"""
|
|
107
|
+
await self._delete_async(self._build_path(dataset, trigger_id))
|
|
108
|
+
|
|
109
|
+
# -------------------------------------------------------------------------
|
|
110
|
+
# Sync methods
|
|
111
|
+
# -------------------------------------------------------------------------
|
|
112
|
+
|
|
113
|
+
def list(self, dataset: str) -> list[Trigger]:
|
|
114
|
+
"""List all triggers for a dataset.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
dataset: Dataset slug.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
List of Trigger objects.
|
|
121
|
+
"""
|
|
122
|
+
if not self._client.is_sync:
|
|
123
|
+
raise RuntimeError("Use list_async() for async mode, or pass sync=True to client")
|
|
124
|
+
data = self._get_sync(self._build_path(dataset))
|
|
125
|
+
return self._parse_model_list(Trigger, data)
|
|
126
|
+
|
|
127
|
+
def get(self, dataset: str, trigger_id: str) -> Trigger:
|
|
128
|
+
"""Get a specific trigger.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
dataset: Dataset slug.
|
|
132
|
+
trigger_id: Trigger ID.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Trigger object.
|
|
136
|
+
"""
|
|
137
|
+
if not self._client.is_sync:
|
|
138
|
+
raise RuntimeError("Use get_async() for async mode, or pass sync=True to client")
|
|
139
|
+
data = self._get_sync(self._build_path(dataset, trigger_id))
|
|
140
|
+
return self._parse_model(Trigger, data)
|
|
141
|
+
|
|
142
|
+
def create(self, dataset: str, trigger: TriggerCreate) -> Trigger:
|
|
143
|
+
"""Create a new trigger.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
dataset: Dataset slug.
|
|
147
|
+
trigger: Trigger configuration.
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Created Trigger object.
|
|
151
|
+
"""
|
|
152
|
+
if not self._client.is_sync:
|
|
153
|
+
raise RuntimeError("Use create_async() for async mode, or pass sync=True to client")
|
|
154
|
+
data = self._post_sync(self._build_path(dataset), json=trigger.model_dump_for_api())
|
|
155
|
+
return self._parse_model(Trigger, data)
|
|
156
|
+
|
|
157
|
+
def update(self, dataset: str, trigger_id: str, trigger: TriggerCreate) -> Trigger:
|
|
158
|
+
"""Update an existing trigger.
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
dataset: Dataset slug.
|
|
162
|
+
trigger_id: Trigger ID.
|
|
163
|
+
trigger: Updated trigger configuration.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Updated Trigger object.
|
|
167
|
+
"""
|
|
168
|
+
if not self._client.is_sync:
|
|
169
|
+
raise RuntimeError("Use update_async() for async mode, or pass sync=True to client")
|
|
170
|
+
data = self._put_sync(
|
|
171
|
+
self._build_path(dataset, trigger_id), json=trigger.model_dump_for_api()
|
|
172
|
+
)
|
|
173
|
+
return self._parse_model(Trigger, data)
|
|
174
|
+
|
|
175
|
+
def delete(self, dataset: str, trigger_id: str) -> None:
|
|
176
|
+
"""Delete a trigger.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
dataset: Dataset slug.
|
|
180
|
+
trigger_id: Trigger ID.
|
|
181
|
+
"""
|
|
182
|
+
if not self._client.is_sync:
|
|
183
|
+
raise RuntimeError("Use delete_async() for async mode, or pass sync=True to client")
|
|
184
|
+
self._delete_sync(self._build_path(dataset, trigger_id))
|
|
185
|
+
|
|
186
|
+
# -------------------------------------------------------------------------
|
|
187
|
+
# Trigger Bundle creation helpers (async)
|
|
188
|
+
# -------------------------------------------------------------------------
|
|
189
|
+
|
|
190
|
+
async def create_from_bundle_async(self, bundle: TriggerBundle) -> Trigger:
|
|
191
|
+
"""Create trigger from bundle with recipient orchestration (async).
|
|
192
|
+
|
|
193
|
+
Orchestrates:
|
|
194
|
+
1. Create/find inline recipients (idempotent)
|
|
195
|
+
2. Create trigger with recipient IDs
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
bundle: TriggerBundle from TriggerBuilder.build_bundle()
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
Created Trigger object
|
|
202
|
+
|
|
203
|
+
Example:
|
|
204
|
+
>>> bundle = (
|
|
205
|
+
... TriggerBuilder("High Error Rate")
|
|
206
|
+
... .dataset("api-logs")
|
|
207
|
+
... .last_30_minutes()
|
|
208
|
+
... .count()
|
|
209
|
+
... .threshold_gt(100)
|
|
210
|
+
... .email("oncall@example.com")
|
|
211
|
+
... .build_bundle()
|
|
212
|
+
... )
|
|
213
|
+
>>> trigger = await client.triggers.create_from_bundle_async(bundle)
|
|
214
|
+
"""
|
|
215
|
+
from ._recipient_utils import process_inline_recipients
|
|
216
|
+
|
|
217
|
+
# Handle inline recipients with idempotency
|
|
218
|
+
if bundle.inline_recipients:
|
|
219
|
+
processed_recipients = await process_inline_recipients(
|
|
220
|
+
self._client, bundle.inline_recipients
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# Merge with existing recipients in trigger
|
|
224
|
+
existing_recipients = bundle.trigger.recipients or []
|
|
225
|
+
all_recipients = existing_recipients + processed_recipients
|
|
226
|
+
|
|
227
|
+
# Create new trigger object with all recipients
|
|
228
|
+
trigger_with_ids = TriggerCreate(
|
|
229
|
+
name=bundle.trigger.name,
|
|
230
|
+
description=bundle.trigger.description,
|
|
231
|
+
threshold=bundle.trigger.threshold,
|
|
232
|
+
frequency=bundle.trigger.frequency,
|
|
233
|
+
query=bundle.trigger.query,
|
|
234
|
+
disabled=bundle.trigger.disabled,
|
|
235
|
+
alert_type=bundle.trigger.alert_type,
|
|
236
|
+
recipients=all_recipients if all_recipients else None,
|
|
237
|
+
tags=bundle.trigger.tags,
|
|
238
|
+
baseline_details=bundle.trigger.baseline_details,
|
|
239
|
+
)
|
|
240
|
+
else:
|
|
241
|
+
trigger_with_ids = bundle.trigger
|
|
242
|
+
|
|
243
|
+
# Create trigger
|
|
244
|
+
return await self.create_async(bundle.dataset, trigger_with_ids)
|
|
245
|
+
|
|
246
|
+
# -------------------------------------------------------------------------
|
|
247
|
+
# Trigger Bundle creation helpers (sync)
|
|
248
|
+
# -------------------------------------------------------------------------
|
|
249
|
+
|
|
250
|
+
def create_from_bundle(self, bundle: TriggerBundle) -> Trigger:
|
|
251
|
+
"""Create trigger from bundle with recipient orchestration (sync).
|
|
252
|
+
|
|
253
|
+
Orchestrates:
|
|
254
|
+
1. Create/find inline recipients (idempotent)
|
|
255
|
+
2. Create trigger with recipient IDs
|
|
256
|
+
|
|
257
|
+
Args:
|
|
258
|
+
bundle: TriggerBundle from TriggerBuilder.build_bundle()
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
Created Trigger object
|
|
262
|
+
|
|
263
|
+
Raises:
|
|
264
|
+
RuntimeError: If client is in async mode
|
|
265
|
+
|
|
266
|
+
Example:
|
|
267
|
+
>>> bundle = (
|
|
268
|
+
... TriggerBuilder("High Error Rate")
|
|
269
|
+
... .dataset("api-logs")
|
|
270
|
+
... .last_30_minutes()
|
|
271
|
+
... .count()
|
|
272
|
+
... .threshold_gt(100)
|
|
273
|
+
... .email("oncall@example.com")
|
|
274
|
+
... .build_bundle()
|
|
275
|
+
... )
|
|
276
|
+
>>> trigger = client.triggers.create_from_bundle(bundle)
|
|
277
|
+
"""
|
|
278
|
+
if not self._client.is_sync:
|
|
279
|
+
raise RuntimeError(
|
|
280
|
+
"Cannot use sync method with async client. "
|
|
281
|
+
"Use create_from_bundle_async() for async mode, or pass sync=True to client"
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
return asyncio.run(self.create_from_bundle_async(bundle))
|