Skip to content

Commit f6deec0

Browse files
committed
streaming source fix
1 parent 5baa65a commit f6deec0

5 files changed

Lines changed: 35 additions & 53 deletions

File tree

src/datacustomcode/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,17 @@ def _streaming_source_name() -> str:
5555
"""Return the streaming transform's read-source name.
5656
5757
Resolved from ``config.streaming_source``, which ``run_entrypoint``
58-
populates from config.json's ``permissions.read`` entry.
58+
populates from config.json's ``streamingSource`` field.
5959
6060
Raises:
6161
RuntimeError: If no ``streaming_source`` has been configured (e.g. the
62-
transform's config.json has no ``permissions.read`` entry).
62+
transform's config.json has no ``streamingSource`` field).
6363
"""
6464
source = config.streaming_source
6565
if not source:
6666
raise RuntimeError(
6767
"No streaming source configured. A streaming transform must declare "
68-
"its read source in config.json under 'permissions.read'."
68+
"its read source in config.json under 'streamingSource'."
6969
)
7070
return source
7171

src/datacustomcode/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class ClientConfig(BaseConfig):
9090
SparkProviderConfig[BaseSparkSessionProvider], None
9191
] = None
9292
# Source object name for a streaming (DELTA_SYNC) transform, populated by
93-
# ``run_entrypoint`` from config.json's ``permissions.read``
93+
# ``run_entrypoint`` from config.json's ``streamingSource`` field
9494
streaming_source: Union[str, None] = None
9595

9696
def update(self, other: ClientConfig) -> ClientConfig:

src/datacustomcode/run.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,14 @@ def _set_config_option(config_obj, key: str, value: Optional[str]) -> None:
4242
config_obj.options[key] = value
4343

4444

45-
def _read_source_from_permissions(config_json: dict) -> Optional[str]:
46-
"""Return the read-source name from config.json ``permissions.read``.
45+
def _read_streaming_source(config_json: dict) -> Optional[str]:
46+
"""Return the streaming source name from config.json's ``streamingSource``.
4747
"""
48-
permissions = config_json.get("permissions")
49-
if not isinstance(permissions, dict):
48+
source = config_json.get("streamingSource")
49+
if not isinstance(source, dict):
5050
return None
51-
read = permissions.get("read")
52-
if not isinstance(read, dict):
53-
return None
54-
for layer in ("dlo", "dmo"):
55-
names = read.get(layer)
56-
if names:
57-
return names[0]
58-
return None
51+
name = source.get("name")
52+
return str(name) if name else None
5953

6054

6155
def _update_config_options(profile: Optional[str], sf_cli_org: Optional[str]):
@@ -141,7 +135,7 @@ def run_entrypoint(
141135
_set_config_option(config.reader_config, "dataspace", dataspace)
142136
_set_config_option(config.writer_config, "dataspace", dataspace)
143137

144-
config.streaming_source = _read_source_from_permissions(config_json)
138+
config.streaming_source = _read_streaming_source(config_json)
145139

146140
_update_config_options(profile, sf_cli_org)
147141

tests/test_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def test_read_dlo_deltas(self, reset_client, mock_spark):
301301
reader.read_dlo_deltas.return_value = mock_df
302302

303303
client = StreamingClient(reader=reader, writer=writer)
304-
304+
305305
with patch("datacustomcode.client.config") as mock_config:
306306
mock_config.streaming_source = "Account_std__dll"
307307
result = client.read_dlo_deltas()
@@ -323,7 +323,7 @@ def test_read_dlo_deltas_without_configured_source_raises(
323323
with pytest.raises(RuntimeError) as exc_info:
324324
client.read_dlo_deltas()
325325

326-
assert "permissions.read" in str(exc_info.value)
326+
assert "streamingSource" in str(exc_info.value)
327327
reader.read_dlo_deltas.assert_not_called()
328328

329329
def test_read_dmo_deltas(self, reset_client, mock_spark):

tests/test_run.py

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -490,51 +490,39 @@ def test_run_entrypoint_empty_dataspace_value(self):
490490
os.unlink(config_json_path)
491491

492492

493-
class TestReadSourceFromPermissions:
494-
"""`_read_source_from_permissions` extracts the streaming read source from
495-
config.json's `permissions.read`."""
493+
class TestReadStreamingSource:
494+
"""`_read_streaming_source` extracts the source name from config.json's
495+
`streamingSource` object."""
496496

