honeycomb-api 0.1.0__py3-none-any.whl → 0.5.3__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 +9 -0
- honeycomb/_generated/api/auth/get_auth.py +2 -5
- honeycomb/_generated/api/auth/get_v2_auth.py +2 -5
- honeycomb/_generated/api/boards/create_board.py +6 -5
- honeycomb/_generated/api/boards/create_board_view.py +14 -9
- honeycomb/_generated/api/boards/delete_board.py +2 -5
- honeycomb/_generated/api/boards/delete_board_view.py +2 -5
- honeycomb/_generated/api/boards/get_board.py +2 -5
- honeycomb/_generated/api/boards/get_board_view.py +2 -5
- honeycomb/_generated/api/boards/list_board_views.py +10 -9
- honeycomb/_generated/api/boards/list_boards.py +2 -5
- honeycomb/_generated/api/boards/update_board.py +10 -5
- honeycomb/_generated/api/boards/update_board_view.py +2 -5
- honeycomb/_generated/api/burn_alerts/create_burn_alert.py +6 -8
- honeycomb/_generated/api/burn_alerts/delete_burn_alert.py +2 -5
- honeycomb/_generated/api/burn_alerts/get_burn_alert.py +2 -5
- honeycomb/_generated/api/burn_alerts/list_burn_alerts_by_slo.py +2 -5
- honeycomb/_generated/api/calculated_fields/create_calculated_field.py +2 -5
- honeycomb/_generated/api/calculated_fields/delete_calculated_field.py +2 -5
- honeycomb/_generated/api/calculated_fields/get_calculated_field.py +2 -5
- honeycomb/_generated/api/calculated_fields/list_calculated_fields.py +2 -8
- honeycomb/_generated/api/calculated_fields/update_calculated_field.py +2 -5
- honeycomb/_generated/api/columns/create_column.py +2 -5
- honeycomb/_generated/api/columns/delete_column.py +2 -5
- honeycomb/_generated/api/columns/get_column.py +2 -5
- honeycomb/_generated/api/columns/list_columns.py +2 -8
- honeycomb/_generated/api/columns/update_column.py +2 -5
- honeycomb/_generated/api/dataset_definitions/list_dataset_definitions.py +2 -5
- honeycomb/_generated/api/dataset_definitions/patch_dataset_definitions.py +2 -5
- honeycomb/_generated/api/datasets/create_dataset.py +2 -5
- honeycomb/_generated/api/datasets/delete_dataset.py +2 -5
- honeycomb/_generated/api/datasets/get_dataset.py +2 -5
- honeycomb/_generated/api/datasets/list_datasets.py +2 -5
- honeycomb/_generated/api/datasets/update_dataset.py +2 -5
- honeycomb/_generated/api/enhance/record_enhance_indexer_usage.py +4 -6
- honeycomb/_generated/api/environments/create_environment.py +2 -5
- honeycomb/_generated/api/environments/delete_environment.py +2 -5
- honeycomb/_generated/api/environments/get_environment.py +2 -5
- honeycomb/_generated/api/environments/list_environments.py +2 -7
- honeycomb/_generated/api/environments/update_environment.py +2 -5
- honeycomb/_generated/api/events/create_event.py +2 -7
- honeycomb/_generated/api/events/create_events.py +7 -11
- honeycomb/_generated/api/key_management/create_api_key.py +2 -5
- honeycomb/_generated/api/key_management/delete_api_key.py +2 -5
- honeycomb/_generated/api/key_management/get_api_key.py +2 -5
- honeycomb/_generated/api/key_management/list_api_keys.py +2 -7
- honeycomb/_generated/api/key_management/update_api_key.py +2 -5
- honeycomb/_generated/api/kinesis_events/create_kinesis_events.py +2 -5
- honeycomb/_generated/api/marker_settings/create_marker_setting.py +2 -5
- honeycomb/_generated/api/marker_settings/delete_marker_settings.py +2 -5
- honeycomb/_generated/api/marker_settings/list_marker_settings.py +2 -5
- honeycomb/_generated/api/marker_settings/update_marker_settings.py +2 -5
- honeycomb/_generated/api/markers/create_marker.py +2 -5
- honeycomb/_generated/api/markers/create_marker_v2.py +2 -5
- honeycomb/_generated/api/markers/delete_marker.py +2 -5
- honeycomb/_generated/api/markers/get_marker.py +2 -5
- honeycomb/_generated/api/markers/update_marker.py +2 -5
- honeycomb/_generated/api/markers/update_marker_v2.py +2 -5
- honeycomb/_generated/api/pipelines/get_pipeline_configuration.py +4 -8
- honeycomb/_generated/api/pipelines/record_pipeline_usage.py +4 -6
- honeycomb/_generated/api/pipelines/update_pipeline_configuration_rollout.py +6 -7
- honeycomb/_generated/api/queries/create_query.py +2 -5
- honeycomb/_generated/api/queries/get_query.py +2 -5
- honeycomb/_generated/api/query_annotations/create_query_annotation.py +2 -5
- honeycomb/_generated/api/query_annotations/delete_query_annotation.py +2 -5
- honeycomb/_generated/api/query_annotations/get_query_annotation.py +2 -5
- honeycomb/_generated/api/query_annotations/list_query_annotations.py +2 -7
- honeycomb/_generated/api/query_annotations/update_query_annotation.py +2 -5
- honeycomb/_generated/api/query_data/create_query_result.py +2 -5
- honeycomb/_generated/api/query_data/get_query_result.py +2 -5
- honeycomb/_generated/api/recipients/create_recipient.py +2 -6
- honeycomb/_generated/api/recipients/delete_recipient.py +2 -5
- honeycomb/_generated/api/recipients/get_recipient.py +2 -6
- honeycomb/_generated/api/recipients/list_recipients.py +2 -6
- honeycomb/_generated/api/recipients/update_recipient.py +2 -6
- honeycomb/_generated/api/reporting/get_slo_history.py +2 -5
- honeycomb/_generated/api/service_maps/create_map_dependency_request.py +6 -9
- honeycomb/_generated/api/service_maps/get_map_dependencies.py +2 -7
- honeycomb/_generated/api/sl_os/create_slo.py +2 -5
- honeycomb/_generated/api/sl_os/delete_slo.py +2 -5
- honeycomb/_generated/api/sl_os/get_slo.py +2 -8
- honeycomb/_generated/api/sl_os/list_slos.py +2 -5
- honeycomb/_generated/api/sl_os/update_slo.py +2 -5
- honeycomb/_generated/api/triggers/create_trigger.py +2 -6
- honeycomb/_generated/api/triggers/delete_trigger.py +2 -5
- honeycomb/_generated/api/triggers/get_trigger.py +2 -5
- honeycomb/_generated/api/triggers/list_triggers.py +2 -5
- honeycomb/_generated/api/triggers/list_triggers_with_recipient.py +2 -5
- honeycomb/_generated/api/triggers/update_trigger.py +2 -5
- honeycomb/_generated/client.py +2 -5
- honeycomb/_generated/models/__init__.py +195 -88
- honeycomb/_generated/models/api_key_create_request.py +6 -5
- honeycomb/_generated/models/api_key_create_request_data.py +15 -11
- honeycomb/_generated/models/api_key_create_request_data_relationships.py +2 -3
- honeycomb/_generated/models/api_key_create_request_data_type.py +1 -0
- honeycomb/_generated/models/api_key_list_response.py +2 -5
- honeycomb/_generated/models/api_key_object.py +14 -14
- honeycomb/_generated/models/api_key_object_links.py +2 -9
- honeycomb/_generated/models/api_key_object_relationships.py +5 -9
- honeycomb/_generated/models/api_key_object_type.py +1 -0
- honeycomb/_generated/models/api_key_response.py +2 -3
- honeycomb/_generated/models/api_key_update_request.py +15 -17
- honeycomb/_generated/models/auth.py +2 -5
- honeycomb/_generated/models/auth_api_key_access.py +2 -9
- honeycomb/_generated/models/auth_environment.py +2 -9
- honeycomb/_generated/models/auth_team.py +2 -9
- honeycomb/_generated/models/auth_type.py +1 -0
- honeycomb/_generated/models/auth_v2_response.py +5 -8
- honeycomb/_generated/models/auth_v2_response_data.py +14 -11
- honeycomb/_generated/models/auth_v2_response_data_attributes.py +10 -9
- honeycomb/_generated/models/auth_v2_response_data_attributes_key_type.py +1 -0
- honeycomb/_generated/models/auth_v2_response_data_attributes_timestamps.py +4 -12
- honeycomb/_generated/models/auth_v2_response_data_relationships.py +1 -7
- honeycomb/_generated/models/auth_v2_response_data_type.py +1 -0
- honeycomb/_generated/models/base_trigger.py +21 -18
- honeycomb/_generated/models/base_trigger_alert_type.py +1 -0
- honeycomb/_generated/models/base_trigger_baseline_details_type_0.py +5 -9
- honeycomb/_generated/models/base_trigger_baseline_details_type_0_offset_minutes.py +1 -0
- honeycomb/_generated/models/base_trigger_baseline_details_type_0_type.py +1 -0
- honeycomb/_generated/models/base_trigger_evaluation_schedule.py +8 -6
- honeycomb/_generated/models/base_trigger_evaluation_schedule_type.py +1 -0
- honeycomb/_generated/models/base_trigger_evaluation_schedule_window.py +4 -9
- honeycomb/_generated/models/base_trigger_evaluation_schedule_window_days_of_week_item.py +1 -0
- honeycomb/_generated/models/base_trigger_threshold.py +2 -9
- honeycomb/_generated/models/base_trigger_threshold_op.py +1 -0
- honeycomb/_generated/models/batch_event.py +2 -5
- honeycomb/_generated/models/board.py +15 -17
- honeycomb/_generated/models/board_layout_generation.py +1 -0
- honeycomb/_generated/models/board_links.py +2 -9
- honeycomb/_generated/models/board_panel_position.py +2 -9
- honeycomb/_generated/models/board_query_visualization_settings.py +8 -8
- honeycomb/_generated/models/board_query_visualization_settings_charts_item.py +4 -10
- honeycomb/_generated/models/board_query_visualization_settings_charts_item_chart_type.py +1 -0
- honeycomb/_generated/models/board_type.py +1 -0
- honeycomb/_generated/models/board_view_filter.py +2 -9
- honeycomb/_generated/models/board_view_filter_operation.py +1 -0
- honeycomb/_generated/models/board_view_response.py +2 -5
- honeycomb/_generated/models/budget_rate.py +4 -12
- honeycomb/_generated/models/budget_rate_alert_type.py +1 -0
- honeycomb/_generated/models/burn_alert_shared_params.py +4 -12
- honeycomb/_generated/models/calculated_field.py +2 -9
- honeycomb/_generated/models/configuration_key_attributes.py +16 -12
- honeycomb/_generated/models/configuration_key_attributes_key_type.py +1 -0
- honeycomb/_generated/models/configuration_key_attributes_permissions.py +172 -0
- honeycomb/_generated/models/configuration_key_attributes_timestamps.py +4 -12
- honeycomb/_generated/models/configuration_key_request.py +101 -0
- honeycomb/_generated/models/configuration_key_request_attributes.py +107 -0
- honeycomb/_generated/models/configuration_key_request_attributes_permissions.py +168 -0
- honeycomb/_generated/models/configuration_key_request_type.py +8 -0
- honeycomb/_generated/models/create_board_view_request.py +2 -3
- honeycomb/_generated/models/create_budget_rate_burn_alert_request.py +10 -10
- honeycomb/_generated/models/create_budget_rate_burn_alert_request_slo.py +1 -7
- honeycomb/_generated/models/create_column.py +2 -9
- honeycomb/_generated/models/create_column_type.py +1 -0
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request.py +8 -6
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data.py +10 -7
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes.py +8 -8
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data.py +8 -6
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item.py +8 -6
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item.py +8 -6
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item.py +8 -8
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum.py +10 -7
- 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 +1 -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 +8 -6
- 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 +8 -6
- 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 +2 -9
- honeycomb/_generated/models/create_enhance_indexer_usage_record_request_data_type.py +1 -0
- honeycomb/_generated/models/create_environment_request.py +8 -6
- honeycomb/_generated/models/create_environment_request_data.py +10 -7
- honeycomb/_generated/models/create_environment_request_data_attributes.py +2 -9
- honeycomb/_generated/models/create_environment_request_data_type.py +1 -0
- honeycomb/_generated/models/create_events_content_encoding.py +1 -0
- honeycomb/_generated/models/create_events_response_200_item.py +2 -9
- honeycomb/_generated/models/create_exhaustion_time_burn_alert_request.py +10 -10
- honeycomb/_generated/models/create_exhaustion_time_burn_alert_request_slo.py +1 -7
- honeycomb/_generated/models/create_map_dependencies_request.py +2 -5
- honeycomb/_generated/models/create_map_dependencies_response.py +4 -10
- honeycomb/_generated/models/create_map_dependencies_response_status.py +1 -0
- honeycomb/_generated/models/create_pipeline_health_record_request.py +8 -6
- honeycomb/_generated/models/create_pipeline_health_record_request_data.py +10 -7
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes.py +8 -8
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data.py +8 -6
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item.py +8 -6
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item.py +8 -6
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item.py +8 -8
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum.py +10 -7
- honeycomb/_generated/models/create_pipeline_health_record_request_data_attributes_usage_data_resource_metrics_item_scope_metrics_item_metrics_item_sum_aggregation_temporality.py +1 -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 +8 -6
- 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 +8 -6
- 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 +2 -9
- honeycomb/_generated/models/create_pipeline_health_record_request_data_type.py +1 -0
- honeycomb/_generated/models/create_query_result_request.py +2 -9
- honeycomb/_generated/models/dataset.py +2 -6
- honeycomb/_generated/models/dataset_creation_payload.py +2 -9
- honeycomb/_generated/models/dataset_definition_type_1.py +4 -10
- honeycomb/_generated/models/dataset_definition_type_1_column_type.py +1 -0
- honeycomb/_generated/models/dataset_definitions.py +2 -6
- honeycomb/_generated/models/dataset_relationship.py +2 -3
- honeycomb/_generated/models/dataset_relationship_data.py +2 -8
- honeycomb/_generated/models/dataset_relationship_data_type.py +1 -0
- honeycomb/_generated/models/dataset_settings.py +2 -9
- honeycomb/_generated/models/dataset_update_payload.py +8 -8
- honeycomb/_generated/models/dataset_update_payload_settings.py +2 -9
- honeycomb/_generated/models/detailed_error.py +2 -9
- honeycomb/_generated/models/email_recipient.py +4 -7
- honeycomb/_generated/models/email_recipient_details.py +1 -7
- honeycomb/_generated/models/email_recipient_type.py +1 -0
- honeycomb/_generated/models/environment.py +6 -7
- honeycomb/_generated/models/environment_attributes.py +11 -9
- honeycomb/_generated/models/environment_attributes_color_type_1.py +1 -0
- honeycomb/_generated/models/environment_attributes_settings.py +1 -7
- honeycomb/_generated/models/environment_color.py +1 -0
- honeycomb/_generated/models/environment_links.py +1 -7
- honeycomb/_generated/models/environment_list_response.py +2 -5
- honeycomb/_generated/models/environment_relationship.py +8 -6
- honeycomb/_generated/models/environment_relationship_data.py +3 -8
- honeycomb/_generated/models/environment_relationship_data_type.py +1 -0
- honeycomb/_generated/models/environment_response.py +2 -3
- honeycomb/_generated/models/environment_type.py +1 -0
- honeycomb/_generated/models/error.py +2 -9
- honeycomb/_generated/models/event.py +2 -8
- honeycomb/_generated/models/exhaustion_time.py +4 -12
- honeycomb/_generated/models/exhaustion_time_alert_type.py +1 -0
- honeycomb/_generated/models/exhaustion_time_burn_alert_list_response.py +10 -10
- honeycomb/_generated/models/exhaustion_time_burn_alert_list_response_slo.py +2 -9
- honeycomb/_generated/models/filter_op.py +1 -0
- honeycomb/_generated/models/get_map_dependencies_response.py +7 -10
- honeycomb/_generated/models/get_map_dependencies_response_status.py +1 -0
- honeycomb/_generated/models/having_calculate_op.py +1 -0
- honeycomb/_generated/models/having_op.py +1 -0
- honeycomb/_generated/models/included_resource.py +6 -7
- honeycomb/_generated/models/included_resource_attributes.py +1 -7
- honeycomb/_generated/models/ingest_key_attributes.py +14 -11
- honeycomb/_generated/models/ingest_key_attributes_key_type.py +1 -0
- honeycomb/_generated/models/ingest_key_attributes_permissions.py +2 -9
- honeycomb/_generated/models/ingest_key_attributes_timestamps.py +4 -12
- honeycomb/_generated/models/ingest_key_request.py +100 -0
- honeycomb/_generated/models/ingest_key_request_attributes.py +75 -0
- honeycomb/_generated/models/ingest_key_request_type.py +8 -0
- honeycomb/_generated/models/ingest_key_type.py +2 -9
- honeycomb/_generated/models/ingest_key_type_key_type.py +1 -0
- honeycomb/_generated/models/jsonapi_error_source.py +2 -9
- honeycomb/_generated/models/kinesis_event.py +2 -5
- honeycomb/_generated/models/kinesis_event_record.py +2 -9
- honeycomb/_generated/models/kinesis_response.py +2 -9
- honeycomb/_generated/models/list_api_keys_filtertype.py +1 -0
- honeycomb/_generated/models/map_dependency.py +2 -5
- honeycomb/_generated/models/map_node.py +2 -9
- honeycomb/_generated/models/map_node_type.py +1 -0
- honeycomb/_generated/models/marker.py +2 -9
- honeycomb/_generated/models/marker_create_request.py +2 -3
- honeycomb/_generated/models/marker_create_request_data.py +16 -10
- honeycomb/_generated/models/marker_create_request_data_attributes.py +2 -9
- honeycomb/_generated/models/marker_create_request_data_relationships.py +2 -3
- honeycomb/_generated/models/marker_create_request_data_type.py +1 -0
- honeycomb/_generated/models/marker_object.py +7 -8
- honeycomb/_generated/models/marker_object_attributes.py +8 -8
- honeycomb/_generated/models/marker_object_attributes_timestamps.py +4 -12
- honeycomb/_generated/models/marker_object_links.py +2 -9
- honeycomb/_generated/models/marker_object_relationships.py +8 -8
- honeycomb/_generated/models/marker_object_relationships_dataset.py +8 -9
- honeycomb/_generated/models/marker_object_relationships_dataset_data_type_0.py +4 -10
- honeycomb/_generated/models/marker_object_relationships_dataset_data_type_0_type.py +1 -0
- honeycomb/_generated/models/marker_object_type.py +1 -0
- honeycomb/_generated/models/marker_response.py +2 -3
- honeycomb/_generated/models/marker_setting.py +2 -10
- honeycomb/_generated/models/marker_update_request.py +2 -3
- honeycomb/_generated/models/marker_update_request_data.py +16 -10
- honeycomb/_generated/models/marker_update_request_data_attributes.py +2 -9
- honeycomb/_generated/models/marker_update_request_data_relationships.py +2 -3
- honeycomb/_generated/models/marker_update_request_data_type.py +1 -0
- honeycomb/_generated/models/ms_teams_recipient.py +4 -7
- honeycomb/_generated/models/ms_teams_recipient_details.py +1 -7
- honeycomb/_generated/models/ms_teams_recipient_type.py +1 -0
- honeycomb/_generated/models/ms_teams_workflow_recipient.py +12 -11
- honeycomb/_generated/models/ms_teams_workflow_recipient_details.py +1 -7
- honeycomb/_generated/models/ms_teams_workflow_recipient_type.py +1 -0
- honeycomb/_generated/models/notification_recipient.py +8 -8
- honeycomb/_generated/models/notification_recipient_details.py +10 -9
- honeycomb/_generated/models/notification_recipient_details_pagerduty_severity.py +1 -0
- honeycomb/_generated/models/notification_recipient_details_variables_item.py +2 -9
- honeycomb/_generated/models/pager_duty_recipient.py +8 -9
- honeycomb/_generated/models/pager_duty_recipient_details.py +1 -7
- honeycomb/_generated/models/pager_duty_recipient_type.py +1 -0
- honeycomb/_generated/models/pagination_links.py +2 -8
- honeycomb/_generated/models/payload_template.py +2 -9
- honeycomb/_generated/models/pipeline_configuration_response.py +16 -10
- honeycomb/_generated/models/pipeline_configuration_response_attributes.py +8 -8
- honeycomb/_generated/models/pipeline_configuration_response_attributes_configs_item.py +1 -7
- honeycomb/_generated/models/pipeline_configuration_response_links.py +2 -9
- honeycomb/_generated/models/pipeline_configuration_response_type.py +1 -0
- honeycomb/_generated/models/pipeline_configuration_rollout.py +16 -10
- honeycomb/_generated/models/pipeline_configuration_rollout_attributes.py +3 -8
- honeycomb/_generated/models/pipeline_configuration_rollout_attributes_status.py +1 -0
- honeycomb/_generated/models/pipeline_configuration_rollout_links.py +2 -9
- honeycomb/_generated/models/pipeline_configuration_rollout_type.py +1 -0
- honeycomb/_generated/models/preset_filter.py +1 -7
- honeycomb/_generated/models/query.py +11 -11
- honeycomb/_generated/models/query_annotation.py +4 -12
- honeycomb/_generated/models/query_annotation_source.py +1 -0
- honeycomb/_generated/models/query_calculated_fields_item.py +1 -7
- honeycomb/_generated/models/query_calculations_item.py +2 -10
- honeycomb/_generated/models/query_compare_time_offset_seconds.py +1 -0
- honeycomb/_generated/models/query_filter_combination.py +1 -0
- honeycomb/_generated/models/query_filters_item.py +2 -11
- honeycomb/_generated/models/query_havings_item.py +2 -10
- honeycomb/_generated/models/query_op.py +1 -0
- honeycomb/_generated/models/query_orders_item.py +2 -9
- honeycomb/_generated/models/query_orders_item_order.py +1 -0
- honeycomb/_generated/models/query_panel.py +2 -6
- honeycomb/_generated/models/query_panel_query_panel.py +10 -9
- honeycomb/_generated/models/query_panel_query_panel_query_style.py +1 -0
- honeycomb/_generated/models/query_result.py +2 -5
- honeycomb/_generated/models/query_result_details.py +5 -8
- honeycomb/_generated/models/query_result_details_data.py +5 -8
- honeycomb/_generated/models/query_result_details_links.py +2 -9
- honeycomb/_generated/models/query_result_links.py +2 -9
- honeycomb/_generated/models/query_results_data.py +2 -5
- honeycomb/_generated/models/query_results_data_data.py +2 -8
- honeycomb/_generated/models/query_results_series.py +2 -5
- honeycomb/_generated/models/recipient_properties.py +4 -12
- honeycomb/_generated/models/recipient_type.py +1 -0
- honeycomb/_generated/models/slack_recipient.py +4 -7
- honeycomb/_generated/models/slack_recipient_details.py +1 -7
- honeycomb/_generated/models/slack_recipient_type.py +1 -0
- honeycomb/_generated/models/slo.py +4 -8
- honeycomb/_generated/models/slo_create.py +4 -8
- honeycomb/_generated/models/slo_create_sli.py +1 -7
- honeycomb/_generated/models/slo_detailed_response.py +4 -8
- honeycomb/_generated/models/slo_detailed_response_status.py +1 -0
- honeycomb/_generated/models/slo_history.py +2 -9
- honeycomb/_generated/models/slo_history_request.py +2 -8
- honeycomb/_generated/models/slo_history_response.py +2 -3
- honeycomb/_generated/models/slo_panel.py +2 -6
- honeycomb/_generated/models/slo_panel_slo_panel.py +2 -9
- honeycomb/_generated/models/slo_sli.py +1 -7
- honeycomb/_generated/models/tag.py +1 -7
- honeycomb/_generated/models/team_relationship.py +2 -3
- honeycomb/_generated/models/team_relationship_team.py +6 -5
- honeycomb/_generated/models/team_relationship_team_data.py +3 -8
- honeycomb/_generated/models/team_relationship_team_data_type.py +1 -0
- honeycomb/_generated/models/template_variable_definition.py +2 -9
- honeycomb/_generated/models/text_panel.py +2 -6
- honeycomb/_generated/models/text_panel_text_panel.py +1 -7
- honeycomb/_generated/models/trigger_response.py +27 -21
- honeycomb/_generated/models/trigger_with_inline_query.py +27 -21
- honeycomb/_generated/models/trigger_with_inline_query_query.py +1 -7
- honeycomb/_generated/models/trigger_with_query_reference.py +21 -18
- honeycomb/_generated/models/update_board_view_request.py +2 -5
- honeycomb/_generated/models/update_environment_request.py +8 -6
- honeycomb/_generated/models/update_environment_request_data.py +10 -7
- honeycomb/_generated/models/update_environment_request_data_attributes.py +8 -8
- honeycomb/_generated/models/update_environment_request_data_attributes_settings.py +2 -9
- honeycomb/_generated/models/update_environment_request_data_type.py +1 -0
- honeycomb/_generated/models/update_exhaustion_time_burn_alert_request.py +4 -7
- honeycomb/_generated/models/update_pipeline_configuration_rollout.py +10 -7
- honeycomb/_generated/models/update_pipeline_configuration_rollout_attributes.py +3 -8
- honeycomb/_generated/models/update_pipeline_configuration_rollout_attributes_status.py +1 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request.py +8 -6
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request_data.py +10 -7
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request_data_attributes.py +3 -8
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request_data_attributes_status.py +1 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_request_data_type.py +1 -0
- honeycomb/_generated/models/update_pipeline_configuration_rollout_response.py +8 -6
- honeycomb/_generated/models/update_pipeline_configuration_rollout_type.py +1 -0
- honeycomb/_generated/models/user_relationship.py +2 -3
- honeycomb/_generated/models/user_relationship_data.py +2 -8
- honeycomb/_generated/models/user_relationship_data_type.py +1 -0
- honeycomb/_generated/models/validation_error.py +8 -8
- honeycomb/_generated/models/validation_error_type_detail_item.py +4 -10
- honeycomb/_generated/models/validation_error_type_detail_item_code.py +1 -0
- honeycomb/_generated/models/webhook_header.py +2 -9
- honeycomb/_generated/models/webhook_recipient.py +4 -7
- honeycomb/_generated/models/webhook_recipient_details.py +8 -8
- honeycomb/_generated/models/webhook_recipient_details_webhook_payloads.py +12 -10
- honeycomb/_generated/models/webhook_recipient_details_webhook_payloads_payload_templates.py +2 -5
- honeycomb/_generated/models/webhook_recipient_type.py +1 -0
- honeycomb/_generated/types.py +1 -1
- honeycomb/cli/__init__.py +85 -0
- honeycomb/cli/api_keys.py +205 -0
- honeycomb/cli/auth.py +70 -0
- honeycomb/cli/boards.py +203 -0
- honeycomb/cli/columns.py +256 -0
- honeycomb/cli/config.py +259 -0
- honeycomb/cli/datasets.py +186 -0
- honeycomb/cli/derived_columns.py +222 -0
- honeycomb/cli/environments.py +240 -0
- honeycomb/cli/formatters.py +242 -0
- honeycomb/cli/markers.py +151 -0
- honeycomb/cli/queries.py +380 -0
- honeycomb/cli/recipients.py +211 -0
- honeycomb/cli/slos.py +338 -0
- honeycomb/cli/triggers.py +271 -0
- honeycomb/client.py +13 -7
- honeycomb/models/__init__.py +18 -3
- honeycomb/models/api_keys.py +49 -5
- honeycomb/models/auth.py +71 -0
- honeycomb/models/board_builder.py +97 -25
- honeycomb/models/boards.py +95 -1
- honeycomb/models/datasets.py +42 -0
- honeycomb/models/queries.py +21 -0
- honeycomb/models/query_builder.py +119 -59
- honeycomb/models/recipient_builder.py +51 -4
- honeycomb/models/slo_builder.py +24 -19
- honeycomb/models/slos.py +50 -3
- honeycomb/models/tool_inputs.py +630 -0
- honeycomb/models/triggers.py +39 -9
- honeycomb/resources/__init__.py +2 -0
- honeycomb/resources/api_keys.py +66 -29
- honeycomb/resources/auth.py +97 -0
- honeycomb/resources/boards.py +272 -18
- honeycomb/resources/datasets.py +49 -11
- honeycomb/resources/environments.py +54 -31
- honeycomb/resources/slos.py +87 -61
- honeycomb/tools/__main__.py +40 -4
- honeycomb/tools/builders.py +235 -150
- honeycomb/tools/descriptions.py +175 -7
- honeycomb/tools/executor.py +212 -25
- honeycomb/tools/generator.py +61 -2264
- honeycomb/tools/resources/__init__.py +42 -0
- honeycomb/tools/resources/api_keys.py +249 -0
- honeycomb/tools/resources/auth.py +98 -0
- honeycomb/tools/resources/boards.py +313 -0
- honeycomb/tools/resources/burn_alerts.py +278 -0
- honeycomb/tools/resources/columns.py +257 -0
- honeycomb/tools/resources/datasets.py +215 -0
- honeycomb/tools/resources/derived_columns.py +311 -0
- honeycomb/tools/resources/environments.py +211 -0
- honeycomb/tools/resources/events.py +158 -0
- honeycomb/tools/resources/marker_settings.py +216 -0
- honeycomb/tools/resources/markers.py +197 -0
- honeycomb/tools/resources/queries.py +220 -0
- honeycomb/tools/resources/recipients.py +297 -0
- honeycomb/tools/resources/service_map.py +110 -0
- honeycomb/tools/resources/slos.py +276 -0
- honeycomb/tools/resources/triggers.py +328 -0
- honeycomb/tools/schemas.py +81 -0
- {honeycomb_api-0.1.0.dist-info → honeycomb_api-0.5.3.dist-info}/METADATA +33 -8
- honeycomb_api-0.5.3.dist-info/RECORD +497 -0
- honeycomb_api-0.5.3.dist-info/entry_points.txt +5 -0
- honeycomb_api-0.1.0.dist-info/RECORD +0 -453
- {honeycomb_api-0.1.0.dist-info → honeycomb_api-0.5.3.dist-info}/WHEEL +0 -0
- {honeycomb_api-0.1.0.dist-info → honeycomb_api-0.5.3.dist-info}/licenses/LICENSE +0 -0
honeycomb/models/queries.py
CHANGED
|
@@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
8
8
|
from pydantic import BaseModel, Field, field_validator
|
|
9
9
|
|
|
10
10
|
from honeycomb.models.query_builder import (
|
|
11
|
+
VALID_COMPARE_OFFSETS,
|
|
11
12
|
Calculation,
|
|
12
13
|
Filter,
|
|
13
14
|
FilterCombination,
|
|
@@ -91,6 +92,15 @@ class QuerySpec(BaseModel):
|
|
|
91
92
|
havings: list[Having | dict[str, Any]] | None = Field(
|
|
92
93
|
default=None, description="Having clauses"
|
|
93
94
|
)
|
|
95
|
+
calculated_fields: list[dict[str, str]] | None = Field(
|
|
96
|
+
default=None,
|
|
97
|
+
description="Inline calculated fields (derived columns) for this query",
|
|
98
|
+
)
|
|
99
|
+
compare_time_offset_seconds: int | None = Field(
|
|
100
|
+
default=None,
|
|
101
|
+
description="Compare against historical data offset by N seconds "
|
|
102
|
+
"(1800, 3600, 7200, 28800, 86400, 604800, 2419200, 15724800)",
|
|
103
|
+
)
|
|
94
104
|
|
|
95
105
|
@field_validator("limit")
|
|
96
106
|
@classmethod
|
|
@@ -104,6 +114,17 @@ class QuerySpec(BaseModel):
|
|
|
104
114
|
)
|
|
105
115
|
return v
|
|
106
116
|
|
|
117
|
+
@field_validator("compare_time_offset_seconds")
|
|
118
|
+
@classmethod
|
|
119
|
+
def validate_compare_time_offset(cls, v: int | None) -> int | None:
|
|
120
|
+
"""Validate that compare_time_offset_seconds is a valid offset value."""
|
|
121
|
+
if v is not None and v not in VALID_COMPARE_OFFSETS:
|
|
122
|
+
raise ValueError(
|
|
123
|
+
f"Invalid compare_time_offset_seconds: {v}. "
|
|
124
|
+
f"Must be one of: {sorted(VALID_COMPARE_OFFSETS)}"
|
|
125
|
+
)
|
|
126
|
+
return v
|
|
127
|
+
|
|
107
128
|
@classmethod
|
|
108
129
|
def builder(cls) -> QueryBuilder:
|
|
109
130
|
"""Create a QueryBuilder for fluent query construction.
|
|
@@ -11,12 +11,18 @@ from __future__ import annotations
|
|
|
11
11
|
from enum import Enum
|
|
12
12
|
from typing import TYPE_CHECKING, Any
|
|
13
13
|
|
|
14
|
-
from pydantic import BaseModel, Field
|
|
14
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
15
15
|
|
|
16
16
|
if TYPE_CHECKING:
|
|
17
17
|
from honeycomb.models.queries import QuerySpec
|
|
18
18
|
from honeycomb.models.triggers import TriggerQuery
|
|
19
19
|
|
|
20
|
+
# Valid time offset values for compare queries (in seconds)
|
|
21
|
+
# 30min, 1hr, 2hr, 8hr, 24hr, 7d, 28d, 6mo
|
|
22
|
+
VALID_COMPARE_OFFSETS: frozenset[int] = frozenset(
|
|
23
|
+
{1800, 3600, 7200, 28800, 86400, 604800, 2419200, 15724800}
|
|
24
|
+
)
|
|
25
|
+
|
|
20
26
|
|
|
21
27
|
# =============================================================================
|
|
22
28
|
# Enums
|
|
@@ -51,7 +57,7 @@ class CalcOp(str, Enum):
|
|
|
51
57
|
|
|
52
58
|
|
|
53
59
|
class FilterOp(str, Enum):
|
|
54
|
-
"""Filter operations for Honeycomb queries."""
|
|
60
|
+
"""Filter operations for Honeycomb queries and board views."""
|
|
55
61
|
|
|
56
62
|
EQUALS = "="
|
|
57
63
|
NOT_EQUALS = "!="
|
|
@@ -61,6 +67,8 @@ class FilterOp(str, Enum):
|
|
|
61
67
|
LESS_THAN_OR_EQUAL = "<="
|
|
62
68
|
STARTS_WITH = "starts-with"
|
|
63
69
|
DOES_NOT_START_WITH = "does-not-start-with"
|
|
70
|
+
ENDS_WITH = "ends-with"
|
|
71
|
+
DOES_NOT_END_WITH = "does-not-end-with"
|
|
64
72
|
CONTAINS = "contains"
|
|
65
73
|
DOES_NOT_CONTAIN = "does-not-contain"
|
|
66
74
|
EXISTS = "exists"
|
|
@@ -94,21 +102,19 @@ class Calculation(BaseModel):
|
|
|
94
102
|
Examples:
|
|
95
103
|
>>> Calculation(op=CalcOp.COUNT)
|
|
96
104
|
>>> Calculation(op=CalcOp.P99, column="duration_ms")
|
|
97
|
-
>>> Calculation(op="AVG", column="response_time"
|
|
105
|
+
>>> Calculation(op="AVG", column="response_time")
|
|
98
106
|
"""
|
|
99
107
|
|
|
100
|
-
|
|
108
|
+
model_config = ConfigDict(extra="forbid")
|
|
109
|
+
|
|
110
|
+
op: CalcOp = Field(description="Calculation operation (COUNT, AVG, P99, etc.)")
|
|
101
111
|
column: str | None = Field(default=None, description="Column to calculate on")
|
|
102
|
-
alias: str | None = Field(default=None, description="Alias for the result column")
|
|
103
112
|
|
|
104
113
|
def to_dict(self) -> dict[str, Any]:
|
|
105
114
|
"""Convert to API dict format."""
|
|
106
|
-
|
|
107
|
-
result: dict[str, Any] = {"op": op_value}
|
|
115
|
+
result: dict[str, Any] = {"op": self.op.value}
|
|
108
116
|
if self.column is not None:
|
|
109
117
|
result["column"] = self.column
|
|
110
|
-
if self.alias is not None:
|
|
111
|
-
result["alias"] = self.alias
|
|
112
118
|
return result
|
|
113
119
|
|
|
114
120
|
|
|
@@ -121,14 +127,15 @@ class Filter(BaseModel):
|
|
|
121
127
|
>>> Filter(column="service", op="in", value=["api", "web"])
|
|
122
128
|
"""
|
|
123
129
|
|
|
130
|
+
model_config = ConfigDict(extra="forbid")
|
|
131
|
+
|
|
124
132
|
column: str = Field(description="Column to filter on")
|
|
125
|
-
op: FilterOp
|
|
133
|
+
op: FilterOp = Field(description="Filter operator (=, !=, >, <, contains, etc.)")
|
|
126
134
|
value: Any = Field(description="Filter value")
|
|
127
135
|
|
|
128
136
|
def to_dict(self) -> dict[str, Any]:
|
|
129
137
|
"""Convert to API dict format."""
|
|
130
|
-
|
|
131
|
-
return {"column": self.column, "op": op_value, "value": self.value}
|
|
138
|
+
return {"column": self.column, "op": self.op.value, "value": self.value}
|
|
132
139
|
|
|
133
140
|
|
|
134
141
|
class Order(BaseModel):
|
|
@@ -139,17 +146,15 @@ class Order(BaseModel):
|
|
|
139
146
|
>>> Order(op=CalcOp.AVG, column="duration_ms", order=OrderDirection.ASCENDING)
|
|
140
147
|
"""
|
|
141
148
|
|
|
142
|
-
|
|
149
|
+
model_config = ConfigDict(extra="forbid")
|
|
150
|
+
|
|
151
|
+
op: CalcOp = Field(description="Calculation to order by")
|
|
143
152
|
column: str | None = Field(default=None, description="Column for the calculation")
|
|
144
|
-
order: OrderDirection
|
|
145
|
-
default=OrderDirection.DESCENDING, description="Sort direction"
|
|
146
|
-
)
|
|
153
|
+
order: OrderDirection = Field(default=OrderDirection.DESCENDING, description="Sort direction")
|
|
147
154
|
|
|
148
155
|
def to_dict(self) -> dict[str, Any]:
|
|
149
156
|
"""Convert to API dict format."""
|
|
150
|
-
|
|
151
|
-
order_value = self.order.value if isinstance(self.order, OrderDirection) else self.order
|
|
152
|
-
result: dict[str, Any] = {"op": op_value, "order": order_value}
|
|
157
|
+
result: dict[str, Any] = {"op": self.op.value, "order": self.order.value}
|
|
153
158
|
if self.column is not None:
|
|
154
159
|
result["column"] = self.column
|
|
155
160
|
return result
|
|
@@ -163,20 +168,18 @@ class Having(BaseModel):
|
|
|
163
168
|
>>> Having(calculate_op=CalcOp.AVG, column="duration_ms", op=">", value=500.0)
|
|
164
169
|
"""
|
|
165
170
|
|
|
166
|
-
|
|
171
|
+
model_config = ConfigDict(extra="forbid")
|
|
172
|
+
|
|
173
|
+
calculate_op: CalcOp = Field(description="Calculation to filter on")
|
|
167
174
|
column: str | None = Field(default=None, description="Column for the calculation")
|
|
168
|
-
op: FilterOp
|
|
175
|
+
op: FilterOp = Field(description="Comparison operator")
|
|
169
176
|
value: float = Field(description="Threshold value")
|
|
170
177
|
|
|
171
178
|
def to_dict(self) -> dict[str, Any]:
|
|
172
179
|
"""Convert to API dict format."""
|
|
173
|
-
calc_op_value = (
|
|
174
|
-
self.calculate_op.value if isinstance(self.calculate_op, CalcOp) else self.calculate_op
|
|
175
|
-
)
|
|
176
|
-
op_value = self.op.value if isinstance(self.op, FilterOp) else self.op
|
|
177
180
|
result: dict[str, Any] = {
|
|
178
|
-
"calculate_op":
|
|
179
|
-
"op":
|
|
181
|
+
"calculate_op": self.calculate_op.value,
|
|
182
|
+
"op": self.op.value,
|
|
180
183
|
"value": self.value,
|
|
181
184
|
}
|
|
182
185
|
if self.column is not None:
|
|
@@ -243,6 +246,8 @@ class QueryBuilder:
|
|
|
243
246
|
self._orders: list[Order] = []
|
|
244
247
|
self._limit: int | None = None
|
|
245
248
|
self._havings: list[Having] = []
|
|
249
|
+
self._calculated_fields: list[dict[str, str]] = []
|
|
250
|
+
self._compare_time_offset_seconds: int | None = None
|
|
246
251
|
# Query metadata (for board integration)
|
|
247
252
|
self._dataset: str | None = None
|
|
248
253
|
self._query_name: str | None = name
|
|
@@ -381,69 +386,66 @@ class QueryBuilder:
|
|
|
381
386
|
# Calculation Methods (additive - each call adds to the list)
|
|
382
387
|
# -------------------------------------------------------------------------
|
|
383
388
|
|
|
384
|
-
def calculate(
|
|
385
|
-
self, op: CalcOp | str, column: str | None = None, alias: str | None = None
|
|
386
|
-
) -> QueryBuilder:
|
|
389
|
+
def calculate(self, op: CalcOp | str, column: str | None = None) -> QueryBuilder:
|
|
387
390
|
"""Add a calculation to the query.
|
|
388
391
|
|
|
389
392
|
Args:
|
|
390
393
|
op: Calculation operation (e.g., CalcOp.COUNT, "AVG")
|
|
391
394
|
column: Column to calculate on (optional for COUNT)
|
|
392
|
-
alias: Alias for the result column
|
|
393
395
|
|
|
394
396
|
Returns:
|
|
395
397
|
self for chaining
|
|
396
398
|
"""
|
|
397
|
-
self._calculations.append(Calculation(op=op, column=column
|
|
399
|
+
self._calculations.append(Calculation(op=op, column=column))
|
|
398
400
|
return self
|
|
399
401
|
|
|
400
|
-
def count(self
|
|
402
|
+
def count(self) -> QueryBuilder:
|
|
401
403
|
"""Add a COUNT calculation."""
|
|
402
|
-
return self.calculate(CalcOp.COUNT
|
|
404
|
+
return self.calculate(CalcOp.COUNT)
|
|
403
405
|
|
|
404
|
-
def sum(self, column: str
|
|
406
|
+
def sum(self, column: str) -> QueryBuilder:
|
|
405
407
|
"""Add a SUM calculation on a column."""
|
|
406
|
-
return self.calculate(CalcOp.SUM, column=column
|
|
408
|
+
return self.calculate(CalcOp.SUM, column=column)
|
|
407
409
|
|
|
408
|
-
def avg(self, column: str
|
|
410
|
+
def avg(self, column: str) -> QueryBuilder:
|
|
409
411
|
"""Add an AVG calculation on a column."""
|
|
410
|
-
return self.calculate(CalcOp.AVG, column=column
|
|
412
|
+
return self.calculate(CalcOp.AVG, column=column)
|
|
411
413
|
|
|
412
|
-
def min(self, column: str
|
|
414
|
+
def min(self, column: str) -> QueryBuilder:
|
|
413
415
|
"""Add a MIN calculation on a column."""
|
|
414
|
-
return self.calculate(CalcOp.MIN, column=column
|
|
416
|
+
return self.calculate(CalcOp.MIN, column=column)
|
|
415
417
|
|
|
416
|
-
def max(self, column: str
|
|
418
|
+
def max(self, column: str) -> QueryBuilder:
|
|
417
419
|
"""Add a MAX calculation on a column."""
|
|
418
|
-
return self.calculate(CalcOp.MAX, column=column
|
|
420
|
+
return self.calculate(CalcOp.MAX, column=column)
|
|
419
421
|
|
|
420
|
-
def count_distinct(self, column: str
|
|
422
|
+
def count_distinct(self, column: str) -> QueryBuilder:
|
|
421
423
|
"""Add a COUNT_DISTINCT calculation on a column."""
|
|
422
|
-
return self.calculate(CalcOp.COUNT_DISTINCT, column=column
|
|
424
|
+
return self.calculate(CalcOp.COUNT_DISTINCT, column=column)
|
|
423
425
|
|
|
424
|
-
def p50(self, column: str
|
|
426
|
+
def p50(self, column: str) -> QueryBuilder:
|
|
425
427
|
"""Add a P50 (median) calculation on a column."""
|
|
426
|
-
return self.calculate(CalcOp.P50, column=column
|
|
428
|
+
return self.calculate(CalcOp.P50, column=column)
|
|
427
429
|
|
|
428
|
-
def p90(self, column: str
|
|
430
|
+
def p90(self, column: str) -> QueryBuilder:
|
|
429
431
|
"""Add a P90 calculation on a column."""
|
|
430
|
-
return self.calculate(CalcOp.P90, column=column
|
|
432
|
+
return self.calculate(CalcOp.P90, column=column)
|
|
431
433
|
|
|
432
|
-
def p95(self, column: str
|
|
434
|
+
def p95(self, column: str) -> QueryBuilder:
|
|
433
435
|
"""Add a P95 calculation on a column."""
|
|
434
|
-
return self.calculate(CalcOp.P95, column=column
|
|
436
|
+
return self.calculate(CalcOp.P95, column=column)
|
|
435
437
|
|
|
436
|
-
def p99(self, column: str
|
|
438
|
+
def p99(self, column: str) -> QueryBuilder:
|
|
437
439
|
"""Add a P99 calculation on a column."""
|
|
438
|
-
return self.calculate(CalcOp.P99, column=column
|
|
440
|
+
return self.calculate(CalcOp.P99, column=column)
|
|
439
441
|
|
|
440
|
-
def heatmap(self, column: str
|
|
442
|
+
def heatmap(self, column: str) -> QueryBuilder:
|
|
441
443
|
"""Add a HEATMAP calculation on a column."""
|
|
442
|
-
return self.calculate(CalcOp.HEATMAP, column=column
|
|
444
|
+
return self.calculate(CalcOp.HEATMAP, column=column)
|
|
443
445
|
|
|
444
|
-
def concurrency(self
|
|
446
|
+
def concurrency(self) -> QueryBuilder:
|
|
445
447
|
"""Add a CONCURRENCY calculation."""
|
|
446
|
-
return self.calculate(CalcOp.CONCURRENCY
|
|
448
|
+
return self.calculate(CalcOp.CONCURRENCY)
|
|
447
449
|
|
|
448
450
|
# -------------------------------------------------------------------------
|
|
449
451
|
# Filter Methods
|
|
@@ -568,10 +570,10 @@ class QueryBuilder:
|
|
|
568
570
|
Returns:
|
|
569
571
|
self for chaining
|
|
570
572
|
"""
|
|
571
|
-
if isinstance(combination,
|
|
572
|
-
self._filter_combination = FilterCombination(combination)
|
|
573
|
-
else:
|
|
573
|
+
if isinstance(combination, FilterCombination):
|
|
574
574
|
self._filter_combination = combination
|
|
575
|
+
else:
|
|
576
|
+
self._filter_combination = FilterCombination(combination)
|
|
575
577
|
return self
|
|
576
578
|
|
|
577
579
|
# -------------------------------------------------------------------------
|
|
@@ -678,6 +680,62 @@ class QueryBuilder:
|
|
|
678
680
|
self._havings.append(Having(calculate_op=calculate_op, column=column, op=op, value=value))
|
|
679
681
|
return self
|
|
680
682
|
|
|
683
|
+
# -------------------------------------------------------------------------
|
|
684
|
+
# Calculated Fields (Inline Derived Columns)
|
|
685
|
+
# -------------------------------------------------------------------------
|
|
686
|
+
|
|
687
|
+
def calculated_field(self, name: str, expression: str) -> QueryBuilder:
|
|
688
|
+
"""Add an inline calculated field (derived column) for this query only.
|
|
689
|
+
|
|
690
|
+
Creates a computed column available within this query. For reusable
|
|
691
|
+
derived columns, use the Derived Columns API instead.
|
|
692
|
+
|
|
693
|
+
Args:
|
|
694
|
+
name: Field name/alias to reference in calculations and breakdowns
|
|
695
|
+
expression: Formula using $column_name syntax
|
|
696
|
+
See https://docs.honeycomb.io/reference/derived-column-formula/
|
|
697
|
+
|
|
698
|
+
Returns:
|
|
699
|
+
self for chaining
|
|
700
|
+
|
|
701
|
+
Example:
|
|
702
|
+
>>> (QueryBuilder()
|
|
703
|
+
... .calculated_field("latency_bucket",
|
|
704
|
+
... "IF(LTE($duration_ms, 100), 'fast', 'slow')")
|
|
705
|
+
... .group_by("latency_bucket")
|
|
706
|
+
... .count())
|
|
707
|
+
"""
|
|
708
|
+
self._calculated_fields.append({"name": name, "expression": expression})
|
|
709
|
+
return self
|
|
710
|
+
|
|
711
|
+
# -------------------------------------------------------------------------
|
|
712
|
+
# Compare Time Offset (Historical Comparison)
|
|
713
|
+
# -------------------------------------------------------------------------
|
|
714
|
+
|
|
715
|
+
def compare_time_offset(self, seconds: int) -> QueryBuilder:
|
|
716
|
+
"""Compare against historical data offset by N seconds.
|
|
717
|
+
|
|
718
|
+
When set, the query results will include comparison data from
|
|
719
|
+
the specified time in the past.
|
|
720
|
+
|
|
721
|
+
Args:
|
|
722
|
+
seconds: Offset in seconds. Must be one of:
|
|
723
|
+
1800 (30min), 3600 (1hr), 7200 (2hr), 28800 (8hr),
|
|
724
|
+
86400 (24hr), 604800 (7d), 2419200 (28d), 15724800 (6mo)
|
|
725
|
+
|
|
726
|
+
Returns:
|
|
727
|
+
self for chaining
|
|
728
|
+
|
|
729
|
+
Example:
|
|
730
|
+
>>> QueryBuilder().last_1_hour().count().compare_time_offset(86400) # Compare to 24h ago
|
|
731
|
+
"""
|
|
732
|
+
if seconds not in VALID_COMPARE_OFFSETS:
|
|
733
|
+
raise ValueError(
|
|
734
|
+
f"Invalid compare_time_offset: {seconds}. Must be one of: {sorted(VALID_COMPARE_OFFSETS)}"
|
|
735
|
+
)
|
|
736
|
+
self._compare_time_offset_seconds = seconds
|
|
737
|
+
return self
|
|
738
|
+
|
|
681
739
|
# -------------------------------------------------------------------------
|
|
682
740
|
# Dataset Scoping
|
|
683
741
|
# -------------------------------------------------------------------------
|
|
@@ -803,6 +861,8 @@ class QueryBuilder:
|
|
|
803
861
|
orders=self._orders if self._orders else None,
|
|
804
862
|
limit=self._limit,
|
|
805
863
|
havings=self._havings if self._havings else None,
|
|
864
|
+
calculated_fields=self._calculated_fields if self._calculated_fields else None,
|
|
865
|
+
compare_time_offset_seconds=self._compare_time_offset_seconds,
|
|
806
866
|
)
|
|
807
867
|
|
|
808
868
|
def build_for_trigger(self) -> TriggerQuery:
|
|
@@ -78,13 +78,22 @@ class RecipientMixin:
|
|
|
78
78
|
)
|
|
79
79
|
return self
|
|
80
80
|
|
|
81
|
-
def webhook(
|
|
81
|
+
def webhook(
|
|
82
|
+
self,
|
|
83
|
+
url: str,
|
|
84
|
+
name: str = "Webhook",
|
|
85
|
+
secret: str | None = None,
|
|
86
|
+
headers: list[dict[str, str]] | None = None,
|
|
87
|
+
) -> Self:
|
|
82
88
|
"""Add a webhook recipient (inline format for triggers/burn alerts).
|
|
83
89
|
|
|
84
90
|
Args:
|
|
85
91
|
url: Webhook URL to POST to.
|
|
86
92
|
name: A name for this webhook (default: "Webhook").
|
|
87
93
|
secret: Optional webhook secret for signing.
|
|
94
|
+
headers: Optional HTTP headers (max 5). Each dict should have
|
|
95
|
+
'header' (required) and optionally 'value'.
|
|
96
|
+
Example: [{"header": "Authorization", "value": "Bearer xyz"}]
|
|
88
97
|
|
|
89
98
|
Returns:
|
|
90
99
|
Self for method chaining.
|
|
@@ -99,6 +108,8 @@ class RecipientMixin:
|
|
|
99
108
|
}
|
|
100
109
|
if secret:
|
|
101
110
|
details["webhook_secret"] = secret
|
|
111
|
+
if headers:
|
|
112
|
+
details["webhook_headers"] = headers
|
|
102
113
|
|
|
103
114
|
self._new_recipients.append(
|
|
104
115
|
{
|
|
@@ -209,16 +220,43 @@ class RecipientBuilder:
|
|
|
209
220
|
url: str,
|
|
210
221
|
name: str = "Webhook",
|
|
211
222
|
secret: str | None = None,
|
|
223
|
+
headers: list[dict[str, str]] | None = None,
|
|
224
|
+
payload_templates: dict[str, dict[str, str]] | None = None,
|
|
225
|
+
template_variables: list[dict[str, str]] | None = None,
|
|
212
226
|
) -> RecipientCreate:
|
|
213
227
|
"""Create a webhook recipient.
|
|
214
228
|
|
|
215
229
|
Args:
|
|
216
|
-
url: Webhook URL to POST to.
|
|
217
|
-
name: A name for this webhook.
|
|
218
|
-
secret: Optional webhook secret for signing.
|
|
230
|
+
url: Webhook URL to POST to (max 2048 chars).
|
|
231
|
+
name: A name for this webhook (max 255 chars).
|
|
232
|
+
secret: Optional webhook secret for signing (max 255 chars).
|
|
233
|
+
headers: Optional HTTP headers (max 5). Each dict should have
|
|
234
|
+
'header' (required, max 64 chars) and optionally 'value' (max 750 chars).
|
|
235
|
+
Example: [{"header": "Authorization", "value": "Bearer xyz"}]
|
|
236
|
+
payload_templates: Optional custom payload templates for different alert types.
|
|
237
|
+
Example: {"trigger": {"body": "{\"custom\": \"json\"}"}}
|
|
238
|
+
template_variables: Optional template variables for payload substitution (max 10).
|
|
239
|
+
Example: [{"name": "severity", "default_value": "warning"}]
|
|
219
240
|
|
|
220
241
|
Returns:
|
|
221
242
|
RecipientCreate object.
|
|
243
|
+
|
|
244
|
+
Example:
|
|
245
|
+
>>> # Basic webhook
|
|
246
|
+
>>> RecipientBuilder.webhook("https://example.com/webhook")
|
|
247
|
+
|
|
248
|
+
>>> # Webhook with auth header
|
|
249
|
+
>>> RecipientBuilder.webhook(
|
|
250
|
+
... "https://example.com/webhook",
|
|
251
|
+
... headers=[{"header": "Authorization", "value": "Bearer token123"}]
|
|
252
|
+
... )
|
|
253
|
+
|
|
254
|
+
>>> # Advanced webhook with custom payload
|
|
255
|
+
>>> RecipientBuilder.webhook(
|
|
256
|
+
... "https://example.com/webhook",
|
|
257
|
+
... template_variables=[{"name": "env", "default_value": "prod"}],
|
|
258
|
+
... payload_templates={"trigger": {"body": "{\"environment\": \"{{env}}\"}"}}
|
|
259
|
+
... )
|
|
222
260
|
"""
|
|
223
261
|
details: dict[str, Any] = {
|
|
224
262
|
"webhook_url": url,
|
|
@@ -226,6 +264,15 @@ class RecipientBuilder:
|
|
|
226
264
|
}
|
|
227
265
|
if secret:
|
|
228
266
|
details["webhook_secret"] = secret
|
|
267
|
+
if headers:
|
|
268
|
+
details["webhook_headers"] = headers
|
|
269
|
+
if template_variables or payload_templates:
|
|
270
|
+
webhook_payloads: dict[str, Any] = {}
|
|
271
|
+
if template_variables:
|
|
272
|
+
webhook_payloads["template_variables"] = template_variables
|
|
273
|
+
if payload_templates:
|
|
274
|
+
webhook_payloads["payload_templates"] = payload_templates
|
|
275
|
+
details["webhook_payloads"] = webhook_payloads
|
|
229
276
|
return RecipientCreate(type=RecipientType.WEBHOOK, details=details)
|
|
230
277
|
|
|
231
278
|
@staticmethod
|
honeycomb/models/slo_builder.py
CHANGED
|
@@ -195,7 +195,7 @@ class SLOBuilder:
|
|
|
195
195
|
slo = (
|
|
196
196
|
SLOBuilder("Cross-Service Availability")
|
|
197
197
|
.datasets(["api-logs", "web-logs", "worker-logs"])
|
|
198
|
-
.
|
|
198
|
+
.target_percentage(99.9)
|
|
199
199
|
.sli(
|
|
200
200
|
alias="service_success",
|
|
201
201
|
expression="IF(EQUALS($status, 200), 1, 0)",
|
|
@@ -219,6 +219,7 @@ class SLOBuilder:
|
|
|
219
219
|
self._time_period_days: int = 30
|
|
220
220
|
self._sli: SLIDefinition | None = None
|
|
221
221
|
self._burn_alerts: list[BurnAlertDefinition] = []
|
|
222
|
+
self._tags: list[dict[str, str]] = []
|
|
222
223
|
|
|
223
224
|
# -------------------------------------------------------------------------
|
|
224
225
|
# Basic configuration
|
|
@@ -229,6 +230,25 @@ class SLOBuilder:
|
|
|
229
230
|
self._description = desc
|
|
230
231
|
return self
|
|
231
232
|
|
|
233
|
+
def tag(self, key: str, value: str) -> SLOBuilder:
|
|
234
|
+
"""Add a tag key-value pair for organizing the SLO.
|
|
235
|
+
|
|
236
|
+
Tags are useful for filtering and grouping SLOs by team, service,
|
|
237
|
+
criticality, or other dimensions.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
key: Tag key (lowercase letters, max 32 chars)
|
|
241
|
+
value: Tag value (alphanumeric, /, -, max 128 chars)
|
|
242
|
+
|
|
243
|
+
Example:
|
|
244
|
+
>>> builder.tag("team", "platform").tag("service", "api")
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
self for chaining
|
|
248
|
+
"""
|
|
249
|
+
self._tags.append({"key": key, "value": value})
|
|
250
|
+
return self
|
|
251
|
+
|
|
232
252
|
# -------------------------------------------------------------------------
|
|
233
253
|
# Dataset scope
|
|
234
254
|
# -------------------------------------------------------------------------
|
|
@@ -267,20 +287,6 @@ class SLOBuilder:
|
|
|
267
287
|
self._target_per_million = int(percent * 10000)
|
|
268
288
|
return self
|
|
269
289
|
|
|
270
|
-
def target_nines(self, nines: int) -> SLOBuilder:
|
|
271
|
-
"""Set target by number of nines.
|
|
272
|
-
|
|
273
|
-
Examples:
|
|
274
|
-
2 nines = 99%
|
|
275
|
-
3 nines = 99.9%
|
|
276
|
-
4 nines = 99.99%
|
|
277
|
-
|
|
278
|
-
Args:
|
|
279
|
-
nines: Number of nines (1-5)
|
|
280
|
-
"""
|
|
281
|
-
percentage = 100 - (100 / (10**nines))
|
|
282
|
-
return self.target_percentage(percentage)
|
|
283
|
-
|
|
284
290
|
def target_per_million(self, value: int) -> SLOBuilder:
|
|
285
291
|
"""Set target directly as per-million value.
|
|
286
292
|
|
|
@@ -422,10 +428,7 @@ class SLOBuilder:
|
|
|
422
428
|
raise ValueError("At least one dataset is required. Use dataset() or datasets().")
|
|
423
429
|
|
|
424
430
|
if self._target_per_million is None:
|
|
425
|
-
raise ValueError(
|
|
426
|
-
"Target is required. Use target_percentage(), "
|
|
427
|
-
"target_nines(), or target_per_million()."
|
|
428
|
-
)
|
|
431
|
+
raise ValueError("Target is required. Use target_percentage() or target_per_million().")
|
|
429
432
|
|
|
430
433
|
if self._sli is None:
|
|
431
434
|
raise ValueError("SLI is required. Use sli(alias=...) to define it.")
|
|
@@ -452,6 +455,8 @@ class SLOBuilder:
|
|
|
452
455
|
sli=SLI(alias=self._sli.alias),
|
|
453
456
|
time_period_days=self._time_period_days,
|
|
454
457
|
target_per_million=self._target_per_million,
|
|
458
|
+
tags=self._tags if self._tags else None,
|
|
459
|
+
dataset_slugs=self._datasets if is_multi_dataset else None,
|
|
455
460
|
)
|
|
456
461
|
|
|
457
462
|
return SLOBundle(
|
honeycomb/models/slos.py
CHANGED
|
@@ -7,11 +7,32 @@ from typing import Any
|
|
|
7
7
|
|
|
8
8
|
from pydantic import BaseModel, Field
|
|
9
9
|
|
|
10
|
+
from honeycomb.models.tool_inputs import TagInput
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
class SLI(BaseModel):
|
|
12
|
-
"""Service Level Indicator configuration.
|
|
14
|
+
"""Service Level Indicator configuration.
|
|
15
|
+
|
|
16
|
+
The SLI references a derived column by alias. You can either:
|
|
17
|
+
1. Reference an existing derived column: just provide alias
|
|
18
|
+
2. Create a new derived column inline: provide alias + expression
|
|
19
|
+
|
|
20
|
+
When expression is provided, a new derived column will be created automatically
|
|
21
|
+
before the SLO is created.
|
|
22
|
+
"""
|
|
13
23
|
|
|
14
|
-
alias: str | None = Field(
|
|
24
|
+
alias: str | None = Field(
|
|
25
|
+
default=None, description="Alias for the derived column (existing or new)"
|
|
26
|
+
)
|
|
27
|
+
expression: str | None = Field(
|
|
28
|
+
default=None,
|
|
29
|
+
description="If provided, creates a new derived column with this expression. "
|
|
30
|
+
"If omitted, uses an existing derived column with the given alias.",
|
|
31
|
+
)
|
|
32
|
+
description: str | None = Field(
|
|
33
|
+
default=None,
|
|
34
|
+
description="Description for the new derived column (only used when expression is provided)",
|
|
35
|
+
)
|
|
15
36
|
|
|
16
37
|
|
|
17
38
|
class SLOCreate(BaseModel):
|
|
@@ -28,9 +49,17 @@ class SLOCreate(BaseModel):
|
|
|
28
49
|
)
|
|
29
50
|
target_per_million: int = Field(
|
|
30
51
|
ge=0,
|
|
31
|
-
le=
|
|
52
|
+
le=999999,
|
|
32
53
|
description="Target success rate per million (e.g., 999000 = 99.9%)",
|
|
33
54
|
)
|
|
55
|
+
tags: list[TagInput] | None = Field(
|
|
56
|
+
default=None,
|
|
57
|
+
description="Key-value pairs for organizing SLOs (max 10 tags)",
|
|
58
|
+
)
|
|
59
|
+
dataset_slugs: list[str] | None = Field(
|
|
60
|
+
default=None,
|
|
61
|
+
description="Dataset slugs for multi-dataset SLOs (used with __all__ endpoint)",
|
|
62
|
+
)
|
|
34
63
|
|
|
35
64
|
def model_dump_for_api(self) -> dict[str, Any]:
|
|
36
65
|
"""Serialize for API request."""
|
|
@@ -47,6 +76,12 @@ class SLOCreate(BaseModel):
|
|
|
47
76
|
if self.sli.alias:
|
|
48
77
|
data["sli"]["alias"] = self.sli.alias
|
|
49
78
|
|
|
79
|
+
if self.tags:
|
|
80
|
+
data["tags"] = [{"key": tag.key, "value": tag.value} for tag in self.tags]
|
|
81
|
+
|
|
82
|
+
if self.dataset_slugs:
|
|
83
|
+
data["dataset_slugs"] = self.dataset_slugs
|
|
84
|
+
|
|
50
85
|
return data
|
|
51
86
|
|
|
52
87
|
|
|
@@ -64,3 +99,15 @@ class SLO(BaseModel):
|
|
|
64
99
|
updated_at: datetime | None = Field(default=None, description="Last update timestamp")
|
|
65
100
|
|
|
66
101
|
model_config = {"extra": "allow"}
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def dataset(self) -> str | None:
|
|
105
|
+
"""Return the first dataset slug for convenience (SLOs can span multiple datasets)."""
|
|
106
|
+
if self.dataset_slugs and len(self.dataset_slugs) > 0:
|
|
107
|
+
return self.dataset_slugs[0]
|
|
108
|
+
return None
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def target_percentage(self) -> float:
|
|
112
|
+
"""Convert target_per_million to percentage for display (e.g., 999000 → 99.9)."""
|
|
113
|
+
return self.target_per_million / 10000
|