salesforce-data-customcode 7.0.0rc4__tar.gz → 7.0.0rc5__tar.gz
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.
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/PKG-INFO +13 -1
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/README.md +12 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/pyproject.toml +1 -1
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/client.py +19 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/deploy.py +8 -11
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/writer/base.py +33 -1
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/scan.py +26 -6
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/LICENSE.txt +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/auth.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/cli.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/cmd.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/common_config.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/config.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/config.yaml +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/constants.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/credentials.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_platform_client.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_platform_config.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_predictions/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_predictions/base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_predictions/errors.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_predictions/impl/default.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_predictions/spark_base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_predictions/spark_default.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_predictions/types.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/einstein_predictions_config.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/file/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/file/base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/file/path/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/file/path/default.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/function/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/function/base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/function/feature_types/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/function/feature_types/chunking.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/function/runtime.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/function_utils.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/cdf.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/reader/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/reader/base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/reader/local_deltas.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/reader/query_api.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/reader/sf_cli.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/reader/streaming_seeder.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/reader/utils.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/writer/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/writer/csv.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/writer/local_deltas.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/io/writer/print.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/lineage/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/lineage/_worker.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/lineage/capture.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/lineage/tracer.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/default.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/errors.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/spark_base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/spark_default.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/types/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/types/generate_text_request.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/types/generate_text_request_builder.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/types/generate_text_response.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway/types/generate_text_response_builder.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/llm_gateway_config.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/mixin.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/default.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/direct/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/direct/auth.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/direct/credentials.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/direct/transport.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/direct/url_resolver.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/errors.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/spark_base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/spark_default.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/types/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/types/http_method.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/types/http_request.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/types/http_request_builder.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/types/http_response.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential/types/http_response_builder.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/named_credential_config.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/py.typed +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/run.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/spark/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/spark/base.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/spark/column_hints.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/spark/default.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/template.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/__init__.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/.devcontainer/devcontainer.json +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/Dockerfile.dependencies +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/README.md +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/build_native_dependencies.sh +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/chunking/payload/config.json +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/chunking/payload/entrypoint.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/chunking/requirements.txt +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/example/chunking_with_llm/config.json +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/example/chunking_with_llm/entrypoint.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/example/chunking_with_llm/files/chunking_prompt.txt +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/example/chunking_with_llm/tests/test.json +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/example/chunking_with_prediction/config.json +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/example/chunking_with_prediction/entrypoint.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/example/chunking_with_prediction/tests/test.json +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/payload/config.json +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/payload/entrypoint.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/payload/utility.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/requirements-dev.txt +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/function/requirements.txt +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/.devcontainer/devcontainer.json +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/Dockerfile +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/Dockerfile.dependencies +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/README.md +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/account.ipynb +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/build_native_dependencies.sh +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/examples/employee_hierarchy/employee_data.csv +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/examples/employee_hierarchy/entrypoint.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/examples/streaming_deltas/entrypoint.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/jupyterlab.sh +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/payload/config.json +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/payload/entrypoint.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/requirements-dev.txt +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/templates/script/requirements.txt +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/token_provider.py +0 -0
- {salesforce_data_customcode-7.0.0rc4 → salesforce_data_customcode-7.0.0rc5}/src/datacustomcode/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: salesforce-data-customcode
|
|
3
|
-
Version: 7.0.
|
|
3
|
+
Version: 7.0.0rc5
|
|
4
4
|
Summary: Data Cloud Custom Code SDK
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
License-File: LICENSE.txt
|
|
@@ -183,6 +183,7 @@ For a streaming (delta) transform, use `StreamingClient`, which exposes the stre
|
|
|
183
183
|
* `read_dlo_deltas()` – Read the streaming change feed (deltas) of a Data Lake Object as a streaming DataFrame.
|
|
184
184
|
* `read_dmo_deltas()` – Read the streaming change feed (deltas) of a Data Model Object as a streaming DataFrame.
|
|
185
185
|
* `write_dlo_deltas(name, spark_dataframe)` – Write a streaming DataFrame of deltas to a Data Lake Object; returns the started `StreamingQuery`
|
|
186
|
+
* `write_dmo_deltas(name, spark_dataframe)` – Write a streaming DataFrame of deltas to a Data Model Object; returns the started `StreamingQuery`
|
|
186
187
|
|
|
187
188
|
`find_file_path`, `llm_gateway_generate_text`, and `einstein_predict` are available on both clients.
|
|
188
189
|
|
|
@@ -247,6 +248,15 @@ query = client.write_dlo_deltas("Output__dll", transformed)
|
|
|
247
248
|
query.awaitTermination()
|
|
248
249
|
```
|
|
249
250
|
|
|
251
|
+
A streaming transform can also read and write Data Model Objects with `read_dmo_deltas()` and `write_dmo_deltas()`:
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
deltas = client.read_dmo_deltas()
|
|
255
|
+
transformed = deltas.withColumn("description__c", upper(col("description__c")))
|
|
256
|
+
query = client.write_dmo_deltas("Output__dlm", transformed)
|
|
257
|
+
query.awaitTermination()
|
|
258
|
+
```
|
|
259
|
+
|
|
250
260
|
Notes:
|
|
251
261
|
|
|
252
262
|
- These methods only run inside the Data Cloud streaming (`DELTA_SYNC`) runtime. Locally (`datacustomcode run`) they raise `NotImplementedError`, since there is no change feed to stream.
|
|
@@ -408,6 +418,8 @@ Options:
|
|
|
408
418
|
#### `datacustomcode zip`
|
|
409
419
|
Zip a transformation job in preparation to upload to Data Cloud. Make sure to change directory into your code package folder (e.g., `my_package`) before running this command.
|
|
410
420
|
|
|
421
|
+
Symlinks inside the payload folder are not followed or packaged. Each symlinked file that is skipped is reported with a warning, and symlinked directories are not included. `datacustomcode deploy` zips the same way.
|
|
422
|
+
|
|
411
423
|
Arguments:
|
|
412
424
|
- `PATH`: Path to the code directory i.e. the payload folder (default: "payload")
|
|
413
425
|
|
|
@@ -158,6 +158,7 @@ For a streaming (delta) transform, use `StreamingClient`, which exposes the stre
|
|
|
158
158
|
* `read_dlo_deltas()` – Read the streaming change feed (deltas) of a Data Lake Object as a streaming DataFrame.
|
|
159
159
|
* `read_dmo_deltas()` – Read the streaming change feed (deltas) of a Data Model Object as a streaming DataFrame.
|
|
160
160
|
* `write_dlo_deltas(name, spark_dataframe)` – Write a streaming DataFrame of deltas to a Data Lake Object; returns the started `StreamingQuery`
|
|
161
|
+
* `write_dmo_deltas(name, spark_dataframe)` – Write a streaming DataFrame of deltas to a Data Model Object; returns the started `StreamingQuery`
|
|
161
162
|
|
|
162
163
|
`find_file_path`, `llm_gateway_generate_text`, and `einstein_predict` are available on both clients.
|
|
163
164
|
|
|
@@ -222,6 +223,15 @@ query = client.write_dlo_deltas("Output__dll", transformed)
|
|
|
222
223
|
query.awaitTermination()
|
|
223
224
|
```
|
|
224
225
|
|
|
226
|
+
A streaming transform can also read and write Data Model Objects with `read_dmo_deltas()` and `write_dmo_deltas()`:
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
deltas = client.read_dmo_deltas()
|
|
230
|
+
transformed = deltas.withColumn("description__c", upper(col("description__c")))
|
|
231
|
+
query = client.write_dmo_deltas("Output__dlm", transformed)
|
|
232
|
+
query.awaitTermination()
|
|
233
|
+
```
|
|
234
|
+
|
|
225
235
|
Notes:
|
|
226
236
|
|
|
227
237
|
- These methods only run inside the Data Cloud streaming (`DELTA_SYNC`) runtime. Locally (`datacustomcode run`) they raise `NotImplementedError`, since there is no change feed to stream.
|
|
@@ -383,6 +393,8 @@ Options:
|
|
|
383
393
|
#### `datacustomcode zip`
|
|
384
394
|
Zip a transformation job in preparation to upload to Data Cloud. Make sure to change directory into your code package folder (e.g., `my_package`) before running this command.
|
|
385
395
|
|
|
396
|
+
Symlinks inside the payload folder are not followed or packaged. Each symlinked file that is skipped is reported with a warning, and symlinked directories are not included. `datacustomcode deploy` zips the same way.
|
|
397
|
+
|
|
386
398
|
Arguments:
|
|
387
399
|
- `PATH`: Path to the code directory i.e. the payload folder (default: "payload")
|
|
388
400
|
|
|
@@ -726,6 +726,25 @@ class StreamingClient(_BaseClient):
|
|
|
726
726
|
self._validate_data_layer_history_does_not_contain(DataCloudObjectType.DMO)
|
|
727
727
|
return self._writer.write_dlo_deltas(name, dataframe, **kwargs) # type: ignore[no-any-return]
|
|
728
728
|
|
|
729
|
+
def write_dmo_deltas(
|
|
730
|
+
self, name: str, dataframe: PySparkDataFrame, **kwargs
|
|
731
|
+
) -> StreamingQuery:
|
|
732
|
+
"""Write a streaming DataFrame of deltas to a DMO in Data Cloud.
|
|
733
|
+
|
|
734
|
+
Starts a streaming query that writes each micro-batch to the
|
|
735
|
+
target DMO and returns the ``StreamingQuery`` handle; the caller
|
|
736
|
+
typically calls ``query.awaitTermination()``.
|
|
737
|
+
|
|
738
|
+
Args:
|
|
739
|
+
name: The name of the DMO to write to.
|
|
740
|
+
dataframe: The streaming PySpark DataFrame to write.
|
|
741
|
+
|
|
742
|
+
Returns:
|
|
743
|
+
The started ``StreamingQuery``.
|
|
744
|
+
"""
|
|
745
|
+
self._validate_data_layer_history_does_not_contain(DataCloudObjectType.DLO)
|
|
746
|
+
return self._writer.write_dmo_deltas(name, dataframe, **kwargs) # type: ignore[no-any-return]
|
|
747
|
+
|
|
729
748
|
def auto_write_to_dlo(self, name: str, dataframe: PySparkDataFrame) -> None:
|
|
730
749
|
"""Write a PySpark DataFrame to a DLO in Data Cloud automatically picking
|
|
731
750
|
the WriteMode.
|
|
@@ -415,13 +415,7 @@ class DataTransformConfig(BaseConfig):
|
|
|
415
415
|
def _validate_layers(self) -> "DataTransformConfig":
|
|
416
416
|
read_is_dlo = isinstance(self.permissions.read, DloPermission)
|
|
417
417
|
write_is_dlo = isinstance(self.permissions.write, DloPermission)
|
|
418
|
-
if
|
|
419
|
-
if not write_is_dlo:
|
|
420
|
-
raise ValueError(
|
|
421
|
-
"A streaming transform must write to a DLO "
|
|
422
|
-
"(permissions.write must be a 'dlo' entry)."
|
|
423
|
-
)
|
|
424
|
-
elif read_is_dlo != write_is_dlo:
|
|
418
|
+
if read_is_dlo != write_is_dlo:
|
|
425
419
|
raise ValueError(
|
|
426
420
|
"permissions.read and permissions.write must both reference "
|
|
427
421
|
"DLOs or both reference DMOs (got "
|
|
@@ -630,12 +624,15 @@ def zip(
|
|
|
630
624
|
logger.debug(f"Zipping directory... {directory}")
|
|
631
625
|
|
|
632
626
|
with zipfile.ZipFile(ZIP_FILE_NAME, "w", zipfile.ZIP_DEFLATED) as zipf:
|
|
633
|
-
for root, dirs, files in os.walk(directory):
|
|
634
|
-
# Skip .DS_Store and local credentials.
|
|
627
|
+
for root, dirs, files in os.walk(directory, followlinks=False):
|
|
628
|
+
# Skip symlinks, .DS_Store and local credentials.
|
|
635
629
|
for file in files:
|
|
630
|
+
abs_path = os.path.join(root, file)
|
|
631
|
+
arcname = os.path.relpath(abs_path, directory)
|
|
632
|
+
if os.path.islink(abs_path):
|
|
633
|
+
logger.warning(f"Skipping symlink file {arcname}")
|
|
634
|
+
continue
|
|
636
635
|
if file not in EXCLUDED_FILES:
|
|
637
|
-
abs_path = os.path.join(root, file)
|
|
638
|
-
arcname = os.path.relpath(abs_path, directory)
|
|
639
636
|
zipf.write(abs_path, arcname)
|
|
640
637
|
|
|
641
638
|
logger.debug(f"Created zip file: {ZIP_FILE_NAME}")
|
|
@@ -87,7 +87,7 @@ class BaseDataCloudWriter(BaseDataAccessLayer):
|
|
|
87
87
|
Args:
|
|
88
88
|
name: Target Data Lake Object name.
|
|
89
89
|
dataframe: Streaming PySpark DataFrame produced from a
|
|
90
|
-
``read_dlo_deltas``
|
|
90
|
+
``read_dlo_deltas`` source.
|
|
91
91
|
|
|
92
92
|
Returns:
|
|
93
93
|
The started ``StreamingQuery``; the caller drives its lifecycle
|
|
@@ -102,3 +102,35 @@ class BaseDataCloudWriter(BaseDataAccessLayer):
|
|
|
102
102
|
"streaming runtime; the local writer does not support streaming "
|
|
103
103
|
"deltas."
|
|
104
104
|
)
|
|
105
|
+
|
|
106
|
+
def write_dmo_deltas(
|
|
107
|
+
self, name: str, dataframe: PySparkDataFrame
|
|
108
|
+
) -> StreamingQuery:
|
|
109
|
+
"""Write a streaming DataFrame of deltas to a Data Model Object.
|
|
110
|
+
|
|
111
|
+
Streaming counterpart to :meth:`write_to_dmo`. Starts a streaming query
|
|
112
|
+
that writes each micro-batch to the target DMO via the Data Cloud
|
|
113
|
+
streaming sink and returns the resulting ``StreamingQuery`` handle. The
|
|
114
|
+
runtime owns the trigger and checkpoint location; callers pass only the
|
|
115
|
+
table name. Concrete streaming behavior is provided by the deployed
|
|
116
|
+
Data Cloud runtime; the base implementation raises
|
|
117
|
+
:class:`NotImplementedError`.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
name: Target Data Model Object name.
|
|
121
|
+
dataframe: Streaming PySpark DataFrame produced from a
|
|
122
|
+
``read_dmo_deltas`` source.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
The started ``StreamingQuery``; the caller drives its lifecycle
|
|
126
|
+
(typically ``query.awaitTermination()``).
|
|
127
|
+
|
|
128
|
+
Raises:
|
|
129
|
+
NotImplementedError: If the active writer does not support streaming
|
|
130
|
+
deltas (e.g. the local development writers).
|
|
131
|
+
"""
|
|
132
|
+
raise NotImplementedError(
|
|
133
|
+
"write_dmo_deltas is only supported when running in the Data Cloud "
|
|
134
|
+
"streaming runtime; the local writer does not support streaming "
|
|
135
|
+
"deltas."
|
|
136
|
+
)
|
|
@@ -34,7 +34,7 @@ from datacustomcode.version import get_version
|
|
|
34
34
|
|
|
35
35
|
DATA_ACCESS_METHODS = ["read_dlo", "read_dmo", "write_to_dlo", "write_to_dmo"]
|
|
36
36
|
STREAMING_READ_METHODS = ["read_dlo_deltas", "read_dmo_deltas"]
|
|
37
|
-
STREAMING_WRITE_METHODS = ["write_dlo_deltas"]
|
|
37
|
+
STREAMING_WRITE_METHODS = ["write_dlo_deltas", "write_dmo_deltas"]
|
|
38
38
|
|
|
39
39
|
DATA_TRANSFORM_CONFIG_TEMPLATE = {
|
|
40
40
|
"sdkVersion": get_version(),
|
|
@@ -181,6 +181,7 @@ class StreamingDataAccessLayerCalls(pydantic.BaseModel):
|
|
|
181
181
|
read_dlo_deltas: bool
|
|
182
182
|
read_dmo_deltas: bool
|
|
183
183
|
write_dlo_deltas: frozenset[str]
|
|
184
|
+
write_dmo_deltas: frozenset[str]
|
|
184
185
|
|
|
185
186
|
@pydantic.model_validator(mode="after")
|
|
186
187
|
def validate_access_layer(self) -> StreamingDataAccessLayerCalls:
|
|
@@ -193,10 +194,19 @@ class StreamingDataAccessLayerCalls(pydantic.BaseModel):
|
|
|
193
194
|
"A streaming transform must read from at least one DLO or DMO "
|
|
194
195
|
"delta stream (read_dlo_deltas / read_dmo_deltas)."
|
|
195
196
|
)
|
|
196
|
-
if not self.write_dlo_deltas:
|
|
197
|
+
if not self.write_dlo_deltas and not self.write_dmo_deltas:
|
|
197
198
|
raise ValueError(
|
|
198
|
-
"A streaming transform must write to at least one DLO
|
|
199
|
-
"write_dlo_deltas."
|
|
199
|
+
"A streaming transform must write to at least one DLO or DMO "
|
|
200
|
+
"via write_dlo_deltas / write_dmo_deltas."
|
|
201
|
+
)
|
|
202
|
+
if self.write_dlo_deltas and self.write_dmo_deltas:
|
|
203
|
+
raise ValueError(
|
|
204
|
+
"Cannot write DLO and DMO deltas in the same streaming transform."
|
|
205
|
+
)
|
|
206
|
+
if self.read_layer != self.write_layer:
|
|
207
|
+
raise ValueError(
|
|
208
|
+
"A streaming transform must read and write the same layer "
|
|
209
|
+
f"(got read={self.read_layer}, write={self.write_layer})."
|
|
200
210
|
)
|
|
201
211
|
return self
|
|
202
212
|
|
|
@@ -205,6 +215,11 @@ class StreamingDataAccessLayerCalls(pydantic.BaseModel):
|
|
|
205
215
|
"""Return the read source layer, ``"dlo"`` or ``"dmo"``."""
|
|
206
216
|
return "dlo" if self.read_dlo_deltas else "dmo"
|
|
207
217
|
|
|
218
|
+
@property
|
|
219
|
+
def write_layer(self) -> str:
|
|
220
|
+
"""Return the write target layer, ``"dlo"`` or ``"dmo"``."""
|
|
221
|
+
return "dlo" if self.write_dlo_deltas else "dmo"
|
|
222
|
+
|
|
208
223
|
|
|
209
224
|
class ClientMethodVisitor(ast.NodeVisitor):
|
|
210
225
|
"""AST Visitor that finds all instances of Client read/write method calls."""
|
|
@@ -217,6 +232,7 @@ class ClientMethodVisitor(ast.NodeVisitor):
|
|
|
217
232
|
self._read_dlo_deltas: bool = False
|
|
218
233
|
self._read_dmo_deltas: bool = False
|
|
219
234
|
self._write_dlo_deltas_instances: set[str] = set()
|
|
235
|
+
self._write_dmo_deltas_instances: set[str] = set()
|
|
220
236
|
self.variable_values: Dict[str, Union[str, None]] = {}
|
|
221
237
|
|
|
222
238
|
def visit_Assign(self, node: ast.Assign) -> None:
|
|
@@ -261,6 +277,8 @@ class ClientMethodVisitor(ast.NodeVisitor):
|
|
|
261
277
|
name = self._resolve_name_arg(node.args[0])
|
|
262
278
|
if name and method_name == "write_dlo_deltas":
|
|
263
279
|
self._write_dlo_deltas_instances.add(name)
|
|
280
|
+
elif name and method_name == "write_dmo_deltas":
|
|
281
|
+
self._write_dmo_deltas_instances.add(name)
|
|
264
282
|
self.generic_visit(node)
|
|
265
283
|
|
|
266
284
|
def _resolve_name_arg(self, arg: ast.expr) -> Union[str, None]:
|
|
@@ -278,6 +296,7 @@ class ClientMethodVisitor(ast.NodeVisitor):
|
|
|
278
296
|
self._read_dlo_deltas
|
|
279
297
|
or self._read_dmo_deltas
|
|
280
298
|
or bool(self._write_dlo_deltas_instances)
|
|
299
|
+
or bool(self._write_dmo_deltas_instances)
|
|
281
300
|
)
|
|
282
301
|
|
|
283
302
|
def found(self) -> DataAccessLayerCalls:
|
|
@@ -293,6 +312,7 @@ class ClientMethodVisitor(ast.NodeVisitor):
|
|
|
293
312
|
read_dlo_deltas=self._read_dlo_deltas,
|
|
294
313
|
read_dmo_deltas=self._read_dmo_deltas,
|
|
295
314
|
write_dlo_deltas=frozenset(self._write_dlo_deltas_instances),
|
|
315
|
+
write_dmo_deltas=frozenset(self._write_dmo_deltas_instances),
|
|
296
316
|
)
|
|
297
317
|
|
|
298
318
|
|
|
@@ -516,10 +536,10 @@ def _update_streaming_config(existing_config: dict[str, Any], file_path: str) ->
|
|
|
516
536
|
)
|
|
517
537
|
|
|
518
538
|
read_names = [source_name] if source_name else []
|
|
519
|
-
write_names = list(output.write_dlo_deltas)
|
|
539
|
+
write_names = list(output.write_dlo_deltas or output.write_dmo_deltas)
|
|
520
540
|
existing_config["permissions"] = {
|
|
521
541
|
"read": {read_layer: read_names},
|
|
522
|
-
"write": {
|
|
542
|
+
"write": {output.write_layer: write_names},
|
|
523
543
|
}
|
|
524
544
|
|
|
525
545
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|