Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dataconnect/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ class _PublishEnvelopeResult:
checks: ResultChecks = field(default_factory=ResultChecks)
errors: list[str] = field(default_factory=list)
invalid_records: pd.DataFrame | None = None
blinding_status: str | None = None
warnings: list[str] = field(default_factory=list)

# Flat accessors below are deprecated views onto the envelope, kept so
# existing notebooks keep working. Prefer metadata/metrics/checks.
Expand Down
2 changes: 2 additions & 0 deletions dataconnect/service/mappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ def _envelope_to_domain(envelope: PublishEnvelope, result_cls: type[_ResultT]) -
),
errors=envelope.errors,
invalid_records=envelope.invalid_records,
blinding_status=envelope.blinding_status,
warnings=envelope.warnings,
)


Expand Down
4 changes: 4 additions & 0 deletions dataconnect/transport/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ class PublishEnvelope:
errors: list[str] = field(default_factory=list)
invalid_records: pd.DataFrame | None = None
"""Populated from the Arrow IPC channel, not from the JSON payload."""
blinding_status: str | None = None
warnings: list[str] = field(default_factory=list)

@classmethod
def from_json(cls, payload: dict, invalid_records: pd.DataFrame | None = None) -> PublishEnvelope:
Expand Down Expand Up @@ -178,6 +180,8 @@ def from_json(cls, payload: dict, invalid_records: pd.DataFrame | None = None) -
),
errors=payload.get("errors") or [],
invalid_records=invalid_records,
blinding_status=payload.get("blinding_status"),
warnings=payload.get("warnings") or [],
)


Expand Down
41 changes: 41 additions & 0 deletions tests/test_dry_publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ def _make_dry_publish_response(**overrides: object) -> DryPublishResponse:
"duplicate_record_count": 0,
"invalid_record_count": 0,
"invalid_records": None,
"blinding_status": None,
"warnings": [],
**overrides,
}
return DryPublishResponse(
Expand All @@ -85,6 +87,8 @@ def _make_dry_publish_response(**overrides: object) -> DryPublishResponse:
),
errors=flat["errors"],
invalid_records=flat["invalid_records"],
blinding_status=flat["blinding_status"],
warnings=flat["warnings"],
)


Expand Down Expand Up @@ -230,6 +234,24 @@ def test_trace_id_is_not_added_to_result_contract(self) -> None:
result = dry_publish_response_to_domain(_make_dry_publish_response())
assert not hasattr(result, "trace_id")

def test_blinding_status_mapped(self) -> None:
result = dry_publish_response_to_domain(_make_dry_publish_response(blinding_status="UNBLINDING"))
assert result.blinding_status == "UNBLINDING"

def test_warnings_list_mapped_without_conversion_to_errors(self) -> None:
warnings = ["Prior version had a different key column", "Source dataset pending blinding review"]
result = dry_publish_response_to_domain(_make_dry_publish_response(warnings=warnings))
assert result.warnings == warnings
assert result.errors == []

def test_blinding_status_defaults_to_none_when_omitted(self) -> None:
result = dry_publish_response_to_domain(_make_dry_publish_response())
assert result.blinding_status is None

def test_warnings_defaults_to_empty_list_when_omitted(self) -> None:
result = dry_publish_response_to_domain(_make_dry_publish_response())
assert result.warnings == []


# ---------------------------------------------------------------------------
# DefaultDataConnectService.dry_publish
Expand Down Expand Up @@ -542,6 +564,25 @@ def test_errors_list_parsed_from_json(self) -> None:
result = transport.dry_publish_dataset(PublishRequest(input_config="{}", data=pd.DataFrame({"x": [1]})))
assert result.errors == ["err1", "err2"]

def test_blinding_fields_default_when_omitted_from_legacy_json(self) -> None:
transport = _make_flight_transport()
_wire_do_put(transport, _VALID_JSON_RESP) # no blinding_status/warnings keys

result = transport.dry_publish_dataset(PublishRequest(input_config="{}", data=pd.DataFrame({"x": [1]})))
assert result.blinding_status is None
assert result.warnings == []

def test_blinding_fields_parsed_from_json_when_present(self) -> None:
transport = _make_flight_transport()
_wire_do_put(
transport,
{**_VALID_JSON_RESP, "blinding_status": "UNBLINDING", "warnings": ["w1", "w2"]},
)

result = transport.dry_publish_dataset(PublishRequest(input_config="{}", data=pd.DataFrame({"x": [1]})))
assert result.blinding_status == "UNBLINDING"
assert result.warnings == ["w1", "w2"]

def test_none_ipc_buf_yields_no_invalid_records(self) -> None:
transport = _make_flight_transport()
# Second reader.read() returns None — server sent no invalid-records table
Expand Down
Loading