chalkpy 2.89.22__py3-none-any.whl → 2.95.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chalk/__init__.py +2 -1
- chalk/_gen/chalk/arrow/v1/arrow_pb2.py +7 -5
- chalk/_gen/chalk/arrow/v1/arrow_pb2.pyi +6 -0
- chalk/_gen/chalk/artifacts/v1/chart_pb2.py +36 -33
- chalk/_gen/chalk/artifacts/v1/chart_pb2.pyi +41 -1
- chalk/_gen/chalk/artifacts/v1/cron_query_pb2.py +8 -7
- chalk/_gen/chalk/artifacts/v1/cron_query_pb2.pyi +5 -0
- chalk/_gen/chalk/common/v1/offline_query_pb2.py +19 -13
- chalk/_gen/chalk/common/v1/offline_query_pb2.pyi +37 -0
- chalk/_gen/chalk/common/v1/online_query_pb2.py +54 -54
- chalk/_gen/chalk/common/v1/online_query_pb2.pyi +13 -1
- chalk/_gen/chalk/common/v1/script_task_pb2.py +13 -11
- chalk/_gen/chalk/common/v1/script_task_pb2.pyi +19 -1
- chalk/_gen/chalk/dataframe/__init__.py +0 -0
- chalk/_gen/chalk/dataframe/v1/__init__.py +0 -0
- chalk/_gen/chalk/dataframe/v1/dataframe_pb2.py +48 -0
- chalk/_gen/chalk/dataframe/v1/dataframe_pb2.pyi +123 -0
- chalk/_gen/chalk/dataframe/v1/dataframe_pb2_grpc.py +4 -0
- chalk/_gen/chalk/dataframe/v1/dataframe_pb2_grpc.pyi +4 -0
- chalk/_gen/chalk/graph/v1/graph_pb2.py +150 -149
- chalk/_gen/chalk/graph/v1/graph_pb2.pyi +25 -0
- chalk/_gen/chalk/graph/v1/sources_pb2.py +94 -84
- chalk/_gen/chalk/graph/v1/sources_pb2.pyi +56 -0
- chalk/_gen/chalk/kubernetes/v1/horizontalpodautoscaler_pb2.py +79 -0
- chalk/_gen/chalk/kubernetes/v1/horizontalpodautoscaler_pb2.pyi +377 -0
- chalk/_gen/chalk/kubernetes/v1/horizontalpodautoscaler_pb2_grpc.py +4 -0
- chalk/_gen/chalk/kubernetes/v1/horizontalpodautoscaler_pb2_grpc.pyi +4 -0
- chalk/_gen/chalk/kubernetes/v1/scaledobject_pb2.py +43 -7
- chalk/_gen/chalk/kubernetes/v1/scaledobject_pb2.pyi +252 -2
- chalk/_gen/chalk/protosql/v1/sql_service_pb2.py +54 -27
- chalk/_gen/chalk/protosql/v1/sql_service_pb2.pyi +131 -3
- chalk/_gen/chalk/protosql/v1/sql_service_pb2_grpc.py +45 -0
- chalk/_gen/chalk/protosql/v1/sql_service_pb2_grpc.pyi +14 -0
- chalk/_gen/chalk/python/v1/types_pb2.py +14 -14
- chalk/_gen/chalk/python/v1/types_pb2.pyi +8 -0
- chalk/_gen/chalk/server/v1/benchmark_pb2.py +76 -0
- chalk/_gen/chalk/server/v1/benchmark_pb2.pyi +156 -0
- chalk/_gen/chalk/server/v1/benchmark_pb2_grpc.py +258 -0
- chalk/_gen/chalk/server/v1/benchmark_pb2_grpc.pyi +84 -0
- chalk/_gen/chalk/server/v1/billing_pb2.py +40 -38
- chalk/_gen/chalk/server/v1/billing_pb2.pyi +17 -1
- chalk/_gen/chalk/server/v1/branches_pb2.py +45 -0
- chalk/_gen/chalk/server/v1/branches_pb2.pyi +80 -0
- chalk/_gen/chalk/server/v1/branches_pb2_grpc.pyi +36 -0
- chalk/_gen/chalk/server/v1/builder_pb2.py +372 -272
- chalk/_gen/chalk/server/v1/builder_pb2.pyi +479 -12
- chalk/_gen/chalk/server/v1/builder_pb2_grpc.py +360 -0
- chalk/_gen/chalk/server/v1/builder_pb2_grpc.pyi +96 -0
- chalk/_gen/chalk/server/v1/chart_pb2.py +10 -10
- chalk/_gen/chalk/server/v1/chart_pb2.pyi +18 -2
- chalk/_gen/chalk/server/v1/clickhouse_pb2.py +42 -0
- chalk/_gen/chalk/server/v1/clickhouse_pb2.pyi +17 -0
- chalk/_gen/chalk/server/v1/clickhouse_pb2_grpc.py +78 -0
- chalk/_gen/chalk/server/v1/clickhouse_pb2_grpc.pyi +38 -0
- chalk/_gen/chalk/server/v1/cloud_components_pb2.py +153 -107
- chalk/_gen/chalk/server/v1/cloud_components_pb2.pyi +146 -4
- chalk/_gen/chalk/server/v1/cloud_components_pb2_grpc.py +180 -0
- chalk/_gen/chalk/server/v1/cloud_components_pb2_grpc.pyi +48 -0
- chalk/_gen/chalk/server/v1/cloud_credentials_pb2.py +11 -3
- chalk/_gen/chalk/server/v1/cloud_credentials_pb2.pyi +20 -0
- chalk/_gen/chalk/server/v1/cloud_credentials_pb2_grpc.py +45 -0
- chalk/_gen/chalk/server/v1/cloud_credentials_pb2_grpc.pyi +12 -0
- chalk/_gen/chalk/server/v1/dataplanejobqueue_pb2.py +59 -35
- chalk/_gen/chalk/server/v1/dataplanejobqueue_pb2.pyi +127 -1
- chalk/_gen/chalk/server/v1/dataplanejobqueue_pb2_grpc.py +135 -0
- chalk/_gen/chalk/server/v1/dataplanejobqueue_pb2_grpc.pyi +36 -0
- chalk/_gen/chalk/server/v1/dataplaneworkflows_pb2.py +90 -0
- chalk/_gen/chalk/server/v1/dataplaneworkflows_pb2.pyi +264 -0
- chalk/_gen/chalk/server/v1/dataplaneworkflows_pb2_grpc.py +170 -0
- chalk/_gen/chalk/server/v1/dataplaneworkflows_pb2_grpc.pyi +62 -0
- chalk/_gen/chalk/server/v1/datasets_pb2.py +36 -24
- chalk/_gen/chalk/server/v1/datasets_pb2.pyi +71 -2
- chalk/_gen/chalk/server/v1/datasets_pb2_grpc.py +45 -0
- chalk/_gen/chalk/server/v1/datasets_pb2_grpc.pyi +12 -0
- chalk/_gen/chalk/server/v1/deploy_pb2.py +9 -3
- chalk/_gen/chalk/server/v1/deploy_pb2.pyi +12 -0
- chalk/_gen/chalk/server/v1/deploy_pb2_grpc.py +45 -0
- chalk/_gen/chalk/server/v1/deploy_pb2_grpc.pyi +12 -0
- chalk/_gen/chalk/server/v1/deployment_pb2.py +20 -15
- chalk/_gen/chalk/server/v1/deployment_pb2.pyi +25 -0
- chalk/_gen/chalk/server/v1/environment_pb2.py +25 -15
- chalk/_gen/chalk/server/v1/environment_pb2.pyi +93 -1
- chalk/_gen/chalk/server/v1/eventbus_pb2.py +44 -0
- chalk/_gen/chalk/server/v1/eventbus_pb2.pyi +64 -0
- chalk/_gen/chalk/server/v1/eventbus_pb2_grpc.py +4 -0
- chalk/_gen/chalk/server/v1/eventbus_pb2_grpc.pyi +4 -0
- chalk/_gen/chalk/server/v1/files_pb2.py +65 -0
- chalk/_gen/chalk/server/v1/files_pb2.pyi +167 -0
- chalk/_gen/chalk/server/v1/files_pb2_grpc.py +4 -0
- chalk/_gen/chalk/server/v1/files_pb2_grpc.pyi +4 -0
- chalk/_gen/chalk/server/v1/graph_pb2.py +41 -3
- chalk/_gen/chalk/server/v1/graph_pb2.pyi +191 -0
- chalk/_gen/chalk/server/v1/graph_pb2_grpc.py +92 -0
- chalk/_gen/chalk/server/v1/graph_pb2_grpc.pyi +32 -0
- chalk/_gen/chalk/server/v1/incident_pb2.py +57 -0
- chalk/_gen/chalk/server/v1/incident_pb2.pyi +165 -0
- chalk/_gen/chalk/server/v1/incident_pb2_grpc.py +4 -0
- chalk/_gen/chalk/server/v1/incident_pb2_grpc.pyi +4 -0
- chalk/_gen/chalk/server/v1/indexing_job_pb2.py +44 -0
- chalk/_gen/chalk/server/v1/indexing_job_pb2.pyi +38 -0
- chalk/_gen/chalk/server/v1/indexing_job_pb2_grpc.py +78 -0
- chalk/_gen/chalk/server/v1/indexing_job_pb2_grpc.pyi +38 -0
- chalk/_gen/chalk/server/v1/integrations_pb2.py +11 -9
- chalk/_gen/chalk/server/v1/integrations_pb2.pyi +34 -2
- chalk/_gen/chalk/server/v1/kube_pb2.py +29 -19
- chalk/_gen/chalk/server/v1/kube_pb2.pyi +28 -0
- chalk/_gen/chalk/server/v1/kube_pb2_grpc.py +45 -0
- chalk/_gen/chalk/server/v1/kube_pb2_grpc.pyi +12 -0
- chalk/_gen/chalk/server/v1/log_pb2.py +21 -3
- chalk/_gen/chalk/server/v1/log_pb2.pyi +68 -0
- chalk/_gen/chalk/server/v1/log_pb2_grpc.py +90 -0
- chalk/_gen/chalk/server/v1/log_pb2_grpc.pyi +24 -0
- chalk/_gen/chalk/server/v1/metadataplanejobqueue_pb2.py +73 -0
- chalk/_gen/chalk/server/v1/metadataplanejobqueue_pb2.pyi +212 -0
- chalk/_gen/chalk/server/v1/metadataplanejobqueue_pb2_grpc.py +217 -0
- chalk/_gen/chalk/server/v1/metadataplanejobqueue_pb2_grpc.pyi +74 -0
- chalk/_gen/chalk/server/v1/model_registry_pb2.py +10 -10
- chalk/_gen/chalk/server/v1/model_registry_pb2.pyi +4 -1
- chalk/_gen/chalk/server/v1/monitoring_pb2.py +84 -75
- chalk/_gen/chalk/server/v1/monitoring_pb2.pyi +1 -0
- chalk/_gen/chalk/server/v1/monitoring_pb2_grpc.py +136 -0
- chalk/_gen/chalk/server/v1/monitoring_pb2_grpc.pyi +38 -0
- chalk/_gen/chalk/server/v1/offline_queries_pb2.py +32 -10
- chalk/_gen/chalk/server/v1/offline_queries_pb2.pyi +73 -0
- chalk/_gen/chalk/server/v1/offline_queries_pb2_grpc.py +90 -0
- chalk/_gen/chalk/server/v1/offline_queries_pb2_grpc.pyi +24 -0
- chalk/_gen/chalk/server/v1/plandebug_pb2.py +53 -0
- chalk/_gen/chalk/server/v1/plandebug_pb2.pyi +86 -0
- chalk/_gen/chalk/server/v1/plandebug_pb2_grpc.py +168 -0
- chalk/_gen/chalk/server/v1/plandebug_pb2_grpc.pyi +60 -0
- chalk/_gen/chalk/server/v1/queries_pb2.py +76 -48
- chalk/_gen/chalk/server/v1/queries_pb2.pyi +155 -2
- chalk/_gen/chalk/server/v1/queries_pb2_grpc.py +180 -0
- chalk/_gen/chalk/server/v1/queries_pb2_grpc.pyi +48 -0
- chalk/_gen/chalk/server/v1/scheduled_query_pb2.py +4 -2
- chalk/_gen/chalk/server/v1/scheduled_query_pb2_grpc.py +45 -0
- chalk/_gen/chalk/server/v1/scheduled_query_pb2_grpc.pyi +12 -0
- chalk/_gen/chalk/server/v1/scheduled_query_run_pb2.py +12 -6
- chalk/_gen/chalk/server/v1/scheduled_query_run_pb2.pyi +75 -2
- chalk/_gen/chalk/server/v1/scheduler_pb2.py +24 -12
- chalk/_gen/chalk/server/v1/scheduler_pb2.pyi +61 -1
- chalk/_gen/chalk/server/v1/scheduler_pb2_grpc.py +90 -0
- chalk/_gen/chalk/server/v1/scheduler_pb2_grpc.pyi +24 -0
- chalk/_gen/chalk/server/v1/script_tasks_pb2.py +26 -14
- chalk/_gen/chalk/server/v1/script_tasks_pb2.pyi +33 -3
- chalk/_gen/chalk/server/v1/script_tasks_pb2_grpc.py +90 -0
- chalk/_gen/chalk/server/v1/script_tasks_pb2_grpc.pyi +24 -0
- chalk/_gen/chalk/server/v1/sql_interface_pb2.py +75 -0
- chalk/_gen/chalk/server/v1/sql_interface_pb2.pyi +142 -0
- chalk/_gen/chalk/server/v1/sql_interface_pb2_grpc.py +349 -0
- chalk/_gen/chalk/server/v1/sql_interface_pb2_grpc.pyi +114 -0
- chalk/_gen/chalk/server/v1/sql_queries_pb2.py +48 -0
- chalk/_gen/chalk/server/v1/sql_queries_pb2.pyi +150 -0
- chalk/_gen/chalk/server/v1/sql_queries_pb2_grpc.py +123 -0
- chalk/_gen/chalk/server/v1/sql_queries_pb2_grpc.pyi +52 -0
- chalk/_gen/chalk/server/v1/team_pb2.py +156 -137
- chalk/_gen/chalk/server/v1/team_pb2.pyi +56 -10
- chalk/_gen/chalk/server/v1/team_pb2_grpc.py +90 -0
- chalk/_gen/chalk/server/v1/team_pb2_grpc.pyi +24 -0
- chalk/_gen/chalk/server/v1/topic_pb2.py +5 -3
- chalk/_gen/chalk/server/v1/topic_pb2.pyi +10 -1
- chalk/_gen/chalk/server/v1/trace_pb2.py +50 -28
- chalk/_gen/chalk/server/v1/trace_pb2.pyi +121 -0
- chalk/_gen/chalk/server/v1/trace_pb2_grpc.py +135 -0
- chalk/_gen/chalk/server/v1/trace_pb2_grpc.pyi +42 -0
- chalk/_gen/chalk/server/v1/webhook_pb2.py +9 -3
- chalk/_gen/chalk/server/v1/webhook_pb2.pyi +18 -0
- chalk/_gen/chalk/server/v1/webhook_pb2_grpc.py +45 -0
- chalk/_gen/chalk/server/v1/webhook_pb2_grpc.pyi +12 -0
- chalk/_gen/chalk/streaming/v1/debug_service_pb2.py +62 -0
- chalk/_gen/chalk/streaming/v1/debug_service_pb2.pyi +75 -0
- chalk/_gen/chalk/streaming/v1/debug_service_pb2_grpc.py +221 -0
- chalk/_gen/chalk/streaming/v1/debug_service_pb2_grpc.pyi +88 -0
- chalk/_gen/chalk/streaming/v1/simple_streaming_service_pb2.py +19 -7
- chalk/_gen/chalk/streaming/v1/simple_streaming_service_pb2.pyi +96 -3
- chalk/_gen/chalk/streaming/v1/simple_streaming_service_pb2_grpc.py +48 -0
- chalk/_gen/chalk/streaming/v1/simple_streaming_service_pb2_grpc.pyi +20 -0
- chalk/_gen/chalk/utils/v1/field_change_pb2.py +32 -0
- chalk/_gen/chalk/utils/v1/field_change_pb2.pyi +42 -0
- chalk/_gen/chalk/utils/v1/field_change_pb2_grpc.py +4 -0
- chalk/_gen/chalk/utils/v1/field_change_pb2_grpc.pyi +4 -0
- chalk/_lsp/error_builder.py +11 -0
- chalk/_monitoring/Chart.py +1 -3
- chalk/_version.py +1 -1
- chalk/cli.py +5 -10
- chalk/client/client.py +178 -64
- chalk/client/client_async.py +154 -0
- chalk/client/client_async_impl.py +22 -0
- chalk/client/client_grpc.py +738 -112
- chalk/client/client_impl.py +541 -136
- chalk/client/dataset.py +27 -6
- chalk/client/models.py +99 -2
- chalk/client/serialization/model_serialization.py +126 -10
- chalk/config/project_config.py +1 -1
- chalk/df/LazyFramePlaceholder.py +1154 -0
- chalk/df/ast_parser.py +2 -10
- chalk/features/_class_property.py +7 -0
- chalk/features/_embedding/embedding.py +1 -0
- chalk/features/_embedding/sentence_transformer.py +1 -1
- chalk/features/_encoding/converter.py +83 -2
- chalk/features/_encoding/pyarrow.py +20 -4
- chalk/features/_encoding/rich.py +1 -3
- chalk/features/_tensor.py +1 -2
- chalk/features/dataframe/_filters.py +14 -5
- chalk/features/dataframe/_impl.py +91 -36
- chalk/features/dataframe/_validation.py +11 -7
- chalk/features/feature_field.py +40 -30
- chalk/features/feature_set.py +1 -2
- chalk/features/feature_set_decorator.py +1 -0
- chalk/features/feature_wrapper.py +42 -3
- chalk/features/hooks.py +81 -12
- chalk/features/inference.py +65 -10
- chalk/features/resolver.py +338 -56
- chalk/features/tag.py +1 -3
- chalk/features/underscore_features.py +2 -1
- chalk/functions/__init__.py +456 -21
- chalk/functions/holidays.py +1 -3
- chalk/gitignore/gitignore_parser.py +5 -1
- chalk/importer.py +186 -74
- chalk/ml/__init__.py +6 -2
- chalk/ml/model_hooks.py +368 -51
- chalk/ml/model_reference.py +68 -10
- chalk/ml/model_version.py +34 -21
- chalk/ml/utils.py +143 -40
- chalk/operators/_utils.py +14 -3
- chalk/parsed/_proto/export.py +22 -0
- chalk/parsed/duplicate_input_gql.py +4 -0
- chalk/parsed/expressions.py +1 -3
- chalk/parsed/json_conversions.py +21 -14
- chalk/parsed/to_proto.py +16 -4
- chalk/parsed/user_types_to_json.py +31 -10
- chalk/parsed/validation_from_registries.py +182 -0
- chalk/queries/named_query.py +16 -6
- chalk/queries/scheduled_query.py +13 -1
- chalk/serialization/parsed_annotation.py +25 -12
- chalk/sql/__init__.py +221 -0
- chalk/sql/_internal/integrations/athena.py +6 -1
- chalk/sql/_internal/integrations/bigquery.py +22 -2
- chalk/sql/_internal/integrations/databricks.py +61 -18
- chalk/sql/_internal/integrations/mssql.py +281 -0
- chalk/sql/_internal/integrations/postgres.py +11 -3
- chalk/sql/_internal/integrations/redshift.py +4 -0
- chalk/sql/_internal/integrations/snowflake.py +11 -2
- chalk/sql/_internal/integrations/util.py +2 -1
- chalk/sql/_internal/sql_file_resolver.py +55 -10
- chalk/sql/_internal/sql_source.py +36 -2
- chalk/streams/__init__.py +1 -3
- chalk/streams/_kafka_source.py +5 -1
- chalk/streams/_windows.py +16 -4
- chalk/streams/types.py +1 -2
- chalk/utils/__init__.py +1 -3
- chalk/utils/_otel_version.py +13 -0
- chalk/utils/async_helpers.py +14 -5
- chalk/utils/df_utils.py +2 -2
- chalk/utils/duration.py +1 -3
- chalk/utils/job_log_display.py +538 -0
- chalk/utils/missing_dependency.py +5 -4
- chalk/utils/notebook.py +255 -2
- chalk/utils/pl_helpers.py +190 -37
- chalk/utils/pydanticutil/pydantic_compat.py +1 -2
- chalk/utils/storage_client.py +246 -0
- chalk/utils/threading.py +1 -3
- chalk/utils/tracing.py +194 -86
- {chalkpy-2.89.22.dist-info → chalkpy-2.95.3.dist-info}/METADATA +53 -21
- {chalkpy-2.89.22.dist-info → chalkpy-2.95.3.dist-info}/RECORD +268 -198
- {chalkpy-2.89.22.dist-info → chalkpy-2.95.3.dist-info}/WHEEL +0 -0
- {chalkpy-2.89.22.dist-info → chalkpy-2.95.3.dist-info}/entry_points.txt +0 -0
- {chalkpy-2.89.22.dist-info → chalkpy-2.95.3.dist-info}/top_level.txt +0 -0
|
@@ -110,6 +110,22 @@ def project_settings_to_gql(config: ProjectSettings) -> ProjectSettingsGQL:
|
|
|
110
110
|
|
|
111
111
|
|
|
112
112
|
def get_registered_types(scope_to: Path, failed: List[FailedImport]) -> UpsertGraphGQL:
|
|
113
|
+
# Validate registries BEFORE conversion to catch errors early
|
|
114
|
+
# This ensures parity with Proto validation path
|
|
115
|
+
from chalk.parsed.validation_from_registries import validate_all_from_registries
|
|
116
|
+
|
|
117
|
+
try:
|
|
118
|
+
validate_all_from_registries(
|
|
119
|
+
features_registry=FeatureSetBase.registry,
|
|
120
|
+
resolver_registry=RESOLVER_REGISTRY,
|
|
121
|
+
)
|
|
122
|
+
except Exception as e:
|
|
123
|
+
# If validation fails, add to failed but continue
|
|
124
|
+
# to allow other validation to complete
|
|
125
|
+
if not LSPErrorBuilder.promote_exception(e):
|
|
126
|
+
# Not an LSP error, so log it as a failed import
|
|
127
|
+
failed.append(build_failed_import(e, "validation"))
|
|
128
|
+
|
|
113
129
|
features = []
|
|
114
130
|
feature_classes: list[FeatureClassGQL] = []
|
|
115
131
|
for x in FeatureSetBase.registry.values():
|
|
@@ -173,6 +189,14 @@ def get_registered_types(scope_to: Path, failed: List[FailedImport]) -> UpsertGr
|
|
|
173
189
|
named_queries: list[UpsertNamedQueryGQL] = []
|
|
174
190
|
for named_query in NAMED_QUERY_REGISTRY.values():
|
|
175
191
|
if named_query.filename is None or _is_relative_to(Path(named_query.filename), scope_to):
|
|
192
|
+
# only try to convert if there are no errors
|
|
193
|
+
if not named_query.errors:
|
|
194
|
+
try:
|
|
195
|
+
named_queries.append(convert_type_to_gql(named_query, path_prefix=path_prefix_to_remove))
|
|
196
|
+
except Exception as e:
|
|
197
|
+
failed.append(build_failed_import(e, f"named query '{named_query.name}'"))
|
|
198
|
+
|
|
199
|
+
# named_query.errors can go from empty to non-empty after conversion
|
|
176
200
|
if named_query.errors:
|
|
177
201
|
code_object_diagnostics[named_query.filename or ""].extend(
|
|
178
202
|
[
|
|
@@ -185,15 +209,17 @@ def get_registered_types(scope_to: Path, failed: List[FailedImport]) -> UpsertGr
|
|
|
185
209
|
for error in named_query.errors
|
|
186
210
|
]
|
|
187
211
|
)
|
|
188
|
-
continue
|
|
189
|
-
try:
|
|
190
|
-
named_queries.append(convert_type_to_gql(named_query, path_prefix=path_prefix_to_remove))
|
|
191
|
-
except Exception as e:
|
|
192
|
-
failed.append(build_failed_import(e, f"named query '{named_query.name}'"))
|
|
193
212
|
|
|
194
213
|
model_references: list[UpsertModelReferenceGQL] = []
|
|
195
214
|
for mr in MODEL_REFERENCE_REGISTRY.values():
|
|
196
215
|
if mr.filename is None or _is_relative_to(Path(mr.filename), scope_to):
|
|
216
|
+
# similar logic to named_queries above
|
|
217
|
+
if not mr.errors:
|
|
218
|
+
try:
|
|
219
|
+
model_references.append(convert_type_to_gql(mr, path_prefix=path_prefix_to_remove))
|
|
220
|
+
except Exception as e:
|
|
221
|
+
failed.append(build_failed_import(e, f"model reference '{mr.name}'"))
|
|
222
|
+
|
|
197
223
|
if mr.errors:
|
|
198
224
|
code_object_diagnostics[mr.filename or ""].extend(
|
|
199
225
|
[
|
|
@@ -206,11 +232,6 @@ def get_registered_types(scope_to: Path, failed: List[FailedImport]) -> UpsertGr
|
|
|
206
232
|
for error in mr.errors
|
|
207
233
|
]
|
|
208
234
|
)
|
|
209
|
-
continue
|
|
210
|
-
try:
|
|
211
|
-
model_references.append(convert_type_to_gql(mr, path_prefix=path_prefix_to_remove))
|
|
212
|
-
except Exception as e:
|
|
213
|
-
failed.append(build_failed_import(e, f"model reference '{mr.name}'"))
|
|
214
235
|
|
|
215
236
|
# online store configs
|
|
216
237
|
for osc in ONLINE_STORE_CONFIG_REGISTRY.values():
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unified validation layer that operates directly on registries.
|
|
3
|
+
|
|
4
|
+
This module provides validation that works for BOTH GQL and Proto conversion paths.
|
|
5
|
+
It triggers lazy validations by accessing properties on registry objects and performs
|
|
6
|
+
explicit validation checks.
|
|
7
|
+
|
|
8
|
+
This ensures validation parity between:
|
|
9
|
+
- GQL path: get_registered_types() → validate_graph()
|
|
10
|
+
- Proto path: ToProtoConverter.convert_graph()
|
|
11
|
+
|
|
12
|
+
By calling validate_all_from_registries() before conversion in both paths, we ensure
|
|
13
|
+
developers cannot add validation to one path and forget the other.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from typing import TYPE_CHECKING
|
|
19
|
+
|
|
20
|
+
from chalk._lsp.error_builder import LSPErrorBuilder
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from chalk.features.feature_field import Feature
|
|
24
|
+
from chalk.features.feature_set import Features
|
|
25
|
+
from chalk.features.resolver import ResolverRegistry
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def validate_all_from_registries(
|
|
29
|
+
features_registry: dict[str, type["Features"]],
|
|
30
|
+
resolver_registry: "ResolverRegistry",
|
|
31
|
+
) -> None:
|
|
32
|
+
"""
|
|
33
|
+
Trigger all validations by accessing properties on registry objects.
|
|
34
|
+
This can be run multiple times and not show duplicates.
|
|
35
|
+
|
|
36
|
+
This function should be called by BOTH GQL and Proto conversion paths BEFORE
|
|
37
|
+
they perform their conversions. It validates by triggering lazy validations:
|
|
38
|
+
|
|
39
|
+
- Error[24]: Feature names with protected prefixes
|
|
40
|
+
- Error[25]: Namespace names with protected prefixes
|
|
41
|
+
- Error[32]: Invalid join syntax (composite joins must use & not and)
|
|
42
|
+
- Error[35]: Missing has-one join definition
|
|
43
|
+
- Error[37]: Join filter with incorrect type annotation
|
|
44
|
+
- Error[40]: Invalid join lambda
|
|
45
|
+
- Error[42]: Bad foreign key types (type mismatch)
|
|
46
|
+
- Error[43]: Multi-namespace joins
|
|
47
|
+
- Error[51]: Multiple primary features (versioned primary keys)
|
|
48
|
+
- Error[119]: State type validation (stream resolvers)
|
|
49
|
+
- Error[135]: Unrecognized feature reference
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
features_registry : dict[str, type[Features]]
|
|
54
|
+
The feature registry to validate (FeatureSetBase.registry).
|
|
55
|
+
resolver_registry : ResolverRegistry
|
|
56
|
+
The resolver registry to validate (RESOLVER_REGISTRY).
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
None
|
|
61
|
+
Validation errors are accumulated in LSPErrorBuilder and raised as exceptions.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
# ========================================================================
|
|
65
|
+
# FEATURE VALIDATION
|
|
66
|
+
# ========================================================================
|
|
67
|
+
|
|
68
|
+
for _, features_cls in features_registry.items():
|
|
69
|
+
# --------------------------------------------------------------------
|
|
70
|
+
# Error[51]: Multiple primary features (versioned primary keys)
|
|
71
|
+
# --------------------------------------------------------------------
|
|
72
|
+
# Accessing __chalk_primary__ triggers _discover_feature() which
|
|
73
|
+
# validates that there's only one primary key. Versioned features
|
|
74
|
+
# create multiple primary keys (e.g., id, id@2, id@3, id@4) which
|
|
75
|
+
# triggers Error[51].
|
|
76
|
+
try:
|
|
77
|
+
_ = features_cls.__chalk_primary__
|
|
78
|
+
except Exception as e:
|
|
79
|
+
# LSPErrorBuilder.promote_exception() re-raises LSP errors
|
|
80
|
+
if not LSPErrorBuilder.promote_exception(e):
|
|
81
|
+
# If it's not an LSP error, something else went wrong
|
|
82
|
+
raise
|
|
83
|
+
|
|
84
|
+
# --------------------------------------------------------------------
|
|
85
|
+
# Iterate through all features in this feature set
|
|
86
|
+
# --------------------------------------------------------------------
|
|
87
|
+
for feature in features_cls.features:
|
|
88
|
+
# Skip autogenerated and no-display features (same as user_types_to_json.py:138)
|
|
89
|
+
# This prevents validating internal features like __chalk_* that are allowed
|
|
90
|
+
# to have protected names
|
|
91
|
+
if feature.is_autogenerated or feature.no_display:
|
|
92
|
+
continue
|
|
93
|
+
|
|
94
|
+
# ----------------------------------------------------------------
|
|
95
|
+
# Error[32,35,37,40,42,43]: Join validation
|
|
96
|
+
# ----------------------------------------------------------------
|
|
97
|
+
# Accessing the .join property triggers:
|
|
98
|
+
# - _validate_join() in feature_field.py (Error[32,37])
|
|
99
|
+
# - _validate_filter() in feature_field.py (Error[40,42,43])
|
|
100
|
+
#
|
|
101
|
+
# During GQL conversion, convert_type_to_gql() also checks:
|
|
102
|
+
# - Error[35]: if t.is_has_one and t.join is None
|
|
103
|
+
try:
|
|
104
|
+
_ = feature.join
|
|
105
|
+
except Exception as e:
|
|
106
|
+
if not LSPErrorBuilder.promote_exception(e):
|
|
107
|
+
raise
|
|
108
|
+
|
|
109
|
+
# ----------------------------------------------------------------
|
|
110
|
+
# Error[24,25]: Feature and namespace name validation
|
|
111
|
+
# ----------------------------------------------------------------
|
|
112
|
+
try:
|
|
113
|
+
_validate_feature_names_from_registry(feature)
|
|
114
|
+
except Exception as e:
|
|
115
|
+
if not LSPErrorBuilder.promote_exception(e):
|
|
116
|
+
raise
|
|
117
|
+
|
|
118
|
+
# ========================================================================
|
|
119
|
+
# RESOLVER VALIDATION
|
|
120
|
+
# ========================================================================
|
|
121
|
+
|
|
122
|
+
for resolver in resolver_registry.get_all_resolvers():
|
|
123
|
+
# --------------------------------------------------------------------
|
|
124
|
+
# Error[135]: Unrecognized feature reference
|
|
125
|
+
# --------------------------------------------------------------------
|
|
126
|
+
# Accessing resolver.inputs triggers _do_parse() which validates
|
|
127
|
+
# that all input features are recognized and exist in the registry.
|
|
128
|
+
try:
|
|
129
|
+
_ = resolver.inputs
|
|
130
|
+
except Exception as e:
|
|
131
|
+
if not LSPErrorBuilder.promote_exception(e):
|
|
132
|
+
raise
|
|
133
|
+
|
|
134
|
+
# --------------------------------------------------------------------
|
|
135
|
+
# Error[119]: State type validation (stream resolvers)
|
|
136
|
+
# --------------------------------------------------------------------
|
|
137
|
+
# Accessing resolver state and default_args triggers validation
|
|
138
|
+
# that default state values match their type annotations.
|
|
139
|
+
try:
|
|
140
|
+
_ = resolver.state
|
|
141
|
+
_ = resolver.default_args
|
|
142
|
+
except Exception as e:
|
|
143
|
+
if not LSPErrorBuilder.promote_exception(e):
|
|
144
|
+
raise
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _validate_feature_names_from_registry(feature: "Feature") -> None:
|
|
148
|
+
"""
|
|
149
|
+
Validate that feature names and namespace names don't use protected prefixes.
|
|
150
|
+
|
|
151
|
+
This performs the same validation as _validate_feature_names() in
|
|
152
|
+
_graph_validation.py, but operates on Feature objects from the registry
|
|
153
|
+
rather than UpsertFeatureGQL objects.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
feature : Feature
|
|
158
|
+
The feature to validate from FeatureSetBase.registry
|
|
159
|
+
|
|
160
|
+
Raises
|
|
161
|
+
------
|
|
162
|
+
Exception
|
|
163
|
+
If feature or namespace name starts with '_chalk' or '__'
|
|
164
|
+
"""
|
|
165
|
+
# Error[24]: Feature names cannot begin with '_chalk' or '__'
|
|
166
|
+
if feature.name.startswith("__") or feature.name.startswith("_chalk"):
|
|
167
|
+
feature.lsp_error_builder.add_diagnostic(
|
|
168
|
+
message="Feature names cannot begin with '_chalk' or '__'.",
|
|
169
|
+
range=feature.lsp_error_builder.property_range(feature.attribute_name or feature.name),
|
|
170
|
+
label="protected name",
|
|
171
|
+
code="24",
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Error[25]: Namespace names cannot begin with '_chalk' or '__'
|
|
175
|
+
if feature.namespace.startswith("__") or feature.namespace.startswith("_chalk"):
|
|
176
|
+
feature.lsp_error_builder.add_diagnostic(
|
|
177
|
+
message="Feature classes cannot have names that begin with '_chalk' or '__'.",
|
|
178
|
+
label="protected namespace",
|
|
179
|
+
range=feature.lsp_error_builder.decorator_kwarg_value_range("name")
|
|
180
|
+
or feature.lsp_error_builder.class_definition_range(),
|
|
181
|
+
code="25",
|
|
182
|
+
)
|
chalk/queries/named_query.py
CHANGED
|
@@ -4,6 +4,7 @@ import inspect
|
|
|
4
4
|
import traceback
|
|
5
5
|
from typing import TYPE_CHECKING, Mapping, Sequence
|
|
6
6
|
|
|
7
|
+
from chalk._lsp.error_builder import LSPErrorBuilder
|
|
7
8
|
from chalk.features import unwrap_feature
|
|
8
9
|
from chalk.utils.object_inspect import get_source_object_starting
|
|
9
10
|
from chalk.utils.source_parsing import should_skip_source_code_parsing
|
|
@@ -157,9 +158,12 @@ class NamedQuery:
|
|
|
157
158
|
self._input = [str(f) for f in self._input_raw]
|
|
158
159
|
elif self._output_raw is not None:
|
|
159
160
|
self._input = [str(unwrap_feature(o).primary_feature) for o in self._output_raw]
|
|
160
|
-
except Exception:
|
|
161
|
+
except Exception as e:
|
|
161
162
|
self._input = None
|
|
162
|
-
|
|
163
|
+
if not LSPErrorBuilder.promote_exception(e):
|
|
164
|
+
self.errors.append(
|
|
165
|
+
f"Error creating NamedQuery '{self.name} ({self.version})': {traceback.format_exc()}"
|
|
166
|
+
)
|
|
163
167
|
|
|
164
168
|
return self._input
|
|
165
169
|
|
|
@@ -170,9 +174,12 @@ class NamedQuery:
|
|
|
170
174
|
try:
|
|
171
175
|
if self._output_raw is not None:
|
|
172
176
|
self._output = [str(o) for o in self._output_raw]
|
|
173
|
-
except Exception:
|
|
177
|
+
except Exception as e:
|
|
174
178
|
self._output = None
|
|
175
|
-
|
|
179
|
+
if not LSPErrorBuilder.promote_exception(e):
|
|
180
|
+
self.errors.append(
|
|
181
|
+
f"Error creating NamedQuery '{self.name} ({self.version})': {traceback.format_exc()}"
|
|
182
|
+
)
|
|
176
183
|
|
|
177
184
|
return self._output
|
|
178
185
|
|
|
@@ -183,9 +190,12 @@ class NamedQuery:
|
|
|
183
190
|
try:
|
|
184
191
|
if self._additional_logged_features_raw is not None:
|
|
185
192
|
self._additional_logged_features = [str(alf) for alf in self._additional_logged_features_raw]
|
|
186
|
-
except Exception:
|
|
193
|
+
except Exception as e:
|
|
187
194
|
self._additional_logged_features = None
|
|
188
|
-
|
|
195
|
+
if not LSPErrorBuilder.promote_exception(e):
|
|
196
|
+
self.errors.append(
|
|
197
|
+
f"Error creating NamedQuery '{self.name} ({self.version})': {traceback.format_exc()}"
|
|
198
|
+
)
|
|
189
199
|
|
|
190
200
|
return self._additional_logged_features
|
|
191
201
|
|
chalk/queries/scheduled_query.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import inspect
|
|
4
|
-
from datetime import datetime, timezone
|
|
4
|
+
from datetime import datetime, timedelta, timezone
|
|
5
5
|
from typing import TYPE_CHECKING, Collection
|
|
6
6
|
|
|
7
7
|
from chalk.utils.duration import CronTab, Duration
|
|
@@ -21,12 +21,16 @@ class ScheduledQuery:
|
|
|
21
21
|
lower_bound: datetime | None = None,
|
|
22
22
|
upper_bound: datetime | None = None,
|
|
23
23
|
tags: Collection[str] | None = None,
|
|
24
|
+
dataset_name: str | None = None,
|
|
24
25
|
required_resolver_tags: Collection[str] | None = None,
|
|
25
26
|
store_online: bool = True,
|
|
26
27
|
store_offline: bool = True,
|
|
27
28
|
incremental_resolvers: Collection[str] | None = None,
|
|
28
29
|
planner_options: dict[str, str] | None = None,
|
|
29
30
|
resource_group: str | None = None,
|
|
31
|
+
completion_deadline: timedelta | None = None,
|
|
32
|
+
num_shards: int | None = None,
|
|
33
|
+
num_workers: int | None = None,
|
|
30
34
|
):
|
|
31
35
|
"""Create an offline query which runs on a schedule.
|
|
32
36
|
|
|
@@ -64,6 +68,8 @@ class ScheduledQuery:
|
|
|
64
68
|
incrementalization.
|
|
65
69
|
tags
|
|
66
70
|
Allows selecting resolvers with these tags.
|
|
71
|
+
dataset_name
|
|
72
|
+
Associated dataset name for the scheduled query.
|
|
67
73
|
required_resolver_tags
|
|
68
74
|
Requires that resolvers have these tags.
|
|
69
75
|
store_online
|
|
@@ -143,6 +149,7 @@ class ScheduledQuery:
|
|
|
143
149
|
self.lower_bound = lower_bound
|
|
144
150
|
self.upper_bound = upper_bound
|
|
145
151
|
self.tags = tags
|
|
152
|
+
self.dataset_name = dataset_name
|
|
146
153
|
self.required_resolver_tags = required_resolver_tags
|
|
147
154
|
self.filename = caller_filename
|
|
148
155
|
self.store_online = store_online
|
|
@@ -155,6 +162,11 @@ class ScheduledQuery:
|
|
|
155
162
|
self.planner_options = {k: str(v) for k, v in planner_options.items()} if planner_options else None
|
|
156
163
|
self.resource_group = resource_group
|
|
157
164
|
|
|
165
|
+
self.completion_deadline = completion_deadline
|
|
166
|
+
|
|
167
|
+
self.num_shards = num_shards
|
|
168
|
+
self.num_workers = num_workers
|
|
169
|
+
|
|
158
170
|
CRON_QUERY_REGISTRY[name] = self
|
|
159
171
|
|
|
160
172
|
|
|
@@ -111,7 +111,7 @@ class ParsedAnnotation:
|
|
|
111
111
|
typ = self._features_cls.__annotations__[self._attribute_name]
|
|
112
112
|
else:
|
|
113
113
|
typ = self._parsed_annotation or self._underlying or self._unparsed_underlying
|
|
114
|
-
if
|
|
114
|
+
if get_origin(typ) == typing.Annotated:
|
|
115
115
|
typ = typ.__origin__ # pyright: ignore
|
|
116
116
|
if isinstance(typ, type):
|
|
117
117
|
typ = typ.__name__
|
|
@@ -350,6 +350,7 @@ class ParsedAnnotation:
|
|
|
350
350
|
if "__chalk_document__" in args:
|
|
351
351
|
self._is_document = True
|
|
352
352
|
origin = get_origin(annotation)
|
|
353
|
+
self._parsed_annotation = cast(type, annotation)
|
|
353
354
|
|
|
354
355
|
# The only allowed collections here are Set, List, or DataFrame
|
|
355
356
|
if origin in (set, Set):
|
|
@@ -372,17 +373,6 @@ class ParsedAnnotation:
|
|
|
372
373
|
annotation = args[0]
|
|
373
374
|
if origin in (tuple, Tuple):
|
|
374
375
|
args = get_args(annotation)
|
|
375
|
-
if len(args) != 2 or args[1] is not ... or args[0] is ...:
|
|
376
|
-
self._type_error(
|
|
377
|
-
(
|
|
378
|
-
"Tuple should be given exactly two type parameters. "
|
|
379
|
-
"The first should be the type of the elements, and the second should be '...', "
|
|
380
|
-
"which indicates that the tuple is of variable length. "
|
|
381
|
-
"For example, 'Tuple[int, ...]' is a tuple of ints of variable length."
|
|
382
|
-
),
|
|
383
|
-
code="74",
|
|
384
|
-
label="invalid tuple",
|
|
385
|
-
)
|
|
386
376
|
annotation = args[0]
|
|
387
377
|
if origin in (list, List):
|
|
388
378
|
args = get_args(annotation)
|
|
@@ -567,3 +557,26 @@ class ParsedAnnotation:
|
|
|
567
557
|
if self._parsed_annotation is None:
|
|
568
558
|
self._parse_annotation()
|
|
569
559
|
return self._is_feature_time
|
|
560
|
+
|
|
561
|
+
def is_dataframe_annotation(self) -> bool:
|
|
562
|
+
"""
|
|
563
|
+
Check if the annotation represents a DataFrame type, even if validation failed.
|
|
564
|
+
This checks the raw parsed annotation without triggering full validation,
|
|
565
|
+
useful for preventing false positive errors when DataFrame validation fails.
|
|
566
|
+
"""
|
|
567
|
+
from typing import get_args
|
|
568
|
+
|
|
569
|
+
from chalk.features.dataframe import DataFrameMeta
|
|
570
|
+
|
|
571
|
+
if self._parsed_annotation is None:
|
|
572
|
+
self._parse_annotation()
|
|
573
|
+
|
|
574
|
+
# Check if directly a DataFrame
|
|
575
|
+
if isinstance(self.parsed_annotation, DataFrameMeta):
|
|
576
|
+
return True
|
|
577
|
+
|
|
578
|
+
# Check if wrapped in Optional, Union, etc.
|
|
579
|
+
if any(isinstance(x, DataFrameMeta) for x in get_args(self.parsed_annotation)):
|
|
580
|
+
return True
|
|
581
|
+
|
|
582
|
+
return False
|