salesforce-data-customcode 6.0.8.dev1__tar.gz → 6.1.0rc1__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.
Files changed (101) hide show
  1. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/PKG-INFO +1 -1
  2. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/pyproject.toml +1 -1
  3. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_predictions/spark_default.py +88 -27
  4. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/LICENSE.txt +0 -0
  5. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/README.md +0 -0
  6. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/__init__.py +0 -0
  7. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/auth.py +0 -0
  8. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/cli.py +0 -0
  9. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/client.py +0 -0
  10. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/cmd.py +0 -0
  11. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/common_config.py +0 -0
  12. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/config.py +0 -0
  13. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/config.yaml +0 -0
  14. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/constants.py +0 -0
  15. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/credentials.py +0 -0
  16. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/deploy.py +0 -0
  17. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_platform_client.py +0 -0
  18. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_platform_config.py +0 -0
  19. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_predictions/__init__.py +0 -0
  20. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_predictions/base.py +0 -0
  21. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_predictions/errors.py +0 -0
  22. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_predictions/impl/default.py +0 -0
  23. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_predictions/spark_base.py +0 -0
  24. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_predictions/types.py +0 -0
  25. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/einstein_predictions_config.py +0 -0
  26. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/file/__init__.py +0 -0
  27. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/file/base.py +0 -0
  28. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/file/path/__init__.py +0 -0
  29. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/file/path/default.py +0 -0
  30. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/function/__init__.py +0 -0
  31. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/function/base.py +0 -0
  32. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/function/feature_types/__init__.py +0 -0
  33. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/function/feature_types/chunking.py +0 -0
  34. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/function/runtime.py +0 -0
  35. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/function_utils.py +0 -0
  36. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/__init__.py +0 -0
  37. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/base.py +0 -0
  38. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/reader/__init__.py +0 -0
  39. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/reader/base.py +0 -0
  40. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/reader/query_api.py +0 -0
  41. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/reader/sf_cli.py +0 -0
  42. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/reader/utils.py +0 -0
  43. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/writer/__init__.py +0 -0
  44. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/writer/base.py +0 -0
  45. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/writer/csv.py +0 -0
  46. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/io/writer/print.py +0 -0
  47. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/__init__.py +0 -0
  48. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/base.py +0 -0
  49. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/default.py +0 -0
  50. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/errors.py +0 -0
  51. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/spark_base.py +0 -0
  52. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/spark_default.py +0 -0
  53. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/types/__init__.py +0 -0
  54. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/types/generate_text_request.py +0 -0
  55. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/types/generate_text_request_builder.py +0 -0
  56. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/types/generate_text_response.py +0 -0
  57. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway/types/generate_text_response_builder.py +0 -0
  58. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/llm_gateway_config.py +0 -0
  59. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/mixin.py +0 -0
  60. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/py.typed +0 -0
  61. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/run.py +0 -0
  62. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/scan.py +0 -0
  63. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/spark/__init__.py +0 -0
  64. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/spark/base.py +0 -0
  65. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/spark/default.py +0 -0
  66. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/template.py +0 -0
  67. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/__init__.py +0 -0
  68. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/.devcontainer/devcontainer.json +0 -0
  69. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/Dockerfile.dependencies +0 -0
  70. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/README.md +0 -0
  71. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/build_native_dependencies.sh +0 -0
  72. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/chunking/payload/config.json +0 -0
  73. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/chunking/payload/entrypoint.py +0 -0
  74. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/chunking/requirements.txt +0 -0
  75. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/example/chunking_with_llm/config.json +0 -0
  76. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/example/chunking_with_llm/entrypoint.py +0 -0
  77. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/example/chunking_with_llm/files/chunking_prompt.txt +0 -0
  78. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/example/chunking_with_llm/tests/test.json +0 -0
  79. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/example/chunking_with_prediction/config.json +0 -0
  80. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/example/chunking_with_prediction/entrypoint.py +0 -0
  81. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/example/chunking_with_prediction/tests/test.json +0 -0
  82. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/payload/config.json +0 -0
  83. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/payload/entrypoint.py +0 -0
  84. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/payload/utility.py +0 -0
  85. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/requirements-dev.txt +0 -0
  86. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/function/requirements.txt +0 -0
  87. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/.devcontainer/devcontainer.json +0 -0
  88. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/Dockerfile +0 -0
  89. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/Dockerfile.dependencies +0 -0
  90. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/README.md +0 -0
  91. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/account.ipynb +0 -0
  92. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/build_native_dependencies.sh +0 -0
  93. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/examples/employee_hierarchy/employee_data.csv +0 -0
  94. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/examples/employee_hierarchy/entrypoint.py +0 -0
  95. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/jupyterlab.sh +0 -0
  96. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/payload/config.json +0 -0
  97. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/payload/entrypoint.py +0 -0
  98. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/requirements-dev.txt +0 -0
  99. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/templates/script/requirements.txt +0 -0
  100. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/token_provider.py +0 -0
  101. {salesforce_data_customcode-6.0.8.dev1 → salesforce_data_customcode-6.1.0rc1}/src/datacustomcode/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: salesforce-data-customcode
3
- Version: 6.0.8.dev1
3
+ Version: 6.1.0rc1
4
4
  Summary: Data Cloud Custom Code SDK
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE.txt
@@ -18,7 +18,7 @@ license = "Apache-2.0"
18
18
  name = "salesforce-data-customcode"
19
19
  readme = "README.md"
20
20
  requires-python = ">=3.10,<3.12"
21
- version = "6.0.8.dev1"
21
+ version = "6.1.0rc1"
22
22
 
23
23
  [tool.black]
24
24
  exclude = '''
@@ -39,6 +39,9 @@ if TYPE_CHECKING:
39
39
  _STATUS_SUCCESS = "SUCCESS"
40
40
  _STATUS_ERROR = "ERROR"
41
41
 
42
+ # HTTP status considered a successful prediction call.
43
+ _HTTP_OK = 200
44
+
42
45
 
43
46
  class DefaultSparkEinsteinPredictions(SparkEinsteinPredictions):
44
47
 
@@ -104,6 +107,8 @@ class DefaultSparkEinsteinPredictions(SparkEinsteinPredictions):
104
107
 
105
108
  def _predict(values_row: Any) -> Dict[str, Optional[str]]:
106
109
  if values_row is None:
110
+ # An entirely null features struct is not the normal per-feature null
111
+ # case; surface it directly rather than masking it (debuggability).
107
112
  return {
108
113
  "status": _STATUS_ERROR,
109
114
  "response": None,
@@ -181,6 +186,21 @@ def _call_predictions(
181
186
  return predictions.predict(request)
182
187
 
183
188
 
189
+ def _null_feature_name(features: Dict[str, Any]) -> Optional[str]:
190
+ """Return the name of the first null feature value, or ``None``."""
191
+ for name, value in features.items():
192
+ if value is None:
193
+ return name
194
+ return None
195
+
196
+
197
+ def _null_feature_message(name: str) -> str:
198
+ return (
199
+ f"Feature '{name}' has null value. Use coalesce() or when() to handle "
200
+ f"nulls before calling einstein_predict."
201
+ )
202
+
203
+
184
204
  def _invoke_predictions(
185
205
  predictions: "EinsteinPredictions",
186
206
  model_api_name: str,
@@ -190,18 +210,40 @@ def _invoke_predictions(
190
210
  ) -> Dict[str, Any]:
191
211
  from datacustomcode.einstein_predictions.errors import EinsteinPredictionsCallError
192
212
 
193
- response = _call_predictions(
194
- predictions, model_api_name, prediction_type, features, settings
195
- )
196
- if not response.is_success:
197
- error_code = _extract_error_code(response)
213
+ null_feature = _null_feature_name(features)
214
+ if null_feature is not None:
215
+ message = _null_feature_message(null_feature)
216
+ raise EinsteinPredictionsCallError(
217
+ f"Einstein Predictions call failed: {message}",
218
+ status=None,
219
+ error_code=None,
220
+ error_message=message,
221
+ )
222
+
223
+ try:
224
+ response = _call_predictions(
225
+ predictions, model_api_name, prediction_type, features, settings
226
+ )
227
+ except EinsteinPredictionsCallError:
228
+ raise
229
+ except Exception as exc:
230
+ # Transport/build failures: surface the real error (no masking) so local
231
+ # runs stay debuggable. error_code stays None since there is no HTTP status.
232
+ raise EinsteinPredictionsCallError(
233
+ f"Einstein Predictions call failed: {exc}",
234
+ status=None,
235
+ error_code=None,
236
+ error_message=str(exc),
237
+ ) from exc
238
+
239
+ if response.status_code != _HTTP_OK:
240
+ error_message = json.dumps(response.data) if response.data is not None else None
198
241
  raise EinsteinPredictionsCallError(
199
242
  f"Einstein Predictions call failed: "
200
- f"status_code={response.status_code}, "
201
- f"error_code={error_code!r}, message={response.data!r}",
243
+ f"status_code={response.status_code}, message={error_message!r}",
202
244
  status=response.status_code,
203
- error_code=error_code,
204
- error_message=str(response.data) if response.data else None,
245
+ error_code=str(response.status_code),
246
+ error_message=error_message,
205
247
  )
206
248
  return response.data or {}
207
249
 
@@ -213,27 +255,46 @@ def _invoke_predictions_as_struct(
213
255
  features: Dict[str, Any],
214
256
  settings: Optional[Dict[str, Any]],
215
257
  ) -> Dict[str, Optional[str]]:
216
- response = _call_predictions(
217
- predictions, model_api_name, prediction_type, features, settings
218
- )
219
- if not response.is_success:
258
+ # (a) Customer-actionable data condition — surface the actionable message directly.
259
+ null_feature = _null_feature_name(features)
260
+ if null_feature is not None:
220
261
  return {
221
262
  "status": _STATUS_ERROR,
222
263
  "response": None,
223
- "error_code": _extract_error_code(response),
224
- "error_message": str(response.data) if response.data else None,
264
+ "error_code": None,
265
+ "error_message": _null_feature_message(null_feature),
225
266
  }
226
- return {
227
- "status": _STATUS_SUCCESS,
228
- "response": json.dumps(response.data) if response.data is not None else None,
229
- "error_code": None,
230
- "error_message": None,
231
- }
232
267
 
268
+ # (b) Transport/build failures — surface the real error (no masking) so local
269
+ # runs stay debuggable. error_code stays None since there is no HTTP status.
270
+ try:
271
+ response = _call_predictions(
272
+ predictions, model_api_name, prediction_type, features, settings
273
+ )
274
+ except Exception as exc:
275
+ return {
276
+ "status": _STATUS_ERROR,
277
+ "response": None,
278
+ "error_code": None,
279
+ "error_message": str(exc),
280
+ }
233
281
 
234
- def _extract_error_code(response: "PredictionResponse") -> Optional[str]:
235
- if response.data:
236
- error_code = response.data.get("errorCode")
237
- if error_code is not None:
238
- return str(error_code)
239
- return None
282
+ if response.status_code == _HTTP_OK:
283
+ return {
284
+ "status": _STATUS_SUCCESS,
285
+ "response": (
286
+ json.dumps(response.data) if response.data is not None else None
287
+ ),
288
+ "error_code": None,
289
+ "error_message": None,
290
+ }
291
+
292
+ # (c) Non-200 SFAP HTTP error: error_code = status code, error_message = data JSON.
293
+ return {
294
+ "status": _STATUS_ERROR,
295
+ "response": None,
296
+ "error_code": str(response.status_code),
297
+ "error_message": (
298
+ json.dumps(response.data) if response.data is not None else None
299
+ ),
300
+ }