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.

Files changed (361) hide show
  1. _qwak_proto/jfml/hosting_gateway/v1/build_upload_url_pb2.py +8 -23
  2. _qwak_proto/jfml/hosting_gateway/v1/hosting_gateway_service_pb2.py +10 -27
  3. _qwak_proto/qwak/administration/account/v1/account_pb2.py +25 -88
  4. _qwak_proto/qwak/administration/account/v1/account_pb2.pyi +21 -2
  5. _qwak_proto/qwak/administration/account/v1/account_service_pb2.py +42 -187
  6. _qwak_proto/qwak/administration/account/v1/jfrog_tenant_details_pb2.py +26 -114
  7. _qwak_proto/qwak/administration/account/v1/personalization_pb2.py +8 -24
  8. _qwak_proto/qwak/administration/account/v1/preferences_pb2.py +6 -14
  9. _qwak_proto/qwak/administration/account/v1/terms_pb2.py +14 -54
  10. _qwak_proto/qwak/administration/authenticated_user/v1/authenticated_user_service_pb2.py +18 -67
  11. _qwak_proto/qwak/administration/authenticated_user/v1/credentials_pb2.py +8 -24
  12. _qwak_proto/qwak/administration/authenticated_user/v1/credentials_pb2.pyi +1 -1
  13. _qwak_proto/qwak/administration/authenticated_user/v1/details_pb2.py +14 -54
  14. _qwak_proto/qwak/administration/cluster/v2/cluster_pb2.py +38 -173
  15. _qwak_proto/qwak/administration/runtime_configuration/v0/container_registry_config_pb2.py +32 -0
  16. _qwak_proto/qwak/administration/runtime_configuration/v0/container_registry_config_pb2.pyi +65 -0
  17. _qwak_proto/qwak/administration/runtime_configuration/v0/container_registry_config_pb2_grpc.py +4 -0
  18. _qwak_proto/qwak/administration/runtime_configuration/v0/creds/auth_pb2.py +6 -14
  19. _qwak_proto/qwak/administration/runtime_configuration/v0/creds/secret_pb2.py +8 -24
  20. _qwak_proto/qwak/administration/runtime_configuration/v0/data_catalog_config_pb2.py +13 -35
  21. _qwak_proto/qwak/administration/runtime_configuration/v0/data_catalog_config_pb2.pyi +24 -3
  22. _qwak_proto/qwak/administration/runtime_configuration/v0/external/databricks/auth_pb2.py +34 -0
  23. _qwak_proto/qwak/administration/runtime_configuration/v0/external/databricks/auth_pb2.pyi +97 -0
  24. _qwak_proto/qwak/administration/runtime_configuration/v0/external/databricks/auth_pb2_grpc.py +4 -0
  25. _qwak_proto/qwak/administration/runtime_configuration/v0/external/elasticsearch_config_pb2.py +6 -14
  26. _qwak_proto/qwak/administration/runtime_configuration/v0/external/kafka_config_pb2.py +12 -44
  27. _qwak_proto/qwak/administration/runtime_configuration/v0/external/prometheus_config_pb2.py +9 -15
  28. _qwak_proto/qwak/administration/runtime_configuration/v0/external/prometheus_config_pb2.pyi +29 -0
  29. _qwak_proto/qwak/administration/runtime_configuration/v0/external/redis_config_pb2.py +6 -14
  30. _qwak_proto/qwak/administration/runtime_configuration/v0/external/victoriametrics_config_pb2.py +8 -15
  31. _qwak_proto/qwak/administration/runtime_configuration/v0/external/victoriametrics_config_pb2.pyi +16 -0
  32. _qwak_proto/qwak/administration/runtime_configuration/v0/feature_store_config_pb2.py +10 -34
  33. _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/aws/auth_pb2.py +42 -0
  34. _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/aws/auth_pb2.pyi +159 -0
  35. _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/aws/auth_pb2_grpc.py +4 -0
  36. _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/azure/auth_pb2.py +39 -0
  37. _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/azure/auth_pb2.pyi +126 -0
  38. _qwak_proto/qwak/administration/runtime_configuration/v0/hosting/azure/auth_pb2_grpc.py +4 -0
  39. _qwak_proto/qwak/administration/runtime_configuration/v0/hosting_config_pb2.py +19 -55
  40. _qwak_proto/qwak/administration/runtime_configuration/v0/hosting_config_pb2.pyi +38 -6
  41. _qwak_proto/qwak/administration/runtime_configuration/v0/logs_storage_config_pb2.py +6 -14
  42. _qwak_proto/qwak/administration/runtime_configuration/v0/model_analytics_storage_config_pb2.py +6 -14
  43. _qwak_proto/qwak/administration/runtime_configuration/v0/network_config_pb2.py +14 -54
  44. _qwak_proto/qwak/administration/runtime_configuration/v0/object_storage_config_pb2.py +13 -35
  45. _qwak_proto/qwak/administration/runtime_configuration/v0/object_storage_config_pb2.pyi +26 -3
  46. _qwak_proto/qwak/administration/runtime_configuration/v0/observability_config_pb2.py +10 -34
  47. _qwak_proto/qwak/administration/runtime_configuration/v0/runtime_config_pb2.py +8 -15
  48. _qwak_proto/qwak/administration/runtime_configuration/v0/runtime_config_pb2.pyi +7 -2
  49. _qwak_proto/qwak/administration/runtime_configuration/v0/sql_engine_config_pb2.py +13 -35
  50. _qwak_proto/qwak/administration/runtime_configuration/v0/sql_engine_config_pb2.pyi +24 -3
  51. _qwak_proto/qwak/administration/v0/authentication/authentication_service_pb2.py +14 -47
  52. _qwak_proto/qwak/administration/v0/environments/configuration_pb2.py +20 -82
  53. _qwak_proto/qwak/administration/v0/environments/environment_pb2.py +12 -40
  54. _qwak_proto/qwak/administration/v0/environments/environment_service_pb2.py +36 -158
  55. _qwak_proto/qwak/administration/v0/environments/personalization_pb2.py +8 -24
  56. _qwak_proto/qwak/administration/v0/users/user_pb2.py +18 -71
  57. _qwak_proto/qwak/admiral/secret/v0/secret_pb2.py +29 -116
  58. _qwak_proto/qwak/admiral/secret/v0/secret_pb2.pyi +21 -2
  59. _qwak_proto/qwak/admiral/secret/v0/secret_service_pb2.py +18 -67
  60. _qwak_proto/qwak/admiral/secret/v0/system_secret_service_pb2.py +18 -67
  61. _qwak_proto/qwak/admiral/user_application_instance/v0/user_application_instance_pb2.py +38 -174
  62. _qwak_proto/qwak/admiral/user_application_instance/v0/user_application_instance_service_pb2.py +22 -87
  63. _qwak_proto/qwak/analytics/analytics_pb2.py +26 -121
  64. _qwak_proto/qwak/analytics/analytics_service_pb2.py +46 -207
  65. _qwak_proto/qwak/artifactory_settings/artifactory_settings_pb2.py +8 -24
  66. _qwak_proto/qwak/audience/v1/audience_api_pb2.py +30 -127
  67. _qwak_proto/qwak/audience/v1/audience_pb2.py +26 -113
  68. _qwak_proto/qwak/auto_scaling/v1/auto_scaling_pb2.py +18 -79
  69. _qwak_proto/qwak/auto_scaling/v1/auto_scaling_service_pb2.py +10 -27
  70. _qwak_proto/qwak/automation/v1/action_pb2.py +40 -180
  71. _qwak_proto/qwak/automation/v1/auto_scaling_pb2.py +18 -79
  72. _qwak_proto/qwak/automation/v1/automation_execution_pb2.py +12 -43
  73. _qwak_proto/qwak/automation/v1/automation_management_service_pb2.py +56 -258
  74. _qwak_proto/qwak/automation/v1/automation_pb2.py +11 -35
  75. _qwak_proto/qwak/automation/v1/automation_pb2.pyi +5 -1
  76. _qwak_proto/qwak/automation/v1/common_pb2.py +10 -35
  77. _qwak_proto/qwak/automation/v1/notification_pb2.py +16 -68
  78. _qwak_proto/qwak/automation/v1/trigger_pb2.py +14 -54
  79. _qwak_proto/qwak/batch_job/v1/batch_job_events_pb2.py +26 -116
  80. _qwak_proto/qwak/batch_job/v1/batch_job_resources_pb2.py +8 -26
  81. _qwak_proto/qwak/batch_job/v1/batch_job_service_pb2.py +119 -562
  82. _qwak_proto/qwak/batch_job/v1/batch_job_service_pb2.pyi +5 -1
  83. _qwak_proto/qwak/build/v1/build_api_pb2.py +86 -407
  84. _qwak_proto/qwak/build/v1/build_pb2.py +114 -549
  85. _qwak_proto/qwak/build_settings/build_settings_api_pb2.py +18 -67
  86. _qwak_proto/qwak/build_settings/build_settings_pb2.py +18 -74
  87. _qwak_proto/qwak/builds/build_pb2.py +46 -207
  88. _qwak_proto/qwak/builds/build_pb2.pyi +48 -3
  89. _qwak_proto/qwak/builds/build_url_pb2.py +26 -113
  90. _qwak_proto/qwak/builds/build_values_pb2.py +82 -0
  91. _qwak_proto/qwak/builds/build_values_pb2.pyi +559 -0
  92. _qwak_proto/qwak/builds/build_values_pb2_grpc.py +4 -0
  93. _qwak_proto/qwak/builds/builds_orchestrator_service_pb2.py +87 -270
  94. _qwak_proto/qwak/builds/builds_orchestrator_service_pb2.pyi +173 -0
  95. _qwak_proto/qwak/builds/builds_orchestrator_service_pb2_grpc.py +66 -0
  96. _qwak_proto/qwak/builds/builds_pb2.py +87 -528
  97. _qwak_proto/qwak/builds/builds_pb2.pyi +0 -191
  98. _qwak_proto/qwak/builds/builds_pb2_grpc.py +0 -233
  99. _qwak_proto/qwak/builds/internal_builds_orchestrator_service_pb2.py +12 -37
  100. _qwak_proto/qwak/data_versioning/data_versioning_pb2.py +8 -24
  101. _qwak_proto/qwak/data_versioning/data_versioning_service_pb2.py +14 -47
  102. _qwak_proto/qwak/deployment/alert_pb2.py +24 -108
  103. _qwak_proto/qwak/deployment/alert_service_pb2.py +30 -127
  104. _qwak_proto/qwak/deployment/deployment_messages_pb2.py +6 -14
  105. _qwak_proto/qwak/deployment/deployment_pb2.py +124 -588
  106. _qwak_proto/qwak/deployment/deployment_service_pb2.py +86 -419
  107. _qwak_proto/qwak/ecosystem/jfrog/v0/token_pb2.py +47 -165
  108. _qwak_proto/qwak/ecosystem/jfrog/v0/token_pb2.pyi +102 -3
  109. _qwak_proto/qwak/ecosystem/jfrog/v0/token_service_pb2.py +22 -87
  110. _qwak_proto/qwak/ecosystem/v0/auth_pb2.py +28 -0
  111. _qwak_proto/qwak/ecosystem/v0/auth_pb2.pyi +37 -0
  112. _qwak_proto/qwak/ecosystem/v0/auth_pb2_grpc.py +4 -0
  113. _qwak_proto/qwak/ecosystem/v0/azure_credentials_pb2.py +37 -0
  114. _qwak_proto/qwak/ecosystem/v0/azure_credentials_pb2.pyi +117 -0
  115. _qwak_proto/qwak/ecosystem/v0/azure_credentials_pb2_grpc.py +4 -0
  116. _qwak_proto/qwak/ecosystem/v0/credentials_pb2.py +12 -35
  117. _qwak_proto/qwak/ecosystem/v0/credentials_pb2.pyi +8 -3
  118. _qwak_proto/qwak/ecosystem/v0/ecosystem_pb2.py +30 -138
  119. _qwak_proto/qwak/ecosystem/v0/ecosystem_runtime_service_pb2.py +52 -237
  120. _qwak_proto/qwak/execution/v1/backfill_pb2.py +18 -74
  121. _qwak_proto/qwak/execution/v1/batch_pb2.py +10 -34
  122. _qwak_proto/qwak/execution/v1/deletion_pb2.py +12 -44
  123. _qwak_proto/qwak/execution/v1/execution_pb2.py +16 -69
  124. _qwak_proto/qwak/execution/v1/execution_service_pb2.py +64 -298
  125. _qwak_proto/qwak/execution/v1/internal/deployment/platform_details_pb2.py +6 -14
  126. _qwak_proto/qwak/execution/v1/jobs/job_pb2.py +18 -76
  127. _qwak_proto/qwak/execution/v1/jobs/job_service_pb2.py +54 -247
  128. _qwak_proto/qwak/execution/v1/jobs/reports/report_pb2.py +20 -84
  129. _qwak_proto/qwak/execution/v1/state/execution_state_pb2.py +6 -14
  130. _qwak_proto/qwak/execution/v1/state/execution_state_service_pb2.py +30 -127
  131. _qwak_proto/qwak/execution/v1/state/featureset_state_pb2.py +6 -14
  132. _qwak_proto/qwak/execution/v1/state/spark_execution_state_pb2.py +14 -68
  133. _qwak_proto/qwak/execution/v1/streaming_aggregation_pb2.py +22 -55
  134. _qwak_proto/qwak/execution/v1/streaming_aggregation_pb2.pyi +71 -1
  135. _qwak_proto/qwak/execution/v1/streaming_pb2.py +12 -44
  136. _qwak_proto/qwak/feature_store/entities/entity_pb2.py +16 -57
  137. _qwak_proto/qwak/feature_store/entities/entity_service_pb2.py +30 -127
  138. _qwak_proto/qwak/feature_store/features/aggregation_pb2.py +38 -175
  139. _qwak_proto/qwak/feature_store/features/deployment_pb2.py +36 -167
  140. _qwak_proto/qwak/feature_store/features/deployment_service_pb2.py +10 -27
  141. _qwak_proto/qwak/feature_store/features/execution_pb2.py +14 -56
  142. _qwak_proto/qwak/feature_store/features/feature_set_attribute_pb2.py +6 -14
  143. _qwak_proto/qwak/feature_store/features/feature_set_pb2.py +35 -156
  144. _qwak_proto/qwak/feature_store/features/feature_set_pb2.pyi +9 -1
  145. _qwak_proto/qwak/feature_store/features/feature_set_service_pb2.py +97 -440
  146. _qwak_proto/qwak/feature_store/features/feature_set_service_pb2.pyi +25 -0
  147. _qwak_proto/qwak/feature_store/features/feature_set_service_pb2_grpc.py +34 -0
  148. _qwak_proto/qwak/feature_store/features/feature_set_state_pb2.py +38 -181
  149. _qwak_proto/qwak/feature_store/features/feature_set_state_service_pb2.py +26 -107
  150. _qwak_proto/qwak/feature_store/features/feature_set_types_pb2.py +77 -347
  151. _qwak_proto/qwak/feature_store/features/feature_set_types_pb2.pyi +7 -2
  152. _qwak_proto/qwak/feature_store/features/monitoring_pb2.py +10 -34
  153. _qwak_proto/qwak/feature_store/features/real_time_feature_extractor_pb2.py +32 -143
  154. _qwak_proto/qwak/feature_store/jobs/job_pb2.py +12 -46
  155. _qwak_proto/qwak/feature_store/jobs/job_service_pb2.py +30 -127
  156. _qwak_proto/qwak/feature_store/jobs/v1/job_pb2.py +12 -45
  157. _qwak_proto/qwak/feature_store/jobs/v1/job_service_pb2.py +42 -187
  158. _qwak_proto/qwak/feature_store/platform/platform_details_pb2.py +8 -24
  159. _qwak_proto/qwak/feature_store/reports/report_pb2.py +14 -53
  160. _qwak_proto/qwak/feature_store/repository/common/platform_pb2.py +10 -34
  161. _qwak_proto/qwak/feature_store/serving/management_pb2.py +14 -47
  162. _qwak_proto/qwak/feature_store/serving/metadata_pb2.py +12 -44
  163. _qwak_proto/qwak/feature_store/serving/serving_pb2.py +50 -222
  164. _qwak_proto/qwak/feature_store/serving/v1/value_pb2.py +8 -24
  165. _qwak_proto/qwak/feature_store/sinks/sink_pb2.py +14 -54
  166. _qwak_proto/qwak/feature_store/sources/batch_pb2.py +79 -335
  167. _qwak_proto/qwak/feature_store/sources/batch_pb2.pyi +99 -7
  168. _qwak_proto/qwak/feature_store/sources/data_source_attribute_pb2.py +6 -14
  169. _qwak_proto/qwak/feature_store/sources/data_source_pb2.py +15 -55
  170. _qwak_proto/qwak/feature_store/sources/data_source_pb2.pyi +5 -1
  171. _qwak_proto/qwak/feature_store/sources/data_source_service_pb2.py +39 -148
  172. _qwak_proto/qwak/feature_store/sources/data_source_service_pb2.pyi +25 -0
  173. _qwak_proto/qwak/feature_store/sources/data_source_service_pb2_grpc.py +34 -0
  174. _qwak_proto/qwak/feature_store/sources/streaming_pb2.py +34 -146
  175. _qwak_proto/qwak/feature_store/v1/common/jfrog_artifact/jfrog_artifact_pb2.py +6 -14
  176. _qwak_proto/qwak/feature_store/v1/common/source_code/source_code_pb2.py +10 -34
  177. _qwak_proto/qwak/feature_store/v1/internal/data_source/data_source_service_pb2.py +16 -58
  178. _qwak_proto/qwak/feature_store/v1/internal/featureset/featureset_token_service_pb2.py +10 -27
  179. _qwak_proto/qwak/features_operator/v1/features_operator_pb2.py +14 -54
  180. _qwak_proto/qwak/features_operator/v1/features_operator_service_pb2.py +14 -47
  181. _qwak_proto/qwak/features_operator/v2/features_operator_pb2.py +16 -64
  182. _qwak_proto/qwak/features_operator/v2/features_operator_service_pb2.py +12 -37
  183. _qwak_proto/qwak/features_operator/v3/features_operator_async_service_pb2.py +26 -107
  184. _qwak_proto/qwak/features_operator/v3/features_operator_pb2.py +16 -64
  185. _qwak_proto/qwak/file_versioning/file_versioning_pb2.py +10 -33
  186. _qwak_proto/qwak/file_versioning/file_versioning_service_pb2.py +14 -47
  187. _qwak_proto/qwak/fitness_service/constructs_pb2.py +23 -100
  188. _qwak_proto/qwak/fitness_service/constructs_pb2.pyi +24 -0
  189. _qwak_proto/qwak/fitness_service/fitness_pb2.py +7 -34
  190. _qwak_proto/qwak/fitness_service/fitness_pb2.pyi +0 -93
  191. _qwak_proto/qwak/fitness_service/status_pb2.py +17 -108
  192. _qwak_proto/qwak/fitness_service/status_pb2.pyi +1 -121
  193. _qwak_proto/qwak/inference/feedback/feedback_pb2.py +28 -96
  194. _qwak_proto/qwak/instance_template/instance_template_pb2.py +13 -41
  195. _qwak_proto/qwak/instance_template/instance_template_pb2.pyi +4 -1
  196. _qwak_proto/qwak/instance_template/instance_template_service_pb2.py +14 -47
  197. _qwak_proto/qwak/integration/hugging_face_integration_pb2.py +16 -64
  198. _qwak_proto/qwak/integration/integration_pb2.py +28 -126
  199. _qwak_proto/qwak/integration/integration_service_pb2.py +34 -147
  200. _qwak_proto/qwak/integration/open_a_i_integration_pb2.py +16 -64
  201. _qwak_proto/qwak/integration/opsgenie_integration_pb2.py +20 -82
  202. _qwak_proto/qwak/integration/pagerduty_integration_pb2.py +24 -104
  203. _qwak_proto/qwak/integration/slack_app_integration_pb2.py +24 -104
  204. _qwak_proto/qwak/kube_deployment_captain/alert_pb2.py +22 -97
  205. _qwak_proto/qwak/kube_deployment_captain/alerting_pb2.py +12 -44
  206. _qwak_proto/qwak/kube_deployment_captain/batch_job_pb2.py +70 -323
  207. _qwak_proto/qwak/kube_deployment_captain/batch_job_pb2.pyi +20 -5
  208. _qwak_proto/qwak/kube_deployment_captain/deployment_pb2.py +44 -167
  209. _qwak_proto/qwak/kube_deployment_captain/feature_set_deployment_pb2.py +32 -144
  210. _qwak_proto/qwak/kube_deployment_captain/kube_deployment_captain_service_pb2.py +108 -519
  211. _qwak_proto/qwak/kube_deployment_captain/traffic_mapping_pb2.py +8 -24
  212. _qwak_proto/qwak/logging/log_filter_pb2.py +12 -44
  213. _qwak_proto/qwak/logging/log_line_pb2.py +8 -25
  214. _qwak_proto/qwak/logging/log_reader_service_pb2.py +10 -27
  215. _qwak_proto/qwak/logging/log_source_pb2.py +30 -134
  216. _qwak_proto/qwak/model_descriptor/open_ai_descriptor_pb2.py +18 -74
  217. _qwak_proto/qwak/model_group/model_group_pb2.py +25 -48
  218. _qwak_proto/qwak/model_group/model_group_pb2.pyi +88 -0
  219. _qwak_proto/qwak/model_group/model_group_pb2_grpc.py +70 -0
  220. _qwak_proto/qwak/model_group/model_group_repository_details_pb2.py +23 -75
  221. _qwak_proto/qwak/model_group/model_group_repository_details_pb2.pyi +44 -6
  222. _qwak_proto/qwak/models/models_pb2.py +99 -406
  223. _qwak_proto/qwak/models/models_pb2.pyi +86 -0
  224. _qwak_proto/qwak/models/models_pb2_grpc.py +34 -0
  225. _qwak_proto/qwak/models/models_query_pb2.py +16 -56
  226. _qwak_proto/qwak/models/models_query_pb2.pyi +4 -4
  227. _qwak_proto/qwak/monitoring/v0/alerting_channel_management_service_pb2.py +30 -127
  228. _qwak_proto/qwak/monitoring/v0/alerting_channel_pb2.py +34 -152
  229. _qwak_proto/qwak/monitoring/v0/alerting_channel_sync_service_pb2.py +14 -47
  230. _qwak_proto/qwak/offline/serving/v1/feature_values_pb2.py +6 -14
  231. _qwak_proto/qwak/offline/serving/v1/offline_serving_async_service_pb2.py +30 -123
  232. _qwak_proto/qwak/offline/serving/v1/options_pb2.py +6 -14
  233. _qwak_proto/qwak/offline/serving/v1/population_pb2.py +14 -54
  234. _qwak_proto/qwak/projects/jfrog_project_spec_pb2.py +6 -14
  235. _qwak_proto/qwak/projects/projects_pb2.py +50 -192
  236. _qwak_proto/qwak/projects/projects_pb2.pyi +35 -0
  237. _qwak_proto/qwak/prompt/v1/prompt/prompt_manager_service_pb2.py +54 -247
  238. _qwak_proto/qwak/prompt/v1/prompt/prompt_pb2.py +46 -214
  239. _qwak_proto/qwak/secret_service/secret_service_pb2.py +18 -67
  240. _qwak_proto/qwak/secret_service/secret_service_pb2.pyi +1 -1
  241. _qwak_proto/qwak/self_service/account/v0/account_membership_pb2.py +24 -106
  242. _qwak_proto/qwak/self_service/account/v0/account_membership_service_pb2.py +50 -227
  243. _qwak_proto/qwak/self_service/account/v0/account_status_pb2.py +16 -65
  244. _qwak_proto/qwak/self_service/account/v0/managing_account_pb2.py +37 -132
  245. _qwak_proto/qwak/self_service/account/v0/managing_account_pb2.pyi +40 -2
  246. _qwak_proto/qwak/self_service/account/v0/managing_account_service_pb2.py +22 -87
  247. _qwak_proto/qwak/self_service/user/v1/api_key_pb2.py +6 -14
  248. _qwak_proto/qwak/self_service/user/v1/user_pb2.py +6 -14
  249. _qwak_proto/qwak/self_service/user/v1/user_service_pb2.py +30 -121
  250. _qwak_proto/qwak/service_discovery/service_discovery_location_pb2.py +12 -44
  251. _qwak_proto/qwak/service_discovery/service_discovery_location_service_pb2.py +10 -27
  252. _qwak_proto/qwak/traffic/v1/traffic_api_pb2.py +22 -87
  253. _qwak_proto/qwak/traffic/v1/traffic_pb2.py +26 -113
  254. _qwak_proto/qwak/user_application/common/v0/resources_pb2.py +31 -139
  255. _qwak_proto/qwak/user_application/common/v0/resources_pb2.pyi +24 -0
  256. _qwak_proto/qwak/user_application/v0/user_application_pb2.py +11 -44
  257. _qwak_proto/qwak/user_application/v0/user_application_pb2.pyi +6 -0
  258. _qwak_proto/qwak/vectors/v1/collection/collection_pb2.py +24 -106
  259. _qwak_proto/qwak/vectors/v1/collection/collection_service_pb2.py +38 -167
  260. _qwak_proto/qwak/vectors/v1/collection/event/collection_event_pb2.py +6 -14
  261. _qwak_proto/qwak/vectors/v1/filters_pb2.py +30 -134
  262. _qwak_proto/qwak/vectors/v1/vector_pb2.py +14 -54
  263. _qwak_proto/qwak/vectors/v1/vector_service_pb2.py +26 -107
  264. _qwak_proto/qwak/workspace/workspace_pb2.py +22 -107
  265. _qwak_proto/qwak/workspace/workspace_service_pb2.py +62 -287
  266. qwak/__init__.py +1 -1
  267. qwak/automations/automations.py +3 -0
  268. qwak/clients/feature_store/execution_management_client.py +28 -0
  269. qwak/clients/feature_store/management_client.py +156 -206
  270. qwak/clients/feature_store/operator_client.py +19 -1
  271. qwak/clients/logging_client/client.py +13 -18
  272. qwak/clients/model_management/client.py +0 -5
  273. qwak/clients/project/client.py +0 -7
  274. qwak/exceptions/__init__.py +1 -0
  275. qwak/exceptions/qwak_grpc_address_exception.py +9 -0
  276. qwak/feature_store/_common/artifact_utils.py +10 -8
  277. qwak/feature_store/_common/packaging.py +39 -21
  278. qwak/feature_store/_common/source_code_spec.py +61 -11
  279. qwak/feature_store/_common/source_code_spec_factory.py +63 -10
  280. qwak/feature_store/data_sources/__init__.py +2 -0
  281. qwak/feature_store/data_sources/base.py +11 -7
  282. qwak/feature_store/data_sources/batch/snowflake.py +34 -8
  283. qwak/feature_store/data_sources/batch/unity_catalog.py +107 -0
  284. qwak/feature_store/execution/streaming_backfill.py +48 -0
  285. qwak/feature_store/feature_sets/base_feature_set.py +1 -0
  286. qwak/feature_store/feature_sets/streaming.py +84 -63
  287. qwak/feature_store/feature_sets/streaming_backfill.py +88 -124
  288. qwak/feature_store/online/client.py +20 -4
  289. qwak/feature_store/validations/validation_decorators.py +70 -0
  290. qwak/feature_store/validations/validation_response.py +3 -1
  291. qwak/feature_store/validations/validator.py +11 -3
  292. qwak/inner/build_logic/interface/context_interface.py +4 -0
  293. qwak/inner/build_logic/phases/phase_010_fetch_model/post_fetch_validation_step.py +1 -1
  294. qwak/inner/const.py +2 -6
  295. qwak/inner/di_configuration/__init__.py +1 -69
  296. qwak/inner/di_configuration/account.py +18 -63
  297. qwak/inner/di_configuration/containers.py +5 -1
  298. qwak/inner/di_configuration/dependency_wiring.py +98 -0
  299. qwak/inner/tool/auth.py +10 -80
  300. qwak/inner/tool/grpc/grpc_auth.py +0 -32
  301. qwak/inner/tool/grpc/grpc_tools.py +125 -11
  302. qwak/inner/tool/grpc/grpc_try_wrapping.py +140 -3
  303. qwak/llmops/generation/chat/openai/types/chat/chat_completion.py +24 -6
  304. qwak/llmops/generation/chat/openai/types/chat/chat_completion_chunk.py +44 -8
  305. qwak/llmops/generation/chat/openai/types/chat/chat_completion_message.py +6 -3
  306. qwak/qwak_client/client.py +2 -13
  307. qwak/vector_store/rest_helpers.py +4 -16
  308. qwak_core-0.5.19.dist-info/METADATA +48 -0
  309. {qwak_core-0.4.278.dist-info → qwak_core-0.5.19.dist-info}/RECORD +316 -334
  310. qwak_services_mock/mocks/execution_management_service.py +9 -1
  311. qwak_services_mock/mocks/feature_store_data_sources_manager_api.py +55 -13
  312. qwak_services_mock/mocks/feature_store_entities_manager_api.py +31 -29
  313. qwak_services_mock/mocks/features_operator_v3_service.py +20 -0
  314. qwak_services_mock/mocks/qwak_mocks.py +0 -2
  315. qwak_services_mock/services_mock.py +1 -11
  316. _qwak_proto/qwak/fitness_service/fitness_service_pb2.py +0 -110
  317. _qwak_proto/qwak/fitness_service/fitness_service_pb2.pyi +0 -121
  318. _qwak_proto/qwak/fitness_service/fitness_service_pb2_grpc.py +0 -169
  319. frogml_storage/__init__.py +0 -1
  320. frogml_storage/artifactory/__init__.py +0 -1
  321. frogml_storage/artifactory/_artifactory_api.py +0 -315
  322. frogml_storage/authentication/login/__init__.py +0 -1
  323. frogml_storage/authentication/login/_login_cli.py +0 -239
  324. frogml_storage/authentication/login/_login_command.py +0 -74
  325. frogml_storage/authentication/models/__init__.py +0 -3
  326. frogml_storage/authentication/models/_auth.py +0 -24
  327. frogml_storage/authentication/models/_auth_config.py +0 -70
  328. frogml_storage/authentication/models/_login.py +0 -22
  329. frogml_storage/authentication/utils/__init__.py +0 -17
  330. frogml_storage/authentication/utils/_authentication_utils.py +0 -281
  331. frogml_storage/authentication/utils/_login_checks_utils.py +0 -114
  332. frogml_storage/base_storage.py +0 -140
  333. frogml_storage/constants.py +0 -56
  334. frogml_storage/exceptions/checksum_verification_error.py +0 -3
  335. frogml_storage/exceptions/validation_error.py +0 -4
  336. frogml_storage/frog_ml.py +0 -668
  337. frogml_storage/http/__init__.py +0 -1
  338. frogml_storage/http/http_client.py +0 -83
  339. frogml_storage/logging/__init__.py +0 -1
  340. frogml_storage/logging/_log_config.py +0 -45
  341. frogml_storage/logging/log_utils.py +0 -21
  342. frogml_storage/models/__init__.py +0 -1
  343. frogml_storage/models/_download_context.py +0 -54
  344. frogml_storage/models/dataset_manifest.py +0 -13
  345. frogml_storage/models/entity_manifest.py +0 -93
  346. frogml_storage/models/frogml_dataset_version.py +0 -21
  347. frogml_storage/models/frogml_entity_type_info.py +0 -50
  348. frogml_storage/models/frogml_entity_version.py +0 -34
  349. frogml_storage/models/frogml_model_version.py +0 -21
  350. frogml_storage/models/model_manifest.py +0 -60
  351. frogml_storage/models/serialization_metadata.py +0 -15
  352. frogml_storage/utils/__init__.py +0 -12
  353. frogml_storage/utils/_environment.py +0 -21
  354. frogml_storage/utils/_input_checks_utility.py +0 -104
  355. frogml_storage/utils/_storage_utils.py +0 -15
  356. frogml_storage/utils/_url_utils.py +0 -27
  357. qwak/clients/build_management/__init__.py +0 -1
  358. qwak/clients/build_management/client.py +0 -114
  359. qwak_core-0.4.278.dist-info/METADATA +0 -415
  360. qwak_services_mock/mocks/build_management.py +0 -100
  361. {qwak_core-0.4.278.dist-info → qwak_core-0.5.19.dist-info}/WHEEL +0 -0
