Skip to content

Feat: Add Safe Data Preview#36

Open
kw-datamasque wants to merge 3 commits into
mainfrom
typed-safe-data-preview
Open

Feat: Add Safe Data Preview#36
kw-datamasque wants to merge 3 commits into
mainfrom
typed-safe-data-preview

Conversation

@kw-datamasque

Copy link
Copy Markdown

Adds SafeDataPreviewOptions on InDataDiscoveryConfig and a typed safe_data_preview field on schema-discovery result columns. Changelog entry under 1.1.8 (unreleased).

@ClassicMMT
ClassicMMT force-pushed the typed-safe-data-preview branch 3 times, most recently from 69ef38f to 9111d65 Compare July 16, 2026 02:27
@ClassicMMT ClassicMMT changed the title feat(discovery): Add typed Safe Data Preview options and result field feat: Add safe data preview results Jul 16, 2026
@ClassicMMT
ClassicMMT marked this pull request as ready for review July 16, 2026 02:33

@cph-datamasque cph-datamasque left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a think about whether the UnknownPreview is a safe idea from the point of view of a person using this library.

Remove tests that are just testing pydantic, and collapse repetitive tests using pytest.mark.parametrize().

pass
try:
return UnknownPreview.model_validate(value)
except ValidationError:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of future-proofing fallback isn't present for any other model in the client, so unsure how I feel about it - catching client bugs is good and having a defined shape makes using it much easier. But on the other hand we can catch bugs using tests. What do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I agree with the principle in general but would defend it here.
I added this fallback so in some case where something changed in datamasque, say a new kind was added, and dm-python wasn't updated then falling back wouldn't cause the discovery run to crash.
In my opinion this is important so a change in SDP doesn't crash discovery runs since there's nothing pinning the client and servers together currently.
However happy to change it if I'm wrong.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After looking into it further have concluded that it's not as bad as I thought if a run fails here since discovery runs are owned inside DM itself. Therefore, will get rid of the UnknownPreview entirely since the shape should be always known.

Would be good, in the future, to add some sort of compatibility check/matrix between DM and dm-python.

Comment thread tests/test_discovery.py Outdated
}


def test_schema_discovery_request_model_dump_includes_safe_data_preview():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of several tests that don't add any value. This is just testing pydantic's behaviour. If you want to test this, at least call the API method that sends the SD request and check the request body (or fold into one of the existing tests that does that).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Dropped.

Comment thread tests/test_discovery.py Outdated
assert preview.statistics_common.count_distinct == 988


def test_schema_discovery_result_without_safe_data_preview():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Borderline not worth it (again you're testing that the default is None, which it is because we can see it right there - no actual logic tested, except for the bit where the validator tolerates and spits out None when given None).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed. Good spotting!

Comment thread tests/test_safe_data_preview.py Outdated
_assert_no_unexpected_extras(item)


def test_each_preview_parses_to_its_typed_variant():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use pytest.mark.parametrize()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

Comment thread tests/test_safe_data_preview.py Outdated
assert type(parse_safe_data_preview(_UNSUPPORTED_PREVIEW)) is UnsupportedPreview


def test_each_preview_round_trips():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests pydantic not our code, remove

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Comment thread tests/test_safe_data_preview.py Outdated
assert parse_safe_data_preview(_UNSUPPORTED_PREVIEW).model_dump(mode="json") == _UNSUPPORTED_PREVIEW


def test_each_preview_has_no_untyped_fields():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use pytest.mark.parametrize

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Changed.

Comment thread tests/test_safe_data_preview.py Outdated
assert preview.statistics_kind.reason == "Binary data isn't previewed"


def test_none_passes_through():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already tested by the one I flagged earlier, remove one of them

@ClassicMMT ClassicMMT Jul 20, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Combined all tests testing null behaviour into one with pytest.mark.parametrize. Also removed one since it was testing the same arm.

Comment thread tests/test_safe_data_preview.py Outdated
assert preview.statistics_common.count_null == 0


def test_unparseable_payload_falls_back_without_raising():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the kind of thing I was worried about with the fallback. If someone wrote some code using the library that tried to do maths on the count_row, it would just crash. We should at least ensure UnknownPreview has all fields present, typed, and with defaults if we are going to keep it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't be a problem anymore because of this.

Comment thread tests/test_safe_data_preview.py Outdated
assert preview.kind == 123


def test_non_dict_preview_is_none():

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be an error?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a problem anymore either because of this.

Comment thread HISTORY.rst Outdated
Comment on lines +10 to +13
* ``safe_data_preview`` on ``InDataDiscoveryConfig`` (via ``SafeDataPreviewOptions``)
to configure or disable the preview.
* ``safe_data_preview`` on schema-discovery result columns and file-discovery locators,
typed by ``kind``.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line length is 120

Suggested change
* ``safe_data_preview`` on ``InDataDiscoveryConfig`` (via ``SafeDataPreviewOptions``)
to configure or disable the preview.
* ``safe_data_preview`` on schema-discovery result columns and file-discovery locators,
typed by ``kind``.
* ``safe_data_preview`` on ``InDataDiscoveryConfig`` (via ``SafeDataPreviewOptions``) to configure or disable the preview.
* ``safe_data_preview`` on schema-discovery result columns and file-discovery locators, typed by ``kind``.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find. Fixed.

Comment thread tests/test_safe_data_preview.py Outdated
Comment thread datamasque/client/models/safe_data_preview.py Outdated
Comment thread datamasque/client/models/safe_data_preview.py Outdated
Comment thread datamasque/client/models/safe_data_preview.py Outdated
@ClassicMMT
ClassicMMT force-pushed the typed-safe-data-preview branch 2 times, most recently from 62e576e to 5bcf818 Compare July 19, 2026 22:44
@ClassicMMT ClassicMMT changed the title feat: Add safe data preview results Feat: Add Safe Data Preview Jul 19, 2026
Comment thread datamasque/client/models/safe_data_preview.py Outdated
@ClassicMMT
ClassicMMT force-pushed the typed-safe-data-preview branch 2 times, most recently from 799f58f to 10f2e69 Compare July 20, 2026 03:16
@ClassicMMT
ClassicMMT force-pushed the typed-safe-data-preview branch from 10f2e69 to f01e0b2 Compare July 20, 2026 20:07

@kanewilliams kanewilliams left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good on my end, conditional on @cph-datamasque's review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants