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,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import math
|
|
3
|
-
from io import StringIO
|
|
4
3
|
from typing import TYPE_CHECKING, List, Optional, Sequence, Tuple
|
|
5
4
|
|
|
6
5
|
from _qwak_proto.qwak.ecosystem.v0.ecosystem_pb2 import AuthenticatedUnifiedUserContext
|
|
@@ -205,9 +204,26 @@ class OnlineClient:
|
|
|
205
204
|
response_df_json, _ = self._serving_client.GetMultiFeatures.with_call(
|
|
206
205
|
request, metadata=self._metadata
|
|
207
206
|
)
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
try:
|
|
208
|
+
# Try orjson first (fastest - 6x speedup)
|
|
209
|
+
import orjson
|
|
210
|
+
|
|
211
|
+
parsed_data = orjson.loads(response_df_json.pandas_df_as_json)
|
|
212
|
+
features_df: pd.DataFrame = pd.DataFrame(
|
|
213
|
+
data=parsed_data["data"],
|
|
214
|
+
columns=parsed_data["columns"],
|
|
215
|
+
index=parsed_data["index"],
|
|
216
|
+
)
|
|
217
|
+
except ImportError:
|
|
218
|
+
# Fallback: Direct json.loads + DataFrame (2x speedup, no deps)
|
|
219
|
+
import json
|
|
220
|
+
|
|
221
|
+
parsed_data = json.loads(response_df_json.pandas_df_as_json)
|
|
222
|
+
features_df: pd.DataFrame = pd.DataFrame(
|
|
223
|
+
data=parsed_data["data"],
|
|
224
|
+
columns=parsed_data["columns"],
|
|
225
|
+
index=parsed_data["index"],
|
|
226
|
+
)
|
|
211
227
|
results.append(
|
|
212
228
|
pd.concat(
|
|
213
229
|
[population_df.reset_index(drop=True), features_df],
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from functools import wraps
|
|
2
|
+
|
|
3
|
+
from qwak.exceptions import QwakException
|
|
4
|
+
from qwak.feature_store.validations.validation_response import SuccessValidationResponse
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def silence_backend_specific_validation_exceptions(*error_messages_to_silence):
|
|
8
|
+
"""
|
|
9
|
+
A decorator that catches specific backend validation exceptions and returns a standardized
|
|
10
|
+
validation success response encapsulating the exception details. Used to skip the validation
|
|
11
|
+
process for certain backend exceptions. hopefully will be removed soon after validations will be supported on
|
|
12
|
+
all environment types.
|
|
13
|
+
|
|
14
|
+
Parameters:
|
|
15
|
+
*error_messages_to_silence: Variable length argument list
|
|
16
|
+
Messages that, if present in the exception message, should trigger the
|
|
17
|
+
standardized validation success response instead of propagating the exception.
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
function
|
|
21
|
+
The wrapped function that will catch specified backend validation exceptions
|
|
22
|
+
and return a standardized validation success response if any of the specified
|
|
23
|
+
error messages are found in the exception message.
|
|
24
|
+
|
|
25
|
+
Usage:
|
|
26
|
+
------
|
|
27
|
+
@silence_backend_specific_validation_exceptions(
|
|
28
|
+
"Validating DataSource is not supported for self-hosted environments",
|
|
29
|
+
"Validating DataSource is not supported for SAAS environments"
|
|
30
|
+
)
|
|
31
|
+
def validate_data_source():
|
|
32
|
+
# Your function implementation
|
|
33
|
+
|
|
34
|
+
When 'validate_data_source_blocking' raises a QwakException containing one of the specified error messages,
|
|
35
|
+
it will return a SuccessValidationResponse, including the
|
|
36
|
+
exception's representation in stderr and in the sample as a dataframe with a warning column.
|
|
37
|
+
If the exception message does not contain any of the specified error messages, the exception is raised normally.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def decorator(func):
|
|
41
|
+
@wraps(func)
|
|
42
|
+
def wrapper(*args, silence_specific_exceptions: bool = True, **kwargs):
|
|
43
|
+
try:
|
|
44
|
+
return func(*args, **kwargs)
|
|
45
|
+
except QwakException as e:
|
|
46
|
+
is_to_silent_error = silence_specific_exceptions and any(
|
|
47
|
+
error_message in repr(e)
|
|
48
|
+
for error_message in error_messages_to_silence
|
|
49
|
+
)
|
|
50
|
+
if not is_to_silent_error:
|
|
51
|
+
raise e
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
import pandas as pd
|
|
55
|
+
except ImportError as exc:
|
|
56
|
+
raise QwakException("Missing required Pandas dependency") from exc
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
SuccessValidationResponse(
|
|
60
|
+
sample=pd.DataFrame({"errors": [repr(e)]}),
|
|
61
|
+
features=[],
|
|
62
|
+
stdout="",
|
|
63
|
+
stderr=repr(e),
|
|
64
|
+
),
|
|
65
|
+
None,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return wrapper
|
|
69
|
+
|
|
70
|
+
return decorator
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ast
|
|
2
2
|
from abc import ABC
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
+
from io import StringIO
|
|
4
5
|
from typing import TYPE_CHECKING, List
|
|
5
6
|
|
|
6
7
|
from _qwak_proto.qwak.feature_store.features.feature_set_pb2 import (
|
|
@@ -87,8 +88,9 @@ class ValidationResponseFactory:
|
|
|
87
88
|
success: ProtoValidationSuccessResponse = (
|
|
88
89
|
validation_response.success_response
|
|
89
90
|
)
|
|
91
|
+
|
|
90
92
|
pd_sample: pd.DataFrame = pd.read_json(
|
|
91
|
-
path_or_buf=ast.literal_eval(success.sample),
|
|
93
|
+
path_or_buf=StringIO(ast.literal_eval(success.sample)),
|
|
92
94
|
dtype=success.spark_column_description,
|
|
93
95
|
)
|
|
94
96
|
|
|
@@ -9,6 +9,9 @@ from qwak.clients.feature_store.operator_client import FeaturesOperatorClient
|
|
|
9
9
|
from qwak.exceptions import QwakException
|
|
10
10
|
from qwak.feature_store.data_sources.base import BaseSource
|
|
11
11
|
from qwak.feature_store.feature_sets.base_feature_set import BaseFeatureSet
|
|
12
|
+
from qwak.feature_store.validations.validation_decorators import (
|
|
13
|
+
silence_backend_specific_validation_exceptions,
|
|
14
|
+
)
|
|
12
15
|
from qwak.feature_store.validations.validation_options import (
|
|
13
16
|
DataSourceValidationOptions,
|
|
14
17
|
FeatureSetValidationOptions,
|
|
@@ -52,13 +55,16 @@ class FeaturesOperatorValidator(Validator):
|
|
|
52
55
|
self._operator_client = FeaturesOperatorClient()
|
|
53
56
|
self._registry_client = FeatureRegistryClient()
|
|
54
57
|
|
|
58
|
+
@silence_backend_specific_validation_exceptions(
|
|
59
|
+
"Validating DataSource is not supported for self-hosted environments"
|
|
60
|
+
)
|
|
55
61
|
def validate_data_source(
|
|
56
62
|
self,
|
|
57
63
|
data_source: BaseSource,
|
|
58
64
|
sample_size: int = 10,
|
|
59
65
|
validation_options: Optional[DataSourceValidationOptions] = None,
|
|
60
66
|
) -> Tuple[ValidationResponse, Optional[str]]:
|
|
61
|
-
if 0
|
|
67
|
+
if sample_size <= 0 or 1_000 < sample_size:
|
|
62
68
|
raise ValueError(
|
|
63
69
|
f"sample_size must be under 1000 and positive, got: {sample_size}"
|
|
64
70
|
)
|
|
@@ -76,18 +82,20 @@ class FeaturesOperatorValidator(Validator):
|
|
|
76
82
|
|
|
77
83
|
return ValidationResponseFactory.from_proto(proto_response), artifact_url
|
|
78
84
|
|
|
85
|
+
@silence_backend_specific_validation_exceptions(
|
|
86
|
+
"Validating FeatureSet is not supported for self-hosted environments"
|
|
87
|
+
)
|
|
79
88
|
def validate_featureset(
|
|
80
89
|
self,
|
|
81
90
|
featureset: BaseFeatureSet,
|
|
82
91
|
sample_size: int = 10,
|
|
83
92
|
validation_options: Optional[FeatureSetValidationOptions] = None,
|
|
84
93
|
) -> Tuple[ValidationResponse, Optional[str]]:
|
|
85
|
-
if 0
|
|
94
|
+
if sample_size <= 0 or 1_000 < sample_size:
|
|
86
95
|
raise ValueError(
|
|
87
96
|
f"sample_size must be under 1000 and positive, got: {sample_size}"
|
|
88
97
|
)
|
|
89
98
|
artifact_url: Optional[str] = None
|
|
90
|
-
|
|
91
99
|
featureset_spec, artifact_url = featureset._to_proto(
|
|
92
100
|
feature_registry=self._registry_client, features=None, git_commit=None
|
|
93
101
|
)
|
|
@@ -60,3 +60,7 @@ class Context(metaclass=ABCMeta):
|
|
|
60
60
|
# Upload Custom Wheels
|
|
61
61
|
custom_runtime_wheel: Optional[Path] = field(default=None)
|
|
62
62
|
custom_core_wheel: Optional[Path] = field(default=None)
|
|
63
|
+
|
|
64
|
+
platform_url: Optional[str] = field(
|
|
65
|
+
default_factory=UserAccountConfiguration().retrieve_platform_url
|
|
66
|
+
)
|
|
@@ -104,7 +104,7 @@ class PostFetchValidationStep(Step):
|
|
|
104
104
|
def _create_wheel(self, package_dir, target_path):
|
|
105
105
|
dist_dir = package_dir / "dist"
|
|
106
106
|
shutil.rmtree(dist_dir, ignore_errors=True)
|
|
107
|
-
output = subprocess.check_output(["make", "
|
|
107
|
+
output = subprocess.check_output(["make", "sync"], cwd=package_dir) # nosec
|
|
108
108
|
for line in output.decode().split("\n"):
|
|
109
109
|
self.build_logger.debug(f">>> {line}")
|
|
110
110
|
output = subprocess.check_output(["poetry", "build"], cwd=package_dir) # nosec
|
qwak/inner/const.py
CHANGED
|
@@ -33,10 +33,6 @@ class QwakConstants:
|
|
|
33
33
|
|
|
34
34
|
TOKEN_AUDIENCE: str = "https://auth-token.qwak.ai/" # nosec B105
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
QWAK_APP_URL: str = "https://app.qwak.ai"
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
"https://grpc.qwak.ai/api/v0/runtime/get-authenticated-user-context"
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
JFROG_TENANT_HEADER_KEY = "X-JFrog-Tenant-Id"
|
|
38
|
+
CONTROL_PLANE_GRPC_ADDRESS_ENVAR_NAME: str = "CONTROL_PLANE_GRPC_ADDRESS"
|
|
@@ -1,71 +1,3 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
1
|
from .account import UserAccountConfiguration
|
|
4
2
|
from .containers import QwakContainer
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
def wire_dependencies():
|
|
8
|
-
container = QwakContainer()
|
|
9
|
-
|
|
10
|
-
default_config_file = os.path.join(os.path.dirname(__file__), "config.yml")
|
|
11
|
-
container.config.from_yaml(default_config_file)
|
|
12
|
-
|
|
13
|
-
from qwak.clients import (
|
|
14
|
-
administration,
|
|
15
|
-
alert_management,
|
|
16
|
-
alerts_registry,
|
|
17
|
-
analytics,
|
|
18
|
-
audience,
|
|
19
|
-
automation_management,
|
|
20
|
-
autoscaling,
|
|
21
|
-
batch_job_management,
|
|
22
|
-
build_management,
|
|
23
|
-
build_orchestrator,
|
|
24
|
-
data_versioning,
|
|
25
|
-
deployment,
|
|
26
|
-
feature_store,
|
|
27
|
-
file_versioning,
|
|
28
|
-
instance_template,
|
|
29
|
-
integration_management,
|
|
30
|
-
kube_deployment_captain,
|
|
31
|
-
logging_client,
|
|
32
|
-
model_management,
|
|
33
|
-
project,
|
|
34
|
-
prompt_manager,
|
|
35
|
-
system_secret,
|
|
36
|
-
user_application_instance,
|
|
37
|
-
vector_store,
|
|
38
|
-
workspace_manager,
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
container.wire(
|
|
42
|
-
packages=[
|
|
43
|
-
administration,
|
|
44
|
-
alert_management,
|
|
45
|
-
audience,
|
|
46
|
-
automation_management,
|
|
47
|
-
autoscaling,
|
|
48
|
-
analytics,
|
|
49
|
-
batch_job_management,
|
|
50
|
-
build_management,
|
|
51
|
-
build_orchestrator,
|
|
52
|
-
data_versioning,
|
|
53
|
-
deployment,
|
|
54
|
-
file_versioning,
|
|
55
|
-
instance_template,
|
|
56
|
-
kube_deployment_captain,
|
|
57
|
-
logging_client,
|
|
58
|
-
model_management,
|
|
59
|
-
project,
|
|
60
|
-
feature_store,
|
|
61
|
-
user_application_instance,
|
|
62
|
-
alerts_registry,
|
|
63
|
-
workspace_manager,
|
|
64
|
-
vector_store,
|
|
65
|
-
integration_management,
|
|
66
|
-
system_secret,
|
|
67
|
-
prompt_manager,
|
|
68
|
-
]
|
|
69
|
-
)
|
|
70
|
-
|
|
71
|
-
return container
|
|
3
|
+
from .dependency_wiring import wire_dependencies
|
|
@@ -2,13 +2,12 @@ import configparser
|
|
|
2
2
|
import errno
|
|
3
3
|
import os
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from typing import Optional, Type
|
|
5
|
+
from typing import Optional, Type
|
|
6
6
|
|
|
7
7
|
from qwak.exceptions import QwakLoginException
|
|
8
8
|
from qwak.inner.const import QwakConstants
|
|
9
9
|
from qwak.inner.di_configuration.session import Session
|
|
10
|
-
from qwak.inner.tool.auth import Auth0ClientBase
|
|
11
|
-
from frogml_storage.authentication.login import frogml_login
|
|
10
|
+
from qwak.inner.tool.auth import Auth0ClientBase
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
@dataclass
|
|
@@ -23,18 +22,6 @@ class UserAccount:
|
|
|
23
22
|
# Assigned username
|
|
24
23
|
username: Optional[str] = None
|
|
25
24
|
|
|
26
|
-
# Assigned password
|
|
27
|
-
password: Optional[str] = None
|
|
28
|
-
|
|
29
|
-
# Assigned URL
|
|
30
|
-
url: Optional[str] = None
|
|
31
|
-
|
|
32
|
-
# Anonymous login
|
|
33
|
-
anonymous: bool = False
|
|
34
|
-
|
|
35
|
-
# Interactive login
|
|
36
|
-
is_interactive: bool = False
|
|
37
|
-
|
|
38
25
|
|
|
39
26
|
class UserAccountConfiguration:
|
|
40
27
|
USER_FIELD = "user"
|
|
@@ -43,9 +30,9 @@ class UserAccountConfiguration:
|
|
|
43
30
|
|
|
44
31
|
def __init__(
|
|
45
32
|
self,
|
|
46
|
-
config_file=QwakConstants.QWAK_CONFIG_FILE,
|
|
47
|
-
auth_file=QwakConstants.QWAK_AUTHORIZATION_FILE,
|
|
48
|
-
auth_client:
|
|
33
|
+
config_file: str = QwakConstants.QWAK_CONFIG_FILE,
|
|
34
|
+
auth_file: str = QwakConstants.QWAK_AUTHORIZATION_FILE,
|
|
35
|
+
auth_client: Type[Auth0ClientBase] = Auth0ClientBase,
|
|
49
36
|
):
|
|
50
37
|
self._config_file = config_file
|
|
51
38
|
self._auth_file = auth_file
|
|
@@ -53,52 +40,12 @@ class UserAccountConfiguration:
|
|
|
53
40
|
self._auth = configparser.ConfigParser()
|
|
54
41
|
self._environment = Session().get_environment()
|
|
55
42
|
self._auth_client = auth_client
|
|
56
|
-
self._force_qwak_auth = os.getenv("FORCE_QWAK_AUTH", "False") == "True"
|
|
57
|
-
|
|
58
|
-
if not self._auth_client:
|
|
59
|
-
# Determine auth client based on FrogML configuration
|
|
60
|
-
try:
|
|
61
|
-
from frogml_storage.authentication.utils import (
|
|
62
|
-
get_frogml_configuration,
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
get_frogml_configuration() or os.getenv("JF_URL")
|
|
67
|
-
) and not self._force_qwak_auth:
|
|
68
|
-
self._auth_client = FrogMLAuthClient
|
|
69
|
-
else:
|
|
70
|
-
self._auth_client = Auth0ClientBase
|
|
71
|
-
except (ImportError, Exception):
|
|
72
|
-
self._auth_client = Auth0ClientBase
|
|
73
43
|
|
|
74
44
|
def configure_user(self, user_account: UserAccount):
|
|
75
45
|
"""
|
|
76
46
|
Configure user authentication based on the authentication client type
|
|
77
47
|
"""
|
|
78
|
-
|
|
79
|
-
# Existing Qwak authentication flow
|
|
80
|
-
self.__qwak_login(user_account)
|
|
81
|
-
|
|
82
|
-
elif issubclass(self._auth_client, FrogMLAuthClient):
|
|
83
|
-
# Use FrogML's login flow
|
|
84
|
-
success = frogml_login(
|
|
85
|
-
url=user_account.url,
|
|
86
|
-
username=user_account.username,
|
|
87
|
-
password=user_account.password,
|
|
88
|
-
token=user_account.api_key,
|
|
89
|
-
anonymous=user_account.anonymous,
|
|
90
|
-
is_interactive=user_account.is_interactive,
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
if not success:
|
|
94
|
-
raise QwakLoginException("Failed to authenticate with JFrog")
|
|
95
|
-
# Validate access token
|
|
96
|
-
# TODO: Remove once we support reference token
|
|
97
|
-
token = self._auth_client().get_token()
|
|
98
|
-
if not token or len(token) <= 64:
|
|
99
|
-
raise QwakLoginException(
|
|
100
|
-
"Authentication with JFrog failed: Only Access Tokens are supported. Please ensure you are using a valid Access Token."
|
|
101
|
-
)
|
|
48
|
+
self.__qwak_login(user_account)
|
|
102
49
|
|
|
103
50
|
def __qwak_login(self, user_account: UserAccount):
|
|
104
51
|
self._auth.read(self._auth_file)
|
|
@@ -139,8 +86,6 @@ class UserAccountConfiguration:
|
|
|
139
86
|
:return:
|
|
140
87
|
"""
|
|
141
88
|
try:
|
|
142
|
-
if issubclass(self._auth_client, FrogMLAuthClient):
|
|
143
|
-
return UserAccount()
|
|
144
89
|
username = os.environ.get("QWAK_USERNAME")
|
|
145
90
|
api_key = os.environ.get("QWAK_API_KEY")
|
|
146
91
|
if not api_key and (
|
|
@@ -179,8 +124,6 @@ class UserAccountConfiguration:
|
|
|
179
124
|
:return:
|
|
180
125
|
"""
|
|
181
126
|
try:
|
|
182
|
-
if issubclass(self._auth_client, FrogMLAuthClient):
|
|
183
|
-
return ""
|
|
184
127
|
api_key = os.environ.get("QWAK_API_KEY")
|
|
185
128
|
if api_key:
|
|
186
129
|
Session().set_environment(api_key)
|
|
@@ -202,3 +145,15 @@ class UserAccountConfiguration:
|
|
|
202
145
|
f"Environment {self._environment} has not be configured."
|
|
203
146
|
f"Please ensure it is configured using the `qwak configure` command."
|
|
204
147
|
)
|
|
148
|
+
|
|
149
|
+
def retrieve_platform_url(self) -> str:
|
|
150
|
+
"""
|
|
151
|
+
Retrieve the platform URL based on the configured authentication client.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
str: The platform URL.
|
|
155
|
+
"""
|
|
156
|
+
auth_client_instance = self._auth_client()
|
|
157
|
+
base_url = auth_client_instance.get_base_url()
|
|
158
|
+
|
|
159
|
+
return base_url
|
|
@@ -22,6 +22,7 @@ class QwakContainer(containers.DeclarativeContainer):
|
|
|
22
22
|
status_for_retry=(
|
|
23
23
|
grpc.StatusCode.UNAVAILABLE,
|
|
24
24
|
grpc.StatusCode.CANCELLED,
|
|
25
|
+
grpc.StatusCode.DEADLINE_EXCEEDED,
|
|
25
26
|
),
|
|
26
27
|
)
|
|
27
28
|
|
|
@@ -37,5 +38,8 @@ class QwakContainer(containers.DeclarativeContainer):
|
|
|
37
38
|
url=config.grpc.builds.internal_address,
|
|
38
39
|
enable_ssl=config.grpc.builds.enable_ssl,
|
|
39
40
|
enable_auth=False,
|
|
40
|
-
status_for_retry=(
|
|
41
|
+
status_for_retry=(
|
|
42
|
+
grpc.StatusCode.UNAVAILABLE,
|
|
43
|
+
grpc.StatusCode.DEADLINE_EXCEEDED,
|
|
44
|
+
),
|
|
41
45
|
)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from qwak.inner.const import QwakConstants
|
|
6
|
+
from qwak.inner.di_configuration import QwakContainer
|
|
7
|
+
from qwak.inner.tool.grpc.grpc_tools import validate_grpc_address
|
|
8
|
+
from qwak.tools.logger import get_qwak_logger
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
logger = get_qwak_logger()
|
|
12
|
+
|
|
13
|
+
__DEFAULT_CONFIG_FILE_PATH: Path = Path(__file__).parent / "config.yml"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def wire_dependencies():
|
|
17
|
+
container = QwakContainer()
|
|
18
|
+
|
|
19
|
+
container.config.from_yaml(__DEFAULT_CONFIG_FILE_PATH)
|
|
20
|
+
control_plane_grpc_address_override: Optional[str] = os.getenv(
|
|
21
|
+
QwakConstants.CONTROL_PLANE_GRPC_ADDRESS_ENVAR_NAME
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if control_plane_grpc_address_override:
|
|
25
|
+
validate_grpc_address(control_plane_grpc_address_override)
|
|
26
|
+
__override_control_plane_grpc_address(
|
|
27
|
+
container, control_plane_grpc_address_override
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
from qwak.clients import (
|
|
31
|
+
administration,
|
|
32
|
+
alert_management,
|
|
33
|
+
alerts_registry,
|
|
34
|
+
analytics,
|
|
35
|
+
audience,
|
|
36
|
+
automation_management,
|
|
37
|
+
autoscaling,
|
|
38
|
+
batch_job_management,
|
|
39
|
+
build_orchestrator,
|
|
40
|
+
data_versioning,
|
|
41
|
+
deployment,
|
|
42
|
+
feature_store,
|
|
43
|
+
file_versioning,
|
|
44
|
+
instance_template,
|
|
45
|
+
integration_management,
|
|
46
|
+
kube_deployment_captain,
|
|
47
|
+
logging_client,
|
|
48
|
+
model_management,
|
|
49
|
+
project,
|
|
50
|
+
prompt_manager,
|
|
51
|
+
system_secret,
|
|
52
|
+
user_application_instance,
|
|
53
|
+
vector_store,
|
|
54
|
+
workspace_manager,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
container.wire(
|
|
58
|
+
packages=[
|
|
59
|
+
administration,
|
|
60
|
+
alert_management,
|
|
61
|
+
audience,
|
|
62
|
+
automation_management,
|
|
63
|
+
autoscaling,
|
|
64
|
+
analytics,
|
|
65
|
+
batch_job_management,
|
|
66
|
+
build_orchestrator,
|
|
67
|
+
data_versioning,
|
|
68
|
+
deployment,
|
|
69
|
+
file_versioning,
|
|
70
|
+
instance_template,
|
|
71
|
+
kube_deployment_captain,
|
|
72
|
+
logging_client,
|
|
73
|
+
model_management,
|
|
74
|
+
project,
|
|
75
|
+
feature_store,
|
|
76
|
+
user_application_instance,
|
|
77
|
+
alerts_registry,
|
|
78
|
+
workspace_manager,
|
|
79
|
+
vector_store,
|
|
80
|
+
integration_management,
|
|
81
|
+
system_secret,
|
|
82
|
+
prompt_manager,
|
|
83
|
+
]
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
return container
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def __override_control_plane_grpc_address(
|
|
90
|
+
container: "QwakContainer", control_plane_grpc_address_override: str
|
|
91
|
+
):
|
|
92
|
+
logger.debug(
|
|
93
|
+
"Overriding control plane gRPC address from environment variable to %s.",
|
|
94
|
+
control_plane_grpc_address_override,
|
|
95
|
+
)
|
|
96
|
+
container.config.grpc.core.address.from_value(
|
|
97
|
+
control_plane_grpc_address_override.strip()
|
|
98
|
+
)
|
qwak/inner/tool/auth.py
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import warnings
|
|
2
2
|
from filelock import FileLock
|
|
3
|
-
from typing_extensions import Self
|
|
4
3
|
|
|
5
4
|
from qwak.inner.di_configuration.session import Session
|
|
6
5
|
from abc import ABC, abstractmethod
|
|
7
6
|
from typing import Optional
|
|
8
|
-
from frogml_storage.authentication.utils import get_credentials
|
|
9
|
-
from frogml_storage.authentication.models import AuthConfig
|
|
10
7
|
|
|
11
8
|
warnings.filterwarnings(action="ignore", module=".*jose.*")
|
|
12
9
|
|
|
@@ -28,6 +25,13 @@ class BaseAuthClient(ABC):
|
|
|
28
25
|
def login(self) -> None:
|
|
29
26
|
pass
|
|
30
27
|
|
|
28
|
+
@abstractmethod
|
|
29
|
+
def get_base_url(self) -> str:
|
|
30
|
+
"""
|
|
31
|
+
Returns the base URL for the authentication service.
|
|
32
|
+
"""
|
|
33
|
+
return ""
|
|
34
|
+
|
|
31
35
|
|
|
32
36
|
class Auth0ClientBase(BaseAuthClient):
|
|
33
37
|
_TOKENS_FIELD = "TOKENS"
|
|
@@ -46,6 +50,9 @@ class Auth0ClientBase(BaseAuthClient):
|
|
|
46
50
|
self.audience = audience
|
|
47
51
|
self.api_key = api_key
|
|
48
52
|
|
|
53
|
+
def get_base_url(self) -> str:
|
|
54
|
+
return QwakConstants.QWAK_APP_URL
|
|
55
|
+
|
|
49
56
|
# Returns Non if token is expired
|
|
50
57
|
def get_token(self):
|
|
51
58
|
if self._environment != Session().get_environment():
|
|
@@ -130,80 +137,3 @@ class Auth0ClientBase(BaseAuthClient):
|
|
|
130
137
|
raise e
|
|
131
138
|
except Exception:
|
|
132
139
|
raise QwakLoginException()
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
class FrogMLAuthClient(BaseAuthClient):
|
|
136
|
-
__MIN_TOKEN_LENGTH: int = 64
|
|
137
|
-
|
|
138
|
-
def __init__(self, auth_config: Optional[AuthConfig] = None):
|
|
139
|
-
self.auth_config = auth_config
|
|
140
|
-
self._token = None
|
|
141
|
-
self._tenant_id = None
|
|
142
|
-
|
|
143
|
-
def get_token(self) -> Optional[str]:
|
|
144
|
-
if not self._token:
|
|
145
|
-
self.login()
|
|
146
|
-
return self._token
|
|
147
|
-
|
|
148
|
-
def get_tenant_id(self) -> Optional[str]:
|
|
149
|
-
if not self._tenant_id:
|
|
150
|
-
self.login()
|
|
151
|
-
return self._tenant_id
|
|
152
|
-
|
|
153
|
-
def login(self) -> None:
|
|
154
|
-
artifactory_url, auth = get_credentials(self.auth_config)
|
|
155
|
-
# For now, we only support Bearer token authentication
|
|
156
|
-
if not hasattr(auth, "token"):
|
|
157
|
-
return
|
|
158
|
-
|
|
159
|
-
# noinspection PyUnresolvedReferences
|
|
160
|
-
self._token = auth.token
|
|
161
|
-
self.__validate_token()
|
|
162
|
-
|
|
163
|
-
# Remove '/artifactory/' from the URL
|
|
164
|
-
if "/artifactory" in artifactory_url:
|
|
165
|
-
base_url = artifactory_url.replace("/artifactory", "")
|
|
166
|
-
else:
|
|
167
|
-
# Remove trailing slash if exists
|
|
168
|
-
base_url = artifactory_url.rstrip("/")
|
|
169
|
-
try:
|
|
170
|
-
response = requests.get(
|
|
171
|
-
f"{base_url}/ui/api/v1/system/auth/screen/footer",
|
|
172
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
173
|
-
timeout=60,
|
|
174
|
-
)
|
|
175
|
-
response.raise_for_status() # Raises an HTTPError for bad responses
|
|
176
|
-
response_data = response.json()
|
|
177
|
-
if "serverId" not in response_data:
|
|
178
|
-
response = requests.get(
|
|
179
|
-
f"{base_url}/jfconnect/api/v1/system/jpd_id",
|
|
180
|
-
headers={"Authorization": f"Bearer {self._token}"},
|
|
181
|
-
timeout=60,
|
|
182
|
-
)
|
|
183
|
-
if response.status_code == 200:
|
|
184
|
-
self._tenant_id = response.text
|
|
185
|
-
elif response.status_code == 401:
|
|
186
|
-
raise QwakLoginException(
|
|
187
|
-
"Failed to authenticate with JFrog. Please check your credentials"
|
|
188
|
-
)
|
|
189
|
-
else:
|
|
190
|
-
raise QwakLoginException(
|
|
191
|
-
"Failed to authenticate with JFrog. Please check your artifactory configuration"
|
|
192
|
-
)
|
|
193
|
-
else:
|
|
194
|
-
self._tenant_id = response_data["serverId"]
|
|
195
|
-
except requests.exceptions.RequestException:
|
|
196
|
-
raise QwakLoginException(
|
|
197
|
-
"Failed to authenticate with JFrog. Please check your artifactory configuration"
|
|
198
|
-
)
|
|
199
|
-
except ValueError: # This catches JSON decode errors
|
|
200
|
-
raise QwakLoginException(
|
|
201
|
-
"Failed to authenticate with JFrog. Please check your artifactory configuration"
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
def __validate_token(self: Self):
|
|
205
|
-
if self._token is None or len(self._token) <= self.__MIN_TOKEN_LENGTH:
|
|
206
|
-
raise QwakLoginException(
|
|
207
|
-
"Authentication with JFrog failed: Only JWT Access Tokens are supported. "
|
|
208
|
-
"Please ensure you are using a valid JWT Access Token."
|
|
209
|
-
)
|