@@ -0,0 +1,48 @@
1
+ import pathlib
2
+
3
+ from qwak.clients.feature_store.execution_management_client import (
4
+ ExecutionManagementClient,
5
+ )
6
+ from qwak.feature_store.feature_sets.streaming_backfill import StreamingBackfill
7
+
8
+
9
+ class StreamingAggregationBackfill:
10
+ def __init__(
11
+ self,
12
+ streaming_backfill: StreamingBackfill,
13
+ source_definition_path: pathlib.Path,
14
+ ):
15
+ """
16
+ Initialize the streaming aggregation backfill executor.
17
+
18
+ Args:
19
+ streaming_backfill (StreamingBackfill): Specification containing the
20
+ featureset name, time range, data sources, and transformation
21
+ source_definition_path (Path): Path to the Python file containing the backfill
22
+ definition. Required for locating UDF artifacts.
23
+ """
24
+ self._streaming_backfill = streaming_backfill
25
+ self._source_definition_path = source_definition_path
26
+
27
+ def trigger(self) -> str:
28
+ """
29
+ Triggers the streaming aggregation backfill execution.
30
+
31
+ Converts the backfill specification to proto format and sends it to
32
+ the execution manager to start the backfill job.
33
+
34
+ Returns:
35
+ str: The execution ID for tracking the backfill job status
36
+
37
+ Raises:
38
+ QwakException: If the execution manager request fails
39
+ """
40
+ backfill_proto = self._streaming_backfill._to_proto(
41
+ str(self._source_definition_path)
42
+ )
43
+
44
+ execution_client = ExecutionManagementClient()
45
+ response = execution_client.trigger_streaming_aggregation_backfill(
46
+ backfill_proto
47
+ )
48
+ return response.execution_id
@@ -139,6 +139,7 @@ class BaseFeatureSet(ABC):
139
139
  featureset=self,
