datamasque-python 1.0.2__tar.gz → 1.0.3__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.
Files changed (73) hide show
  1. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/HISTORY.rst +6 -0
  2. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/PKG-INFO +1 -1
  3. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/__init__.py +2 -2
  4. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/connection.py +27 -6
  5. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/pyproject.toml +1 -1
  6. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/setup.cfg +1 -1
  7. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_connections.py +46 -42
  8. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/uv.lock +1 -1
  9. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/.editorconfig +0 -0
  10. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/.github/workflows/ci.yml +0 -0
  11. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/.github/workflows/release-testpypi.yml +0 -0
  12. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/.github/workflows/release.yml +0 -0
  13. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/.gitignore +0 -0
  14. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/.readthedocs.yaml +0 -0
  15. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/CONTRIBUTING.rst +0 -0
  16. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/LICENSE +0 -0
  17. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/MANIFEST.in +0 -0
  18. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/Makefile +0 -0
  19. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/NOTICE +0 -0
  20. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/README.rst +0 -0
  21. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/base.py +0 -0
  22. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/connections.py +0 -0
  23. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/discovery.py +0 -0
  24. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/dmclient.py +0 -0
  25. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/exceptions.py +0 -0
  26. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/files.py +0 -0
  27. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/ifm.py +0 -0
  28. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/license.py +0 -0
  29. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/__init__.py +0 -0
  30. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/data_selection.py +0 -0
  31. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/discovery.py +0 -0
  32. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/dm_instance.py +0 -0
  33. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/files.py +0 -0
  34. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/ifm.py +0 -0
  35. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/license.py +0 -0
  36. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/pagination.py +0 -0
  37. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/ruleset.py +0 -0
  38. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/ruleset_library.py +0 -0
  39. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/runs.py +0 -0
  40. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/status.py +0 -0
  41. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/models/user.py +0 -0
  42. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/py.typed +0 -0
  43. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/ruleset_libraries.py +0 -0
  44. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/rulesets.py +0 -0
  45. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/runs.py +0 -0
  46. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/settings.py +0 -0
  47. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/datamasque/client/users.py +0 -0
  48. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/Makefile +0 -0
  49. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/client.models.rst +0 -0
  50. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/client.rst +0 -0
  51. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/conf.py +0 -0
  52. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/contributing.rst +0 -0
  53. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/history.rst +0 -0
  54. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/index.rst +0 -0
  55. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/installation.rst +0 -0
  56. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/make.bat +0 -0
  57. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/modules.rst +0 -0
  58. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/readme.rst +0 -0
  59. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/docs/usage.rst +0 -0
  60. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/__init__.py +0 -0
  61. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/conftest.py +0 -0
  62. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/helpers.py +0 -0
  63. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_base.py +0 -0
  64. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_discovery.py +0 -0
  65. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_files.py +0 -0
  66. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_ifm.py +0 -0
  67. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_license.py +0 -0
  68. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_pagination.py +0 -0
  69. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_ruleset_library.py +0 -0
  70. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_rulesets.py +0 -0
  71. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_runs.py +0 -0
  72. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_settings.py +0 -0
  73. {datamasque_python-1.0.2 → datamasque_python-1.0.3}/tests/test_users.py +0 -0
@@ -2,6 +2,12 @@
2
2
  History
3
3
  =======
4
4
 
5
+ 1.0.3 (2026-05-27)
6
+ ------------------
7
+
8
+ * Added ``databricks`` to ``DatabaseType`` enum.
9
+ * Removed ``DatabricksDeltaS3ConnectionConfig``.
10
+
5
11
  1.0.2 (2026-05-14)
6
12
  ------------------
