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
qwak/clients/project/client.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
1
|
import grpc
|
|
4
2
|
from _qwak_proto.qwak.projects.projects_pb2 import (
|
|
5
3
|
CreateProjectRequest,
|
|
@@ -8,7 +6,6 @@ from _qwak_proto.qwak.projects.projects_pb2 import (
|
|
|
8
6
|
ListProjectsRequest,
|
|
9
7
|
)
|
|
10
8
|
from _qwak_proto.qwak.projects.projects_pb2_grpc import ProjectsManagementServiceStub
|
|
11
|
-
from _qwak_proto.qwak.projects.jfrog_project_spec_pb2 import ModelRepositoryJFrogSpec
|
|
12
9
|
from dependency_injector.wiring import Provide, inject
|
|
13
10
|
from qwak.exceptions import QwakException
|
|
14
11
|
from qwak.inner.di_configuration import QwakContainer
|
|
@@ -34,16 +31,12 @@ class ProjectsManagementClient:
|
|
|
34
31
|
self,
|
|
35
32
|
project_name,
|
|
36
33
|
project_description,
|
|
37
|
-
jfrog_project_key: Optional[str] = None,
|
|
38
34
|
):
|
|
39
35
|
try:
|
|
40
36
|
return self._projects_management_service.CreateProject(
|
|
41
37
|
CreateProjectRequest(
|
|
42
38
|
project_name=project_name,
|
|
43
39
|
project_description=project_description,
|
|
44
|
-
jfrog_spec=ModelRepositoryJFrogSpec(
|
|
45
|
-
jfrog_project_key=jfrog_project_key
|
|
46
|
-
),
|
|
47
40
|
)
|
|
48
41
|
)
|
|
49
42
|
|
qwak/exceptions/__init__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from .quiet_error import QuietError
|
|
2
2
|
from .qwak_exception import QwakException
|
|
3
3
|
from .qwak_general_build_exception import QwakGeneralBuildException
|
|
4
|
+
from .qwak_grpc_address_exception import QwakGrpcAddressException
|
|
4
5
|
from .qwak_http_exception import QwakHTTPException
|
|
5
6
|
from .qwak_inference_exception import QwakInferenceException
|
|
6
7
|
from .qwak_load_configuration_exception import LoadConfigurationException
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
from urllib.parse import ParseResult
|
|
3
|
+
|
|
4
|
+
from qwak.exceptions import QwakException
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class QwakGrpcAddressException(QwakException):
|
|
8
|
+
def __init__(self, details: str, grpc_address: Union[str, ParseResult]):
|
|
9
|
+
self.message = f"Not a valid gRPC address: '{grpc_address}'. Details: {details}"
|
|
@@ -23,7 +23,7 @@ class ArtifactSpec:
|
|
|
23
23
|
artifact_name: str
|
|
24
24
|
root_module_path: Path
|
|
25
25
|
artifact_object: Union["BaseTransformation", "Deserializer"]
|
|
26
|
-
callables: List[Callable] = field(default_factory=
|
|
26
|
+
callables: List[Callable] = field(default_factory=list)
|
|
27
27
|
suffix: str = ""
|
|
28
28
|
|
|
29
29
|
|
|
@@ -48,10 +48,12 @@ class ArtifactsUploader:
|
|
|
48
48
|
transformation_functions: Optional[List[Callable[..., Any]]] = (
|
|
49
49
|
transformation.get_functions()
|
|
50
50
|
)
|
|
51
|
-
if
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
if not transformation_functions:
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
return ArtifactSpec(
|
|
55
|
+
artifact_name=featureset_name,
|
|
56
|
+
root_module_path=Path(__instance_module_path__).parent,
|
|
57
|
+
artifact_object=transformation,
|
|
58
|
+
callables=transformation_functions,
|
|
59
|
+
)
|
|
@@ -6,16 +6,17 @@ import zipfile
|
|
|
6
6
|
from io import BytesIO
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from shutil import make_archive
|
|
9
|
-
from typing import TYPE_CHECKING, Callable, List, Union
|
|
9
|
+
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Union
|
|
10
10
|
from uuid import uuid4
|
|
11
11
|
|
|
12
12
|
import requests
|
|
13
|
-
|
|
14
13
|
from qwak.clients.feature_store.management_client import FeatureRegistryClient
|
|
15
14
|
from qwak.exceptions import QwakException
|
|
16
15
|
from qwak.feature_store._common.value import (
|
|
17
16
|
UPDATE_QWAK_SDK_WITH_FEATURE_STORE_EXTRA_MSG,
|
|
18
17
|
)
|
|
18
|
+
from requests import HTTPError, Response
|
|
19
|
+
from urllib.parse import urlparse, ParseResult
|
|
19
20
|
|
|
20
21
|
ZIP_FUNCTION_CONTENT_TYPE = "text/plain"
|
|
21
22
|
|
|
@@ -195,29 +196,47 @@ def upload_artifact(
|
|
|
195
196
|
return uploaded_artifact_url
|
|
196
197
|
|
|
197
198
|
|
|
198
|
-
def
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
199
|
+
def put_files_content(
|
|
200
|
+
url: str,
|
|
201
|
+
content: bytes,
|
|
202
|
+
content_type: str,
|
|
203
|
+
extra_headers: Optional[Dict[str, str]] = None,
|
|
204
|
+
) -> None:
|
|
205
|
+
"""
|
|
206
|
+
uploads files content to s3 using presigned url or to jfrog artifactory using url and authentication headers
|
|
207
|
+
"""
|
|
208
|
+
extra_headers = extra_headers or {}
|
|
209
|
+
try:
|
|
210
|
+
http_response: Response = requests.put(
|
|
211
|
+
url,
|
|
212
|
+
headers={"content-type": content_type, **extra_headers},
|
|
213
|
+
data=content,
|
|
214
|
+
timeout=300,
|
|
208
215
|
)
|
|
216
|
+
http_response.raise_for_status()
|
|
217
|
+
except HTTPError as e:
|
|
218
|
+
raise QwakException(
|
|
219
|
+
f"Error while uploading artifact. status code: {e.response.status_code} with reason: {e.response.reason}"
|
|
220
|
+
) from e
|
|
209
221
|
|
|
210
222
|
|
|
211
223
|
def upload_to_s3(presign_url: str, in_memory_zip: bytes, content_type: str) -> str:
|
|
212
|
-
|
|
213
|
-
|
|
224
|
+
parsed_url: ParseResult = urlparse(presign_url)
|
|
225
|
+
extra_headers: Dict[str, str] = (
|
|
226
|
+
{"x-ms-blob-type": "BlockBlob"}
|
|
227
|
+
if parsed_url.hostname.endswith(".blob.core.windows.net")
|
|
228
|
+
else None
|
|
229
|
+
)
|
|
230
|
+
put_files_content(
|
|
231
|
+
url=presign_url,
|
|
232
|
+
content=in_memory_zip,
|
|
233
|
+
content_type=content_type,
|
|
234
|
+
extra_headers=extra_headers,
|
|
214
235
|
)
|
|
215
|
-
from urllib.parse import urlparse
|
|
216
236
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
s3_path = f"s3://{bucket}{postfix}" # noqa: E231
|
|
237
|
+
postfix: str = parsed_url.path
|
|
238
|
+
bucket: str = parsed_url.hostname.split(".s3.")[0]
|
|
239
|
+
s3_path: str = f"s3://{bucket}{postfix}" # noqa: E231
|
|
221
240
|
return s3_path
|
|
222
241
|
|
|
223
242
|
|
|
@@ -227,8 +246,7 @@ def base_upload_function_code(
|
|
|
227
246
|
feature_module_dir: Path,
|
|
228
247
|
) -> str:
|
|
229
248
|
"""
|
|
230
|
-
get presign url and prepare a zip file with the functions code
|
|
231
|
-
and it's module and upload it to clients' s3 bucket
|
|
249
|
+
get presign url and prepare a zip file with the functions code and it's module than uploads it to clients' s3 bucket
|
|
232
250
|
Args:
|
|
233
251
|
presign_url: presign url
|
|
234
252
|
functions: udf functions
|
|
@@ -1,48 +1,98 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
-
from dataclasses import dataclass, field
|
|
3
2
|
from typing import Optional
|
|
4
3
|
|
|
4
|
+
from _qwak_proto.qwak.feature_store.v1.common.jfrog_artifact.jfrog_artifact_pb2 import (
|
|
5
|
+
JfrogArtifact as ProtoJfrogArtifact,
|
|
6
|
+
)
|
|
5
7
|
from _qwak_proto.qwak.feature_store.v1.common.source_code.source_code_pb2 import (
|
|
6
|
-
SourceCodeSpec as ProtoSourceCodeSpec,
|
|
7
8
|
SourceCodeArtifact as ProtoSourceCodeArtifact,
|
|
9
|
+
SourceCodeSpec as ProtoSourceCodeSpec,
|
|
8
10
|
ZipArtifact as ProtoZipArtifact,
|
|
9
11
|
)
|
|
12
|
+
from pydantic import BaseModel, Field, model_validator
|
|
10
13
|
from qwak.exceptions import QwakException
|
|
14
|
+
from typing_extensions import Self
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class JfrogArtifact(BaseModel):
|
|
18
|
+
path: str
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def from_proto(cls, proto: ProtoJfrogArtifact) -> "JfrogArtifact":
|
|
22
|
+
return cls(path=proto.path)
|
|
23
|
+
|
|
24
|
+
def to_proto(self) -> ProtoJfrogArtifact:
|
|
25
|
+
return ProtoJfrogArtifact(path=self.path)
|
|
11
26
|
|
|
12
27
|
|
|
13
|
-
class SourceCodeArtifact(ABC):
|
|
28
|
+
class SourceCodeArtifact(BaseModel, ABC):
|
|
14
29
|
@abstractmethod
|
|
15
30
|
def _to_proto(self) -> ProtoSourceCodeArtifact:
|
|
16
31
|
pass
|
|
17
32
|
|
|
18
33
|
|
|
19
|
-
@dataclass
|
|
20
34
|
class ZipArtifact(SourceCodeArtifact):
|
|
21
|
-
artifact_path: str
|
|
22
35
|
main_file: str
|
|
36
|
+
qwak_artifact_path: Optional[str] = None
|
|
37
|
+
jfrog_artifact_path: Optional[JfrogArtifact] = None
|
|
38
|
+
|
|
39
|
+
@model_validator(mode="after")
|
|
40
|
+
def validate_only_one_artifact_path_type_provided(self: Self) -> Self:
|
|
41
|
+
"""
|
|
42
|
+
Ensures that either 'qwak_artifact_path' or 'jfrog_artifact_path' is provided,
|
|
43
|
+
but not both.
|
|
44
|
+
"""
|
|
45
|
+
if (self.qwak_artifact_path is None) == (self.jfrog_artifact_path is None):
|
|
46
|
+
raise QwakException(
|
|
47
|
+
"Either `qwak_artifact_path` or `jfrog_artifact_path` must be provided."
|
|
48
|
+
)
|
|
49
|
+
return self
|
|
23
50
|
|
|
24
51
|
@classmethod
|
|
25
52
|
def _from_proto(cls, proto: ProtoSourceCodeArtifact) -> "ZipArtifact":
|
|
26
53
|
artifact_type: str = proto.WhichOneof("type")
|
|
27
54
|
if artifact_type != "zip_artifact":
|
|
28
|
-
raise QwakException(
|
|
55
|
+
raise QwakException(
|
|
56
|
+
f"Instead of `zip_artifact` got: {artifact_type}" # noqa
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
artifact_path_type: str = proto.zip_artifact.WhichOneof("path_type")
|
|
60
|
+
jfrog_artifact_path: Optional[JfrogArtifact] = None
|
|
61
|
+
qwak_artifact_path: Optional[str] = None
|
|
62
|
+
|
|
63
|
+
if artifact_path_type == "jfrog_artifact_path":
|
|
64
|
+
jfrog_artifact_path = JfrogArtifact.from_proto(
|
|
65
|
+
proto.zip_artifact.jfrog_artifact_path
|
|
66
|
+
)
|
|
67
|
+
elif artifact_path_type == "path":
|
|
68
|
+
qwak_artifact_path = proto.zip_artifact.path
|
|
69
|
+
else:
|
|
70
|
+
raise QwakException(
|
|
71
|
+
"Either `path` or `jfrog_artifact_path` must be provided inside SourceCodeArtifact proto."
|
|
72
|
+
)
|
|
29
73
|
|
|
30
74
|
return cls(
|
|
31
|
-
|
|
75
|
+
jfrog_artifact_path=jfrog_artifact_path,
|
|
76
|
+
qwak_artifact_path=qwak_artifact_path,
|
|
32
77
|
main_file=proto.zip_artifact.main_file,
|
|
33
78
|
)
|
|
34
79
|
|
|
35
80
|
def _to_proto(self) -> ProtoSourceCodeArtifact:
|
|
36
81
|
return ProtoSourceCodeArtifact(
|
|
37
82
|
zip_artifact=ProtoZipArtifact(
|
|
38
|
-
|
|
83
|
+
jfrog_artifact_path=(
|
|
84
|
+
self.jfrog_artifact_path.to_proto()
|
|
85
|
+
if self.jfrog_artifact_path
|
|
86
|
+
else None
|
|
87
|
+
),
|
|
88
|
+
path=self.qwak_artifact_path,
|
|
89
|
+
main_file=self.main_file,
|
|
39
90
|
)
|
|
40
91
|
)
|
|
41
92
|
|
|
42
93
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
artifact: Optional[SourceCodeArtifact] = field(default=None)
|
|
94
|
+
class SourceCodeSpec(BaseModel):
|
|
95
|
+
artifact: Optional[SourceCodeArtifact] = Field(default=None)
|
|
46
96
|
|
|
47
97
|
@classmethod
|
|
48
98
|
def _from_proto(cls, proto: ProtoSourceCodeSpec) -> "SourceCodeSpec":
|
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from pathlib import Path
|
|
3
|
-
from typing import Optional
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
4
|
|
|
5
5
|
from qwak.exceptions import QwakException
|
|
6
6
|
from qwak.feature_store._common import packaging
|
|
7
|
-
from qwak.feature_store._common.source_code_spec import
|
|
7
|
+
from qwak.feature_store._common.source_code_spec import (
|
|
8
|
+
JfrogArtifact,
|
|
9
|
+
SourceCodeSpec,
|
|
10
|
+
ZipArtifact,
|
|
11
|
+
)
|
|
8
12
|
|
|
9
13
|
|
|
10
14
|
class SourceCodeSpecFactory:
|
|
11
15
|
@staticmethod
|
|
12
|
-
def _upload_source_code_dir(
|
|
16
|
+
def _upload_source_code_dir(
|
|
17
|
+
main_entity_path: Path, url: str, extra_headers: Dict[str, Any]
|
|
18
|
+
):
|
|
13
19
|
zip_location: Optional[Path] = None
|
|
14
20
|
try:
|
|
15
21
|
zip_location = packaging.zip_source_code_dir(base_path=main_entity_path)
|
|
16
22
|
with open(zip_location, "rb") as zip_file:
|
|
17
|
-
packaging.
|
|
18
|
-
|
|
23
|
+
packaging.put_files_content(
|
|
24
|
+
url=url,
|
|
19
25
|
content=zip_file.read(),
|
|
20
26
|
content_type="application/octet-stream",
|
|
27
|
+
extra_headers=extra_headers,
|
|
21
28
|
)
|
|
22
29
|
except Exception as e:
|
|
23
30
|
raise QwakException("Got an error while trying to upload file.") from e
|
|
@@ -25,25 +32,71 @@ class SourceCodeSpecFactory:
|
|
|
25
32
|
if zip_location:
|
|
26
33
|
os.remove(zip_location)
|
|
27
34
|
|
|
28
|
-
@
|
|
35
|
+
@classmethod
|
|
29
36
|
def get_zip_source_code_spec(
|
|
30
|
-
|
|
37
|
+
cls,
|
|
38
|
+
main_entity_path: Path,
|
|
39
|
+
url: str,
|
|
40
|
+
extra_headers: Optional[Dict[str, str]] = None,
|
|
31
41
|
) -> SourceCodeSpec:
|
|
32
42
|
"""
|
|
33
43
|
Zips and upload the artifact,
|
|
34
44
|
the main "entity" relative path is set as the main_entity_path
|
|
35
45
|
"""
|
|
36
|
-
|
|
37
|
-
main_entity_path=main_entity_path,
|
|
46
|
+
cls._upload_source_code_dir(
|
|
47
|
+
main_entity_path=main_entity_path,
|
|
48
|
+
url=url,
|
|
49
|
+
extra_headers=extra_headers or {},
|
|
38
50
|
)
|
|
39
51
|
|
|
40
52
|
parent_base_path = (
|
|
41
53
|
main_entity_path.parent if main_entity_path.is_file() else main_entity_path
|
|
42
54
|
)
|
|
43
55
|
|
|
56
|
+
if cls._is_artifactory_source_code(extra_headers):
|
|
57
|
+
return cls._build_artifactory_source_code_spec(
|
|
58
|
+
url=url,
|
|
59
|
+
parent_base_path=parent_base_path,
|
|
60
|
+
main_entity_path=main_entity_path,
|
|
61
|
+
)
|
|
62
|
+
else:
|
|
63
|
+
return cls._build_qwak_source_code_spec(
|
|
64
|
+
url=url,
|
|
65
|
+
parent_base_path=parent_base_path,
|
|
66
|
+
main_entity_path=main_entity_path,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
@classmethod
|
|
70
|
+
def _is_artifactory_source_code(
|
|
71
|
+
cls, extra_headers: Optional[Dict[str, str]]
|
|
72
|
+
) -> bool:
|
|
73
|
+
"""
|
|
74
|
+
Check if the source code is from Artifactory by checking the extra headers.
|
|
75
|
+
"""
|
|
76
|
+
if not extra_headers:
|
|
77
|
+
return False
|
|
78
|
+
return True
|
|
79
|
+
|
|
80
|
+
@classmethod
|
|
81
|
+
def _build_artifactory_source_code_spec(
|
|
82
|
+
cls, url: str, parent_base_path: Path, main_entity_path: Path
|
|
83
|
+
) -> SourceCodeSpec:
|
|
84
|
+
return SourceCodeSpec(
|
|
85
|
+
artifact=ZipArtifact(
|
|
86
|
+
jfrog_artifact_path=JfrogArtifact(path=url),
|
|
87
|
+
main_file=str(
|
|
88
|
+
Path(parent_base_path.name) / Path(main_entity_path.name)
|
|
89
|
+
),
|
|
90
|
+
)
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
def _build_qwak_source_code_spec(
|
|
95
|
+
cls, url: str, parent_base_path: Path, main_entity_path: Path
|
|
96
|
+
) -> SourceCodeSpec:
|
|
44
97
|
return SourceCodeSpec(
|
|
45
98
|
artifact=ZipArtifact(
|
|
46
|
-
|
|
99
|
+
qwak_artifact_path=url,
|
|
47
100
|
main_file=str(
|
|
48
101
|
Path(parent_base_path.name) / Path(main_entity_path.name)
|
|
49
102
|
),
|
|
@@ -2,6 +2,7 @@ from qwak.feature_store.data_sources.batch.athena import AthenaSource
|
|
|
2
2
|
from qwak.feature_store.data_sources.batch.big_query import BigQuerySource
|
|
3
3
|
from qwak.feature_store.data_sources.batch.clickhouse import ClickhouseSource
|
|
4
4
|
from qwak.feature_store.data_sources.batch.csv import CsvSource
|
|
5
|
+
from qwak.feature_store.data_sources.batch.unity_catalog import UnityCatalogSource
|
|
5
6
|
from qwak.feature_store.data_sources.batch.elastic_search import ElasticSearchSource
|
|
6
7
|
from qwak.feature_store.data_sources.batch.filesystem.aws import (
|
|
7
8
|
AnonymousS3Configuration,
|
|
@@ -52,6 +53,7 @@ __all__ = [
|
|
|
52
53
|
"RedshiftSource",
|
|
53
54
|
"SnowflakeSource",
|
|
54
55
|
"VerticaSource",
|
|
56
|
+
"UnityCatalogSource",
|
|
55
57
|
"KafkaSource",
|
|
56
58
|
"Deserializer",
|
|
57
59
|
"CustomDeserializer",
|
|
@@ -6,12 +6,13 @@ from typing import TYPE_CHECKING, Optional, Tuple
|
|
|
6
6
|
from _qwak_proto.qwak.feature_store.sources.data_source_pb2 import (
|
|
7
7
|
DataSourceSpec as ProtoDataSourceSpec,
|
|
8
8
|
)
|
|
9
|
+
from _qwak_proto.qwak.feature_store.v1.internal.data_source.data_source_service_pb2 import (
|
|
10
|
+
GetDataSourceSourceCodeUploadResponse,
|
|
11
|
+
)
|
|
9
12
|
from qwak.clients.feature_store import FeatureRegistryClient
|
|
10
13
|
from qwak.exceptions import QwakException
|
|
11
14
|
from qwak.feature_store._common.artifact_utils import ArtifactSpec, ArtifactsUploader
|
|
12
|
-
from qwak.feature_store._common.source_code_spec import
|
|
13
|
-
SourceCodeSpec,
|
|
14
|
-
)
|
|
15
|
+
from qwak.feature_store._common.source_code_spec import SourceCodeSpec
|
|
15
16
|
from qwak.feature_store._common.source_code_spec_factory import SourceCodeSpecFactory
|
|
16
17
|
from qwak.feature_store.data_sources.attributes import DataSourceAttributes
|
|
17
18
|
from qwak.feature_store.validations.validation_options import (
|
|
@@ -63,14 +64,16 @@ class BaseSource(ABC):
|
|
|
63
64
|
uploaded_artifact_url = self._upload_artifact()
|
|
64
65
|
|
|
65
66
|
if source_definition_path:
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
code_upload_args: (
|
|
68
|
+
GetDataSourceSourceCodeUploadResponse
|
|
68
69
|
) = FeatureRegistryClient().get_datasource_source_code_presign_url(
|
|
69
|
-
ds_name=self.name
|
|
70
|
+
ds_name=self.name, repository_name=getattr(self, "repository")
|
|
70
71
|
)
|
|
71
72
|
source_code_spec: SourceCodeSpec = (
|
|
72
73
|
SourceCodeSpecFactory.get_zip_source_code_spec(
|
|
73
|
-
main_entity_path=source_definition_path,
|
|
74
|
+
main_entity_path=source_definition_path,
|
|
75
|
+
url=code_upload_args.upload_url,
|
|
76
|
+
extra_headers=code_upload_args.extra_headers,
|
|
74
77
|
)
|
|
75
78
|
)
|
|
76
79
|
|
|
@@ -113,6 +116,7 @@ class BaseSource(ABC):
|
|
|
113
116
|
data_source=self,
|
|
114
117
|
sample_size=number_of_rows,
|
|
115
118
|
validation_options=validation_options,
|
|
119
|
+
silence_specific_exceptions=False,
|
|
116
120
|
)
|
|
117
121
|
|
|
118
122
|
if isinstance(response, SuccessValidationResponse):
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from typing import Optional
|
|
3
|
+
import warnings
|
|
3
4
|
|
|
4
5
|
from _qwak_proto.qwak.feature_store.sources.batch_pb2 import (
|
|
5
6
|
BatchSource as ProtoBatchSource,
|
|
@@ -11,15 +12,18 @@ from _qwak_proto.qwak.feature_store.sources.data_source_pb2 import (
|
|
|
11
12
|
from qwak.exceptions import QwakException
|
|
12
13
|
from qwak.feature_store.data_sources.batch._batch import BaseBatchSource
|
|
13
14
|
|
|
15
|
+
warnings.simplefilter("once", DeprecationWarning)
|
|
16
|
+
|
|
14
17
|
|
|
15
18
|
@dataclass
|
|
16
19
|
class SnowflakeSource(BaseBatchSource):
|
|
17
20
|
host: str
|
|
18
21
|
username_secret_name: str
|
|
19
|
-
password_secret_name: str
|
|
20
22
|
database: str
|
|
21
23
|
schema: str
|
|
22
24
|
warehouse: str
|
|
25
|
+
password_secret_name: Optional[str] = None
|
|
26
|
+
pem_private_key_secret_name: Optional[str] = None
|
|
23
27
|
table: Optional[str] = None
|
|
24
28
|
query: Optional[str] = None
|
|
25
29
|
repository: Optional[str] = None
|
|
@@ -28,16 +32,36 @@ class SnowflakeSource(BaseBatchSource):
|
|
|
28
32
|
self._validate()
|
|
29
33
|
|
|
30
34
|
def _validate(self):
|
|
31
|
-
if self.table and self.query:
|
|
32
|
-
raise QwakException("Only one of query and table may be set")
|
|
33
|
-
if not self.table and not self.query:
|
|
34
|
-
raise QwakException("One of table or query must be set")
|
|
35
|
-
|
|
36
35
|
if not self.username_secret_name:
|
|
37
36
|
raise QwakException("username_secret_name must be set!")
|
|
38
37
|
|
|
39
|
-
if not self.
|
|
40
|
-
raise QwakException("
|
|
38
|
+
if not self.database:
|
|
39
|
+
raise QwakException("database must be set!")
|
|
40
|
+
|
|
41
|
+
if not self.schema:
|
|
42
|
+
raise QwakException("schema must be set!")
|
|
43
|
+
|
|
44
|
+
if self.password_secret_name:
|
|
45
|
+
warnings.warn(
|
|
46
|
+
"Snowflake basic authentication is deprecated and should not be used. Use key-pair authentication instead.",
|
|
47
|
+
DeprecationWarning,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
no_unique_source_exception_message = "Only one of query or table may be set"
|
|
51
|
+
has_table = bool(self.table)
|
|
52
|
+
has_query = bool(self.query)
|
|
53
|
+
no_source_set = not (has_table or has_query)
|
|
54
|
+
both_source_set = has_table and has_query
|
|
55
|
+
if no_source_set or both_source_set:
|
|
56
|
+
raise QwakException(no_unique_source_exception_message)
|
|
57
|
+
|
|
58
|
+
no_unique_auth_exception_message = "Exactly one of 'password_secret_name' or 'pem_private_key_secret_name' must be set"
|
|
59
|
+
has_password_secret = bool(self.password_secret_name)
|
|
60
|
+
has_pem_private_key_secret = bool(self.pem_private_key_secret_name)
|
|
61
|
+
no_auth_set = not (has_password_secret or has_pem_private_key_secret)
|
|
62
|
+
both_auth_set = has_password_secret and has_pem_private_key_secret
|
|
63
|
+
if no_auth_set or both_auth_set:
|
|
64
|
+
raise QwakException(no_unique_auth_exception_message)
|
|
41
65
|
|
|
42
66
|
def _to_proto(self, artifact_url: Optional[str] = None):
|
|
43
67
|
return ProtoDataSourceSpec(
|
|
@@ -50,6 +74,7 @@ class SnowflakeSource(BaseBatchSource):
|
|
|
50
74
|
host=self.host,
|
|
51
75
|
username_secret_name=self.username_secret_name,
|
|
52
76
|
password_secret_name=self.password_secret_name,
|
|
77
|
+
pem_private_key_secret_name=self.pem_private_key_secret_name,
|
|
53
78
|
database=self.database,
|
|
54
79
|
schema=self.schema,
|
|
55
80
|
warehouse=self.warehouse,
|
|
@@ -69,6 +94,7 @@ class SnowflakeSource(BaseBatchSource):
|
|
|
69
94
|
host=snowflake.host,
|
|
70
95
|
username_secret_name=snowflake.username_secret_name,
|
|
71
96
|
password_secret_name=snowflake.password_secret_name,
|
|
97
|
+
pem_private_key_secret_name=snowflake.pem_private_key_secret_name,
|
|
72
98
|
database=snowflake.database,
|
|
73
99
|
schema=snowflake.schema,
|
|
74
100
|
warehouse=snowflake.warehouse,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from _qwak_proto.qwak.feature_store.sources.batch_pb2 import (
|
|
5
|
+
BatchSource as ProtoBatchSource,
|
|
6
|
+
CatalogSource as ProtoCatalogSource,
|
|
7
|
+
UnityCatalogSource as ProtoUnityCatalogSource,
|
|
8
|
+
)
|
|
9
|
+
from _qwak_proto.qwak.feature_store.sources.data_source_pb2 import (
|
|
10
|
+
DataSourceSpec as ProtoDataSourceSpec,
|
|
11
|
+
)
|
|
12
|
+
from qwak.exceptions import QwakException
|
|
13
|
+
from qwak.feature_store.data_sources.batch._batch import BaseBatchSource
|
|
14
|
+
|
|
15
|
+
RESERVED_CATALOG_NAME = "qwak_catalog"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class UnityCatalogSource(BaseBatchSource):
|
|
20
|
+
"""Unity Catalog batch data source.
|
|
21
|
+
|
|
22
|
+
Attributes:
|
|
23
|
+
uri (str): Connection uri to Unity Catalog i.e https://<workspace-instance-name>.<domain-name>/api/2.1/unity-catalog
|
|
24
|
+
|
|
25
|
+
schema (str): The Unity Catalog schema name where the data is located.
|
|
26
|
+
|
|
27
|
+
catalog (str): The Unity Catalog catalog name.
|
|
28
|
+
|
|
29
|
+
personal_access_token_secret_name (Optional[str]): The name of the secret
|
|
30
|
+
containing the personal access token for authentication. e.g "my-pat-secret"
|
|
31
|
+
|
|
32
|
+
table (Optional[str]): The table name within the specified catalog and schema.
|
|
33
|
+
Either 'table' or 'query' must be provided, but not both. e.g "my_table"
|
|
34
|
+
|
|
35
|
+
query (Optional[str]): A SQL query to execute against the Unity Catalog.
|
|
36
|
+
Either 'query' or 'table' must be provided, but not both. e.g "select * from {catalog}.{schema}.{table}"
|
|
37
|
+
|
|
38
|
+
repository (Optional[str]): The data source group.
|
|
39
|
+
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
uri: str
|
|
43
|
+
schema: str
|
|
44
|
+
catalog: str
|
|
45
|
+
personal_access_token_secret_name: Optional[str] = None
|
|
46
|
+
table: Optional[str] = None
|
|
47
|
+
query: Optional[str] = None
|
|
48
|
+
repository: Optional[str] = None
|
|
49
|
+
|
|
50
|
+
def __post_init__(self):
|
|
51
|
+
self._validate()
|
|
52
|
+
|
|
53
|
+
def _validate(self):
|
|
54
|
+
if not self.uri:
|
|
55
|
+
raise QwakException("`uri` cannot be empty.")
|
|
56
|
+
|
|
57
|
+
if not self.schema:
|
|
58
|
+
raise QwakException("`schema` cannot be empty.")
|
|
59
|
+
|
|
60
|
+
if not self.catalog:
|
|
61
|
+
raise QwakException("`catalog` cannot be empty.")
|
|
62
|
+
|
|
63
|
+
if not self.personal_access_token_secret_name:
|
|
64
|
+
raise QwakException("`personal_access_token_secret_name` cannot be empty.")
|
|
65
|
+
|
|
66
|
+
if self.catalog == RESERVED_CATALOG_NAME:
|
|
67
|
+
raise QwakException(
|
|
68
|
+
f"`catalog` can not be set to `{RESERVED_CATALOG_NAME}`.",
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if bool(self.query) == bool(self.table):
|
|
72
|
+
raise QwakException("Either `query` or `table` must be provided.")
|
|
73
|
+
|
|
74
|
+
def _to_proto(self, artifact_url: Optional[str] = None) -> ProtoDataSourceSpec:
|
|
75
|
+
return ProtoDataSourceSpec(
|
|
76
|
+
data_source_repository_name=self.repository,
|
|
77
|
+
batch_source=ProtoBatchSource(
|
|
78
|
+
name=self.name,
|
|
79
|
+
description=self.description,
|
|
80
|
+
date_created_column=self.date_created_column,
|
|
81
|
+
catalogSource=ProtoCatalogSource(
|
|
82
|
+
url=self.uri,
|
|
83
|
+
query=self.query,
|
|
84
|
+
table=self.table,
|
|
85
|
+
unityCatalogSource=ProtoUnityCatalogSource(
|
|
86
|
+
catalog=self.catalog,
|
|
87
|
+
schema=self.schema,
|
|
88
|
+
personal_access_token_secret_name=self.personal_access_token_secret_name,
|
|
89
|
+
),
|
|
90
|
+
),
|
|
91
|
+
),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
@classmethod
|
|
95
|
+
def _from_proto(cls, proto: ProtoBatchSource) -> "UnityCatalogSource":
|
|
96
|
+
catalog_source = proto.catalogSource
|
|
97
|
+
return cls(
|
|
98
|
+
name=proto.name,
|
|
99
|
+
date_created_column=proto.date_created_column,
|
|
100
|
+
description=proto.description,
|
|
101
|
+
uri=catalog_source.url,
|
|
102
|
+
schema=catalog_source.unityCatalogSource.schema,
|
|
103
|
+
catalog=catalog_source.unityCatalogSource.catalog,
|
|
104
|
+
personal_access_token_secret_name=catalog_source.unityCatalogSource.personal_access_token_secret_name,
|
|
105
|
+
table=catalog_source.table,
|
|
106
|
+
query=catalog_source.query,
|
|
107
|
+
)
|