497-
def test_returns_single_dlo(self):
498-
from datacustomcode.run import _read_source_from_permissions
497+
def test_returns_dlo_name(self):
498+
from datacustomcode.run import _read_streaming_source
499499

500-
config_json = {"permissions": {"read": {"dlo": ["Account_std__dll"]}}}
501-
assert _read_source_from_permissions(config_json) == "Account_std__dll"
500+
config_json = {"streamingSource": {"type": "dlo", "name": "Account_Home__dll"}}
501+
assert _read_streaming_source(config_json) == "Account_Home__dll"
502502

503-
def test_returns_single_dmo(self):
504-
from datacustomcode.run import _read_source_from_permissions
505-
506-
config_json = {"permissions": {"read": {"dmo": ["Account_model__dlm"]}}}
507-
assert _read_source_from_permissions(config_json) == "Account_model__dlm"
508-
509-
def test_dlo_preferred_when_both_present(self):
510-
from datacustomcode.run import _read_source_from_permissions
503+
def test_returns_dmo_name(self):
504+
from datacustomcode.run import _read_streaming_source
511505

512506
config_json = {
513-
"permissions": {"read": {"dlo": ["the_dll"], "dmo": ["the_dlm"]}}
507+
"streamingSource": {"type": "dmo", "name": "AccountTransformed__dlm"}
514508
}
515-
assert _read_source_from_permissions(config_json) == "the_dll"
516-
517-
def test_returns_first_of_multiple(self):
518-
from datacustomcode.run import _read_source_from_permissions
519-
520-
config_json = {"permissions": {"read": {"dlo": ["first__dll", "second__dll"]}}}
521-
assert _read_source_from_permissions(config_json) == "first__dll"
509+
assert _read_streaming_source(config_json) == "AccountTransformed__dlm"
522510

523511
@pytest.mark.parametrize(
524512
"config_json",
525513
[
526514
{},
527-
{"permissions": None},
528-
{"permissions": {}},
529-
{"permissions": {"read": None}},
530-
{"permissions": {"read": {}}},
531-
{"permissions": {"read": {"dlo": []}}},
515+
{"streamingSource": None},
516+
{"streamingSource": {}},
517+
{"streamingSource": {"type": "dlo"}},
518+
{"streamingSource": {"type": "dlo", "name": ""}},
519+
{"streamingSource": {"type": "dlo", "name": None}},
532520
],
533521
)
534522
def test_returns_none_when_absent_or_empty(self, config_json):
535-
from datacustomcode.run import _read_source_from_permissions
523+
from datacustomcode.run import _read_streaming_source
536524

537-
assert _read_source_from_permissions(config_json) is None
525+
assert _read_streaming_source(config_json) is None
538526

539527

540528
class TestStreamingSourceScenarios:
@@ -575,15 +563,15 @@ def _run_capturing_streaming_source(self, config_json_body):
575563
if os.path.exists("streaming_source_output.txt"):
576564
os.unlink("streaming_source_output.txt")
577565

578-
def test_streaming_source_set_from_permissions_read(self):
566+
def test_streaming_source_set_from_streaming_source_field(self):
579567
content = self._run_capturing_streaming_source(
580568
{
581569
"dataspace": "default",
582-
"permissions": {"read": {"dlo": ["Account_std__dll"]}},
570+
"streamingSource": {"type": "dlo", "name": "Account_Home__dll"},
583571
}
584572
)
585-
assert "streaming_source: Account_std__dll" in content
573+
assert "streaming_source: Account_Home__dll" in content
586574

587-
def test_streaming_source_none_for_batch_without_read(self):
575+
def test_streaming_source_none_for_batch_without_field(self):
588576
content = self._run_capturing_streaming_source({"dataspace": "default"})
589577
assert "streaming_source: None" in content

0 commit comments

Comments
 (0)