7
13
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datamasque-python
3
- Version: 1.0.2
3
+ Version: 1.0.3
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/
@@ -30,7 +30,7 @@ from datamasque.client.models.connection import (
30
30
  ConnectionId,
31
31
  DatabaseConnectionConfig,
32
32
  DatabaseType,
33
- DatabricksDeltaS3ConnectionConfig,
33
+ DatabricksConnectionConfig,
34
34
  DynamoConnectionConfig,
35
35
  FileConnectionConfig,
36
36
  MongoConnectionConfig,
@@ -129,7 +129,7 @@ __all__ = [
129
129
  "DataMasqueUserError",
130
130
  "DatabaseConnectionConfig",
131
131
  "DatabaseType",
132
- "DatabricksDeltaS3ConnectionConfig",
132
+ "DatabricksConnectionConfig",
133
133
  "DiscoveryMatch",
134
134
  "DynamoConnectionConfig",
135
135
  "FailedToStartError",
@@ -45,6 +45,7 @@ class DatabaseType(Enum):
45
45
  snowflake = "snowflake"
46
46
  mongodb = "mongodb"
47
47
  databricks_lakebase = "databricks_lakebase"
48
+ databricks = "databricks"
48
49
 
49
50
 
50
51
  class SnowflakeStageLocation(str, Enum):
@@ -280,6 +281,8 @@ class DatabaseConnectionConfig(ConnectionConfig):
280
281
  raise ValueError("For Snowflake, use the SnowflakeConnectionConfig class instead")
281
282
  if self.database_type is DatabaseType.mongodb:
282
283
  raise ValueError("For MongoDB, use the MongoConnectionConfig class instead")
284
+ if self.database_type is DatabaseType.databricks:
285
+ raise ValueError("For Databricks SQL Warehouse, use the DatabricksConnectionConfig class instead")
283
286
  return self
284
287
 
285
288
  mask_type: Literal["database"] = "database"
@@ -391,19 +394,36 @@ class MountedShareConnectionConfig(FileConnectionConfig):
391
394
  type: Literal["mounted_share_connection"] = "mounted_share_connection"
392
395
 
393
396
 
394
- class DatabricksDeltaS3ConnectionConfig(FileConnectionConfig):
395
- """Connection configuration for Databricks Delta tables stored in S3."""
397
+ class DatabricksConnectionConfig(ConnectionConfig):
398
+ """Connection configuration for a Databricks SQL Warehouse."""
396
399
 
397
- type: Literal["databricks_delta_s3_connection"] = "databricks_delta_s3_connection"
398
- bucket: str = ""
399
- iam_role_arn: Optional[str] = None
400
+ server_hostname: str
401
+ http_path: str
402
+ access_token: Optional[str] = None
403
+ catalog: str
404
+ db_schema: Optional[str] = Field(default=None, alias="schema")
405
+ is_read_only: bool = False
406
+ version: str = "1.0"
407
+
408
+ mask_type: Literal["database"] = "database"
409
+ db_type: Literal["databricks"] = "databricks"
410
+
411
+ @property
412
+ def database_type(self) -> DatabaseType:
413
+ return DatabaseType.databricks
414
+
415
+ @model_validator(mode="before")
416
+ @classmethod
417
+ def _strip_encrypted_token(cls, data: dict) -> dict:
418
+ if isinstance(data, dict):
419
+ data.pop("access_token_encrypted", None)
420
+ return data
400
421
 
401
422
 
402
423
  FILE_TYPE_MAP: dict[str, type[FileConnectionConfig]] = {
403
424
  "s3_connection": S3ConnectionConfig,
404
425
  "azure_blob_connection": AzureConnectionConfig,
405
426
  "mounted_share_connection": MountedShareConnectionConfig,
406
- "databricks_delta_s3_connection": DatabricksDeltaS3ConnectionConfig,
407
427
  }
408
428
 
409
429
  DB_TYPE_MAP: dict[str, type[ConnectionConfig]] = {
@@ -411,6 +431,7 @@ DB_TYPE_MAP: dict[str, type[ConnectionConfig]] = {
411
431
  DatabaseType.mongodb.value: MongoConnectionConfig,
412
432
  DatabaseType.snowflake.value: SnowflakeConnectionConfig,
413
433
  DatabaseType.mssql_linked.value: MssqlLinkedServerConnectionConfig,
434
+ DatabaseType.databricks.value: DatabricksConnectionConfig,
414
435
  # others use the default `DatabaseConnectionConfig`
415
436
  }
416
437
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "datamasque-python"
3
- version = "1.0.2"
3
+ version = "1.0.3"
4
4
  description = "Official Python client for the DataMasque data-masking API."
5
5
  authors = [
6
6
  { name = "DataMasque Ltd" },
@@ -1,5 +1,5 @@
1
1
  [bumpversion]
2
- current_version = 1.0.2
2
+ current_version = 1.0.3
3
3
  commit = True
4
4
  tag = True
5
5
 
@@ -9,7 +9,7 @@ from datamasque.client.models.connection import (
9
9
  ConnectionId,
10
10
  DatabaseConnectionConfig,
11
11
  DatabaseType,
12
- DatabricksDeltaS3ConnectionConfig,
12
+ DatabricksConnectionConfig,
13
13
  DynamoConnectionConfig,
14
14
  MongoConnectionConfig,
15
15
  MountedShareConnectionConfig,
@@ -696,63 +696,67 @@ def test_s3_connection_model_validate_no_iam_role():
696
696
  assert conn.iam_role_arn is None
697
697
 
698
698
 
699
- def test_databricks_delta_s3_connection_model_validate():
699
+ def test_databricks_connection_model_validate():
700
700
  payload = {
701
- "id": "11223344-5566-7788-99aa-bbccddeeff00",
702
- "name": "delta_s3",
703
- "mask_type": "file",
704
- "type": "databricks_delta_s3_connection",
705
- "base_directory": "delta/",
706
- "is_file_mask_source": True,
707
- "is_file_mask_destination": False,
708
- "bucket": "my-delta-bucket",
709
- "iam_role_arn": "arn:aws:iam::111122223333:role/delta-role",
701
+ "id": "db-id-1",
702
+ "name": "databricks",
703
+ "mask_type": "database",
704
+ "db_type": "databricks",
705
+ "server_hostname": "adb-1234.azuredatabricks.net",
706
+ "http_path": "/sql/1.0/warehouses/abcd1234",
707
+ "access_token": "dapi1234",
708
+ "catalog": "main",
709
+ "schema": "default",
710
+ "is_read_only": False,
710
711
  }
711
712
 
712
- conn = DatabricksDeltaS3ConnectionConfig.model_validate(payload)
713
+ conn = DatabricksConnectionConfig.model_validate(payload)
713
714
 
714
- assert isinstance(conn, DatabricksDeltaS3ConnectionConfig)
715
- assert conn.id == "11223344-5566-7788-99aa-bbccddeeff00"
716
- assert conn.name == "delta_s3"
717
- assert conn.bucket == "my-delta-bucket"
718
- assert conn.base_directory == "delta/"
719
- assert conn.is_file_mask_source is True
720
- assert conn.is_file_mask_destination is False
721
- assert conn.iam_role_arn == "arn:aws:iam::111122223333:role/delta-role"
715
+ assert isinstance(conn, DatabricksConnectionConfig)
716
+ assert conn.id == "db-id-1"
717
+ assert conn.server_hostname == "adb-1234.azuredatabricks.net"
718
+ assert conn.http_path == "/sql/1.0/warehouses/abcd1234"
719
+ assert conn.access_token == "dapi1234"
720
+ assert conn.catalog == "main"
721
+ assert conn.db_schema == "default"
722
+ assert conn.database_type is DatabaseType.databricks
722
723
 
723
724
 
724
- def test_databricks_delta_s3_connection_model_validate_no_iam_role():
725
+ def test_databricks_connection_model_validate_blanks_encrypted_token():
725
726
  payload = {
726
- "id": "id-delta",
727
- "name": "delta_s3",
728
- "mask_type": "file",
729
- "type": "databricks_delta_s3_connection",
730
- "base_directory": "",
731
- "is_file_mask_source": True,
732
- "is_file_mask_destination": False,
733
- "bucket": "my-delta-bucket",
727
+ "id": "db-id-2",
728
+ "name": "databricks",
729
+ "mask_type": "database",
730
+ "db_type": "databricks",
731
+ "server_hostname": "adb-1234.azuredatabricks.net",
732
+ "http_path": "/sql/1.0/warehouses/abcd1234",
733
+ "access_token_encrypted": "some_base64_here",
734
+ "catalog": "main",
735
+ "is_read_only": False,
734
736
  }
735
737
 
736
- conn = DatabricksDeltaS3ConnectionConfig.model_validate(payload)
737
- assert conn.iam_role_arn is None
738
+ conn = DatabricksConnectionConfig.model_validate(payload)
739
+
740
+ assert isinstance(conn, DatabricksConnectionConfig)
741
+ assert conn.access_token is None
738
742
 
739
743
 
740
- def test_validate_connection_dispatches_databricks_delta_s3():
744
+ def test_validate_connection_dispatches_databricks():
741
745
  payload = {
742
- "id": "aabb-ccdd",
743
- "name": "delta",
744
- "mask_type": "file",
745
- "type": "databricks_delta_s3_connection",
746
- "base_directory": "",
747
- "is_file_mask_source": False,
748
- "is_file_mask_destination": True,
749
- "bucket": "delta-bucket",
746
+ "id": "db-id-3",
747
+ "name": "databricks",
748
+ "mask_type": "database",
749
+ "db_type": "databricks",
750
+ "server_hostname": "adb-1234.azuredatabricks.net",
751
+ "http_path": "/sql/1.0/warehouses/abcd1234",
752
+ "catalog": "main",
753
+ "is_read_only": False,
750
754
  }
751
755
 
752
756
  conn = validate_connection(payload)
753
757
 
754
- assert isinstance(conn, DatabricksDeltaS3ConnectionConfig)
755
- assert conn.bucket == "delta-bucket"
758
+ assert isinstance(conn, DatabricksConnectionConfig)
759
+ assert conn.catalog == "main"
756
760
 
757
761
 
758
762
  def test_azure_connection_model_validate_blanks_encrypted_connection_string():
@@ -428,7 +428,7 @@ toml = [
428
428
 
429
429
  [[package]]
430
430
  name = "datamasque-python"
431
- version = "1.0.2"
431
+ version = "1.0.3"
432
432
  source = { editable = "." }
433
433
  dependencies = [
434
434
  { name = "pydantic" },