datamasque-python 1.1.6__tar.gz → 1.1.8__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.
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/HISTORY.rst +19 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/PKG-INFO +1 -1
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/__init__.py +74 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/dmclient.py +2 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/connection.py +3 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/discovery.py +8 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/ruleset.py +3 -5
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/ruleset_library.py +3 -3
- datamasque_python-1.1.8/datamasque/client/models/safe_data_preview.py +282 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/status.py +13 -1
- datamasque_python-1.1.8/datamasque/client/models/table_reference.py +101 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/ruleset_libraries.py +3 -3
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/rulesets.py +2 -3
- datamasque_python-1.1.8/datamasque/client/table_references.py +144 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/pyproject.toml +1 -1
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/setup.cfg +1 -1
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_connections.py +23 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_discovery.py +20 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_ruleset_library.py +14 -11
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_rulesets.py +21 -13
- datamasque_python-1.1.8/tests/test_safe_data_preview.py +178 -0
- datamasque_python-1.1.8/tests/test_table_references.py +502 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/uv.lock +1 -1
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/.editorconfig +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/.github/workflows/ci.yml +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/.github/workflows/release-testpypi.yml +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/.github/workflows/release.yml +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/.gitignore +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/.readthedocs.yaml +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/CONTRIBUTING.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/LICENSE +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/MANIFEST.in +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/Makefile +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/NOTICE +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/README.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/base.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/connections.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/discovery.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/discovery_config_libraries.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/discovery_configs.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/exceptions.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/files.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/ifm.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/license.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/__init__.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/data_selection.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/discovery_config.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/discovery_config_library.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/dm_instance.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/files.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/git.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/ifm.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/license.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/pagination.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/runs.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/user.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/py.typed +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/runs.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/settings.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/spcs.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/users.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/Makefile +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/client.models.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/client.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/conf.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/contributing.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/history.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/index.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/installation.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/make.bat +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/modules.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/readme.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/docs/usage.rst +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/__init__.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/conftest.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/helpers.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_base.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_discovery_config_libraries.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_discovery_configs.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_files.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_ifm.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_license.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_pagination.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_runs.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_settings.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_spcs.py +0 -0
- {datamasque_python-1.1.6 → datamasque_python-1.1.8}/tests/test_users.py +0 -0
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
History
|
|
3
3
|
=======
|
|
4
4
|
|
|
5
|
+
1.1.8 (2026-07-27)
|
|
6
|
+
------------------
|
|
7
|
+
|
|
8
|
+
* Added typed Safe Data Preview support:
|
|
9
|
+
|
|
10
|
+
* ``safe_data_preview`` on ``InDataDiscoveryConfig`` (via ``SafeDataPreviewOptions``) to configure or disable it.
|
|
11
|
+
* ``safe_data_preview`` on schema-discovery result columns and file-discovery locators, typed by ``kind``.
|
|
12
|
+
|
|
13
|
+
* Added ``row_count`` to ``TableConstraints`` in schema-discovery ``table_metadata``.
|
|
14
|
+
* Added table-reference management APIs (``list_table_references``, ``create_table_reference``, and friends),
|
|
15
|
+
along with the ``TableReference`` and ``TableReferenceOptions`` models.
|
|
16
|
+
|
|
17
|
+
1.1.7 (2026-07-14)
|
|
18
|
+
------------------
|
|
19
|
+
|
|
20
|
+
* Added ``retry_writes`` to ``MongoConnectionConfig`` (default ``True``), serialized only when
|
|
21
|
+
disabled. Set it to ``False`` for AWS DocumentDB, which rejects retryable writes.
|
|
22
|
+
* Updated the validation error API on ``Ruleset`` and ``RulesetLibrary``.
|
|
23
|
+
|
|
5
24
|
1.1.6 (2026-07-13)
|
|
6
25
|
------------------
|
|
7
26
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datamasque-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.8
|
|
4
4
|
Summary: Official Python client for the DataMasque data-masking API.
|
|
5
5
|
Project-URL: Homepage, https://datamasque.com/
|
|
6
6
|
Project-URL: Documentation, https://datamasque-python.readthedocs.io/
|
|
@@ -116,12 +116,51 @@ from datamasque.client.models.runs import (
|
|
|
116
116
|
RunInfo,
|
|
117
117
|
UnfinishedRun,
|
|
118
118
|
)
|
|
119
|
+
from datamasque.client.models.safe_data_preview import (
|
|
120
|
+
BooleanPreview,
|
|
121
|
+
BooleanStatistics,
|
|
122
|
+
ColumnKind,
|
|
123
|
+
ColumnPreview,
|
|
124
|
+
CommonStatistics,
|
|
125
|
+
FirstCharsStatistics,
|
|
126
|
+
LengthEntry,
|
|
127
|
+
LengthsStatistics,
|
|
128
|
+
MaskedFormEntry,
|
|
129
|
+
NumericBin,
|
|
130
|
+
NumericHistograms,
|
|
131
|
+
NumericPreview,
|
|
132
|
+
NumericStatistics,
|
|
133
|
+
NumericSummaries,
|
|
134
|
+
NumericTemporalDisclosureLevel,
|
|
135
|
+
PatternComposition,
|
|
136
|
+
PatternEntry,
|
|
137
|
+
PatternsStatistics,
|
|
138
|
+
SafeDataPreview,
|
|
139
|
+
SafeDataPreviewOptions,
|
|
140
|
+
StringDisclosureLevel,
|
|
141
|
+
StringPreview,
|
|
142
|
+
StringStatistics,
|
|
143
|
+
TemporalBin,
|
|
144
|
+
TemporalHistograms,
|
|
145
|
+
TemporalPreview,
|
|
146
|
+
TemporalStatistics,
|
|
147
|
+
TemporalSummaries,
|
|
148
|
+
UnsupportedPreview,
|
|
149
|
+
UnsupportedStatistics,
|
|
150
|
+
)
|
|
119
151
|
from datamasque.client.models.status import (
|
|
120
152
|
AsyncRulesetGenerationTaskStatus,
|
|
121
153
|
MaskingRunStatus,
|
|
154
|
+
ValidationErrorDetails,
|
|
122
155
|
ValidationErrorType,
|
|
123
156
|
ValidationStatus,
|
|
124
157
|
)
|
|
158
|
+
from datamasque.client.models.table_reference import (
|
|
159
|
+
TableReference,
|
|
160
|
+
TableReferenceFormat,
|
|
161
|
+
TableReferenceId,
|
|
162
|
+
TableReferenceOptions,
|
|
163
|
+
)
|
|
125
164
|
from datamasque.client.models.user import User, UserId, UserRole
|
|
126
165
|
|
|
127
166
|
__version__ = version("datamasque-python")
|
|
@@ -130,6 +169,11 @@ __all__ = [
|
|
|
130
169
|
"AsyncRulesetGenerationInProgressError",
|
|
131
170
|
"AsyncRulesetGenerationTaskStatus",
|
|
132
171
|
"AzureConnectionConfig",
|
|
172
|
+
"BooleanPreview",
|
|
173
|
+
"BooleanStatistics",
|
|
174
|
+
"ColumnKind",
|
|
175
|
+
"ColumnPreview",
|
|
176
|
+
"CommonStatistics",
|
|
133
177
|
"ConnectionConfig",
|
|
134
178
|
"ConnectionId",
|
|
135
179
|
"ConstraintColumns",
|
|
@@ -170,6 +214,7 @@ __all__ = [
|
|
|
170
214
|
"FileId",
|
|
171
215
|
"FileOrContent",
|
|
172
216
|
"FileRulesetGenerationRequest",
|
|
217
|
+
"FirstCharsStatistics",
|
|
173
218
|
"ForeignKeyRef",
|
|
174
219
|
"GitSnapshot",
|
|
175
220
|
"HashColumnsTableConfig",
|
|
@@ -185,16 +230,28 @@ __all__ = [
|
|
|
185
230
|
"InvalidLibraryError",
|
|
186
231
|
"InvalidRulesetError",
|
|
187
232
|
"JsonPath",
|
|
233
|
+
"LengthEntry",
|
|
234
|
+
"LengthsStatistics",
|
|
188
235
|
"LicenseInfo",
|
|
189
236
|
"Locator",
|
|
190
237
|
"MaskType",
|
|
238
|
+
"MaskedFormEntry",
|
|
191
239
|
"MaskingRunOptions",
|
|
192
240
|
"MaskingRunRequest",
|
|
193
241
|
"MaskingRunStatus",
|
|
194
242
|
"MongoConnectionConfig",
|
|
195
243
|
"MountedShareConnectionConfig",
|
|
196
244
|
"MssqlLinkedServerConnectionConfig",
|
|
245
|
+
"NumericBin",
|
|
246
|
+
"NumericHistograms",
|
|
247
|
+
"NumericPreview",
|
|
248
|
+
"NumericStatistics",
|
|
249
|
+
"NumericSummaries",
|
|
250
|
+
"NumericTemporalDisclosureLevel",
|
|
197
251
|
"OracleWalletFile",
|
|
252
|
+
"PatternComposition",
|
|
253
|
+
"PatternEntry",
|
|
254
|
+
"PatternsStatistics",
|
|
198
255
|
"ReferencingForeignKey",
|
|
199
256
|
"Ruleset",
|
|
200
257
|
"RulesetGenerationRequest",
|
|
@@ -212,6 +269,8 @@ __all__ = [
|
|
|
212
269
|
"RunInfo",
|
|
213
270
|
"RunNotCancellableError",
|
|
214
271
|
"S3ConnectionConfig",
|
|
272
|
+
"SafeDataPreview",
|
|
273
|
+
"SafeDataPreviewOptions",
|
|
215
274
|
"SchemaDiscoveryColumn",
|
|
216
275
|
"SchemaDiscoveryFromConfigRequest",
|
|
217
276
|
"SchemaDiscoveryPage",
|
|
@@ -227,13 +286,28 @@ __all__ = [
|
|
|
227
286
|
"SseConfig",
|
|
228
287
|
"SseSelection",
|
|
229
288
|
"SslZipFile",
|
|
289
|
+
"StringDisclosureLevel",
|
|
290
|
+
"StringPreview",
|
|
291
|
+
"StringStatistics",
|
|
230
292
|
"SwitchableLicenseMetadata",
|
|
231
293
|
"TableConstraints",
|
|
294
|
+
"TableReference",
|
|
295
|
+
"TableReferenceFormat",
|
|
296
|
+
"TableReferenceId",
|
|
297
|
+
"TableReferenceOptions",
|
|
298
|
+
"TemporalBin",
|
|
299
|
+
"TemporalHistograms",
|
|
300
|
+
"TemporalPreview",
|
|
301
|
+
"TemporalStatistics",
|
|
302
|
+
"TemporalSummaries",
|
|
232
303
|
"UnfinishedRun",
|
|
304
|
+
"UnsupportedPreview",
|
|
305
|
+
"UnsupportedStatistics",
|
|
233
306
|
"User",
|
|
234
307
|
"UserId",
|
|
235
308
|
"UserRole",
|
|
236
309
|
"UserSelection",
|
|
310
|
+
"ValidationErrorDetails",
|
|
237
311
|
"ValidationErrorType",
|
|
238
312
|
"ValidationStatus",
|
|
239
313
|
]
|
|
@@ -9,6 +9,7 @@ from datamasque.client.ruleset_libraries import RulesetLibraryClient
|
|
|
9
9
|
from datamasque.client.rulesets import RulesetClient
|
|
10
10
|
from datamasque.client.runs import RunClient
|
|
11
11
|
from datamasque.client.settings import SettingsClient
|
|
12
|
+
from datamasque.client.table_references import TableReferenceClient
|
|
12
13
|
from datamasque.client.users import UserClient
|
|
13
14
|
|
|
14
15
|
__all__ = ["DataMasqueClient", "FileOrContent", "UploadFile"]
|
|
@@ -24,6 +25,7 @@ class DataMasqueClient(
|
|
|
24
25
|
DiscoveryClient,
|
|
25
26
|
DiscoveryConfigClient,
|
|
26
27
|
DiscoveryConfigLibraryClient,
|
|
28
|
+
TableReferenceClient,
|
|
27
29
|
UserClient,
|
|
28
30
|
SettingsClient,
|
|
29
31
|
):
|
|
@@ -166,6 +166,7 @@ class MongoConnectionConfig(ConnectionConfig):
|
|
|
166
166
|
tls_ca_file: str = ""
|
|
167
167
|
tls_allow_invalid_certificates: bool = False
|
|
168
168
|
direct_connection: bool = False
|
|
169
|
+
retry_writes: bool = True
|
|
169
170
|
replica_set: str = ""
|
|
170
171
|
is_read_only: bool = False
|
|
171
172
|
|
|
@@ -194,6 +195,8 @@ class MongoConnectionConfig(ConnectionConfig):
|
|
|
194
195
|
d.pop("tls_allow_invalid_certificates", None)
|
|
195
196
|
if not d.get("direct_connection"):
|
|
196
197
|
d.pop("direct_connection", None)
|
|
198
|
+
if d.get("retry_writes", True):
|
|
199
|
+
d.pop("retry_writes", None)
|
|
197
200
|
if not d.get("replica_set"):
|
|
198
201
|
d.pop("replica_set", None)
|
|
199
202
|
if not d.get("user"):
|
|
@@ -10,6 +10,10 @@ from datamasque.client.models.data_selection import HashColumnsTableConfig, Loca
|
|
|
10
10
|
from datamasque.client.models.discovery_config import DiscoveryConfig, DiscoveryConfigId, unwrap_discovery_config_id
|
|
11
11
|
from datamasque.client.models.pagination import Page
|
|
12
12
|
from datamasque.client.models.runs import RunConnectionRef
|
|
13
|
+
from datamasque.client.models.safe_data_preview import (
|
|
14
|
+
SafeDataPreview,
|
|
15
|
+
SafeDataPreviewOptions,
|
|
16
|
+
)
|
|
13
17
|
|
|
14
18
|
|
|
15
19
|
class InDataDiscoveryRule(BaseModel):
|
|
@@ -32,6 +36,7 @@ class InDataDiscoveryConfig(BaseModel):
|
|
|
32
36
|
non_sensitive_rules: Optional[list[InDataDiscoveryRule]] = None
|
|
33
37
|
ignore_rules: Optional[list[InDataDiscoveryRule]] = None
|
|
34
38
|
force: Optional[bool] = None
|
|
39
|
+
safe_data_preview: Optional[SafeDataPreviewOptions] = None
|
|
35
40
|
|
|
36
41
|
|
|
37
42
|
class SchemaDiscoveryRequest(BaseModel):
|
|
@@ -294,6 +299,7 @@ class SchemaDiscoveryColumn(BaseModel):
|
|
|
294
299
|
unique_index_names: list[str]
|
|
295
300
|
referencing_foreign_keys: list[ReferencingForeignKey]
|
|
296
301
|
constraint: str # Primary or Unique, or empty string if column does not participate in a PK/UK
|
|
302
|
+
safe_data_preview: Optional[SafeDataPreview] = None
|
|
297
303
|
|
|
298
304
|
|
|
299
305
|
class SchemaDiscoveryResult(BaseModel):
|
|
@@ -324,6 +330,7 @@ class TableConstraints(BaseModel):
|
|
|
324
330
|
primary_keys: Optional[list[ConstraintColumns]] = None
|
|
325
331
|
unique_keys: Optional[list[ConstraintColumns]] = None
|
|
326
332
|
foreign_keys: Optional[list[ConstraintColumns]] = None
|
|
333
|
+
row_count: Optional[int] = None
|
|
327
334
|
|
|
328
335
|
|
|
329
336
|
class SchemaDiscoveryPage(Page[SchemaDiscoveryResult]):
|
|
@@ -356,6 +363,7 @@ class FileDiscoveryLocatorResult(BaseModel):
|
|
|
356
363
|
locator: Locator
|
|
357
364
|
matches: list[FileDiscoveryMatch]
|
|
358
365
|
data_types: list[str]
|
|
366
|
+
safe_data_preview: Optional[SafeDataPreview] = None
|
|
359
367
|
|
|
360
368
|
|
|
361
369
|
class FileDiscoveryFile(BaseModel):
|
|
@@ -4,7 +4,7 @@ from typing import Any, NewType, Optional
|
|
|
4
4
|
from pydantic import Field
|
|
5
5
|
|
|
6
6
|
from datamasque.client.models.git import GitTrackedEntity
|
|
7
|
-
from datamasque.client.models.status import
|
|
7
|
+
from datamasque.client.models.status import ValidationErrorDetails, ValidationStatus
|
|
8
8
|
|
|
9
9
|
RulesetId = NewType("RulesetId", str)
|
|
10
10
|
|
|
@@ -44,7 +44,5 @@ class Ruleset(GitTrackedEntity):
|
|
|
44
44
|
# Server-populated read-only fields, excluded from request bodies.
|
|
45
45
|
id: Optional[RulesetId] = Field(default=None, exclude=True)
|
|
46
46
|
is_valid: Optional[ValidationStatus] = Field(default=None, exclude=True)
|
|
47
|
-
|
|
48
|
-
"""
|
|
49
|
-
validation_error_type: Optional[ValidationErrorType] = Field(default=None, exclude=True)
|
|
50
|
-
"""Category of the validation failure, or `None` when valid."""
|
|
47
|
+
validation_errors: list[ValidationErrorDetails] = Field(default_factory=list, exclude=True)
|
|
48
|
+
"""Validation errors surfaced by the server; empty when valid."""
|
{datamasque_python-1.1.6 → datamasque_python-1.1.8}/datamasque/client/models/ruleset_library.py
RENAMED
|
@@ -4,7 +4,7 @@ from typing import NewType, Optional
|
|
|
4
4
|
from pydantic import Field
|
|
5
5
|
|
|
6
6
|
from datamasque.client.models.git import GitTrackedEntity
|
|
7
|
-
from datamasque.client.models.status import ValidationStatus
|
|
7
|
+
from datamasque.client.models.status import ValidationErrorDetails, ValidationStatus
|
|
8
8
|
|
|
9
9
|
RulesetLibraryId = NewType("RulesetLibraryId", str)
|
|
10
10
|
|
|
@@ -19,7 +19,7 @@ class RulesetLibrary(GitTrackedEntity):
|
|
|
19
19
|
# Server-populated read-only fields, excluded from request bodies.
|
|
20
20
|
id: Optional[RulesetLibraryId] = Field(default=None, exclude=True)
|
|
21
21
|
is_valid: Optional[ValidationStatus] = Field(default=None, exclude=True)
|
|
22
|
-
|
|
23
|
-
"""
|
|
22
|
+
validation_errors: list[ValidationErrorDetails] = Field(default_factory=list, exclude=True)
|
|
23
|
+
"""Validation errors surfaced by the server; empty when valid."""
|
|
24
24
|
created: Optional[datetime] = Field(default=None, exclude=True)
|
|
25
25
|
modified: Optional[datetime] = Field(default=None, exclude=True)
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"""Typed request and response shapes for Safe Data Preview, part of In-Data Discovery."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
from typing import Annotated, Literal, Optional, Union
|
|
5
|
+
|
|
6
|
+
from pydantic import (
|
|
7
|
+
BaseModel,
|
|
8
|
+
ConfigDict,
|
|
9
|
+
Field,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class StringDisclosureLevel(Enum):
|
|
14
|
+
"""How much detail a string Safe Data Preview reveals."""
|
|
15
|
+
|
|
16
|
+
lengths = "lengths"
|
|
17
|
+
patterns = "patterns"
|
|
18
|
+
first_chars = "first_chars"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class NumericTemporalDisclosureLevel(Enum):
|
|
22
|
+
"""How much detail a numeric or temporal Safe Data Preview reveals."""
|
|
23
|
+
|
|
24
|
+
summaries = "summaries"
|
|
25
|
+
histograms = "histograms"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class SafeDataPreviewOptions(BaseModel):
|
|
29
|
+
"""Configures whether Safe Data Preview runs and how much detail each column reveals."""
|
|
30
|
+
|
|
31
|
+
model_config = ConfigDict(extra="forbid")
|
|
32
|
+
|
|
33
|
+
enabled: Optional[bool] = None
|
|
34
|
+
min_group_size: Optional[int] = None
|
|
35
|
+
string_level: Optional[StringDisclosureLevel] = None
|
|
36
|
+
numeric_level: Optional[NumericTemporalDisclosureLevel] = None
|
|
37
|
+
temporal_level: Optional[NumericTemporalDisclosureLevel] = None
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ColumnKind(str, Enum):
|
|
41
|
+
"""Which shape a column's Safe Data Preview takes."""
|
|
42
|
+
|
|
43
|
+
boolean = "boolean"
|
|
44
|
+
numeric = "numeric"
|
|
45
|
+
string = "string"
|
|
46
|
+
temporal = "temporal"
|
|
47
|
+
unsupported = "unsupported"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class CommonStatistics(BaseModel):
|
|
51
|
+
"""Row counts shared by every preview kind."""
|
|
52
|
+
|
|
53
|
+
model_config = ConfigDict(extra="allow")
|
|
54
|
+
|
|
55
|
+
count_row: int
|
|
56
|
+
count_null: int
|
|
57
|
+
count_distinct: Optional[int] = None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class LengthEntry(BaseModel):
|
|
61
|
+
"""A value length and how many sampled rows had it."""
|
|
62
|
+
|
|
63
|
+
model_config = ConfigDict(extra="allow")
|
|
64
|
+
|
|
65
|
+
length: int
|
|
66
|
+
count: int
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class LengthsStatistics(BaseModel):
|
|
70
|
+
"""Distribution of value lengths."""
|
|
71
|
+
|
|
72
|
+
model_config = ConfigDict(extra="allow")
|
|
73
|
+
|
|
74
|
+
min: int
|
|
75
|
+
max: int
|
|
76
|
+
mean: float
|
|
77
|
+
median: float
|
|
78
|
+
most_common: list[LengthEntry]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class PatternEntry(BaseModel):
|
|
82
|
+
"""A masked character pattern and how many sampled rows matched it."""
|
|
83
|
+
|
|
84
|
+
model_config = ConfigDict(extra="allow")
|
|
85
|
+
|
|
86
|
+
pattern: str
|
|
87
|
+
count: int
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class PatternComposition(BaseModel):
|
|
91
|
+
"""The proportion of letter, digit, and other characters across sampled values."""
|
|
92
|
+
|
|
93
|
+
model_config = ConfigDict(extra="allow")
|
|
94
|
+
|
|
95
|
+
letter: float
|
|
96
|
+
digit: float
|
|
97
|
+
other: float
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class PatternsStatistics(BaseModel):
|
|
101
|
+
"""The most common character patterns and the overall character composition."""
|
|
102
|
+
|
|
103
|
+
model_config = ConfigDict(extra="allow")
|
|
104
|
+
|
|
105
|
+
top: list[PatternEntry]
|
|
106
|
+
composition: PatternComposition
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class MaskedFormEntry(BaseModel):
|
|
110
|
+
"""A masked leading form of a value and how many sampled rows had it."""
|
|
111
|
+
|
|
112
|
+
model_config = ConfigDict(extra="allow")
|
|
113
|
+
|
|
114
|
+
masked: str
|
|
115
|
+
count: int
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class FirstCharsStatistics(BaseModel):
|
|
119
|
+
"""The most common masked leading forms."""
|
|
120
|
+
|
|
121
|
+
model_config = ConfigDict(extra="allow")
|
|
122
|
+
|
|
123
|
+
top: list[MaskedFormEntry]
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class StringStatistics(BaseModel):
|
|
127
|
+
"""String preview statistics; `patterns`/`first_chars` appear at or above certain disclosure levels."""
|
|
128
|
+
|
|
129
|
+
model_config = ConfigDict(extra="allow")
|
|
130
|
+
|
|
131
|
+
lengths: LengthsStatistics
|
|
132
|
+
patterns: Optional[PatternsStatistics] = None
|
|
133
|
+
first_chars: Optional[FirstCharsStatistics] = None
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class NumericSummaries(BaseModel):
|
|
137
|
+
"""Numeric mean and percentile summary."""
|
|
138
|
+
|
|
139
|
+
model_config = ConfigDict(extra="allow")
|
|
140
|
+
|
|
141
|
+
mean: float
|
|
142
|
+
q1: float
|
|
143
|
+
q2: float
|
|
144
|
+
q3: float
|
|
145
|
+
p5: float
|
|
146
|
+
p95: float
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class NumericBin(BaseModel):
|
|
150
|
+
"""One half-open interval `[lower_bound, upper_bound)` of a numeric histogram and its row count."""
|
|
151
|
+
|
|
152
|
+
model_config = ConfigDict(extra="allow")
|
|
153
|
+
|
|
154
|
+
lower_bound: float
|
|
155
|
+
upper_bound: float
|
|
156
|
+
count: int
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class NumericHistograms(BaseModel):
|
|
160
|
+
"""The bins of a numeric histogram."""
|
|
161
|
+
|
|
162
|
+
model_config = ConfigDict(extra="allow")
|
|
163
|
+
|
|
164
|
+
bins: list[NumericBin]
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
class NumericStatistics(BaseModel):
|
|
168
|
+
"""Numeric preview statistics; `histograms` is present only at the histogram disclosure level."""
|
|
169
|
+
|
|
170
|
+
model_config = ConfigDict(extra="allow")
|
|
171
|
+
|
|
172
|
+
summaries: NumericSummaries
|
|
173
|
+
histograms: Optional[NumericHistograms] = None
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class TemporalSummaries(BaseModel):
|
|
177
|
+
"""Temporal mean and percentile summary, each an ISO-formatted string."""
|
|
178
|
+
|
|
179
|
+
model_config = ConfigDict(extra="allow")
|
|
180
|
+
|
|
181
|
+
mean: str
|
|
182
|
+
q1: str
|
|
183
|
+
q2: str
|
|
184
|
+
q3: str
|
|
185
|
+
p5: str
|
|
186
|
+
p95: str
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class TemporalBin(BaseModel):
|
|
190
|
+
"""One interval of a temporal histogram, with ISO-formatted bounds and a human-readable label."""
|
|
191
|
+
|
|
192
|
+
model_config = ConfigDict(extra="allow")
|
|
193
|
+
|
|
194
|
+
lower_bound: str
|
|
195
|
+
upper_bound: str
|
|
196
|
+
label: str
|
|
197
|
+
count: int
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
class TemporalHistograms(BaseModel):
|
|
201
|
+
"""The bins of a temporal histogram."""
|
|
202
|
+
|
|
203
|
+
model_config = ConfigDict(extra="allow")
|
|
204
|
+
|
|
205
|
+
bins: list[TemporalBin]
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class TemporalStatistics(BaseModel):
|
|
209
|
+
"""Temporal preview statistics; `histograms` is present only at the histogram disclosure level."""
|
|
210
|
+
|
|
211
|
+
model_config = ConfigDict(extra="allow")
|
|
212
|
+
|
|
213
|
+
summaries: TemporalSummaries
|
|
214
|
+
histograms: Optional[TemporalHistograms] = None
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class BooleanStatistics(BaseModel):
|
|
218
|
+
"""Counts of true and false values."""
|
|
219
|
+
|
|
220
|
+
model_config = ConfigDict(extra="allow")
|
|
221
|
+
|
|
222
|
+
count_true: int
|
|
223
|
+
count_false: int
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class UnsupportedStatistics(BaseModel):
|
|
227
|
+
"""Why a column could not be previewed."""
|
|
228
|
+
|
|
229
|
+
model_config = ConfigDict(extra="allow")
|
|
230
|
+
|
|
231
|
+
reason: str
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class ColumnPreview(BaseModel):
|
|
235
|
+
"""Fields present on every Safe Data Preview."""
|
|
236
|
+
|
|
237
|
+
model_config = ConfigDict(extra="allow")
|
|
238
|
+
|
|
239
|
+
# For grouped file discovery, the file whose sample produced this preview; None for database columns.
|
|
240
|
+
sampled_from: Optional[str] = None
|
|
241
|
+
statistics_common: CommonStatistics
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class StringPreview(ColumnPreview):
|
|
245
|
+
"""A preview of a string column."""
|
|
246
|
+
|
|
247
|
+
kind: Literal[ColumnKind.string] = ColumnKind.string
|
|
248
|
+
statistics_kind: StringStatistics
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class NumericPreview(ColumnPreview):
|
|
252
|
+
"""A preview of a numeric column."""
|
|
253
|
+
|
|
254
|
+
kind: Literal[ColumnKind.numeric] = ColumnKind.numeric
|
|
255
|
+
statistics_kind: NumericStatistics
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class TemporalPreview(ColumnPreview):
|
|
259
|
+
"""A preview of a date/time column."""
|
|
260
|
+
|
|
261
|
+
kind: Literal[ColumnKind.temporal] = ColumnKind.temporal
|
|
262
|
+
statistics_kind: TemporalStatistics
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class BooleanPreview(ColumnPreview):
|
|
266
|
+
"""A preview of a boolean column."""
|
|
267
|
+
|
|
268
|
+
kind: Literal[ColumnKind.boolean] = ColumnKind.boolean
|
|
269
|
+
statistics_kind: BooleanStatistics
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class UnsupportedPreview(ColumnPreview):
|
|
273
|
+
"""A column the preview ran against but declined; `statistics_kind.reason` says why."""
|
|
274
|
+
|
|
275
|
+
kind: Literal[ColumnKind.unsupported] = ColumnKind.unsupported
|
|
276
|
+
statistics_kind: UnsupportedStatistics
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
SafeDataPreview = Annotated[
|
|
280
|
+
Union[StringPreview, NumericPreview, TemporalPreview, BooleanPreview, UnsupportedPreview],
|
|
281
|
+
Field(discriminator="kind"),
|
|
282
|
+
]
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import enum
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from pydantic import BaseModel
|
|
2
5
|
|
|
3
6
|
|
|
4
7
|
class ValidationStatus(enum.Enum):
|
|
@@ -11,7 +14,7 @@ class ValidationStatus(enum.Enum):
|
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
class ValidationErrorType(enum.Enum):
|
|
14
|
-
"""Categorises why
|
|
17
|
+
"""Categorises why validation failed (see `ValidationErrorDetails.validation_error_type`)."""
|
|
15
18
|
|
|
16
19
|
ruleset = "ruleset"
|
|
17
20
|
library_missing = "library_missing"
|
|
@@ -19,6 +22,15 @@ class ValidationErrorType(enum.Enum):
|
|
|
19
22
|
expansion = "expansion" # The ruleset is not valid once its library references are expanded.
|
|
20
23
|
|
|
21
24
|
|
|
25
|
+
class ValidationErrorDetails(BaseModel):
|
|
26
|
+
"""A single validation error, with its position in the YAML when available."""
|
|
27
|
+
|
|
28
|
+
message: str
|
|
29
|
+
validation_error_type: Optional[ValidationErrorType] = None
|
|
30
|
+
line_number: Optional[int] = None
|
|
31
|
+
column_number: Optional[int] = None
|
|
32
|
+
|
|
33
|
+
|
|
22
34
|
class MaskingRunStatus(enum.Enum):
|
|
23
35
|
"""List of valid masking run statuses."""
|
|
24
36
|
|