satisfactoscript 0.5.9__tar.gz → 0.5.10__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.
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/PKG-INFO +1 -1
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/pyproject.toml +1 -1
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/__init__.py +2 -1
- satisfactoscript-0.5.10/src/satisfactoscript/registry.py +7 -0
- satisfactoscript-0.5.10/src/satisfactoscript/utils.py +29 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript.egg-info/PKG-INFO +1 -1
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript.egg-info/SOURCES.txt +5 -1
- satisfactoscript-0.5.10/tests/test_registry_import_paths.py +26 -0
- satisfactoscript-0.5.10/tests/test_utils_safe_columns.py +46 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/README.md +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/setup.cfg +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/agentic/__init__.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/agentic/agent.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/core/__init__.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/core/config.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/core/core.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/core/loaders.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/core/registry.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/semantic/__init__.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/semantic/semantic.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript.egg-info/dependency_links.txt +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript.egg-info/requires.txt +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript.egg-info/top_level.txt +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/tests/test_config.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/tests/test_core.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/tests/test_core_connect_patch.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/tests/test_core_env_detection.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/tests/test_core_join.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/tests/test_core_username.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/tests/test_dummy.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/tests/test_loaders.py +0 -0
- {satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/tests/test_registry.py +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from .core.core import SatisfactoEngine
|
|
2
2
|
from .core.registry import RuleRegistry
|
|
3
3
|
from .core.config import ConfigurationManager
|
|
4
|
+
from .utils import safe_columns
|
|
4
5
|
|
|
5
|
-
__all__ = ["SatisfactoEngine", "RuleRegistry", "ConfigurationManager"]
|
|
6
|
+
__all__ = ["SatisfactoEngine", "RuleRegistry", "ConfigurationManager", "safe_columns"]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Utility helpers for rule authoring — compatible with Databricks Connect v2.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def safe_columns(df):
|
|
7
|
+
"""
|
|
8
|
+
Returns the column names of a DataFrame without triggering a failing AnalyzePlan RPC.
|
|
9
|
+
|
|
10
|
+
On native Databricks (cluster / notebook), this delegates to ``df.columns`` as normal.
|
|
11
|
+
On Databricks Connect v2 from local environments (PyCharm / VS Code on Windows), the
|
|
12
|
+
``AnalyzePlan`` gRPC call that backs ``df.columns`` can fail with
|
|
13
|
+
``Missing required field 'UserContext'``. In that case this function returns an empty
|
|
14
|
+
list so that optional-column branches in business rules are silently skipped rather than
|
|
15
|
+
crashing. Core transformations (withColumn, filter, write …) are unaffected because they
|
|
16
|
+
go through ``ExecutePlan``, not ``AnalyzePlan``.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
df: A PySpark DataFrame.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
list[str]: Column names, or ``[]`` when schema inspection fails locally.
|
|
23
|
+
"""
|
|
24
|
+
try:
|
|
25
|
+
return df.columns
|
|
26
|
+
except Exception as e:
|
|
27
|
+
if "UserContext" in str(e) or "INVALID_ARGUMENT" in str(e):
|
|
28
|
+
return []
|
|
29
|
+
raise
|
{satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript.egg-info/SOURCES.txt
RENAMED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
README.md
|
|
2
2
|
pyproject.toml
|
|
3
3
|
src/satisfactoscript/__init__.py
|
|
4
|
+
src/satisfactoscript/registry.py
|
|
5
|
+
src/satisfactoscript/utils.py
|
|
4
6
|
src/satisfactoscript.egg-info/PKG-INFO
|
|
5
7
|
src/satisfactoscript.egg-info/SOURCES.txt
|
|
6
8
|
src/satisfactoscript.egg-info/dependency_links.txt
|
|
@@ -23,4 +25,6 @@ tests/test_core_join.py
|
|
|
23
25
|
tests/test_core_username.py
|
|
24
26
|
tests/test_dummy.py
|
|
25
27
|
tests/test_loaders.py
|
|
26
|
-
tests/test_registry.py
|
|
28
|
+
tests/test_registry.py
|
|
29
|
+
tests/test_registry_import_paths.py
|
|
30
|
+
tests/test_utils_safe_columns.py
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for RuleRegistry import path compatibility.
|
|
3
|
+
All import paths must resolve to the same singleton class.
|
|
4
|
+
"""
|
|
5
|
+
from satisfactoscript.core.registry import RuleRegistry as RR_core
|
|
6
|
+
from satisfactoscript.registry import RuleRegistry as RR_shim
|
|
7
|
+
from satisfactoscript import RuleRegistry as RR_top
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_all_import_paths_resolve_to_same_class():
|
|
11
|
+
"""All three import paths must return the exact same class (same singleton)."""
|
|
12
|
+
assert RR_core is RR_shim
|
|
13
|
+
assert RR_core is RR_top
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_rule_registered_via_shim_is_visible_everywhere():
|
|
17
|
+
"""A rule registered using the shim import must be retrievable from all paths."""
|
|
18
|
+
@RR_shim.register_rule(name="__test_shim_rule__")
|
|
19
|
+
def _my_rule(df):
|
|
20
|
+
return df
|
|
21
|
+
|
|
22
|
+
assert RR_core.get_rule("__test_shim_rule__") is _my_rule
|
|
23
|
+
assert RR_top.get_rule("__test_shim_rule__") is _my_rule
|
|
24
|
+
|
|
25
|
+
# Cleanup
|
|
26
|
+
RR_core._rules.pop("__test_shim_rule__", None)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tests for satisfactoscript.utils.safe_columns.
|
|
3
|
+
"""
|
|
4
|
+
import pytest
|
|
5
|
+
from unittest.mock import MagicMock, PropertyMock
|
|
6
|
+
from satisfactoscript import safe_columns
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TestSafeColumns:
|
|
10
|
+
|
|
11
|
+
def test_returns_df_columns_normally(self):
|
|
12
|
+
df = MagicMock()
|
|
13
|
+
type(df).columns = PropertyMock(return_value=["id", "name", "value"])
|
|
14
|
+
|
|
15
|
+
assert safe_columns(df) == ["id", "name", "value"]
|
|
16
|
+
|
|
17
|
+
def test_returns_empty_list_on_usercontext_grpc_error(self):
|
|
18
|
+
df = MagicMock()
|
|
19
|
+
type(df).columns = PropertyMock(
|
|
20
|
+
side_effect=Exception("gRPC: Missing required field 'UserContext' in the request.")
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
result = safe_columns(df)
|
|
24
|
+
|
|
25
|
+
assert result == []
|
|
26
|
+
|
|
27
|
+
def test_returns_empty_list_on_invalid_argument_grpc_error(self):
|
|
28
|
+
df = MagicMock()
|
|
29
|
+
type(df).columns = PropertyMock(
|
|
30
|
+
side_effect=Exception("StatusCode.INVALID_ARGUMENT details: something")
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
result = safe_columns(df)
|
|
34
|
+
|
|
35
|
+
assert result == []
|
|
36
|
+
|
|
37
|
+
def test_reraises_unrelated_exceptions(self):
|
|
38
|
+
df = MagicMock()
|
|
39
|
+
type(df).columns = PropertyMock(side_effect=RuntimeError("disk full"))
|
|
40
|
+
|
|
41
|
+
with pytest.raises(RuntimeError, match="disk full"):
|
|
42
|
+
safe_columns(df)
|
|
43
|
+
|
|
44
|
+
def test_importable_from_satisfactoscript_top_level(self):
|
|
45
|
+
from satisfactoscript import safe_columns as sc
|
|
46
|
+
assert callable(sc)
|
|
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
|
{satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/semantic/__init__.py
RENAMED
|
File without changes
|
{satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript/semantic/semantic.py
RENAMED
|
File without changes
|
|
File without changes
|
{satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript.egg-info/requires.txt
RENAMED
|
File without changes
|
{satisfactoscript-0.5.9 → satisfactoscript-0.5.10}/src/satisfactoscript.egg-info/top_level.txt
RENAMED
|
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
|