datamasque-python 1.2.3__tar.gz → 1.2.5__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.2.3 → datamasque_python-1.2.5}/HISTORY.rst +16 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/PKG-INFO +1 -1
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/connection.py +23 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/status.py +1 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/pyproject.toml +1 -1
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_connections.py +83 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/uv.lock +1 -1
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/.editorconfig +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/.github/workflows/ci.yml +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/.github/workflows/release-testpypi.yml +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/.github/workflows/release.yml +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/.gitignore +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/.readthedocs.yaml +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/CONTRIBUTING.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/LICENSE +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/MANIFEST.in +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/Makefile +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/NOTICE +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/README.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/RELEASING.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/__init__.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/base.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/connections.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/discovery.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/discovery_config_libraries.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/discovery_configs.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/dmclient.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/exceptions.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/files.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/ifm.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/license.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/__init__.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/data_selection.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/discovery.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/discovery_config.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/discovery_config_library.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/dm_instance.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/files.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/git.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/ifm.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/license.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/pagination.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/rg_config.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/ruleset.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/ruleset_library.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/runs.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/safe_data_preview.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/table_reference.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/user.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/py.typed +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/rg_configs.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/ruleset_libraries.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/rulesets.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/runs.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/settings.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/spcs.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/table_references.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/users.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/Makefile +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/client.models.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/client.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/conf.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/contributing.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/history.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/index.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/installation.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/make.bat +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/modules.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/readme.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/docs/usage.rst +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/__init__.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/conftest.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/helpers.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_base.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_discovery.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_discovery_config_libraries.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_discovery_configs.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_files.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_ifm.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_license.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_pagination.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_rg_configs.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_ruleset_library.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_rulesets.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_runs.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_safe_data_preview.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_settings.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_spcs.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_table_references.py +0 -0
- {datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_users.py +0 -0
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
History
|
|
3
3
|
=======
|
|
4
4
|
|
|
5
|
+
1.2.5 (2026-08-17)
|
|
6
|
+
------------------
|
|
7
|
+
|
|
8
|
+
* Added ``iam_role_arn`` to ``DatabaseConnectionConfig``: the IAM role DataMasque assumes to tag
|
|
9
|
+
the connection's AWS resource, for resources in another AWS account. Sent only for the engines
|
|
10
|
+
that can be an Amazon RDS instance, Aurora cluster or Redshift cluster.
|
|
11
|
+
|
|
12
|
+
Requires server version 3.26.16
|
|
13
|
+
|
|
14
|
+
1.2.4 (2026-08-12)
|
|
15
|
+
------------------
|
|
16
|
+
|
|
17
|
+
* Added ``rg_config`` to ``ValidationErrorType``, covering ruleset generation config validation errors.
|
|
18
|
+
|
|
19
|
+
Requires server version 3.26.15
|
|
20
|
+
|
|
5
21
|
1.2.3 (2026-08-12)
|
|
6
22
|
------------------
|
|
7
23
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: datamasque-python
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.5
|
|
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/
|
|
@@ -289,6 +289,22 @@ class SnowflakeConnectionConfig(ConnectionConfig):
|
|
|
289
289
|
return data
|
|
290
290
|
|
|
291
291
|
|
|
292
|
+
# Engines that can sit behind an Amazon RDS, Aurora or Redshift endpoint, and so can carry a role
|
|
293
|
+
# for DataMasque to assume when tagging the resource. Aurora needs no entry of its own: it uses
|
|
294
|
+
# these same engines with a cluster endpoint.
|
|
295
|
+
_AWS_TAGGABLE_DATABASE_TYPES = frozenset(
|
|
296
|
+
{
|
|
297
|
+
DatabaseType.postgres,
|
|
298
|
+
DatabaseType.mysql,
|
|
299
|
+
DatabaseType.mariadb,
|
|
300
|
+
DatabaseType.oracle,
|
|
301
|
+
DatabaseType.mssql,
|
|
302
|
+
DatabaseType.db2_luw,
|
|
303
|
+
DatabaseType.redshift,
|
|
304
|
+
}
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
|
|
292
308
|
class DatabaseConnectionConfig(ConnectionConfig):
|
|
293
309
|
"""
|
|
294
310
|
Connection configuration for a SQL database.
|
|
@@ -309,6 +325,11 @@ class DatabaseConnectionConfig(ConnectionConfig):
|
|
|
309
325
|
is_read_only: bool = False
|
|
310
326
|
s3_bucket_name: Optional[str] = None
|
|
311
327
|
s3_redshift_iam_role: Optional[str] = None
|
|
328
|
+
# An IAM role for DataMasque to assume when tagging this database's AWS resource after a run.
|
|
329
|
+
# Only the engines in `_AWS_TAGGABLE_DATABASE_TYPES` can be an RDS instance, Aurora cluster or
|
|
330
|
+
# Redshift cluster, so it is pruned for the rest. Distinct from `s3_redshift_iam_role`, which is
|
|
331
|
+
# the role the Redshift cluster itself uses to reach S3.
|
|
332
|
+
iam_role_arn: Optional[str] = None
|
|
312
333
|
|
|
313
334
|
@model_validator(mode="after")
|
|
314
335
|
def _reject_special_engines(self) -> "DatabaseConnectionConfig":
|
|
@@ -348,6 +369,8 @@ class DatabaseConnectionConfig(ConnectionConfig):
|
|
|
348
369
|
if db_type is not DatabaseType.redshift:
|
|
349
370
|
d.pop("s3_bucket_name", None)
|
|
350
371
|
d.pop("s3_redshift_iam_role", None)
|
|
372
|
+
if db_type not in _AWS_TAGGABLE_DATABASE_TYPES:
|
|
373
|
+
d.pop("iam_role_arn", None)
|
|
351
374
|
if not d.get("engine_options"):
|
|
352
375
|
d.pop("engine_options", None)
|
|
353
376
|
return d
|
|
@@ -20,6 +20,7 @@ class ValidationErrorType(enum.Enum):
|
|
|
20
20
|
library_missing = "library_missing"
|
|
21
21
|
library_invalid = "library_invalid"
|
|
22
22
|
expansion = "expansion" # The ruleset is not valid once its library references are expanded.
|
|
23
|
+
rg_config = "rg_config"
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
class ValidationErrorDetails(BaseModel):
|
|
@@ -1400,3 +1400,86 @@ def test_create_or_update_mongo_connection(client):
|
|
|
1400
1400
|
assert sent["db_type"] == "mongodb"
|
|
1401
1401
|
assert sent["dbpassword"] == "hunter2"
|
|
1402
1402
|
assert sent["replica_set"] == "rs0"
|
|
1403
|
+
|
|
1404
|
+
|
|
1405
|
+
def _database_connection(database_type: DatabaseType, **extra) -> DatabaseConnectionConfig:
|
|
1406
|
+
return DatabaseConnectionConfig(
|
|
1407
|
+
name="conn",
|
|
1408
|
+
host="mydb.abc123.ap-southeast-2.rds.amazonaws.com",
|
|
1409
|
+
port=5432,
|
|
1410
|
+
database="db",
|
|
1411
|
+
user="user",
|
|
1412
|
+
password="secret",
|
|
1413
|
+
database_type=database_type,
|
|
1414
|
+
**extra,
|
|
1415
|
+
)
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
@pytest.mark.parametrize(
|
|
1419
|
+
"database_type",
|
|
1420
|
+
[
|
|
1421
|
+
DatabaseType.postgres,
|
|
1422
|
+
DatabaseType.mysql,
|
|
1423
|
+
DatabaseType.mariadb,
|
|
1424
|
+
DatabaseType.oracle,
|
|
1425
|
+
DatabaseType.mssql,
|
|
1426
|
+
DatabaseType.db2_luw,
|
|
1427
|
+
DatabaseType.redshift,
|
|
1428
|
+
],
|
|
1429
|
+
)
|
|
1430
|
+
def test_database_connection_sends_tagging_iam_role_for_aws_hosted_engines(database_type):
|
|
1431
|
+
"""The engines that can sit behind an RDS, Aurora or Redshift endpoint can carry a tagging role."""
|
|
1432
|
+
extra = (
|
|
1433
|
+
{"s3_bucket_name": "bucket", "s3_redshift_iam_role": "arn:aws:iam::123456789012:role/redshift-s3"}
|
|
1434
|
+
if database_type is DatabaseType.redshift
|
|
1435
|
+
else {}
|
|
1436
|
+
)
|
|
1437
|
+
conn = _database_connection(database_type, iam_role_arn="arn:aws:iam::119836602066:role/tagger", **extra)
|
|
1438
|
+
|
|
1439
|
+
api_dict = conn.model_dump(exclude_none=True, by_alias=True, mode="json")
|
|
1440
|
+
|
|
1441
|
+
assert api_dict["iam_role_arn"] == "arn:aws:iam::119836602066:role/tagger"
|
|
1442
|
+
|
|
1443
|
+
|
|
1444
|
+
@pytest.mark.parametrize(
|
|
1445
|
+
"database_type",
|
|
1446
|
+
[
|
|
1447
|
+
DatabaseType.db2i,
|
|
1448
|
+
DatabaseType.informix,
|
|
1449
|
+
DatabaseType.saphana,
|
|
1450
|
+
# The two worth documenting rather than merely covering. `mssql_linked` inherits the field
|
|
1451
|
+
# through `MssqlLinkedServerConnectionConfig` and is excluded only by its own enum value;
|
|
1452
|
+
# `databricks_lakebase` is AWS-hosted, so it reads like an omission from the taggable set
|
|
1453
|
+
# until you know it presents no endpoint tagging can act on.
|
|
1454
|
+
DatabaseType.mssql_linked,
|
|
1455
|
+
DatabaseType.databricks_lakebase,
|
|
1456
|
+
],
|
|
1457
|
+
)
|
|
1458
|
+
def test_database_connection_omits_tagging_iam_role_for_engines_that_cannot_be_aws_resources(database_type):
|
|
1459
|
+
"""Mirrors how `s3_redshift_iam_role` is pruned: the server has no such field on these engines."""
|
|
1460
|
+
conn = _database_connection(database_type, iam_role_arn="arn:aws:iam::119836602066:role/tagger")
|
|
1461
|
+
|
|
1462
|
+
api_dict = conn.model_dump(exclude_none=True, by_alias=True, mode="json")
|
|
1463
|
+
|
|
1464
|
+
assert "iam_role_arn" not in api_dict
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
def test_database_connection_omits_tagging_iam_role_when_unset():
|
|
1468
|
+
conn = _database_connection(DatabaseType.postgres)
|
|
1469
|
+
|
|
1470
|
+
assert "iam_role_arn" not in conn.model_dump(exclude_none=True, by_alias=True, mode="json")
|
|
1471
|
+
|
|
1472
|
+
|
|
1473
|
+
def test_redshift_connection_keeps_its_cluster_s3_role_separate_from_its_tagging_role():
|
|
1474
|
+
"""Two ARNs with different meanings: the cluster's own S3 access, and the role DataMasque assumes to tag."""
|
|
1475
|
+
conn = _database_connection(
|
|
1476
|
+
DatabaseType.redshift,
|
|
1477
|
+
s3_bucket_name="bucket",
|
|
1478
|
+
s3_redshift_iam_role="arn:aws:iam::123456789012:role/redshift-s3",
|
|
1479
|
+
iam_role_arn="arn:aws:iam::119836602066:role/tagger",
|
|
1480
|
+
)
|
|
1481
|
+
|
|
1482
|
+
api_dict = conn.model_dump(exclude_none=True, by_alias=True, mode="json")
|
|
1483
|
+
|
|
1484
|
+
assert api_dict["s3_redshift_iam_role"] == "arn:aws:iam::123456789012:role/redshift-s3"
|
|
1485
|
+
assert api_dict["iam_role_arn"] == "arn:aws:iam::119836602066:role/tagger"
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/discovery_config_libraries.py
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
|
{datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/data_selection.py
RENAMED
|
File without changes
|
|
File without changes
|
{datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/discovery_config.py
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
|
{datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/ruleset_library.py
RENAMED
|
File without changes
|
|
File without changes
|
{datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/safe_data_preview.py
RENAMED
|
File without changes
|
{datamasque_python-1.2.3 → datamasque_python-1.2.5}/datamasque/client/models/table_reference.py
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datamasque_python-1.2.3 → datamasque_python-1.2.5}/tests/test_discovery_config_libraries.py
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|