140
140
  sample_size=number_of_rows,
141
141
  validation_options=validation_options,
142
+ silence_specific_exceptions=False,
142
143
  )
143
144
 
144
145
  if isinstance(response, SuccessValidationResponse):
@@ -2,7 +2,7 @@ import collections
2
2
  import functools
3
3
  import inspect
4
4
  from dataclasses import dataclass, field
5
- from datetime import datetime
5
+ from datetime import datetime, timezone
6
6
  from typing import TYPE_CHECKING, List, Optional, Tuple, Union
7
7
 
8
8
  from _qwak_proto.qwak.feature_store.features.execution_pb2 import (
@@ -21,6 +21,7 @@ from _qwak_proto.qwak.feature_store.sources.streaming_pb2 import (
21
21
  StreamingSource,
22
22
  StreamingSource as ProtoStreamingSource,
23
23
  )
24
+ from google.protobuf.timestamp_pb2 import Timestamp as ProtoTimestamp
24
25
  from qwak.clients.feature_store import FeatureRegistryClient
25
26
  from qwak.exceptions import QwakException
26
27
  from qwak.feature_store._common.artifact_utils import ArtifactSpec, ArtifactsUploader
@@ -34,7 +35,7 @@ from qwak.feature_store.feature_sets.metadata import (
34
35
  set_metadata_on_function,
35
36
  )
36
37
  from qwak.feature_store.feature_sets.streaming_backfill import (
37
- BackfillBatchDataSourceSpec,
38
+ BackfillDataSource,
38
39
  StreamingBackfill,
39
40
  )
40
41
  from qwak.feature_store.feature_sets.transformations import (
@@ -75,6 +76,7 @@ def feature_set(
75
76
  key: Optional[str] = None,
76
77
  auxiliary_sinks: List[BaseSink] = [],
77
78
  repository: Optional[str] = None,
79
+ backfill_max_timestamp: Optional[datetime] = None,
78
80
  ):
79
81
  """
80
82
  Creates a streaming feature set for the specified entity using the given streaming data sources.
@@ -110,6 +112,11 @@ def feature_set(
110
112
  """
111
113
 
112
114
  def decorator(function):
115
+ if isinstance(function, StreamingBackfill):
116
+ raise QwakException(
117
+ "Backfill can no longer be defined as a decorator on the feature set, it must be triggered after feature set creation."
118
+ )
119
+
113
120
  user_transformation = function()
114
121
  FeaturesetUtils.validate_base_featureset_decorator(
115
122
  user_transformation=user_transformation, entity=entity, key=key
@@ -120,10 +127,6 @@ def feature_set(
120
127
  offline_scheduling_policy=offline_scheduling_policy,
121
128
  )
122
129
 
123
- streaming_backfill: Optional[StreamingBackfill] = (
124
- StreamingBackfill.get_streaming_backfill_from_function(function=function)
125
- )
126
-
127
130
  fs_name = name or function.__name__
128
131
  streaming_feature_set = StreamingFeatureSet(
129
132
  name=fs_name,
@@ -150,7 +153,7 @@ def feature_set(
150
153
  online_cluster_template=getattr(
151
154
  function, _ONLINE_CLUSTER_SPEC, ClusterTemplate.SMALL
152
155
  ),
153
- backfill=streaming_backfill,
156
+ backfill_max_timestamp=backfill_max_timestamp,
154
157
  __instance_module_path__=inspect.stack()[1].filename,
155
158
  auxiliary_sinks=auxiliary_sinks,
156
159
  )
@@ -197,55 +200,68 @@ def execution_specification(
197
200
  @typechecked
198
201
  def backfill(
199
202
  *,
200
- start_date: datetime,
201
- end_date: datetime,
202
- data_sources: Union[List[str], List[BackfillBatchDataSourceSpec]],
203
- backfill_transformation: SparkSqlTransformation,
203
+ feature_set_name: str,
204
+ start_date: Optional[datetime],
205
+ end_date: Optional[datetime],
206
+ data_sources: Union[List[str], List[BackfillDataSource]],
204
207
  backfill_cluster_template: Optional[ClusterTemplate] = ClusterTemplate.SMALL,
205
208
  ):
206
209
  """
207
- Configures optional backfill specification for a streaming featureset. Currently available for streaming
210
+ Triggers a backfill execution for an existing streaming featureset. Currently available for streaming
208
211
  aggregation featuresets only.
209
212
 
210
- :param start_date: backfill start date
211
- :param end_date: backfill end date
212
- :param data_sources: a list of dict representations connecting each batch source name to its requested time range
213
- :param backfill_transformation: a backfill SQL transformation. Only SQL transformations are supported for backfill
214
- :param backfill_cluster_template: an optional cluster specification for the backfill job. Defaults to SMALL.
215
-
216
- Example:
217
-
218
- ... code-block:: python
219
-
220
- @streaming.feature_set(
221
- entity="users",
222
- data_sources=["users_registration_stream"],
223
- timestamp_column_name="reg_date"
224
- )
213
+ Args:
214
+ feature_set_name (str): Name of the FeatureSet to trigger a backfill for.
215
+ start_date (datetime): Backfill start date, on Streaming Aggregation Feature Sets,
216
+ needs to align with the FeatureSet tiles.
217
+ end_date (datetime): Backfill end date, on Streaming Aggregation Feature Sets,
218
+ needs to align with the FeatureSet tiles and be smaller than the Feature Set's backfill_max_timestamp.
219
+ data_sources (list[BackfillDataSource] | list[str]): A list of BackfillDataSource objects containing
220
+ batch source name and optional time range, or a list of batch source names (with no time range limits).
221
+ backfill_cluster_template (ClusterTemplate, optional): An optional cluster specification for the backfill job.
222
+ Defaults to SMALL.
223
+
224
+ Examples:
225
225
  @streaming.backfill(
226
- start_date=start_date=(2022,01,01,0,0,0),
227
- end_date=start_date=(2023,09,01,0,0,0),
228
- data_sources=[{"batch_backfill_source_name": BackfillSourceRange(start_date=(2023,01,01,0,0,0),
229
- end_date=(2023,08,01,0,0,0))}],
226
+ feature_set_name="user_streaming_agg_features",
227
+ start_date=datetime(2022,1,1,0,0,0),
228
+ end_date=datetime(2023,9,1,0,0,0),
229
+ data_sources=[BackfillDataSource(data_source_name="backfill_data_source",
230
+ start_datetime=datetime(2023,1,1,0,0,0),
231
+ end_datetime=datetime(2023,8,1,0,0,0))],
230
232
  backfill_cluster_template=ClusterTemplate.SMALL
231
- backfill_transformation=SparkSqlTransformation("SELECT user_id, reg_country, reg_date FROM backfill_data_source")
232
233
  )
233
- def user_streaming_features():
234
- return SparkSqlTransformation("SELECT user_id, reg_country, reg_date FROM data_source")
234
+ def backfill_transformation():
235
+ return SparkSqlTransformation("SELECT user_id, reg_country, reg_date FROM backfill_data_source")
235
236
  """
236
237
 
237
238
  def decorator(function):
238
- _validate_decorator_ordering(function)
239
- StreamingBackfill.set_streaming_backfill_on_function(
240
- function=function,
241
- start_date=start_date,
242
- end_date=end_date,
243
- data_sources=data_sources,
244
- backfill_transformation=backfill_transformation,
245
- backfill_cluster_template=backfill_cluster_template,
239
+ if isinstance(function, StreamingFeatureSet):
240
+ raise QwakException(
241
+ "Backfill can no longer be defined as a decorator on the feature set, it must be triggered after feature set creation."
242
+ )
243
+
244
+ backfill_transformation: SparkSqlTransformation = function()
245
+
246
+ if not isinstance(backfill_transformation, SparkSqlTransformation):
247
+ raise QwakException(
248
+ "Backfill must defined on a method returning a SparkSqlTransformation"
249
+ )
250
+
251
+ streaming_backfill = StreamingBackfill(
252
+ featureset_name=feature_set_name,
253
+ start_datetime=start_date,
254
+ end_datetime=end_date,
255
+ data_sources=StreamingBackfill._get_normalized_backfill_sources_spec(
256
+ data_sources
257
+ ),
258
+ transform=backfill_transformation,
259
+ cluster_template=backfill_cluster_template,
246
260
  )
247
261
 
248
- return function
262
+ functools.update_wrapper(streaming_backfill, backfill_transformation)
263
+
264
+ return streaming_backfill
249
265
 
250
266
  return decorator
251
267
 
@@ -316,7 +332,7 @@ class StreamingFeatureSet(BaseFeatureSet):
316
332
  offline_cluster_template: Optional[ClusterTemplate] = None
317
333
  online_cluster_template: Optional[ClusterTemplate] = None
318
334
  metadata: Optional[Metadata] = None
319
- backfill: Optional[StreamingBackfill] = None
335
+ backfill_max_timestamp: Optional[datetime] = None
320
336
  auxiliary_sinks: List[BaseSink] = field(default_factory=lambda: [])
321
337
 
322
338
  def __post_init__(self):
@@ -399,7 +415,6 @@ class StreamingFeatureSet(BaseFeatureSet):
399
415
  proto_featureset_type = self._get_streaming_aggregation_featureset_proto(
400
416
  artifact_url=artifact_url,
401
417
  streaming_sources=data_sources,
402
- feature_registry=feature_registry,
403
418
  initial_tile_size=maybe_initial_tile_size,
404
419
  )
405
420
 
@@ -453,10 +468,9 @@ class StreamingFeatureSet(BaseFeatureSet):
453
468
  "Auxiliary Sinks Are not supported in Streaming Aggregation Feature Sets"
454
469
  )
455
470
 
456
- # streaming backfill not yet supported for row-level streaming
457
- if self.backfill and not is_streaming_agg:
471
+ if self.backfill_max_timestamp and not is_streaming_agg:
458
472
  raise QwakException(
459
- "Streaming backfill is only supported for streaming aggregation feature sets at the moment"
473
+ "backfill_max_timestamp can only be set for Streaming Aggregation FeatureSet."
460
474
  )
461
475
 
462
476
  # Validate transformation is PySpark when multiple data sources are used
@@ -515,18 +529,29 @@ class StreamingFeatureSet(BaseFeatureSet):
515
529
  )
516
530
  raise QwakException(error_message_str)
517
531
 
518
- # Validate the backfill, if defined
519
- if self.backfill:
520
- self.backfill._validate_tile_size(initial_tile_size)
532
+ if not self.backfill_max_timestamp:
533
+ raise QwakException(
534
+ """
535
+ backfill_max_timestamp must be set for Streaming Aggregation FeatureSet.
536
+ Events earlier than this timestamp can only be processed by triggering backfill,
537
+ the Streaming job will not process events that are earlier than this timestamp.
538
+ """
539
+ )
540
+
541
+ self._validate_streaming_aggregation_backfill_max_timestamp()
521
542
 
522
543
  return initial_tile_size
523
544
 
524
- def _validate_streaming_aggregation_backfill(self):
545
+ def _validate_streaming_aggregation_backfill_max_timestamp(self):
525
546
  initial_tile_size, _ = StreamingFeatureSet._get_default_slide_period(
526
547
  self.transformation.windows
527
548
  )
528
549
 
529
- self.backfill._validate_tile_size(initial_tile_size)
550
+ if self.backfill_max_timestamp.timestamp() % initial_tile_size != 0:
551
+ raise QwakException(
552
+ f"Chosen backfill max timestamp is invalid,"
553
+ f" it has to be exactly dividable by slice size of {initial_tile_size} seconds."
554
+ )
530
555
 
531
556
  @staticmethod
532
557
  def _get_default_slide_period(
@@ -596,9 +621,12 @@ class StreamingFeatureSet(BaseFeatureSet):
596
621
  self,
597
622
  artifact_url: Optional[str],
598
623
  streaming_sources: List[StreamingSource],
599
- feature_registry: FeatureRegistryClient,
600
624
  initial_tile_size: int,
601
625
  ) -> ProtoFeatureSetType:
626
+ backfill_max_timestamp = ProtoTimestamp()
627
+ backfill_max_timestamp.FromDatetime(
628
+ self.backfill_max_timestamp.astimezone(timezone.utc)
629
+ )
602
630
  return ProtoFeatureSetType(
603
631
  streaming_aggregation_feature_set=ProtoStreamingAggregationFeatureSet(
604
632
  transformation=self.transformation._to_proto(
@@ -621,14 +649,7 @@ class StreamingFeatureSet(BaseFeatureSet):
621
649
  allowed_late_arrival_seconds=60 * 10,
622
650
  aggregations=self.transformation._get_aggregations_proto(),
623
651
  ),
624
- backfill_spec=(
625
- self.backfill._to_proto(
626
- feature_registry=feature_registry,
627
- original_instance_module_path=self.__instance_module_path__,
628
- featureset_name=self.name,
629
- )
630
- if self.backfill
631
- else None
632
- ),
652
+ backfill_spec=None,
653
+ backfill_max_timestamp=backfill_max_timestamp,
633
654
  )
634
655
  )
@@ -1,24 +1,18 @@
1
- from abc import ABC, abstractmethod
2
1
  from dataclasses import dataclass
3
2
  from datetime import datetime, timezone
4
3
  from typing import List, Optional, Set, Union
5
4
 
6
5
  from _qwak_proto.qwak.feature_store.features.execution_pb2 import (
7
- BackfillExecutionSpec as ProtoBackfillExecutionSpec,
6
+ ExecutionSpec as ProtoExecutionSpec,
8
7
  )
9
- from _qwak_proto.qwak.feature_store.features.feature_set_types_pb2 import (
10
- BackfillBatchDataSourceSpec as ProtoBackfillBatchDataSourceSpec,
11
- BackfillDataSourceSpec as ProtoBackfillDataSourceSpec,
12
- BackfillSpec as ProtoBackfillSpec,
13
- )
14
- from _qwak_proto.qwak.feature_store.sources.batch_pb2 import (
15
- BatchSource as ProtoBatchSource,
8
+ from _qwak_proto.qwak.execution.v1.streaming_aggregation_pb2 import (
9
+ StreamingAggregationBackfillIngestion as ProtoStreamingAggregationBackfillIngestion,
10
+ BackfillDataSource as ProtoBackfillDataSource,
11
+ TimeRange as ProtoTimeRange,
16
12
  )
17
13
  from google.protobuf.timestamp_pb2 import Timestamp as ProtoTimestamp
18
- from qwak.clients.feature_store import FeatureRegistryClient
19
14
  from qwak.exceptions import QwakException
20
15
  from qwak.feature_store._common.artifact_utils import ArtifactSpec, ArtifactsUploader
21
- from qwak.feature_store._common.feature_set_utils import get_batch_source_for_featureset
22
16
  from qwak.feature_store.feature_sets.execution_spec import ClusterTemplate
23
17
  from qwak.feature_store.feature_sets.transformations import SparkSqlTransformation
24
18
 
@@ -26,36 +20,15 @@ _BACKFILL_ = "_qwak_backfill_specification"
26
20
 
27
21
 
28
22
  @dataclass
29
- class DataSourceBackfillSpec(ABC):
23
+ class BackfillDataSource:
30
24
  data_source_name: str
31
-
32
- @abstractmethod
33
- def _to_proto(self, feature_registry: FeatureRegistryClient):
34
- pass
35
-
36
- @classmethod
37
- def _from_proto(cls, proto: ProtoBackfillDataSourceSpec):
38
- function_mapping = {"batch_data_source_spec": BackfillBatchDataSourceSpec}
39
-
40
- backfill_source_type: str = proto.WhichOneof("type")
41
-
42
- if backfill_source_type in function_mapping:
43
- function_class = function_mapping.get(backfill_source_type)
44
- return function_class._from_proto(proto)
45
-
46
- raise QwakException(
47
- f"Got unsupported backfill source type {backfill_source_type} for streaming backfill"
48
- )
49
-
50
-
51
- @dataclass
52
- class BackfillBatchDataSourceSpec(DataSourceBackfillSpec):
53
25
  start_datetime: Optional[datetime] = None
54
26
  end_datetime: Optional[datetime] = None
55
27
 
56
- def _to_proto(
57
- self, feature_registry: FeatureRegistryClient
58
- ) -> ProtoBackfillBatchDataSourceSpec:
28
+ def __post_init__(self):
29
+ self._validate()
30
+
31
+ def _to_proto(self) -> ProtoBackfillDataSource:
59
32
  start_timestamp: Optional[ProtoTimestamp] = None
60
33
  end_timestamp: Optional[ProtoTimestamp] = None
61
34
 
@@ -67,63 +40,94 @@ class BackfillBatchDataSourceSpec(DataSourceBackfillSpec):
67
40
  start_timestamp = ProtoTimestamp()
68
41
  start_timestamp.FromDatetime(self.start_datetime.astimezone(timezone.utc))
69
42
 
70
- proto_data_source: ProtoBatchSource = get_batch_source_for_featureset(
71
- batch_ds_name=self.data_source_name, feature_registry=feature_registry
72
- )
73
-
74
- return ProtoBackfillBatchDataSourceSpec(
75
- data_source=proto_data_source,
43
+ time_range = ProtoTimeRange(
76
44
  start_timestamp=start_timestamp,
77
45
  end_timestamp=end_timestamp,
78
46
  )
79
47
 
48
+ return ProtoBackfillDataSource(
49
+ data_source_name=self.data_source_name,
50
+ time_range=time_range,
51
+ )
52
+
80
53
  @classmethod
81
- def _from_proto(
82
- cls, proto: ProtoBackfillDataSourceSpec
83
- ) -> "BackfillBatchDataSourceSpec":
54
+ def _from_proto(cls, proto: ProtoBackfillDataSource) -> "BackfillDataSource":
84
55
  start_datetime: Optional[datetime] = None
85
56
  end_datetime: Optional[datetime] = None
86
57
 
87
- batch_backfill_spec: ProtoBackfillBatchDataSourceSpec = (
88
- proto.batch_data_source_spec
89
- )
58
+ time_range: ProtoTimeRange = proto.time_range
90
59
 
91
- proto_start_timestamp: ProtoTimestamp = batch_backfill_spec.start_timestamp
92
- proto_end_timestamp: ProtoTimestamp = batch_backfill_spec.end_timestamp
60
+ proto_start_timestamp: Optional[ProtoTimestamp] = (
61
+ time_range.start_timestamp if time_range.start_timestamp else None
62
+ )
63
+ proto_end_timestamp: Optional[ProtoTimestamp] = (
64
+ time_range.end_timestamp if time_range.end_timestamp else None
65
+ )
93
66
 
94
- start_datetime = datetime.fromtimestamp(
95
- proto_start_timestamp.seconds + proto_start_timestamp.nanos / 1e9
67
+ start_datetime = (
68
+ datetime.fromtimestamp(
69
+ proto_start_timestamp.seconds + proto_start_timestamp.nanos / 1e9
70
+ )
71
+ if proto_start_timestamp
72
+ else None
96
73
  )
97
74
 
98
- end_datetime = datetime.fromtimestamp(
99
- proto_end_timestamp.seconds + proto_end_timestamp.nanos / 1e9
75
+ end_datetime = (
76
+ datetime.fromtimestamp(
77
+ proto_end_timestamp.seconds + proto_end_timestamp.nanos / 1e9
78
+ )
79
+ if proto_end_timestamp
80
+ else None
100
81
  )
101
82
 
102
83
  return cls(
103
- data_source_name=batch_backfill_spec.data_source.name,
84
+ data_source_name=proto.data_source_name,
104
85
  start_datetime=start_datetime,
105
86
  end_datetime=end_datetime,
106
87
  )
107
88
 
89
+ def _validate(self):
90
+ if self.start_datetime and self.end_datetime:
91
+ if self.start_datetime >= self.end_datetime:
92
+ raise QwakException(
93
+ f"Backfill data source {self.data_source_name} has invalid time range: "
94
+ f"start_datetime {self.start_datetime} is after or equal end_datetime {self.end_datetime}."
95
+ )
96
+
97
+ if not self.data_source_name:
98
+ raise QwakException(
99
+ "Backfill data source must have a valid data source name."
100
+ )
101
+
108
102
 
109
103
  @dataclass
110
104
  class StreamingBackfill:
105
+ featureset_name: str
111
106
  start_datetime: datetime
112
107
  end_datetime: datetime
113
- data_sources_specs: List[DataSourceBackfillSpec]
108
+ data_sources: List[BackfillDataSource]
114
109
  transform: "SparkSqlTransformation"
115
110
  cluster_template: Optional[ClusterTemplate] = ClusterTemplate.SMALL
116
111
 
117
112
  def __post_init__(self):
118
- if not self.data_sources_specs:
113
+ if not self.featureset_name:
114
+ raise QwakException("featureset_name must be provided for backfill.")
115
+
116
+ if not self.start_datetime or not self.end_datetime:
119
117
  raise QwakException(
120
- "Trying to create a streaming backfill with no data sources. "
121
- "At least one data source has to be provided when trying to create a streaming backfill."
118
+ "For Streaming backfill, start_datetime and end_datetime are mandatory fields."
122
119
  )
123
120
 
124
- if not self.start_datetime or not self.end_datetime:
121
+ if self.start_datetime >= self.end_datetime:
125
122
  raise QwakException(
126
- "For backfill, start_datetime and end_datetime are mandatory fields."
123
+ f"Backfill has invalid time range: "
124
+ f"start_datetime {self.start_datetime} is after or equal end_datetime {self.end_datetime}."
125
+ )
126
+
127
+ if not self.data_sources:
128
+ raise QwakException(
129
+ "Trying to create a streaming backfill with no data sources. "
130
+ "At least one data source has to be provided when trying to create a streaming backfill."
127
131
  )
128
132
 
129
133
  if type(self.transform) is not SparkSqlTransformation:
@@ -135,7 +139,7 @@ class StreamingBackfill:
135
139
 
136
140
  def _validate_unique_sources(self):
137
141
  source_names: List[str] = [
138
- data_source.data_source_name for data_source in self.data_sources_specs
142
+ data_source.data_source_name for data_source in self.data_sources
139
143
  ]
140
144
  duplicates: Set[str] = {
141
145
  item for item in source_names if source_names.count(item) > 1
@@ -146,23 +150,14 @@ class StreamingBackfill:
146
150
  f"Found these duplicates: {', '.join(set(duplicates))}"
147
151
  )
148
152
 
149
- def _validate_tile_size(self, initial_tile_size: int):
150
- if self.end_datetime.timestamp() % initial_tile_size != 0:
151
- raise QwakException(
152
- f"Chosen backfill end datetime is invalid,"
153
- f" it has to be exactly dividable by slice size of {initial_tile_size} seconds."
154
- )
155
-
156
153
  def _to_proto(
157
154
  self,
158
- feature_registry: FeatureRegistryClient,
159
- featureset_name: str,
160
155
  original_instance_module_path: str,
161
- ) -> ProtoBackfillSpec:
156
+ ) -> ProtoStreamingAggregationBackfillIngestion:
162
157
  artifact_url: Optional[str] = None
163
158
  artifact_spec: Optional[ArtifactSpec] = ArtifactsUploader.get_artifact_spec(
164
159
  transformation=self.transform,
165
- featureset_name=f"{featureset_name}-backfill",
160
+ featureset_name=f"{self.featureset_name}-backfill",
166
161
  __instance_module_path__=original_instance_module_path,
167
162
  )
168
163
 
@@ -175,85 +170,54 @@ class StreamingBackfill:
175
170
  start_timestamp = ProtoTimestamp()
176
171
  start_timestamp.FromDatetime(self.start_datetime.astimezone(timezone.utc))
177
172
 
178
- return ProtoBackfillSpec(
173
+ return ProtoStreamingAggregationBackfillIngestion(
174
+ featureset_name=self.featureset_name,
179
175
  start_timestamp=start_timestamp,
180
176
  end_timestamp=end_timestamp,
181
- execution_spec=ProtoBackfillExecutionSpec(
182
- **{"cluster_template": ClusterTemplate.to_proto(self.cluster_template)}
177
+ execution_spec=ProtoExecutionSpec(
178
+ cluster_template=ClusterTemplate.to_proto(self.cluster_template)
183
179
  ),
184
180
  transformation=self.transform._to_proto(artifact_path=artifact_url),
185
181
  data_source_specs=[
186
- ProtoBackfillDataSourceSpec(
187
- batch_data_source_spec=data_source_spec._to_proto(
188
- feature_registry=feature_registry
189
- )
190
- )
191
- for data_source_spec in self.data_sources_specs
182
+ data_source._to_proto() for data_source in self.data_sources
192
183
  ],
193
184
  )
194
185
 
195
186
  @classmethod
196
- def _from_proto(cls, proto: ProtoBackfillSpec):
197
- datetime.fromtimestamp(
198
- proto.start_timestamp.seconds + proto.start_timestamp.nanos / 1e9
199
- )
200
-
201
- data_sources_specs = [
202
- BackfillBatchDataSourceSpec._from_proto(ds)
203
- for ds in proto.data_source_specs
187
+ def _from_proto(cls, proto: ProtoStreamingAggregationBackfillIngestion):
188
+ backfill_data_sources = [
189
+ BackfillDataSource._from_proto(ds) for ds in proto.data_source_specs
204
190
  ]
205
191
 
206
192
  return cls(
193
+ featureset_name=proto.featureset_name,
207
194
  start_datetime=datetime.fromtimestamp(
208
195
  proto.start_timestamp.seconds + proto.start_timestamp.nanos / 1e9
209
196
  ),
210
197
  end_datetime=datetime.fromtimestamp(
211
198
  proto.end_timestamp.seconds + proto.end_timestamp.nanos / 1e9
212
199
  ),
213
- data_sources_specs=data_sources_specs,
200
+ data_sources=backfill_data_sources,
214
201
  transform=SparkSqlTransformation._from_proto(
215
202
  proto.transformation.sql_transformation
216
203
  ),
204
+ cluster_template=(
205
+ ClusterTemplate.from_proto(proto.execution_spec.cluster_template)
206
+ if proto.execution_spec.cluster_template
207
+ else None
208
+ ),
217
209
  )
218
210
 
219
211
  @staticmethod
220
212
  def _get_normalized_backfill_sources_spec(
221
- data_sources: Union[List[str], List[DataSourceBackfillSpec]],
222
- ) -> List[DataSourceBackfillSpec]:
223
- # reformat all data source specs to 'DataSourceBackfillSpec'
213
+ data_sources: Union[List[str], List[BackfillDataSource]],
214
+ ) -> List[BackfillDataSource]:
215
+ # reformat all data source names to 'BackfillDataSource'
224
216
  return [
225
217
  (
226
- BackfillBatchDataSourceSpec(data_source_name=data_source)
218
+ BackfillDataSource(data_source_name=data_source)
227
219
  if isinstance(data_source, str)
228
220
  else data_source
229
221
  )
230
222
  for data_source in data_sources
231
223
  ]
232
-
233
- @classmethod
234
- def set_streaming_backfill_on_function(
235
- cls,
236
- function,
237
- start_date: datetime,
238
- end_date: datetime,
239
- data_sources: Union[List[str], List[DataSourceBackfillSpec]],
240
- backfill_transformation: SparkSqlTransformation,
241
- backfill_cluster_template: Optional[ClusterTemplate] = ClusterTemplate.SMALL,
242
- ):
243
- setattr(
244
- function,
245
- _BACKFILL_,
246
- cls(
247
- start_datetime=start_date,
248
- end_datetime=end_date,
249
- data_sources_specs=StreamingBackfill._get_normalized_backfill_sources_spec(
250
- data_sources
251
- ),
252
- transform=backfill_transformation,
253
- cluster_template=backfill_cluster_template,
254
- ),
255
- )
256
-
257
- @staticmethod
258
- def get_streaming_backfill_from_function(function):
259
- return getattr(function, _BACKFILL_, None)