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
honeycomb/client.py
ADDED
|
@@ -0,0 +1,736 @@
|
|
|
1
|
+
"""Honeycomb API client with async-first design and sync wrapper."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from contextlib import suppress
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from email.utils import parsedate_to_datetime
|
|
10
|
+
from typing import TYPE_CHECKING, Any
|
|
11
|
+
|
|
12
|
+
import httpx
|
|
13
|
+
|
|
14
|
+
from .auth import create_auth
|
|
15
|
+
from .exceptions import (
|
|
16
|
+
HoneycombAPIError,
|
|
17
|
+
HoneycombAuthError,
|
|
18
|
+
HoneycombConnectionError,
|
|
19
|
+
HoneycombForbiddenError,
|
|
20
|
+
HoneycombNotFoundError,
|
|
21
|
+
HoneycombRateLimitError,
|
|
22
|
+
HoneycombServerError,
|
|
23
|
+
HoneycombTimeoutError,
|
|
24
|
+
HoneycombValidationError,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from .resources.api_keys import ApiKeysResource
|
|
29
|
+
from .resources.boards import BoardsResource
|
|
30
|
+
from .resources.burn_alerts import BurnAlertsResource
|
|
31
|
+
from .resources.columns import ColumnsResource
|
|
32
|
+
from .resources.datasets import DatasetsResource
|
|
33
|
+
from .resources.derived_columns import DerivedColumnsResource
|
|
34
|
+
from .resources.environments import EnvironmentsResource
|
|
35
|
+
from .resources.events import EventsResource
|
|
36
|
+
from .resources.markers import MarkersResource
|
|
37
|
+
from .resources.queries import QueriesResource
|
|
38
|
+
from .resources.query_annotations import QueryAnnotationsResource
|
|
39
|
+
from .resources.query_results import QueryResultsResource
|
|
40
|
+
from .resources.recipients import RecipientsResource
|
|
41
|
+
from .resources.service_map_dependencies import ServiceMapDependenciesResource
|
|
42
|
+
from .resources.slos import SLOsResource
|
|
43
|
+
from .resources.triggers import TriggersResource
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
DEFAULT_BASE_URL = "https://api.honeycomb.io"
|
|
47
|
+
DEFAULT_TIMEOUT = 30.0
|
|
48
|
+
DEFAULT_MAX_RETRIES = 3
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass
|
|
52
|
+
class RetryConfig:
|
|
53
|
+
"""Configuration for retry behavior.
|
|
54
|
+
|
|
55
|
+
Attributes:
|
|
56
|
+
max_retries: Maximum number of retry attempts.
|
|
57
|
+
base_delay: Base delay in seconds for exponential backoff.
|
|
58
|
+
max_delay: Maximum delay in seconds between retries.
|
|
59
|
+
exponential_base: Base for exponential backoff calculation.
|
|
60
|
+
retry_statuses: HTTP status codes that should trigger a retry.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
max_retries: int = 3
|
|
64
|
+
base_delay: float = 1.0
|
|
65
|
+
max_delay: float = 30.0
|
|
66
|
+
exponential_base: float = 2.0
|
|
67
|
+
retry_statuses: set[int] = None # type: ignore
|
|
68
|
+
|
|
69
|
+
def __post_init__(self) -> None:
|
|
70
|
+
"""Initialize default retry statuses if not provided."""
|
|
71
|
+
if self.retry_statuses is None:
|
|
72
|
+
self.retry_statuses = {429, 500, 502, 503, 504}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@dataclass
|
|
76
|
+
class RateLimitInfo:
|
|
77
|
+
"""Rate limit information from response headers.
|
|
78
|
+
|
|
79
|
+
Attributes:
|
|
80
|
+
limit: Total requests allowed in the time window.
|
|
81
|
+
remaining: Remaining requests in the current time window.
|
|
82
|
+
reset: Seconds until the rate limit resets.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
limit: int | None = None
|
|
86
|
+
remaining: int | None = None
|
|
87
|
+
reset: int | None = None
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class HoneycombClient:
|
|
91
|
+
"""Async-first client for the Honeycomb API.
|
|
92
|
+
|
|
93
|
+
Supports both async and sync usage patterns.
|
|
94
|
+
|
|
95
|
+
Example (async - recommended):
|
|
96
|
+
>>> async with HoneycombClient(api_key="your-key") as client:
|
|
97
|
+
... datasets = await client.datasets.list()
|
|
98
|
+
... triggers = await client.triggers.list(dataset="my-dataset")
|
|
99
|
+
|
|
100
|
+
Example (sync):
|
|
101
|
+
>>> with HoneycombClient(api_key="your-key", sync=True) as client:
|
|
102
|
+
... datasets = client.datasets.list()
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
api_key: Honeycomb API key for single-environment access.
|
|
106
|
+
management_key: Management API key ID for multi-environment access.
|
|
107
|
+
management_secret: Management API key secret.
|
|
108
|
+
base_url: API base URL (default: https://api.honeycomb.io).
|
|
109
|
+
timeout: Request timeout in seconds (default: 30).
|
|
110
|
+
max_retries: Maximum retry attempts for failed requests (default: 3).
|
|
111
|
+
retry_config: Custom retry configuration (optional, overrides max_retries).
|
|
112
|
+
sync: If True, use synchronous HTTP client (default: False).
|
|
113
|
+
"""
|
|
114
|
+
|
|
115
|
+
def __init__(
|
|
116
|
+
self,
|
|
117
|
+
*,
|
|
118
|
+
api_key: str | None = None,
|
|
119
|
+
management_key: str | None = None,
|
|
120
|
+
management_secret: str | None = None,
|
|
121
|
+
base_url: str = DEFAULT_BASE_URL,
|
|
122
|
+
timeout: float = DEFAULT_TIMEOUT,
|
|
123
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
124
|
+
retry_config: RetryConfig | None = None,
|
|
125
|
+
sync: bool = False,
|
|
126
|
+
) -> None:
|
|
127
|
+
self._auth = create_auth(
|
|
128
|
+
api_key=api_key,
|
|
129
|
+
management_key=management_key,
|
|
130
|
+
management_secret=management_secret,
|
|
131
|
+
)
|
|
132
|
+
self._base_url = base_url.rstrip("/")
|
|
133
|
+
self._timeout = timeout
|
|
134
|
+
self._max_retries = max_retries
|
|
135
|
+
self._retry_config = retry_config or RetryConfig(max_retries=max_retries)
|
|
136
|
+
self._sync_mode = sync
|
|
137
|
+
|
|
138
|
+
# HTTP clients (lazily initialized)
|
|
139
|
+
self._async_client: httpx.AsyncClient | None = None
|
|
140
|
+
self._sync_client: httpx.Client | None = None
|
|
141
|
+
|
|
142
|
+
# Resource instances (lazily initialized)
|
|
143
|
+
self._triggers: TriggersResource | None = None
|
|
144
|
+
self._slos: SLOsResource | None = None
|
|
145
|
+
self._datasets: DatasetsResource | None = None
|
|
146
|
+
self._boards: BoardsResource | None = None
|
|
147
|
+
self._queries: QueriesResource | None = None
|
|
148
|
+
self._query_annotations: QueryAnnotationsResource | None = None
|
|
149
|
+
self._query_results: QueryResultsResource | None = None
|
|
150
|
+
self._columns: ColumnsResource | None = None
|
|
151
|
+
self._derived_columns: DerivedColumnsResource | None = None
|
|
152
|
+
self._markers: MarkersResource | None = None
|
|
153
|
+
self._recipients: RecipientsResource | None = None
|
|
154
|
+
self._burn_alerts: BurnAlertsResource | None = None
|
|
155
|
+
self._events: EventsResource | None = None
|
|
156
|
+
self._api_keys: ApiKeysResource | None = None
|
|
157
|
+
self._environments: EnvironmentsResource | None = None
|
|
158
|
+
self._service_map_dependencies: ServiceMapDependenciesResource | None = None
|
|
159
|
+
|
|
160
|
+
# -------------------------------------------------------------------------
|
|
161
|
+
# Resource accessors
|
|
162
|
+
# -------------------------------------------------------------------------
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def triggers(self) -> TriggersResource:
|
|
166
|
+
"""Access the Triggers API."""
|
|
167
|
+
if self._triggers is None:
|
|
168
|
+
from .resources.triggers import TriggersResource
|
|
169
|
+
|
|
170
|
+
self._triggers = TriggersResource(self)
|
|
171
|
+
return self._triggers
|
|
172
|
+
|
|
173
|
+
@property
|
|
174
|
+
def slos(self) -> SLOsResource:
|
|
175
|
+
"""Access the SLOs API."""
|
|
176
|
+
if self._slos is None:
|
|
177
|
+
from .resources.slos import SLOsResource
|
|
178
|
+
|
|
179
|
+
self._slos = SLOsResource(self)
|
|
180
|
+
return self._slos
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
def datasets(self) -> DatasetsResource:
|
|
184
|
+
"""Access the Datasets API."""
|
|
185
|
+
if self._datasets is None:
|
|
186
|
+
from .resources.datasets import DatasetsResource
|
|
187
|
+
|
|
188
|
+
self._datasets = DatasetsResource(self)
|
|
189
|
+
return self._datasets
|
|
190
|
+
|
|
191
|
+
@property
|
|
192
|
+
def boards(self) -> BoardsResource:
|
|
193
|
+
"""Access the Boards API."""
|
|
194
|
+
if self._boards is None:
|
|
195
|
+
from .resources.boards import BoardsResource
|
|
196
|
+
|
|
197
|
+
self._boards = BoardsResource(self)
|
|
198
|
+
return self._boards
|
|
199
|
+
|
|
200
|
+
@property
|
|
201
|
+
def queries(self) -> QueriesResource:
|
|
202
|
+
"""Access the Queries API."""
|
|
203
|
+
if self._queries is None:
|
|
204
|
+
from .resources.queries import QueriesResource
|
|
205
|
+
|
|
206
|
+
self._queries = QueriesResource(self)
|
|
207
|
+
return self._queries
|
|
208
|
+
|
|
209
|
+
@property
|
|
210
|
+
def query_annotations(self) -> QueryAnnotationsResource:
|
|
211
|
+
"""Access the Query Annotations API."""
|
|
212
|
+
if self._query_annotations is None:
|
|
213
|
+
from .resources.query_annotations import QueryAnnotationsResource
|
|
214
|
+
|
|
215
|
+
self._query_annotations = QueryAnnotationsResource(self)
|
|
216
|
+
return self._query_annotations
|
|
217
|
+
|
|
218
|
+
@property
|
|
219
|
+
def query_results(self) -> QueryResultsResource:
|
|
220
|
+
"""Access the Query Results API."""
|
|
221
|
+
if self._query_results is None:
|
|
222
|
+
from .resources.query_results import QueryResultsResource
|
|
223
|
+
|
|
224
|
+
self._query_results = QueryResultsResource(self)
|
|
225
|
+
return self._query_results
|
|
226
|
+
|
|
227
|
+
@property
|
|
228
|
+
def columns(self) -> ColumnsResource:
|
|
229
|
+
"""Access the Columns API."""
|
|
230
|
+
if self._columns is None:
|
|
231
|
+
from .resources.columns import ColumnsResource
|
|
232
|
+
|
|
233
|
+
self._columns = ColumnsResource(self)
|
|
234
|
+
return self._columns
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def derived_columns(self) -> DerivedColumnsResource:
|
|
238
|
+
"""Access the Derived Columns (Calculated Fields) API."""
|
|
239
|
+
if self._derived_columns is None:
|
|
240
|
+
from .resources.derived_columns import DerivedColumnsResource
|
|
241
|
+
|
|
242
|
+
self._derived_columns = DerivedColumnsResource(self)
|
|
243
|
+
return self._derived_columns
|
|
244
|
+
|
|
245
|
+
@property
|
|
246
|
+
def markers(self) -> MarkersResource:
|
|
247
|
+
"""Access the Markers API."""
|
|
248
|
+
if self._markers is None:
|
|
249
|
+
from .resources.markers import MarkersResource
|
|
250
|
+
|
|
251
|
+
self._markers = MarkersResource(self)
|
|
252
|
+
return self._markers
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def recipients(self) -> RecipientsResource:
|
|
256
|
+
"""Access the Recipients API."""
|
|
257
|
+
if self._recipients is None:
|
|
258
|
+
from .resources.recipients import RecipientsResource
|
|
259
|
+
|
|
260
|
+
self._recipients = RecipientsResource(self)
|
|
261
|
+
return self._recipients
|
|
262
|
+
|
|
263
|
+
@property
|
|
264
|
+
def burn_alerts(self) -> BurnAlertsResource:
|
|
265
|
+
"""Access the Burn Alerts API."""
|
|
266
|
+
if self._burn_alerts is None:
|
|
267
|
+
from .resources.burn_alerts import BurnAlertsResource
|
|
268
|
+
|
|
269
|
+
self._burn_alerts = BurnAlertsResource(self)
|
|
270
|
+
return self._burn_alerts
|
|
271
|
+
|
|
272
|
+
@property
|
|
273
|
+
def events(self) -> EventsResource:
|
|
274
|
+
"""Access the Events API (data ingestion)."""
|
|
275
|
+
if self._events is None:
|
|
276
|
+
from .resources.events import EventsResource
|
|
277
|
+
|
|
278
|
+
self._events = EventsResource(self)
|
|
279
|
+
return self._events
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def api_keys(self) -> ApiKeysResource:
|
|
283
|
+
"""Access the API Keys API (v2 team-scoped)."""
|
|
284
|
+
if self._api_keys is None:
|
|
285
|
+
from .resources.api_keys import ApiKeysResource
|
|
286
|
+
|
|
287
|
+
self._api_keys = ApiKeysResource(self)
|
|
288
|
+
return self._api_keys
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
def environments(self) -> EnvironmentsResource:
|
|
292
|
+
"""Access the Environments API (v2 team-scoped)."""
|
|
293
|
+
if self._environments is None:
|
|
294
|
+
from .resources.environments import EnvironmentsResource
|
|
295
|
+
|
|
296
|
+
self._environments = EnvironmentsResource(self)
|
|
297
|
+
return self._environments
|
|
298
|
+
|
|
299
|
+
@property
|
|
300
|
+
def service_map_dependencies(self) -> ServiceMapDependenciesResource:
|
|
301
|
+
"""Access the Service Map Dependencies API."""
|
|
302
|
+
if self._service_map_dependencies is None:
|
|
303
|
+
from .resources.service_map_dependencies import ServiceMapDependenciesResource
|
|
304
|
+
|
|
305
|
+
self._service_map_dependencies = ServiceMapDependenciesResource(self)
|
|
306
|
+
return self._service_map_dependencies
|
|
307
|
+
|
|
308
|
+
# -------------------------------------------------------------------------
|
|
309
|
+
# HTTP client management
|
|
310
|
+
# -------------------------------------------------------------------------
|
|
311
|
+
|
|
312
|
+
def _get_sync_client(self) -> httpx.Client:
|
|
313
|
+
"""Get or create the sync HTTP client."""
|
|
314
|
+
if self._sync_client is None:
|
|
315
|
+
self._sync_client = httpx.Client(
|
|
316
|
+
base_url=self._base_url,
|
|
317
|
+
headers=self._auth.get_headers(),
|
|
318
|
+
timeout=self._timeout,
|
|
319
|
+
)
|
|
320
|
+
return self._sync_client
|
|
321
|
+
|
|
322
|
+
def _get_async_client(self) -> httpx.AsyncClient:
|
|
323
|
+
"""Get or create the async HTTP client."""
|
|
324
|
+
if self._async_client is None:
|
|
325
|
+
self._async_client = httpx.AsyncClient(
|
|
326
|
+
base_url=self._base_url,
|
|
327
|
+
headers=self._auth.get_headers(),
|
|
328
|
+
timeout=self._timeout,
|
|
329
|
+
)
|
|
330
|
+
return self._async_client
|
|
331
|
+
|
|
332
|
+
# -------------------------------------------------------------------------
|
|
333
|
+
# Context managers
|
|
334
|
+
# -------------------------------------------------------------------------
|
|
335
|
+
|
|
336
|
+
async def __aenter__(self) -> HoneycombClient:
|
|
337
|
+
"""Async context manager entry."""
|
|
338
|
+
return self
|
|
339
|
+
|
|
340
|
+
async def __aexit__(self, *args: Any) -> None:
|
|
341
|
+
"""Async context manager exit."""
|
|
342
|
+
await self.aclose()
|
|
343
|
+
|
|
344
|
+
def __enter__(self) -> HoneycombClient:
|
|
345
|
+
"""Sync context manager entry."""
|
|
346
|
+
if not self._sync_mode:
|
|
347
|
+
raise RuntimeError("Use 'async with' for async mode, or pass sync=True to constructor")
|
|
348
|
+
return self
|
|
349
|
+
|
|
350
|
+
def __exit__(self, *args: Any) -> None:
|
|
351
|
+
"""Sync context manager exit."""
|
|
352
|
+
self.close()
|
|
353
|
+
|
|
354
|
+
async def aclose(self) -> None:
|
|
355
|
+
"""Close async HTTP client."""
|
|
356
|
+
if self._async_client is not None:
|
|
357
|
+
await self._async_client.aclose()
|
|
358
|
+
self._async_client = None
|
|
359
|
+
|
|
360
|
+
def close(self) -> None:
|
|
361
|
+
"""Close sync HTTP client."""
|
|
362
|
+
if self._sync_client is not None:
|
|
363
|
+
self._sync_client.close()
|
|
364
|
+
self._sync_client = None
|
|
365
|
+
|
|
366
|
+
# -------------------------------------------------------------------------
|
|
367
|
+
# Request methods (internal)
|
|
368
|
+
# -------------------------------------------------------------------------
|
|
369
|
+
|
|
370
|
+
def _parse_rate_limit_headers(self, response: httpx.Response) -> RateLimitInfo:
|
|
371
|
+
"""Parse rate limit information from response headers.
|
|
372
|
+
|
|
373
|
+
Supports multiple header formats:
|
|
374
|
+
- RateLimit: limit=100, remaining=50, reset=60
|
|
375
|
+
- X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
|
|
376
|
+
"""
|
|
377
|
+
info = RateLimitInfo()
|
|
378
|
+
|
|
379
|
+
# Try structured RateLimit header (RFC draft)
|
|
380
|
+
if "RateLimit" in response.headers:
|
|
381
|
+
rate_limit = response.headers["RateLimit"]
|
|
382
|
+
for part in rate_limit.split(","):
|
|
383
|
+
part = part.strip()
|
|
384
|
+
if "=" in part:
|
|
385
|
+
key, value = part.split("=", 1)
|
|
386
|
+
key = key.strip()
|
|
387
|
+
try:
|
|
388
|
+
if key == "limit":
|
|
389
|
+
info.limit = int(value)
|
|
390
|
+
elif key == "remaining":
|
|
391
|
+
info.remaining = int(value)
|
|
392
|
+
elif key == "reset":
|
|
393
|
+
info.reset = int(value)
|
|
394
|
+
except ValueError:
|
|
395
|
+
pass
|
|
396
|
+
|
|
397
|
+
# Try X-RateLimit-* headers (common format)
|
|
398
|
+
if "X-RateLimit-Limit" in response.headers:
|
|
399
|
+
with suppress(ValueError):
|
|
400
|
+
info.limit = int(response.headers["X-RateLimit-Limit"])
|
|
401
|
+
|
|
402
|
+
if "X-RateLimit-Remaining" in response.headers:
|
|
403
|
+
with suppress(ValueError):
|
|
404
|
+
info.remaining = int(response.headers["X-RateLimit-Remaining"])
|
|
405
|
+
|
|
406
|
+
if "X-RateLimit-Reset" in response.headers:
|
|
407
|
+
with suppress(ValueError):
|
|
408
|
+
info.reset = int(response.headers["X-RateLimit-Reset"])
|
|
409
|
+
|
|
410
|
+
return info
|
|
411
|
+
|
|
412
|
+
def _parse_retry_after(self, response: httpx.Response) -> int | None:
|
|
413
|
+
"""Parse Retry-After header.
|
|
414
|
+
|
|
415
|
+
Supports both formats:
|
|
416
|
+
- Delay-seconds: "60"
|
|
417
|
+
- HTTP-date: "Wed, 21 Oct 2015 07:28:00 GMT"
|
|
418
|
+
|
|
419
|
+
Returns:
|
|
420
|
+
Number of seconds to wait, or None if header not present.
|
|
421
|
+
"""
|
|
422
|
+
retry_after = response.headers.get("Retry-After")
|
|
423
|
+
if not retry_after:
|
|
424
|
+
return None
|
|
425
|
+
|
|
426
|
+
# Try parsing as integer (seconds)
|
|
427
|
+
try:
|
|
428
|
+
return int(retry_after)
|
|
429
|
+
except ValueError:
|
|
430
|
+
pass
|
|
431
|
+
|
|
432
|
+
# Try parsing as HTTP date (RFC 7231)
|
|
433
|
+
try:
|
|
434
|
+
retry_date = parsedate_to_datetime(retry_after)
|
|
435
|
+
now = datetime.now(retry_date.tzinfo)
|
|
436
|
+
delta = (retry_date - now).total_seconds()
|
|
437
|
+
return max(int(delta), 0)
|
|
438
|
+
except (ValueError, TypeError):
|
|
439
|
+
pass
|
|
440
|
+
|
|
441
|
+
return None
|
|
442
|
+
|
|
443
|
+
def _parse_error_response(self, response: httpx.Response) -> tuple[str, list[dict] | None]:
|
|
444
|
+
"""Parse error message from response body.
|
|
445
|
+
|
|
446
|
+
Handles multiple error formats:
|
|
447
|
+
- Simple: {"error": "message"}
|
|
448
|
+
- RFC 7807: {"title": "...", "detail": "..."}
|
|
449
|
+
- JSON:API: {"errors": [{"detail": "..."}]}
|
|
450
|
+
"""
|
|
451
|
+
try:
|
|
452
|
+
body = response.json()
|
|
453
|
+
except Exception:
|
|
454
|
+
return response.text or "Unknown error", None
|
|
455
|
+
|
|
456
|
+
errors: list[dict] | None = None
|
|
457
|
+
|
|
458
|
+
# Simple format (most common for Honeycomb)
|
|
459
|
+
if "error" in body:
|
|
460
|
+
return body["error"], None
|
|
461
|
+
|
|
462
|
+
# RFC 7807 Problem Details
|
|
463
|
+
if "title" in body:
|
|
464
|
+
msg = body["title"]
|
|
465
|
+
if "detail" in body:
|
|
466
|
+
msg = f"{msg}: {body['detail']}"
|
|
467
|
+
errors = body.get("type_detail")
|
|
468
|
+
return msg, errors
|
|
469
|
+
|
|
470
|
+
# JSON:API format
|
|
471
|
+
if "errors" in body and isinstance(body["errors"], list):
|
|
472
|
+
first = body["errors"][0] if body["errors"] else {}
|
|
473
|
+
msg = first.get("detail") or first.get("title") or "Unknown error"
|
|
474
|
+
return msg, body["errors"]
|
|
475
|
+
|
|
476
|
+
return str(body), None
|
|
477
|
+
|
|
478
|
+
def _raise_for_status(self, response: httpx.Response) -> None:
|
|
479
|
+
"""Raise appropriate exception for error responses."""
|
|
480
|
+
if response.is_success:
|
|
481
|
+
return
|
|
482
|
+
|
|
483
|
+
status = response.status_code
|
|
484
|
+
message, errors = self._parse_error_response(response)
|
|
485
|
+
request_id = response.headers.get("X-Request-Id")
|
|
486
|
+
|
|
487
|
+
if status == 401:
|
|
488
|
+
raise HoneycombAuthError(message, status, request_id)
|
|
489
|
+
elif status == 403:
|
|
490
|
+
raise HoneycombForbiddenError(message, status, request_id)
|
|
491
|
+
elif status == 404:
|
|
492
|
+
raise HoneycombNotFoundError(message, status, request_id)
|
|
493
|
+
elif status == 422:
|
|
494
|
+
raise HoneycombValidationError(message, status, request_id, errors=errors)
|
|
495
|
+
elif status == 429:
|
|
496
|
+
retry_after = self._parse_retry_after(response)
|
|
497
|
+
raise HoneycombRateLimitError(message, status, request_id, retry_after=retry_after)
|
|
498
|
+
elif 500 <= status < 600:
|
|
499
|
+
raise HoneycombServerError(message, status, request_id)
|
|
500
|
+
else:
|
|
501
|
+
raise HoneycombAPIError(message, status, request_id)
|
|
502
|
+
|
|
503
|
+
def _should_retry(self, response: httpx.Response, attempt: int) -> bool:
|
|
504
|
+
"""Determine if request should be retried."""
|
|
505
|
+
if attempt >= self._retry_config.max_retries:
|
|
506
|
+
return False
|
|
507
|
+
return response.status_code in self._retry_config.retry_statuses
|
|
508
|
+
|
|
509
|
+
def _calculate_backoff(self, attempt: int, retry_after: int | None = None) -> float:
|
|
510
|
+
"""Calculate backoff delay for retry.
|
|
511
|
+
|
|
512
|
+
Args:
|
|
513
|
+
attempt: The current retry attempt number (0-indexed).
|
|
514
|
+
retry_after: Explicit retry delay in seconds from server (optional).
|
|
515
|
+
|
|
516
|
+
Returns:
|
|
517
|
+
Number of seconds to wait before retrying.
|
|
518
|
+
"""
|
|
519
|
+
if retry_after:
|
|
520
|
+
return float(retry_after)
|
|
521
|
+
|
|
522
|
+
# Exponential backoff: base_delay * (exponential_base ^ attempt)
|
|
523
|
+
delay = self._retry_config.base_delay * (self._retry_config.exponential_base**attempt)
|
|
524
|
+
return min(delay, self._retry_config.max_delay)
|
|
525
|
+
|
|
526
|
+
# -------------------------------------------------------------------------
|
|
527
|
+
# Async request methods
|
|
528
|
+
# -------------------------------------------------------------------------
|
|
529
|
+
|
|
530
|
+
async def _request_async(
|
|
531
|
+
self,
|
|
532
|
+
method: str,
|
|
533
|
+
path: str,
|
|
534
|
+
*,
|
|
535
|
+
json: dict | None = None,
|
|
536
|
+
params: dict | None = None,
|
|
537
|
+
headers: dict[str, str] | None = None,
|
|
538
|
+
) -> httpx.Response:
|
|
539
|
+
"""Make an async HTTP request with retry logic."""
|
|
540
|
+
client = self._get_async_client()
|
|
541
|
+
last_response: httpx.Response | None = None
|
|
542
|
+
|
|
543
|
+
for attempt in range(self._max_retries + 1):
|
|
544
|
+
try:
|
|
545
|
+
response = await client.request(
|
|
546
|
+
method,
|
|
547
|
+
path,
|
|
548
|
+
json=json,
|
|
549
|
+
params=params,
|
|
550
|
+
headers=headers,
|
|
551
|
+
)
|
|
552
|
+
last_response = response
|
|
553
|
+
|
|
554
|
+
if response.is_success:
|
|
555
|
+
return response
|
|
556
|
+
|
|
557
|
+
if self._should_retry(response, attempt):
|
|
558
|
+
retry_after = self._parse_retry_after(response)
|
|
559
|
+
delay = self._calculate_backoff(attempt, retry_after)
|
|
560
|
+
await asyncio.sleep(delay)
|
|
561
|
+
continue
|
|
562
|
+
|
|
563
|
+
# Non-retryable error
|
|
564
|
+
self._raise_for_status(response)
|
|
565
|
+
|
|
566
|
+
except httpx.TimeoutException as e:
|
|
567
|
+
if attempt < self._max_retries:
|
|
568
|
+
await asyncio.sleep(self._calculate_backoff(attempt))
|
|
569
|
+
continue
|
|
570
|
+
raise HoneycombTimeoutError(timeout=self._timeout) from e
|
|
571
|
+
|
|
572
|
+
except httpx.ConnectError as e:
|
|
573
|
+
if attempt < self._max_retries:
|
|
574
|
+
await asyncio.sleep(self._calculate_backoff(attempt))
|
|
575
|
+
continue
|
|
576
|
+
raise HoneycombConnectionError(original_error=e) from e
|
|
577
|
+
|
|
578
|
+
# Should not reach here, but just in case
|
|
579
|
+
if last_response is not None:
|
|
580
|
+
self._raise_for_status(last_response)
|
|
581
|
+
raise HoneycombAPIError("Max retries exceeded", 0)
|
|
582
|
+
|
|
583
|
+
async def get_async(self, path: str, *, params: dict | None = None) -> httpx.Response:
|
|
584
|
+
"""Make an async GET request."""
|
|
585
|
+
return await self._request_async("GET", path, params=params)
|
|
586
|
+
|
|
587
|
+
async def post_async(
|
|
588
|
+
self,
|
|
589
|
+
path: str,
|
|
590
|
+
*,
|
|
591
|
+
json: dict | None = None,
|
|
592
|
+
params: dict | None = None,
|
|
593
|
+
headers: dict[str, str] | None = None,
|
|
594
|
+
) -> httpx.Response:
|
|
595
|
+
"""Make an async POST request."""
|
|
596
|
+
return await self._request_async("POST", path, json=json, params=params, headers=headers)
|
|
597
|
+
|
|
598
|
+
async def put_async(
|
|
599
|
+
self,
|
|
600
|
+
path: str,
|
|
601
|
+
*,
|
|
602
|
+
json: dict | None = None,
|
|
603
|
+
params: dict | None = None,
|
|
604
|
+
headers: dict[str, str] | None = None,
|
|
605
|
+
) -> httpx.Response:
|
|
606
|
+
"""Make an async PUT request."""
|
|
607
|
+
return await self._request_async("PUT", path, json=json, params=params, headers=headers)
|
|
608
|
+
|
|
609
|
+
async def patch_async(
|
|
610
|
+
self,
|
|
611
|
+
path: str,
|
|
612
|
+
*,
|
|
613
|
+
json: dict | None = None,
|
|
614
|
+
params: dict | None = None,
|
|
615
|
+
headers: dict[str, str] | None = None,
|
|
616
|
+
) -> httpx.Response:
|
|
617
|
+
"""Make an async PATCH request."""
|
|
618
|
+
return await self._request_async("PATCH", path, json=json, params=params, headers=headers)
|
|
619
|
+
|
|
620
|
+
async def delete_async(self, path: str, *, params: dict | None = None) -> httpx.Response:
|
|
621
|
+
"""Make an async DELETE request."""
|
|
622
|
+
return await self._request_async("DELETE", path, params=params)
|
|
623
|
+
|
|
624
|
+
# -------------------------------------------------------------------------
|
|
625
|
+
# Sync request methods
|
|
626
|
+
# -------------------------------------------------------------------------
|
|
627
|
+
|
|
628
|
+
def _request_sync(
|
|
629
|
+
self,
|
|
630
|
+
method: str,
|
|
631
|
+
path: str,
|
|
632
|
+
*,
|
|
633
|
+
json: dict | None = None,
|
|
634
|
+
params: dict | None = None,
|
|
635
|
+
headers: dict[str, str] | None = None,
|
|
636
|
+
) -> httpx.Response:
|
|
637
|
+
"""Make a sync HTTP request with retry logic."""
|
|
638
|
+
import time
|
|
639
|
+
|
|
640
|
+
client = self._get_sync_client()
|
|
641
|
+
last_response: httpx.Response | None = None
|
|
642
|
+
|
|
643
|
+
for attempt in range(self._max_retries + 1):
|
|
644
|
+
try:
|
|
645
|
+
response = client.request(
|
|
646
|
+
method,
|
|
647
|
+
path,
|
|
648
|
+
json=json,
|
|
649
|
+
params=params,
|
|
650
|
+
headers=headers,
|
|
651
|
+
)
|
|
652
|
+
last_response = response
|
|
653
|
+
|
|
654
|
+
if response.is_success:
|
|
655
|
+
return response
|
|
656
|
+
|
|
657
|
+
if self._should_retry(response, attempt):
|
|
658
|
+
retry_after = self._parse_retry_after(response)
|
|
659
|
+
delay = self._calculate_backoff(attempt, retry_after)
|
|
660
|
+
time.sleep(delay)
|
|
661
|
+
continue
|
|
662
|
+
|
|
663
|
+
# Non-retryable error
|
|
664
|
+
self._raise_for_status(response)
|
|
665
|
+
|
|
666
|
+
except httpx.TimeoutException as e:
|
|
667
|
+
if attempt < self._max_retries:
|
|
668
|
+
time.sleep(self._calculate_backoff(attempt))
|
|
669
|
+
continue
|
|
670
|
+
raise HoneycombTimeoutError(timeout=self._timeout) from e
|
|
671
|
+
|
|
672
|
+
except httpx.ConnectError as e:
|
|
673
|
+
if attempt < self._max_retries:
|
|
674
|
+
time.sleep(self._calculate_backoff(attempt))
|
|
675
|
+
continue
|
|
676
|
+
raise HoneycombConnectionError(original_error=e) from e
|
|
677
|
+
|
|
678
|
+
# Should not reach here, but just in case
|
|
679
|
+
if last_response is not None:
|
|
680
|
+
self._raise_for_status(last_response)
|
|
681
|
+
raise HoneycombAPIError("Max retries exceeded", 0)
|
|
682
|
+
|
|
683
|
+
def get_sync(self, path: str, *, params: dict | None = None) -> httpx.Response:
|
|
684
|
+
"""Make a sync GET request."""
|
|
685
|
+
return self._request_sync("GET", path, params=params)
|
|
686
|
+
|
|
687
|
+
def post_sync(
|
|
688
|
+
self,
|
|
689
|
+
path: str,
|
|
690
|
+
*,
|
|
691
|
+
json: dict | None = None,
|
|
692
|
+
params: dict | None = None,
|
|
693
|
+
headers: dict[str, str] | None = None,
|
|
694
|
+
) -> httpx.Response:
|
|
695
|
+
"""Make a sync POST request."""
|
|
696
|
+
return self._request_sync("POST", path, json=json, params=params, headers=headers)
|
|
697
|
+
|
|
698
|
+
def put_sync(
|
|
699
|
+
self,
|
|
700
|
+
path: str,
|
|
701
|
+
*,
|
|
702
|
+
json: dict | None = None,
|
|
703
|
+
params: dict | None = None,
|
|
704
|
+
headers: dict[str, str] | None = None,
|
|
705
|
+
) -> httpx.Response:
|
|
706
|
+
"""Make a sync PUT request."""
|
|
707
|
+
return self._request_sync("PUT", path, json=json, params=params, headers=headers)
|
|
708
|
+
|
|
709
|
+
def patch_sync(
|
|
710
|
+
self,
|
|
711
|
+
path: str,
|
|
712
|
+
*,
|
|
713
|
+
json: dict | None = None,
|
|
714
|
+
params: dict | None = None,
|
|
715
|
+
headers: dict[str, str] | None = None,
|
|
716
|
+
) -> httpx.Response:
|
|
717
|
+
"""Make a sync PATCH request."""
|
|
718
|
+
return self._request_sync("PATCH", path, json=json, params=params, headers=headers)
|
|
719
|
+
|
|
720
|
+
def delete_sync(self, path: str, *, params: dict | None = None) -> httpx.Response:
|
|
721
|
+
"""Make a sync DELETE request."""
|
|
722
|
+
return self._request_sync("DELETE", path, params=params)
|
|
723
|
+
|
|
724
|
+
# -------------------------------------------------------------------------
|
|
725
|
+
# Convenience properties
|
|
726
|
+
# -------------------------------------------------------------------------
|
|
727
|
+
|
|
728
|
+
@property
|
|
729
|
+
def is_sync(self) -> bool:
|
|
730
|
+
"""Return True if client is in sync mode."""
|
|
731
|
+
return self._sync_mode
|
|
732
|
+
|
|
733
|
+
@property
|
|
734
|
+
def base_url(self) -> str:
|
|
735
|
+
"""Return the API base URL."""
|
|
736
|
+
return self._base_url
|