qwak-core 0.4.278__py3-none-any.whl → 0.5.19__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.
Potentially problematic release.
This version of qwak-core might be problematic. Click here for more details.
- _qwak_proto/jfml/hosting_gateway/v1/build_upload_url_pb2.py +8 -23
- _qwak_proto/jfml/hosting_gateway/v1/hosting_gateway_service_pb2.py +10 -27
- _qwak_proto/qwak/administration/account/v1/account_pb2.py +25 -88
- _qwak_proto/qwak/administration/account/v1/account_pb2.pyi +21 -2
- _qwak_proto/qwak/administration/account/v1/account_service_pb2.py +42 -187
- _qwak_proto/qwak/administration/account/v1/jfrog_tenant_details_pb2.py +26 -114
- _qwak_proto/qwak/administration/account/v1/personalization_pb2.py +8 -24
- _qwak_proto/qwak/administration/account/v1/preferences_pb2.py +6 -14
- _qwak_proto/qwak/administration/account/v1/terms_pb2.py +14 -54
- _qwak_proto/qwak/administration/authenticated_user/v1/authenticated_user_service_pb2.py +18 -67
- _qwak_proto/qwak/administration/authenticated_user/v1/credentials_pb2.py +8 -24
- _qwak_proto/qwak/administration/authenticated_user/v1/credentials_pb2.pyi +1 -1
- _qwak_proto/qwak/administration/authenticated_user/v1/details_pb2.py +14 -54
- _qwak_proto/qwak/administration/cluster/v2/cluster_pb2.py +38 -173
- _qwak_proto/qwak/administration/runtime_configuration/v0/container_registry_config_pb2.py +32 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/container_registry_config_pb2.pyi +65 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/container_registry_config_pb2_grpc.py +4 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/creds/auth_pb2.py +6 -14
- _qwak_proto/qwak/administration/runtime_configuration/v0/creds/secret_pb2.py +8 -24
- _qwak_proto/qwak/administration/runtime_configuration/v0/data_catalog_config_pb2.py +13 -35
- _qwak_proto/qwak/administration/runtime_configuration/v0/data_catalog_config_pb2.pyi +24 -3
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/databricks/auth_pb2.py +34 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/databricks/auth_pb2.pyi +97 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/databricks/auth_pb2_grpc.py +4 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/elasticsearch_config_pb2.py +6 -14
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/kafka_config_pb2.py +12 -44
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/prometheus_config_pb2.py +9 -15
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/prometheus_config_pb2.pyi +29 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/redis_config_pb2.py +6 -14
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/victoriametrics_config_pb2.py +8 -15
- _qwak_proto/qwak/administration/runtime_configuration/v0/external/victoriametrics_config_pb2.pyi +16 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/feature_store_config_pb2.py +10 -34
- _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/aws/auth_pb2.py +42 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/aws/auth_pb2.pyi +159 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/aws/auth_pb2_grpc.py +4 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/azure/auth_pb2.py +39 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/azure/auth_pb2.pyi +126 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/azure/auth_pb2_grpc.py +4 -0
- _qwak_proto/qwak/administration/runtime_configuration/v0/hosting_config_pb2.py +19 -55
- _qwak_proto/qwak/administration/runtime_configuration/v0/hosting_config_pb2.pyi +38 -6
- _qwak_proto/qwak/administration/runtime_configuration/v0/logs_storage_config_pb2.py +6 -14
- _qwak_proto/qwak/administration/runtime_configuration/v0/model_analytics_storage_config_pb2.py +6 -14
- _qwak_proto/qwak/administration/runtime_configuration/v0/network_config_pb2.py +14 -54
- _qwak_proto/qwak/administration/runtime_configuration/v0/object_storage_config_pb2.py +13 -35
- _qwak_proto/qwak/administration/runtime_configuration/v0/object_storage_config_pb2.pyi +26 -3
- _qwak_proto/qwak/administration/runtime_configuration/v0/observability_config_pb2.py +10 -34
- _qwak_proto/qwak/administration/runtime_configuration/v0/runtime_config_pb2.py +8 -15
- _qwak_proto/qwak/administration/runtime_configuration/v0/runtime_config_pb2.pyi +7 -2
- _qwak_proto/qwak/administration/runtime_configuration/v0/sql_engine_config_pb2.py +13 -35
- _qwak_proto/qwak/administration/runtime_configuration/v0/sql_engine_config_pb2.pyi +24 -3
- _qwak_proto/qwak/administration/v0/authentication/authentication_service_pb2.py +14 -47
- _qwak_proto/qwak/administration/v0/environments/configuration_pb2.py +20 -82
- _qwak_proto/qwak/administration/v0/environments/environment_pb2.py +12 -40
- _qwak_proto/qwak/administration/v0/environments/environment_service_pb2.py +36 -158
- _qwak_proto/qwak/administration/v0/environments/personalization_pb2.py +8 -24
- _qwak_proto/qwak/administration/v0/users/user_pb2.py +18 -71
- _qwak_proto/qwak/admiral/secret/v0/secret_pb2.py +29 -116
- _qwak_proto/qwak/admiral/secret/v0/secret_pb2.pyi +21 -2
- _qwak_proto/qwak/admiral/secret/v0/secret_service_pb2.py +18 -67
- _qwak_proto/qwak/admiral/secret/v0/system_secret_service_pb2.py +18 -67
- _qwak_proto/qwak/admiral/user_application_instance/v0/user_application_instance_pb2.py +38 -174
- _qwak_proto/qwak/admiral/user_application_instance/v0/user_application_instance_service_pb2.py +22 -87
- _qwak_proto/qwak/analytics/analytics_pb2.py +26 -121
- _qwak_proto/qwak/analytics/analytics_service_pb2.py +46 -207
- _qwak_proto/qwak/artifactory_settings/artifactory_settings_pb2.py +8 -24
- _qwak_proto/qwak/audience/v1/audience_api_pb2.py +30 -127
- _qwak_proto/qwak/audience/v1/audience_pb2.py +26 -113
- _qwak_proto/qwak/auto_scaling/v1/auto_scaling_pb2.py +18 -79
- _qwak_proto/qwak/auto_scaling/v1/auto_scaling_service_pb2.py +10 -27
- _qwak_proto/qwak/automation/v1/action_pb2.py +40 -180
- _qwak_proto/qwak/automation/v1/auto_scaling_pb2.py +18 -79
- _qwak_proto/qwak/automation/v1/automation_execution_pb2.py +12 -43
- _qwak_proto/qwak/automation/v1/automation_management_service_pb2.py +56 -258
- _qwak_proto/qwak/automation/v1/automation_pb2.py +11 -35
- _qwak_proto/qwak/automation/v1/automation_pb2.pyi +5 -1
- _qwak_proto/qwak/automation/v1/common_pb2.py +10 -35
- _qwak_proto/qwak/automation/v1/notification_pb2.py +16 -68
- _qwak_proto/qwak/automation/v1/trigger_pb2.py +14 -54
- _qwak_proto/qwak/batch_job/v1/batch_job_events_pb2.py +26 -116
- _qwak_proto/qwak/batch_job/v1/batch_job_resources_pb2.py +8 -26
- _qwak_proto/qwak/batch_job/v1/batch_job_service_pb2.py +119 -562
- _qwak_proto/qwak/batch_job/v1/batch_job_service_pb2.pyi +5 -1
- _qwak_proto/qwak/build/v1/build_api_pb2.py +86 -407
- _qwak_proto/qwak/build/v1/build_pb2.py +114 -549
- _qwak_proto/qwak/build_settings/build_settings_api_pb2.py +18 -67
- _qwak_proto/qwak/build_settings/build_settings_pb2.py +18 -74
- _qwak_proto/qwak/builds/build_pb2.py +46 -207
- _qwak_proto/qwak/builds/build_pb2.pyi +48 -3
- _qwak_proto/qwak/builds/build_url_pb2.py +26 -113
- _qwak_proto/qwak/builds/build_values_pb2.py +82 -0
- _qwak_proto/qwak/builds/build_values_pb2.pyi +559 -0
- _qwak_proto/qwak/builds/build_values_pb2_grpc.py +4 -0
- _qwak_proto/qwak/builds/builds_orchestrator_service_pb2.py +87 -270
- _qwak_proto/qwak/builds/builds_orchestrator_service_pb2.pyi +173 -0
- _qwak_proto/qwak/builds/builds_orchestrator_service_pb2_grpc.py +66 -0
- _qwak_proto/qwak/builds/builds_pb2.py +87 -528
- _qwak_proto/qwak/builds/builds_pb2.pyi +0 -191
- _qwak_proto/qwak/builds/builds_pb2_grpc.py +0 -233
- _qwak_proto/qwak/builds/internal_builds_orchestrator_service_pb2.py +12 -37
- _qwak_proto/qwak/data_versioning/data_versioning_pb2.py +8 -24
- _qwak_proto/qwak/data_versioning/data_versioning_service_pb2.py +14 -47
- _qwak_proto/qwak/deployment/alert_pb2.py +24 -108
- _qwak_proto/qwak/deployment/alert_service_pb2.py +30 -127
- _qwak_proto/qwak/deployment/deployment_messages_pb2.py +6 -14
- _qwak_proto/qwak/deployment/deployment_pb2.py +124 -588
- _qwak_proto/qwak/deployment/deployment_service_pb2.py +86 -419
- _qwak_proto/qwak/ecosystem/jfrog/v0/token_pb2.py +47 -165
- _qwak_proto/qwak/ecosystem/jfrog/v0/token_pb2.pyi +102 -3
- _qwak_proto/qwak/ecosystem/jfrog/v0/token_service_pb2.py +22 -87
- _qwak_proto/qwak/ecosystem/v0/auth_pb2.py +28 -0
- _qwak_proto/qwak/ecosystem/v0/auth_pb2.pyi +37 -0
- _qwak_proto/qwak/ecosystem/v0/auth_pb2_grpc.py +4 -0
- _qwak_proto/qwak/ecosystem/v0/azure_credentials_pb2.py +37 -0
- _qwak_proto/qwak/ecosystem/v0/azure_credentials_pb2.pyi +117 -0
- _qwak_proto/qwak/ecosystem/v0/azure_credentials_pb2_grpc.py +4 -0
- _qwak_proto/qwak/ecosystem/v0/credentials_pb2.py +12 -35
- _qwak_proto/qwak/ecosystem/v0/credentials_pb2.pyi +8 -3
- _qwak_proto/qwak/ecosystem/v0/ecosystem_pb2.py +30 -138
- _qwak_proto/qwak/ecosystem/v0/ecosystem_runtime_service_pb2.py +52 -237
- _qwak_proto/qwak/execution/v1/backfill_pb2.py +18 -74
- _qwak_proto/qwak/execution/v1/batch_pb2.py +10 -34
- _qwak_proto/qwak/execution/v1/deletion_pb2.py +12 -44
- _qwak_proto/qwak/execution/v1/execution_pb2.py +16 -69
- _qwak_proto/qwak/execution/v1/execution_service_pb2.py +64 -298
- _qwak_proto/qwak/execution/v1/internal/deployment/platform_details_pb2.py +6 -14
- _qwak_proto/qwak/execution/v1/jobs/job_pb2.py +18 -76
- _qwak_proto/qwak/execution/v1/jobs/job_service_pb2.py +54 -247
- _qwak_proto/qwak/execution/v1/jobs/reports/report_pb2.py +20 -84
- _qwak_proto/qwak/execution/v1/state/execution_state_pb2.py +6 -14
- _qwak_proto/qwak/execution/v1/state/execution_state_service_pb2.py +30 -127
- _qwak_proto/qwak/execution/v1/state/featureset_state_pb2.py +6 -14
- _qwak_proto/qwak/execution/v1/state/spark_execution_state_pb2.py +14 -68
- _qwak_proto/qwak/execution/v1/streaming_aggregation_pb2.py +22 -55
- _qwak_proto/qwak/execution/v1/streaming_aggregation_pb2.pyi +71 -1
- _qwak_proto/qwak/execution/v1/streaming_pb2.py +12 -44
- _qwak_proto/qwak/feature_store/entities/entity_pb2.py +16 -57
- _qwak_proto/qwak/feature_store/entities/entity_service_pb2.py +30 -127
- _qwak_proto/qwak/feature_store/features/aggregation_pb2.py +38 -175
- _qwak_proto/qwak/feature_store/features/deployment_pb2.py +36 -167
- _qwak_proto/qwak/feature_store/features/deployment_service_pb2.py +10 -27
- _qwak_proto/qwak/feature_store/features/execution_pb2.py +14 -56
- _qwak_proto/qwak/feature_store/features/feature_set_attribute_pb2.py +6 -14
- _qwak_proto/qwak/feature_store/features/feature_set_pb2.py +35 -156
- _qwak_proto/qwak/feature_store/features/feature_set_pb2.pyi +9 -1
- _qwak_proto/qwak/feature_store/features/feature_set_service_pb2.py +97 -440
- _qwak_proto/qwak/feature_store/features/feature_set_service_pb2.pyi +25 -0
- _qwak_proto/qwak/feature_store/features/feature_set_service_pb2_grpc.py +34 -0
- _qwak_proto/qwak/feature_store/features/feature_set_state_pb2.py +38 -181
- _qwak_proto/qwak/feature_store/features/feature_set_state_service_pb2.py +26 -107
- _qwak_proto/qwak/feature_store/features/feature_set_types_pb2.py +77 -347
- _qwak_proto/qwak/feature_store/features/feature_set_types_pb2.pyi +7 -2
- _qwak_proto/qwak/feature_store/features/monitoring_pb2.py +10 -34
- _qwak_proto/qwak/feature_store/features/real_time_feature_extractor_pb2.py +32 -143
- _qwak_proto/qwak/feature_store/jobs/job_pb2.py +12 -46
- _qwak_proto/qwak/feature_store/jobs/job_service_pb2.py +30 -127
- _qwak_proto/qwak/feature_store/jobs/v1/job_pb2.py +12 -45
- _qwak_proto/qwak/feature_store/jobs/v1/job_service_pb2.py +42 -187
- _qwak_proto/qwak/feature_store/platform/platform_details_pb2.py +8 -24
- _qwak_proto/qwak/feature_store/reports/report_pb2.py +14 -53
- _qwak_proto/qwak/feature_store/repository/common/platform_pb2.py +10 -34
- _qwak_proto/qwak/feature_store/serving/management_pb2.py +14 -47
- _qwak_proto/qwak/feature_store/serving/metadata_pb2.py +12 -44
- _qwak_proto/qwak/feature_store/serving/serving_pb2.py +50 -222
- _qwak_proto/qwak/feature_store/serving/v1/value_pb2.py +8 -24
- _qwak_proto/qwak/feature_store/sinks/sink_pb2.py +14 -54
- _qwak_proto/qwak/feature_store/sources/batch_pb2.py +79 -335
- _qwak_proto/qwak/feature_store/sources/batch_pb2.pyi +99 -7
- _qwak_proto/qwak/feature_store/sources/data_source_attribute_pb2.py +6 -14
- _qwak_proto/qwak/feature_store/sources/data_source_pb2.py +15 -55
- _qwak_proto/qwak/feature_store/sources/data_source_pb2.pyi +5 -1
- _qwak_proto/qwak/feature_store/sources/data_source_service_pb2.py +39 -148
- _qwak_proto/qwak/feature_store/sources/data_source_service_pb2.pyi +25 -0
- _qwak_proto/qwak/feature_store/sources/data_source_service_pb2_grpc.py +34 -0
- _qwak_proto/qwak/feature_store/sources/streaming_pb2.py +34 -146
- _qwak_proto/qwak/feature_store/v1/common/jfrog_artifact/jfrog_artifact_pb2.py +6 -14
- _qwak_proto/qwak/feature_store/v1/common/source_code/source_code_pb2.py +10 -34
- _qwak_proto/qwak/feature_store/v1/internal/data_source/data_source_service_pb2.py +16 -58
- _qwak_proto/qwak/feature_store/v1/internal/featureset/featureset_token_service_pb2.py +10 -27
- _qwak_proto/qwak/features_operator/v1/features_operator_pb2.py +14 -54
- _qwak_proto/qwak/features_operator/v1/features_operator_service_pb2.py +14 -47
- _qwak_proto/qwak/features_operator/v2/features_operator_pb2.py +16 -64
- _qwak_proto/qwak/features_operator/v2/features_operator_service_pb2.py +12 -37
- _qwak_proto/qwak/features_operator/v3/features_operator_async_service_pb2.py +26 -107
- _qwak_proto/qwak/features_operator/v3/features_operator_pb2.py +16 -64
- _qwak_proto/qwak/file_versioning/file_versioning_pb2.py +10 -33
- _qwak_proto/qwak/file_versioning/file_versioning_service_pb2.py +14 -47
- _qwak_proto/qwak/fitness_service/constructs_pb2.py +23 -100
- _qwak_proto/qwak/fitness_service/constructs_pb2.pyi +24 -0
- _qwak_proto/qwak/fitness_service/fitness_pb2.py +7 -34
- _qwak_proto/qwak/fitness_service/fitness_pb2.pyi +0 -93
- _qwak_proto/qwak/fitness_service/status_pb2.py +17 -108
- _qwak_proto/qwak/fitness_service/status_pb2.pyi +1 -121
- _qwak_proto/qwak/inference/feedback/feedback_pb2.py +28 -96
- _qwak_proto/qwak/instance_template/instance_template_pb2.py +13 -41
- _qwak_proto/qwak/instance_template/instance_template_pb2.pyi +4 -1
- _qwak_proto/qwak/instance_template/instance_template_service_pb2.py +14 -47
- _qwak_proto/qwak/integration/hugging_face_integration_pb2.py +16 -64
- _qwak_proto/qwak/integration/integration_pb2.py +28 -126
- _qwak_proto/qwak/integration/integration_service_pb2.py +34 -147
- _qwak_proto/qwak/integration/open_a_i_integration_pb2.py +16 -64
- _qwak_proto/qwak/integration/opsgenie_integration_pb2.py +20 -82
- _qwak_proto/qwak/integration/pagerduty_integration_pb2.py +24 -104
- _qwak_proto/qwak/integration/slack_app_integration_pb2.py +24 -104
- _qwak_proto/qwak/kube_deployment_captain/alert_pb2.py +22 -97
- _qwak_proto/qwak/kube_deployment_captain/alerting_pb2.py +12 -44
- _qwak_proto/qwak/kube_deployment_captain/batch_job_pb2.py +70 -323
- _qwak_proto/qwak/kube_deployment_captain/batch_job_pb2.pyi +20 -5
- _qwak_proto/qwak/kube_deployment_captain/deployment_pb2.py +44 -167
- _qwak_proto/qwak/kube_deployment_captain/feature_set_deployment_pb2.py +32 -144
- _qwak_proto/qwak/kube_deployment_captain/kube_deployment_captain_service_pb2.py +108 -519
- _qwak_proto/qwak/kube_deployment_captain/traffic_mapping_pb2.py +8 -24
- _qwak_proto/qwak/logging/log_filter_pb2.py +12 -44
- _qwak_proto/qwak/logging/log_line_pb2.py +8 -25
- _qwak_proto/qwak/logging/log_reader_service_pb2.py +10 -27
- _qwak_proto/qwak/logging/log_source_pb2.py +30 -134
- _qwak_proto/qwak/model_descriptor/open_ai_descriptor_pb2.py +18 -74
- _qwak_proto/qwak/model_group/model_group_pb2.py +25 -48
- _qwak_proto/qwak/model_group/model_group_pb2.pyi +88 -0
- _qwak_proto/qwak/model_group/model_group_pb2_grpc.py +70 -0
- _qwak_proto/qwak/model_group/model_group_repository_details_pb2.py +23 -75
- _qwak_proto/qwak/model_group/model_group_repository_details_pb2.pyi +44 -6
- _qwak_proto/qwak/models/models_pb2.py +99 -406
- _qwak_proto/qwak/models/models_pb2.pyi +86 -0
- _qwak_proto/qwak/models/models_pb2_grpc.py +34 -0
- _qwak_proto/qwak/models/models_query_pb2.py +16 -56
- _qwak_proto/qwak/models/models_query_pb2.pyi +4 -4
- _qwak_proto/qwak/monitoring/v0/alerting_channel_management_service_pb2.py +30 -127
- _qwak_proto/qwak/monitoring/v0/alerting_channel_pb2.py +34 -152
- _qwak_proto/qwak/monitoring/v0/alerting_channel_sync_service_pb2.py +14 -47
- _qwak_proto/qwak/offline/serving/v1/feature_values_pb2.py +6 -14
- _qwak_proto/qwak/offline/serving/v1/offline_serving_async_service_pb2.py +30 -123
- _qwak_proto/qwak/offline/serving/v1/options_pb2.py +6 -14
- _qwak_proto/qwak/offline/serving/v1/population_pb2.py +14 -54
- _qwak_proto/qwak/projects/jfrog_project_spec_pb2.py +6 -14
- _qwak_proto/qwak/projects/projects_pb2.py +50 -192
- _qwak_proto/qwak/projects/projects_pb2.pyi +35 -0
- _qwak_proto/qwak/prompt/v1/prompt/prompt_manager_service_pb2.py +54 -247
- _qwak_proto/qwak/prompt/v1/prompt/prompt_pb2.py +46 -214
- _qwak_proto/qwak/secret_service/secret_service_pb2.py +18 -67
- _qwak_proto/qwak/secret_service/secret_service_pb2.pyi +1 -1
- _qwak_proto/qwak/self_service/account/v0/account_membership_pb2.py +24 -106
- _qwak_proto/qwak/self_service/account/v0/account_membership_service_pb2.py +50 -227
- _qwak_proto/qwak/self_service/account/v0/account_status_pb2.py +16 -65
- _qwak_proto/qwak/self_service/account/v0/managing_account_pb2.py +37 -132
- _qwak_proto/qwak/self_service/account/v0/managing_account_pb2.pyi +40 -2
- _qwak_proto/qwak/self_service/account/v0/managing_account_service_pb2.py +22 -87
- _qwak_proto/qwak/self_service/user/v1/api_key_pb2.py +6 -14
- _qwak_proto/qwak/self_service/user/v1/user_pb2.py +6 -14
- _qwak_proto/qwak/self_service/user/v1/user_service_pb2.py +30 -121
- _qwak_proto/qwak/service_discovery/service_discovery_location_pb2.py +12 -44
- _qwak_proto/qwak/service_discovery/service_discovery_location_service_pb2.py +10 -27
- _qwak_proto/qwak/traffic/v1/traffic_api_pb2.py +22 -87
- _qwak_proto/qwak/traffic/v1/traffic_pb2.py +26 -113
- _qwak_proto/qwak/user_application/common/v0/resources_pb2.py +31 -139
- _qwak_proto/qwak/user_application/common/v0/resources_pb2.pyi +24 -0
- _qwak_proto/qwak/user_application/v0/user_application_pb2.py +11 -44
- _qwak_proto/qwak/user_application/v0/user_application_pb2.pyi +6 -0
- _qwak_proto/qwak/vectors/v1/collection/collection_pb2.py +24 -106
- _qwak_proto/qwak/vectors/v1/collection/collection_service_pb2.py +38 -167
- _qwak_proto/qwak/vectors/v1/collection/event/collection_event_pb2.py +6 -14
- _qwak_proto/qwak/vectors/v1/filters_pb2.py +30 -134
- _qwak_proto/qwak/vectors/v1/vector_pb2.py +14 -54
- _qwak_proto/qwak/vectors/v1/vector_service_pb2.py +26 -107
- _qwak_proto/qwak/workspace/workspace_pb2.py +22 -107
- _qwak_proto/qwak/workspace/workspace_service_pb2.py +62 -287
- qwak/__init__.py +1 -1
- qwak/automations/automations.py +3 -0
- qwak/clients/feature_store/execution_management_client.py +28 -0
- qwak/clients/feature_store/management_client.py +156 -206
- qwak/clients/feature_store/operator_client.py +19 -1
- qwak/clients/logging_client/client.py +13 -18
- qwak/clients/model_management/client.py +0 -5
- qwak/clients/project/client.py +0 -7
- qwak/exceptions/__init__.py +1 -0
- qwak/exceptions/qwak_grpc_address_exception.py +9 -0
- qwak/feature_store/_common/artifact_utils.py +10 -8
- qwak/feature_store/_common/packaging.py +39 -21
- qwak/feature_store/_common/source_code_spec.py +61 -11
- qwak/feature_store/_common/source_code_spec_factory.py +63 -10
- qwak/feature_store/data_sources/__init__.py +2 -0
- qwak/feature_store/data_sources/base.py +11 -7
- qwak/feature_store/data_sources/batch/snowflake.py +34 -8
- qwak/feature_store/data_sources/batch/unity_catalog.py +107 -0
- qwak/feature_store/execution/streaming_backfill.py +48 -0
- qwak/feature_store/feature_sets/base_feature_set.py +1 -0
- qwak/feature_store/feature_sets/streaming.py +84 -63
- qwak/feature_store/feature_sets/streaming_backfill.py +88 -124
- qwak/feature_store/online/client.py +20 -4
- qwak/feature_store/validations/validation_decorators.py +70 -0
- qwak/feature_store/validations/validation_response.py +3 -1
- qwak/feature_store/validations/validator.py +11 -3
- qwak/inner/build_logic/interface/context_interface.py +4 -0
- qwak/inner/build_logic/phases/phase_010_fetch_model/post_fetch_validation_step.py +1 -1
- qwak/inner/const.py +2 -6
- qwak/inner/di_configuration/__init__.py +1 -69
- qwak/inner/di_configuration/account.py +18 -63
- qwak/inner/di_configuration/containers.py +5 -1
- qwak/inner/di_configuration/dependency_wiring.py +98 -0
- qwak/inner/tool/auth.py +10 -80
- qwak/inner/tool/grpc/grpc_auth.py +0 -32
- qwak/inner/tool/grpc/grpc_tools.py +125 -11
- qwak/inner/tool/grpc/grpc_try_wrapping.py +140 -3
- qwak/llmops/generation/chat/openai/types/chat/chat_completion.py +24 -6
- qwak/llmops/generation/chat/openai/types/chat/chat_completion_chunk.py +44 -8
- qwak/llmops/generation/chat/openai/types/chat/chat_completion_message.py +6 -3
- qwak/qwak_client/client.py +2 -13
- qwak/vector_store/rest_helpers.py +4 -16
- qwak_core-0.5.19.dist-info/METADATA +48 -0
- {qwak_core-0.4.278.dist-info → qwak_core-0.5.19.dist-info}/RECORD +316 -334
- qwak_services_mock/mocks/execution_management_service.py +9 -1
- qwak_services_mock/mocks/feature_store_data_sources_manager_api.py +55 -13
- qwak_services_mock/mocks/feature_store_entities_manager_api.py +31 -29
- qwak_services_mock/mocks/features_operator_v3_service.py +20 -0
- qwak_services_mock/mocks/qwak_mocks.py +0 -2
- qwak_services_mock/services_mock.py +1 -11
- _qwak_proto/qwak/fitness_service/fitness_service_pb2.py +0 -110
- _qwak_proto/qwak/fitness_service/fitness_service_pb2.pyi +0 -121
- _qwak_proto/qwak/fitness_service/fitness_service_pb2_grpc.py +0 -169
- frogml_storage/__init__.py +0 -1
- frogml_storage/artifactory/__init__.py +0 -1
- frogml_storage/artifactory/_artifactory_api.py +0 -315
- frogml_storage/authentication/login/__init__.py +0 -1
- frogml_storage/authentication/login/_login_cli.py +0 -239
- frogml_storage/authentication/login/_login_command.py +0 -74
- frogml_storage/authentication/models/__init__.py +0 -3
- frogml_storage/authentication/models/_auth.py +0 -24
- frogml_storage/authentication/models/_auth_config.py +0 -70
- frogml_storage/authentication/models/_login.py +0 -22
- frogml_storage/authentication/utils/__init__.py +0 -17
- frogml_storage/authentication/utils/_authentication_utils.py +0 -281
- frogml_storage/authentication/utils/_login_checks_utils.py +0 -114
- frogml_storage/base_storage.py +0 -140
- frogml_storage/constants.py +0 -56
- frogml_storage/exceptions/checksum_verification_error.py +0 -3
- frogml_storage/exceptions/validation_error.py +0 -4
- frogml_storage/frog_ml.py +0 -668
- frogml_storage/http/__init__.py +0 -1
- frogml_storage/http/http_client.py +0 -83
- frogml_storage/logging/__init__.py +0 -1
- frogml_storage/logging/_log_config.py +0 -45
- frogml_storage/logging/log_utils.py +0 -21
- frogml_storage/models/__init__.py +0 -1
- frogml_storage/models/_download_context.py +0 -54
- frogml_storage/models/dataset_manifest.py +0 -13
- frogml_storage/models/entity_manifest.py +0 -93
- frogml_storage/models/frogml_dataset_version.py +0 -21
- frogml_storage/models/frogml_entity_type_info.py +0 -50
- frogml_storage/models/frogml_entity_version.py +0 -34
- frogml_storage/models/frogml_model_version.py +0 -21
- frogml_storage/models/model_manifest.py +0 -60
- frogml_storage/models/serialization_metadata.py +0 -15
- frogml_storage/utils/__init__.py +0 -12
- frogml_storage/utils/_environment.py +0 -21
- frogml_storage/utils/_input_checks_utility.py +0 -104
- frogml_storage/utils/_storage_utils.py +0 -15
- frogml_storage/utils/_url_utils.py +0 -27
- qwak/clients/build_management/__init__.py +0 -1
- qwak/clients/build_management/client.py +0 -114
- qwak_core-0.4.278.dist-info/METADATA +0 -415
- qwak_services_mock/mocks/build_management.py +0 -100
- {qwak_core-0.4.278.dist-info → qwak_core-0.5.19.dist-info}/WHEEL +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from typing import Callable, Tuple
|
|
2
2
|
|
|
3
3
|
import grpc
|
|
4
|
-
from qwak.inner.const import QwakConstants
|
|
5
4
|
|
|
6
5
|
_SIGNATURE_HEADER_KEY = "authorization"
|
|
7
6
|
|
|
@@ -35,34 +34,3 @@ class Auth0Client(grpc.AuthMetadataPlugin):
|
|
|
35
34
|
|
|
36
35
|
self._auth_client = Auth0ClientBase()
|
|
37
36
|
return self._auth_client.get_token()
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
class FrogMLGrpcClient(grpc.AuthMetadataPlugin):
|
|
41
|
-
def __init__(self):
|
|
42
|
-
self._auth_client = None
|
|
43
|
-
|
|
44
|
-
def __call__(
|
|
45
|
-
self,
|
|
46
|
-
context: grpc.AuthMetadataContext,
|
|
47
|
-
callback: Callable[[Tuple[Tuple[str, str]], None], None],
|
|
48
|
-
):
|
|
49
|
-
"""Implements authentication by passing metadata to a callback.
|
|
50
|
-
|
|
51
|
-
Args:
|
|
52
|
-
context: An AuthMetadataContext providing information on the RPC that
|
|
53
|
-
the plugin is being called to authenticate.
|
|
54
|
-
callback: A callback that accepts a tuple of metadata key/value pairs and a None
|
|
55
|
-
parameter.
|
|
56
|
-
"""
|
|
57
|
-
# Get token from FrogML client
|
|
58
|
-
if not self._auth_client:
|
|
59
|
-
from qwak.inner.tool.auth import FrogMLAuthClient
|
|
60
|
-
|
|
61
|
-
self._auth_client = FrogMLAuthClient()
|
|
62
|
-
token = self._auth_client.get_token()
|
|
63
|
-
jfrog_tenant_id = self._auth_client.get_tenant_id()
|
|
64
|
-
metadata = (
|
|
65
|
-
(_SIGNATURE_HEADER_KEY, f"Bearer {token}"),
|
|
66
|
-
(QwakConstants.JFROG_TENANT_HEADER_KEY.lower(), jfrog_tenant_id),
|
|
67
|
-
)
|
|
68
|
-
callback(metadata, None)
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import re
|
|
2
3
|
import time
|
|
3
4
|
from abc import ABC, abstractmethod
|
|
4
5
|
from random import randint
|
|
5
6
|
from typing import Callable, Optional, Tuple
|
|
7
|
+
from urllib.parse import urlparse, ParseResult
|
|
6
8
|
|
|
7
9
|
import grpc
|
|
8
|
-
from qwak.exceptions import QwakException
|
|
9
|
-
from qwak.inner.di_configuration.account import UserAccountConfiguration
|
|
10
|
-
from qwak.inner.tool.auth import Auth0ClientBase
|
|
11
10
|
|
|
12
|
-
from .
|
|
11
|
+
from qwak.exceptions import QwakException, QwakGrpcAddressException
|
|
12
|
+
from .grpc_auth import Auth0Client
|
|
13
13
|
|
|
14
14
|
logger = logging.getLogger()
|
|
15
|
+
HOSTNAME_REGEX: str = r"^(?!-)(?:[A-Za-z0-9-]{1,63}\.)*[A-Za-z0-9-]{1,63}(?<!-)$"
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
def create_grpc_channel(
|
|
@@ -21,7 +22,7 @@ def create_grpc_channel(
|
|
|
21
22
|
auth_metadata_plugin: grpc.AuthMetadataPlugin = None,
|
|
22
23
|
timeout: int = 100,
|
|
23
24
|
options=None,
|
|
24
|
-
backoff_options=
|
|
25
|
+
backoff_options=None,
|
|
25
26
|
max_attempts=4,
|
|
26
27
|
status_for_retry=(grpc.StatusCode.UNAVAILABLE,),
|
|
27
28
|
attempt=0,
|
|
@@ -42,6 +43,9 @@ def create_grpc_channel(
|
|
|
42
43
|
status_for_retry: grpc statuses to retry upon
|
|
43
44
|
Returns: Returns a grpc.Channel
|
|
44
45
|
"""
|
|
46
|
+
if backoff_options is None:
|
|
47
|
+
backoff_options = {}
|
|
48
|
+
|
|
45
49
|
if not url:
|
|
46
50
|
raise QwakException("Unable to create gRPC channel. URL has not been defined.")
|
|
47
51
|
|
|
@@ -49,11 +53,7 @@ def create_grpc_channel(
|
|
|
49
53
|
credentials = grpc.ssl_channel_credentials()
|
|
50
54
|
if enable_auth:
|
|
51
55
|
if auth_metadata_plugin is None:
|
|
52
|
-
|
|
53
|
-
if issubclass(user_config._auth_client, Auth0ClientBase):
|
|
54
|
-
auth_metadata_plugin = Auth0Client()
|
|
55
|
-
else:
|
|
56
|
-
auth_metadata_plugin = FrogMLGrpcClient()
|
|
56
|
+
auth_metadata_plugin = Auth0Client()
|
|
57
57
|
credentials = grpc.composite_channel_credentials(
|
|
58
58
|
credentials, grpc.metadata_call_credentials(auth_metadata_plugin)
|
|
59
59
|
)
|
|
@@ -107,11 +107,14 @@ def create_grpc_channel_or_none(
|
|
|
107
107
|
auth_metadata_plugin: grpc.AuthMetadataPlugin = None,
|
|
108
108
|
timeout: int = 30,
|
|
109
109
|
options=None,
|
|
110
|
-
backoff_options=
|
|
110
|
+
backoff_options=None,
|
|
111
111
|
max_attempts=2,
|
|
112
112
|
status_for_retry=(grpc.StatusCode.UNAVAILABLE,),
|
|
113
113
|
attempt=0,
|
|
114
114
|
) -> Callable[[Optional[str], Optional[bool]], Optional[grpc.Channel]]:
|
|
115
|
+
if backoff_options is None:
|
|
116
|
+
backoff_options = {}
|
|
117
|
+
|
|
115
118
|
def deferred_channel(
|
|
116
119
|
url_overwrite: Optional[str] = None, ssl_overwrite: Optional[bool] = None
|
|
117
120
|
):
|
|
@@ -135,6 +138,117 @@ def create_grpc_channel_or_none(
|
|
|
135
138
|
return deferred_channel
|
|
136
139
|
|
|
137
140
|
|
|
141
|
+
def validate_grpc_address(
|
|
142
|
+
grpc_address: str,
|
|
143
|
+
is_port_specification_allowed: bool = False,
|
|
144
|
+
is_url_scheme_allowed: bool = False,
|
|
145
|
+
):
|
|
146
|
+
"""
|
|
147
|
+
Validate gRPC address format
|
|
148
|
+
Args:
|
|
149
|
+
grpc_address (str): gRPC address to validate
|
|
150
|
+
is_port_specification_allowed (bool): Whether to allow port specification in the address
|
|
151
|
+
is_url_scheme_allowed (bool): Whether to allow URL scheme in the address
|
|
152
|
+
Raises:
|
|
153
|
+
QwakGrpcAddressException: If the gRPC address is invalid
|
|
154
|
+
"""
|
|
155
|
+
parsed_grpc_address: ParseResult = parse_address(grpc_address)
|
|
156
|
+
hostname: str = get_hostname_from_address(parsed_grpc_address)
|
|
157
|
+
validate_paths_are_not_included_in_address(parsed_grpc_address)
|
|
158
|
+
|
|
159
|
+
if not is_url_scheme_allowed:
|
|
160
|
+
__validate_url_scheme_not_included_in_address(parsed_grpc_address)
|
|
161
|
+
|
|
162
|
+
if not is_port_specification_allowed:
|
|
163
|
+
__validate_port_not_included_in_address(parsed_grpc_address)
|
|
164
|
+
|
|
165
|
+
if not is_valid_hostname(hostname):
|
|
166
|
+
raise QwakGrpcAddressException(
|
|
167
|
+
"gRPC address must be a simple hostname or fully qualified domain name.",
|
|
168
|
+
parsed_grpc_address,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def validate_paths_are_not_included_in_address(
|
|
173
|
+
parsed_grpc_address: ParseResult,
|
|
174
|
+
) -> None:
|
|
175
|
+
has_invalid_path: bool = (
|
|
176
|
+
parsed_grpc_address.path not in {"", "/"}
|
|
177
|
+
or parsed_grpc_address.query
|
|
178
|
+
or parsed_grpc_address.fragment
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
if has_invalid_path:
|
|
182
|
+
raise QwakGrpcAddressException(
|
|
183
|
+
"gRPC address must not contain paths, queries, or fragments.",
|
|
184
|
+
parsed_grpc_address,
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def get_hostname_from_address(parsed_grpc_address: ParseResult) -> str:
|
|
189
|
+
hostname: Optional[str] = parsed_grpc_address.hostname
|
|
190
|
+
if not hostname:
|
|
191
|
+
raise QwakGrpcAddressException(
|
|
192
|
+
"gRPC address must contain a valid hostname.", parsed_grpc_address
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
return hostname
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def __validate_url_scheme_not_included_in_address(
|
|
199
|
+
parsed_grpc_address: ParseResult,
|
|
200
|
+
) -> None:
|
|
201
|
+
if parsed_grpc_address.scheme:
|
|
202
|
+
raise QwakGrpcAddressException(
|
|
203
|
+
"URL scheme is not allowed in the gRPC address.", parsed_grpc_address
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def __validate_port_not_included_in_address(parsed_grpc_address: ParseResult):
|
|
208
|
+
try:
|
|
209
|
+
port: Optional[int] = parsed_grpc_address.port
|
|
210
|
+
except ValueError as exc:
|
|
211
|
+
raise QwakGrpcAddressException(
|
|
212
|
+
"Invalid port specification in the gRPC address.", parsed_grpc_address
|
|
213
|
+
) from exc
|
|
214
|
+
|
|
215
|
+
if port:
|
|
216
|
+
raise QwakGrpcAddressException(
|
|
217
|
+
"Port specification is not allowed in the gRPC address.",
|
|
218
|
+
parsed_grpc_address,
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def parse_address(grpc_address: str) -> ParseResult:
|
|
223
|
+
if not grpc_address or not grpc_address.strip():
|
|
224
|
+
raise QwakGrpcAddressException(
|
|
225
|
+
"gRPC address must not be empty or whitespace.", grpc_address
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
trimmed_address: str = grpc_address.strip()
|
|
229
|
+
parsed_address: ParseResult = urlparse(
|
|
230
|
+
trimmed_address if "://" in trimmed_address else f"//{trimmed_address}"
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
return parsed_address
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def is_valid_hostname(hostname: str) -> bool:
|
|
237
|
+
"""
|
|
238
|
+
Validate that the supplied hostname conforms to RFC-style label rules:
|
|
239
|
+
anchored pattern enforces full-string validation, negative lookahead/lookbehind block
|
|
240
|
+
leading or trailing hyphens per label, and each dot-separated label must be 1-63
|
|
241
|
+
alphanumeric/hyphen characters.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
hostname (str): The hostname to validate.
|
|
245
|
+
Returns:
|
|
246
|
+
bool: True if the hostname is valid, False otherwise.
|
|
247
|
+
"""
|
|
248
|
+
hostname_pattern: re.Pattern = re.compile(HOSTNAME_REGEX)
|
|
249
|
+
return bool(hostname_pattern.fullmatch(hostname))
|
|
250
|
+
|
|
251
|
+
|
|
138
252
|
class SleepingPolicy(ABC):
|
|
139
253
|
@abstractmethod
|
|
140
254
|
def sleep(self, try_i: int):
|
|
@@ -1,15 +1,152 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import functools
|
|
3
|
+
import inspect
|
|
4
|
+
from inspect import BoundArguments, Signature
|
|
5
|
+
from typing import Any, Callable, Optional
|
|
6
|
+
|
|
1
7
|
import grpc
|
|
2
8
|
from qwak.exceptions import QwakException
|
|
3
9
|
|
|
10
|
+
logger = logging.getLogger()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def grpc_try_catch_wrapper(
|
|
14
|
+
exception_message: str,
|
|
15
|
+
reraise_non_grpc_error_original_exception: Optional[bool] = False,
|
|
16
|
+
) -> Callable:
|
|
17
|
+
"""A decorator for handling exceptions in client methods.
|
|
18
|
+
|
|
19
|
+
This decorator wraps a function, catching any `grpc.RpcError` or other
|
|
20
|
+
`Exception`. it re-raises them as a `QwakException`. The error message can be a
|
|
21
|
+
static string or a template formatted with the decorated function's
|
|
22
|
+
runtime arguments.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
exception_message : str
|
|
27
|
+
The error message template. This can be a static string or a format
|
|
28
|
+
string using placeholders that match the decorated function's
|
|
29
|
+
parameter names (e.g., "Failed on item {item_id}").
|
|
30
|
+
reraise_non_grpc_error_original_exception : bool, optional
|
|
31
|
+
If `True`, any exception that is *not* a `grpc.RpcError` will be
|
|
32
|
+
re-raised in its original form. If `False` (the default), all
|
|
33
|
+
exceptions are wrapped in `QwakException`.
|
|
34
|
+
|
|
35
|
+
Returns
|
|
36
|
+
-------
|
|
37
|
+
Callable
|
|
38
|
+
A decorator that wraps the function with the error handling logic.
|
|
39
|
+
|
|
40
|
+
Raises
|
|
41
|
+
------
|
|
42
|
+
QwakException
|
|
43
|
+
Raised when the decorated function encounters any exception, unless
|
|
44
|
+
`reraise_non_grpc_error_original_exception` is `True` and the error
|
|
45
|
+
is not a `grpc.RpcError`. The new exception's message is formatted
|
|
46
|
+
and includes details from the original error.
|
|
47
|
+
Exception
|
|
48
|
+
The original non-gRPC exception is re-raised if
|
|
49
|
+
`reraise_non_grpc_error_original_exception` is set to `True`.
|
|
50
|
+
|
|
51
|
+
Usage
|
|
52
|
+
-----
|
|
53
|
+
The decorator can be used with static strings and formatted strings
|
|
54
|
+
|
|
55
|
+
**1. Formatted Error Messages**
|
|
56
|
+
|
|
57
|
+
Use placeholders matching the function's parameter names to create
|
|
58
|
+
context-specific error messages.
|
|
59
|
+
|
|
60
|
+
@grpc_try_catch_wrapper("Failed to delete version {version_number} for FeatureSet {featureset_name}")
|
|
61
|
+
def delete_featureset_version(self, featureset_name: str, version_number: int):
|
|
62
|
+
# ... gRPC call ...
|
|
63
|
+
|
|
64
|
+
If this function fails with a gRPC error, a `QwakException` is raised with a message like:
|
|
65
|
+
`"Failed to delete version 2 for FeatureSet customer_churn - <original gRPC error code> - <original gRPC error details>."`
|
|
66
|
+
|
|
67
|
+
**2. Static Error Messages**
|
|
68
|
+
|
|
69
|
+
When no dynamic context is needed, a simple string is sufficient.
|
|
4
70
|
|
|
5
|
-
|
|
6
|
-
|
|
71
|
+
@grpc_try_catch_wrapper("Failed to retrieve featuresets mapping")
|
|
72
|
+
def get_featuresets_mapping(self):
|
|
73
|
+
# ... gRPC call ...
|
|
74
|
+
|
|
75
|
+
If this fails, the `QwakException` message will be:
|
|
76
|
+
`"Failed to retrieve featuresets mapping - <original gRPC error code> - <original gRPC error details>."`
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
def decorator(function: Callable):
|
|
80
|
+
@functools.wraps(function)
|
|
7
81
|
def _inner_wrapper(*args, **kwargs):
|
|
8
82
|
try:
|
|
9
83
|
return function(*args, **kwargs)
|
|
10
84
|
except grpc.RpcError as e:
|
|
11
|
-
|
|
85
|
+
error_message: str = __get_error_msg(
|
|
86
|
+
exception_message=exception_message, e=e
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
formatted_message = __get_formatted_error_message(
|
|
90
|
+
exception_message=error_message,
|
|
91
|
+
function=function,
|
|
92
|
+
args=args,
|
|
93
|
+
kwargs=kwargs,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
raise QwakException(formatted_message) from e
|
|
97
|
+
|
|
98
|
+
except Exception as e:
|
|
99
|
+
if reraise_non_grpc_error_original_exception:
|
|
100
|
+
raise e
|
|
101
|
+
|
|
102
|
+
formatted_message = __get_formatted_error_message(
|
|
103
|
+
exception_message=exception_message,
|
|
104
|
+
function=function,
|
|
105
|
+
args=args,
|
|
106
|
+
kwargs=kwargs,
|
|
107
|
+
)
|
|
108
|
+
raise QwakException(f"{formatted_message}. Error is: {e}.") from e
|
|
12
109
|
|
|
13
110
|
return _inner_wrapper
|
|
14
111
|
|
|
15
112
|
return decorator
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def __get_error_msg(exception_message: str, e: grpc.RpcError) -> str:
|
|
116
|
+
err_msg: str = (
|
|
117
|
+
f"{exception_message} - {e.code() if hasattr(e, 'code') else 'UNKNOWN'}"
|
|
118
|
+
)
|
|
119
|
+
if hasattr(e, "details") and e.details() is not None:
|
|
120
|
+
err_msg: str = f"{err_msg} - {e.details()}"
|
|
121
|
+
elif hasattr(e, "debug_error_string"):
|
|
122
|
+
err_msg: str = f"{err_msg} - {e.debug_error_string()}"
|
|
123
|
+
logger.debug(f"{err_msg}: {e}")
|
|
124
|
+
return err_msg
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def __get_formatted_error_message(
|
|
128
|
+
exception_message: str, function: Callable, args: tuple[Any], kwargs: dict[str, Any]
|
|
129
|
+
) -> str:
|
|
130
|
+
"""Formats an error message string with the runtime arguments of a function.
|
|
131
|
+
|
|
132
|
+
It inspects the function's signature and binds the passed args and kwargs
|
|
133
|
+
to their parameter names, then uses them to format the message string.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
exception_message (str): The error message template with placeholders.
|
|
137
|
+
function (Callable): The decorated function.
|
|
138
|
+
args (tuple[Any]): The positional arguments passed to the function.
|
|
139
|
+
kwargs (dict[str, Any]): The keyword arguments passed to the function.
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
str: The error message with placeholders filled in.
|
|
143
|
+
"""
|
|
144
|
+
try:
|
|
145
|
+
sig: Signature = inspect.signature(function)
|
|
146
|
+
bound_args: BoundArguments = sig.bind(*args, **kwargs)
|
|
147
|
+
bound_args.apply_defaults()
|
|
148
|
+
|
|
149
|
+
return exception_message.format(**bound_args.arguments)
|
|
150
|
+
except (ValueError, KeyError, TypeError):
|
|
151
|
+
# Fallback if formatting fails (e.g., missing key in template)
|
|
152
|
+
return exception_message
|
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
from dataclasses import dataclass
|
|
17
17
|
from typing import List, Optional
|
|
18
18
|
|
|
19
|
-
from typing_extensions import Literal
|
|
20
|
-
|
|
21
19
|
from qwak.llmops.generation.base import ModelResponse
|
|
22
20
|
from .chat_completion_message import ChatCompletionMessage
|
|
23
21
|
from .chat_completion_token_logprob import ChatCompletionTokenLogprob
|
|
@@ -34,9 +32,7 @@ class ChoiceLogprobs:
|
|
|
34
32
|
|
|
35
33
|
@dataclass
|
|
36
34
|
class Choice:
|
|
37
|
-
finish_reason:
|
|
38
|
-
"stop", "length", "tool_calls", "content_filter", "function_call"
|
|
39
|
-
]
|
|
35
|
+
finish_reason: str
|
|
40
36
|
"""The reason the model stopped generating tokens.
|
|
41
37
|
|
|
42
38
|
This will be `stop` if the model hit a natural stop point or a provided stop
|
|
@@ -55,6 +51,21 @@ class Choice:
|
|
|
55
51
|
logprobs: Optional[ChoiceLogprobs] = None
|
|
56
52
|
"""Log probability information for the choice."""
|
|
57
53
|
|
|
54
|
+
def __post_init__(self):
|
|
55
|
+
"""Validates that finish_reason is one of the allowed values."""
|
|
56
|
+
allowed_reasons = {
|
|
57
|
+
"stop",
|
|
58
|
+
"length",
|
|
59
|
+
"tool_calls",
|
|
60
|
+
"content_filter",
|
|
61
|
+
"function_call",
|
|
62
|
+
}
|
|
63
|
+
if self.finish_reason not in allowed_reasons:
|
|
64
|
+
raise ValueError(
|
|
65
|
+
f"Invalid finish_reason: '{self.finish_reason}'. "
|
|
66
|
+
f"Must be one of {allowed_reasons}"
|
|
67
|
+
)
|
|
68
|
+
|
|
58
69
|
|
|
59
70
|
@dataclass
|
|
60
71
|
class ChatCompletion(ModelResponse):
|
|
@@ -73,7 +84,7 @@ class ChatCompletion(ModelResponse):
|
|
|
73
84
|
model: str
|
|
74
85
|
"""The model used for the chat completion."""
|
|
75
86
|
|
|
76
|
-
object:
|
|
87
|
+
object: str
|
|
77
88
|
"""The object type, which is always `chat.completion`."""
|
|
78
89
|
|
|
79
90
|
system_fingerprint: Optional[str] = None
|
|
@@ -85,3 +96,10 @@ class ChatCompletion(ModelResponse):
|
|
|
85
96
|
|
|
86
97
|
usage: Optional[CompletionUsage] = None
|
|
87
98
|
"""Usage statistics for the completion request."""
|
|
99
|
+
|
|
100
|
+
def __post_init__(self):
|
|
101
|
+
"""Validates that the object type is correct."""
|
|
102
|
+
if self.object != "chat.completion":
|
|
103
|
+
raise ValueError(
|
|
104
|
+
f"Invalid object type: '{self.object}'. Must be 'chat.completion'"
|
|
105
|
+
)
|
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
from dataclasses import dataclass
|
|
17
17
|
from typing import List, Optional
|
|
18
18
|
|
|
19
|
-
from typing_extensions import Literal
|
|
20
|
-
|
|
21
19
|
from qwak.llmops.generation.base import ModelResponse
|
|
22
20
|
from .chat_completion_token_logprob import ChatCompletionTokenLogprob
|
|
23
21
|
|
|
@@ -69,9 +67,16 @@ class ChoiceDeltaToolCall:
|
|
|
69
67
|
|
|
70
68
|
function: Optional[ChoiceDeltaToolCallFunction] = None
|
|
71
69
|
|
|
72
|
-
type: Optional[
|
|
70
|
+
type: Optional[str] = None
|
|
73
71
|
"""The type of the tool. Currently, only `function` is supported."""
|
|
74
72
|
|
|
73
|
+
def __post_init__(self):
|
|
74
|
+
"""Validates that type is 'function' if present."""
|
|
75
|
+
if self.type is not None and self.type != "function":
|
|
76
|
+
raise ValueError(
|
|
77
|
+
f"Invalid type: '{self.type}'. Must be 'function' or None."
|
|
78
|
+
)
|
|
79
|
+
|
|
75
80
|
|
|
76
81
|
@dataclass
|
|
77
82
|
class ChoiceDelta:
|
|
@@ -85,11 +90,21 @@ class ChoiceDelta:
|
|
|
85
90
|
model.
|
|
86
91
|
"""
|
|
87
92
|
|
|
88
|
-
role: Optional[
|
|
93
|
+
role: Optional[str] = None
|
|
89
94
|
"""The role of the author of this message."""
|
|
90
95
|
|
|
91
96
|
tool_calls: Optional[List[ChoiceDeltaToolCall]] = None
|
|
92
97
|
|
|
98
|
+
def __post_init__(self):
|
|
99
|
+
"""Validates that role is one of the allowed values if present."""
|
|
100
|
+
if self.role is not None:
|
|
101
|
+
allowed_roles = {"system", "user", "assistant", "tool"}
|
|
102
|
+
if self.role not in allowed_roles:
|
|
103
|
+
raise ValueError(
|
|
104
|
+
f"Invalid role: '{self.role}'. "
|
|
105
|
+
f"Must be one of {allowed_roles} or None."
|
|
106
|
+
)
|
|
107
|
+
|
|
93
108
|
|
|
94
109
|
@dataclass
|
|
95
110
|
class ChoiceLogprobs:
|
|
@@ -105,9 +120,7 @@ class Choice:
|
|
|
105
120
|
index: int
|
|
106
121
|
"""The index of the choice in the list of choices."""
|
|
107
122
|
|
|
108
|
-
finish_reason: Optional[
|
|
109
|
-
Literal["stop", "length", "tool_calls", "content_filter", "function_call"]
|
|
110
|
-
] = None
|
|
123
|
+
finish_reason: Optional[str] = None
|
|
111
124
|
"""The reason the model stopped generating tokens.
|
|
112
125
|
|
|
113
126
|
This will be `stop` if the model hit a natural stop point or a provided stop
|
|
@@ -120,6 +133,22 @@ class Choice:
|
|
|
120
133
|
logprobs: Optional[ChoiceLogprobs] = None
|
|
121
134
|
"""Log probability information for the choice."""
|
|
122
135
|
|
|
136
|
+
def __post_init__(self):
|
|
137
|
+
"""Validates that finish_reason is one of the allowed values if present."""
|
|
138
|
+
if self.finish_reason is not None:
|
|
139
|
+
allowed_reasons = {
|
|
140
|
+
"stop",
|
|
141
|
+
"length",
|
|
142
|
+
"tool_calls",
|
|
143
|
+
"content_filter",
|
|
144
|
+
"function_call",
|
|
145
|
+
}
|
|
146
|
+
if self.finish_reason not in allowed_reasons:
|
|
147
|
+
raise ValueError(
|
|
148
|
+
f"Invalid finish_reason: '{self.finish_reason}'. "
|
|
149
|
+
f"Must be one of {allowed_reasons} or None."
|
|
150
|
+
)
|
|
151
|
+
|
|
123
152
|
|
|
124
153
|
@dataclass
|
|
125
154
|
class ChatCompletionChunk(ModelResponse):
|
|
@@ -141,7 +170,7 @@ class ChatCompletionChunk(ModelResponse):
|
|
|
141
170
|
model: str
|
|
142
171
|
"""The model to generate the completion."""
|
|
143
172
|
|
|
144
|
-
object:
|
|
173
|
+
object: str
|
|
145
174
|
"""The object type, which is always `chat.completion.chunk`."""
|
|
146
175
|
|
|
147
176
|
system_fingerprint: Optional[str] = None
|
|
@@ -150,3 +179,10 @@ class ChatCompletionChunk(ModelResponse):
|
|
|
150
179
|
Can be used in conjunction with the `seed` request parameter to understand when
|
|
151
180
|
backend changes have been made that might impact determinism.
|
|
152
181
|
"""
|
|
182
|
+
|
|
183
|
+
def __post_init__(self):
|
|
184
|
+
"""Validates that the object type is correct."""
|
|
185
|
+
if self.object != "chat.completion.chunk":
|
|
186
|
+
raise ValueError(
|
|
187
|
+
f"Invalid object type: '{self.object}'. Must be 'chat.completion.chunk'"
|
|
188
|
+
)
|
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
from dataclasses import dataclass
|
|
17
17
|
from typing import List, Optional
|
|
18
18
|
|
|
19
|
-
from typing_extensions import Literal
|
|
20
|
-
|
|
21
19
|
from .chat_completion_message_tool_call import ChatCompletionMessageToolCall
|
|
22
20
|
|
|
23
21
|
__all__ = ["ChatCompletionMessage", "FunctionCall"]
|
|
@@ -39,7 +37,7 @@ class FunctionCall:
|
|
|
39
37
|
|
|
40
38
|
@dataclass
|
|
41
39
|
class ChatCompletionMessage:
|
|
42
|
-
role:
|
|
40
|
+
role: str
|
|
43
41
|
"""The role of the author of this message."""
|
|
44
42
|
|
|
45
43
|
content: Optional[str] = None
|
|
@@ -54,3 +52,8 @@ class ChatCompletionMessage:
|
|
|
54
52
|
|
|
55
53
|
tool_calls: Optional[List[ChatCompletionMessageToolCall]] = None
|
|
56
54
|
"""The tool calls generated by the model, such as function calls."""
|
|
55
|
+
|
|
56
|
+
def __post_init__(self):
|
|
57
|
+
"""Validates that the role type is correct."""
|
|
58
|
+
if self.role != "assistant":
|
|
59
|
+
raise ValueError(f"Invalid object type: '{self.role}'. Must be 'assistant'")
|
qwak/qwak_client/client.py
CHANGED
|
@@ -8,7 +8,6 @@ from _qwak_proto.qwak.build.v1.build_pb2 import DESCRIPTOR
|
|
|
8
8
|
from qwak.clients.analytics.client import AnalyticsEngineClient
|
|
9
9
|
from qwak.clients.automation_management.client import AutomationsManagementClient
|
|
10
10
|
from qwak.clients.batch_job_management.client import BatchJobManagerClient
|
|
11
|
-
from qwak.clients.build_management.client import BuildsManagementClient
|
|
12
11
|
from qwak.clients.build_orchestrator.client import BuildFilter, BuildOrchestratorClient
|
|
13
12
|
from qwak.clients.data_versioning.client import DataVersioningManagementClient
|
|
14
13
|
from qwak.clients.data_versioning.data_tag_filter import DataTagFilter
|
|
@@ -58,10 +57,6 @@ class QwakClient:
|
|
|
58
57
|
def _get_model_management(self):
|
|
59
58
|
return ModelsManagementClient()
|
|
60
59
|
|
|
61
|
-
@lru_cache(maxsize=1)
|
|
62
|
-
def _get_build_management(self):
|
|
63
|
-
return BuildsManagementClient()
|
|
64
|
-
|
|
65
60
|
@lru_cache(maxsize=1)
|
|
66
61
|
def _get_build_orchestrator(self):
|
|
67
62
|
return BuildOrchestratorClient()
|
|
@@ -243,8 +238,8 @@ class QwakClient:
|
|
|
243
238
|
model = self._get_model_management().get_model(model_id=model_id)
|
|
244
239
|
model_uuid = model.uuid
|
|
245
240
|
|
|
246
|
-
metric_filters =
|
|
247
|
-
parameter_filters =
|
|
241
|
+
metric_filters = []
|
|
242
|
+
parameter_filters = []
|
|
248
243
|
|
|
249
244
|
for build_filter in filters:
|
|
250
245
|
if isinstance(build_filter, MetricFilter):
|
|
@@ -361,7 +356,6 @@ class QwakClient:
|
|
|
361
356
|
self,
|
|
362
357
|
project_name: str,
|
|
363
358
|
project_description: str,
|
|
364
|
-
jfrog_project_key: Optional[str] = None,
|
|
365
359
|
) -> str:
|
|
366
360
|
"""
|
|
367
361
|
Create project
|
|
@@ -369,7 +363,6 @@ class QwakClient:
|
|
|
369
363
|
Args:
|
|
370
364
|
project_name (str): The requested name
|
|
371
365
|
project_description (str): The requested description
|
|
372
|
-
jfrog_project_key (Optional[str]): The requested jfrog project key
|
|
373
366
|
|
|
374
367
|
Returns:
|
|
375
368
|
str: The project ID of the newly created project
|
|
@@ -378,7 +371,6 @@ class QwakClient:
|
|
|
378
371
|
project = self._get_project_management().create_project(
|
|
379
372
|
project_name=project_name,
|
|
380
373
|
project_description=project_description,
|
|
381
|
-
jfrog_project_key=jfrog_project_key,
|
|
382
374
|
)
|
|
383
375
|
|
|
384
376
|
return project.project.project_id
|
|
@@ -424,7 +416,6 @@ class QwakClient:
|
|
|
424
416
|
project_id: str,
|
|
425
417
|
model_name: str,
|
|
426
418
|
model_description: str,
|
|
427
|
-
jfrog_project_key: Optional[str] = None,
|
|
428
419
|
) -> str:
|
|
429
420
|
"""
|
|
430
421
|
Create model
|
|
@@ -433,7 +424,6 @@ class QwakClient:
|
|
|
433
424
|
project_id (str): The project ID to associate the model
|
|
434
425
|
model_name (str): The requested name
|
|
435
426
|
model_description (str): The requested description
|
|
436
|
-
jfrog_project_key (Optional[str]): The jfrog project key
|
|
437
427
|
|
|
438
428
|
Returns:
|
|
439
429
|
str: The model ID of the newly created project
|
|
@@ -443,7 +433,6 @@ class QwakClient:
|
|
|
443
433
|
project_id=project_id,
|
|
444
434
|
model_name=model_name,
|
|
445
435
|
model_description=model_description,
|
|
446
|
-
jfrog_project_key=jfrog_project_key,
|
|
447
436
|
)
|
|
448
437
|
|
|
449
438
|
return model.model_id
|
|
@@ -4,25 +4,16 @@ import socket
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
|
|
6
6
|
import requests
|
|
7
|
-
from qwak.inner.
|
|
8
|
-
from qwak.inner.tool.auth import Auth0ClientBase, FrogMLAuthClient
|
|
9
|
-
from qwak.inner.const import QwakConstants
|
|
7
|
+
from qwak.inner.tool.auth import Auth0ClientBase
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
def _get_authorization():
|
|
13
|
-
|
|
14
|
-
if issubclass(user_account_configuration._auth_client, Auth0ClientBase):
|
|
15
|
-
auth_client = Auth0ClientBase()
|
|
16
|
-
tenant_id = None
|
|
17
|
-
else:
|
|
18
|
-
auth_client = FrogMLAuthClient()
|
|
19
|
-
tenant_id = auth_client.get_tenant_id()
|
|
20
|
-
|
|
11
|
+
auth_client = Auth0ClientBase()
|
|
21
12
|
token = auth_client.get_token()
|
|
22
13
|
token_split = token.split(".")
|
|
23
14
|
decoded_token = json.loads(_base64url_decode(token_split[1]).decode("utf-8"))
|
|
24
15
|
token_expiration = datetime.fromtimestamp(decoded_token["exp"])
|
|
25
|
-
return f"Bearer {token}", token_expiration
|
|
16
|
+
return f"Bearer {token}", token_expiration
|
|
26
17
|
|
|
27
18
|
|
|
28
19
|
def _base64url_decode(input):
|
|
@@ -77,8 +68,5 @@ class RestSession(requests.Session):
|
|
|
77
68
|
return super().prepare_request(request)
|
|
78
69
|
|
|
79
70
|
def prepare_request_token(self):
|
|
80
|
-
auth_token, self.jwt_expiration
|
|
71
|
+
auth_token, self.jwt_expiration = _get_authorization()
|
|
81
72
|
self.headers["Authorization"] = auth_token
|
|
82
|
-
|
|
83
|
-
if tenant_id:
|
|
84
|
-
self.headers[QwakConstants.JFROG_TENANT_HEADER_KEY] = tenant_id
|