datamasque-python 1.1.8__tar.gz → 1.2.0__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 (87) hide show
  1. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/HISTORY.rst +10 -0
  2. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/PKG-INFO +1 -1
  3. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/discovery_config_libraries.py +14 -26
  4. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/discovery_config_library.py +2 -4
  5. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/pyproject.toml +1 -1
  6. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/setup.cfg +1 -1
  7. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_discovery_config_libraries.py +12 -142
  8. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/uv.lock +1 -1
  9. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/.editorconfig +0 -0
  10. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/.github/workflows/ci.yml +0 -0
  11. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/.github/workflows/release-testpypi.yml +0 -0
  12. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/.github/workflows/release.yml +0 -0
  13. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/.gitignore +0 -0
  14. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/.readthedocs.yaml +0 -0
  15. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/CONTRIBUTING.rst +0 -0
  16. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/LICENSE +0 -0
  17. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/MANIFEST.in +0 -0
  18. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/Makefile +0 -0
  19. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/NOTICE +0 -0
  20. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/README.rst +0 -0
  21. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/__init__.py +0 -0
  22. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/base.py +0 -0
  23. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/connections.py +0 -0
  24. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/discovery.py +0 -0
  25. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/discovery_configs.py +0 -0
  26. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/dmclient.py +0 -0
  27. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/exceptions.py +0 -0
  28. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/files.py +0 -0
  29. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/ifm.py +0 -0
  30. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/license.py +0 -0
  31. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/__init__.py +0 -0
  32. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/connection.py +0 -0
  33. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/data_selection.py +0 -0
  34. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/discovery.py +0 -0
  35. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/discovery_config.py +0 -0
  36. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/dm_instance.py +0 -0
  37. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/files.py +0 -0
  38. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/git.py +0 -0
  39. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/ifm.py +0 -0
  40. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/license.py +0 -0
  41. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/pagination.py +0 -0
  42. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/ruleset.py +0 -0
  43. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/ruleset_library.py +0 -0
  44. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/runs.py +0 -0
  45. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/safe_data_preview.py +0 -0
  46. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/status.py +0 -0
  47. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/table_reference.py +0 -0
  48. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/models/user.py +0 -0
  49. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/py.typed +0 -0
  50. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/ruleset_libraries.py +0 -0
  51. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/rulesets.py +0 -0
  52. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/runs.py +0 -0
  53. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/settings.py +0 -0
  54. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/spcs.py +0 -0
  55. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/table_references.py +0 -0
  56. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/datamasque/client/users.py +0 -0
  57. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/Makefile +0 -0
  58. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/client.models.rst +0 -0
  59. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/client.rst +0 -0
  60. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/conf.py +0 -0
  61. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/contributing.rst +0 -0
  62. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/history.rst +0 -0
  63. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/index.rst +0 -0
  64. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/installation.rst +0 -0
  65. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/make.bat +0 -0
  66. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/modules.rst +0 -0
  67. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/readme.rst +0 -0
  68. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/docs/usage.rst +0 -0
  69. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/__init__.py +0 -0
  70. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/conftest.py +0 -0
  71. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/helpers.py +0 -0
  72. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_base.py +0 -0
  73. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_connections.py +0 -0
  74. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_discovery.py +0 -0
  75. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_discovery_configs.py +0 -0
  76. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_files.py +0 -0
  77. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_ifm.py +0 -0
  78. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_license.py +0 -0
  79. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_pagination.py +0 -0
  80. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_ruleset_library.py +0 -0
  81. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_rulesets.py +0 -0
  82. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_runs.py +0 -0
  83. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_safe_data_preview.py +0 -0
  84. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_settings.py +0 -0
  85. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_spcs.py +0 -0
  86. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_table_references.py +0 -0
  87. {datamasque_python-1.1.8 → datamasque_python-1.2.0}/tests/test_users.py +0 -0
@@ -2,6 +2,16 @@
2
2
  History
3
3
  =======
4
4
 
5
+ 1.2.0 (2026-07-27)
6
+ ------------------
7
+
8
+ * Made discovery config libraries untyped, matching the DataMasque 3.26.14 server. A single
9
+ library is now identified by ``(namespace, name)`` and may be imported by both database and
10
+ file discovery configs. **Breaking:** removed the ``config_type`` field from
11
+ ``DiscoveryConfigLibrary`` and the ``config_type`` argument from
12
+ ``get_discovery_config_library_by_name``, ``create_or_update_discovery_config_library``, and
13
+ ``delete_discovery_config_library_by_name_if_exists``. Requires a 3.26.14 or later server.
14
+
5
15
  1.1.8 (2026-07-27)
6
16
  ------------------
7
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datamasque-python
3
- Version: 1.1.8
3
+ Version: 1.2.0
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/
@@ -3,7 +3,6 @@ from typing import Optional
3
3
 
4
4
  from datamasque.client.base import BaseClient
5
5
  from datamasque.client.exceptions import DataMasqueApiError
6
- from datamasque.client.models.discovery_config import DiscoveryConfigType
7
6
  from datamasque.client.models.discovery_config_library import DiscoveryConfigLibrary, DiscoveryConfigLibraryId
8
7
 
9
8
  logger = logging.getLogger(__name__)
@@ -31,14 +30,12 @@ class DiscoveryConfigLibraryClient(BaseClient):
31
30
  response = self.make_request("GET", f"/api/discovery/config-libraries/{library_id}/")
32
31
  return DiscoveryConfigLibrary.model_validate(response.json())
33
32
 
34
- def _get_discovery_config_library_id_by_name(
35
- self, name: str, config_type: DiscoveryConfigType, namespace: str
36
- ) -> Optional[DiscoveryConfigLibraryId]:
33
+ def _get_discovery_config_library_id_by_name(self, name: str, namespace: str) -> Optional[DiscoveryConfigLibraryId]:
37
34
  """
38
- Returns the ID of the library with the given name, type, and namespace, or `None` if there is none.
35
+ Returns the ID of the library with the given name and namespace, or `None` if there is none.
39
36
 
40
37
  The listing is filtered by name to keep the response small;
41
- type and namespace are matched client-side,
38
+ the namespace is matched client-side,
42
39
  since the API's namespace filter cannot select the default (empty) namespace.
43
40
  """
44
41
 
@@ -48,11 +45,7 @@ class DiscoveryConfigLibraryClient(BaseClient):
48
45
  params={"name_exact": name},
49
46
  )
50
47
  entries = [DiscoveryConfigLibrary.model_validate(item) for item in response.json()]
51
- matches = [
52
- entry
53
- for entry in entries
54
- if entry.name == name and entry.namespace == namespace and entry.config_type is config_type
55
- ]
48
+ matches = [entry for entry in entries if entry.name == name and entry.namespace == namespace]
56
49
  if not matches:
57
50
  return None
58
51
 
@@ -64,18 +57,15 @@ class DiscoveryConfigLibraryClient(BaseClient):
64
57
 
65
58
  return matches[0].id
66
59
 
67
- def get_discovery_config_library_by_name(
68
- self, name: str, config_type: DiscoveryConfigType, namespace: str = ""
69
- ) -> Optional[DiscoveryConfigLibrary]:
60
+ def get_discovery_config_library_by_name(self, name: str, namespace: str = "") -> Optional[DiscoveryConfigLibrary]:
70
61
  """
71
- Looks for a discovery config library matching the given name, type, and namespace (case-sensitive, exact match).
62
+ Looks for a discovery config library matching the given name and namespace (case-sensitive, exact match).
72
63
 
73
- Library names are unique per type within a namespace,
74
- so a type is required to identify a single library.
64
+ Library names are unique within a namespace.
75
65
  Returns it (with full YAML content) if found, otherwise `None`.
76
66
  """
77
67
 
78
- library_id = self._get_discovery_config_library_id_by_name(name, config_type, namespace)
68
+ library_id = self._get_discovery_config_library_id_by_name(name, namespace)
79
69
  if library_id is None:
80
70
  return None
81
71
 
@@ -106,7 +96,6 @@ class DiscoveryConfigLibraryClient(BaseClient):
106
96
 
107
97
  The library must have its `id` set (i.e., it must have been previously created or retrieved from the server)
108
98
  and its `yaml` content present.
109
- A library's `config_type` is fixed at creation and cannot be changed by an update.
110
99
  """
111
100
 
112
101
  if library.id is None:
@@ -129,12 +118,12 @@ class DiscoveryConfigLibraryClient(BaseClient):
129
118
 
130
119
  def create_or_update_discovery_config_library(self, library: DiscoveryConfigLibrary) -> DiscoveryConfigLibrary:
131
120
  """
132
- Creates the library, or updates the existing one with the same name, namespace, and config type.
121
+ Creates the library, or updates the existing one with the same name and namespace.
133
122
 
134
123
  Sets the library's `id` property.
135
124
  """
136
125
 
137
- library_id = self._get_discovery_config_library_id_by_name(library.name, library.config_type, library.namespace)
126
+ library_id = self._get_discovery_config_library_id_by_name(library.name, library.namespace)
138
127
  if library_id is not None:
139
128
  library.id = library_id
140
129
  return self.update_discovery_config_library(library)
@@ -157,16 +146,15 @@ class DiscoveryConfigLibraryClient(BaseClient):
157
146
  self._delete_if_exists(f"/api/discovery/config-libraries/{library_id}/", params=params)
158
147
 
159
148
  def delete_discovery_config_library_by_name_if_exists(
160
- self, name: str, config_type: DiscoveryConfigType, namespace: str = "", *, force: bool = False
149
+ self, name: str, namespace: str = "", *, force: bool = False
161
150
  ) -> None:
162
151
  """
163
- Deletes the discovery config library with the given name, type, and namespace.
152
+ Deletes the discovery config library with the given name and namespace.
164
153
 
165
- Library names are unique per type within a namespace,
166
- so a type is required to identify a single library.
154
+ Library names are unique within a namespace.
167
155
  No-op if no such library exists.
168
156
  """
169
157
 
170
- library_id = self._get_discovery_config_library_id_by_name(name, config_type, namespace)
158
+ library_id = self._get_discovery_config_library_id_by_name(name, namespace)
171
159
  if library_id is not None:
172
160
  self.delete_discovery_config_library_by_id_if_exists(library_id, force=force)
@@ -3,7 +3,6 @@ from typing import NewType, Optional
3
3
 
4
4
  from pydantic import BaseModel, ConfigDict, Field
5
5
 
6
- from datamasque.client.models.discovery_config import DiscoveryConfigType
7
6
  from datamasque.client.models.status import ValidationStatus
8
7
 
9
8
  DiscoveryConfigLibraryId = NewType("DiscoveryConfigLibraryId", str)
@@ -13,14 +12,13 @@ class DiscoveryConfigLibrary(BaseModel):
13
12
  """
14
13
  Represents a named, namespaced, persisted YAML discovery config library.
15
14
 
16
- Library names are unique per config type within a namespace,
17
- so a database and a file library may share a name.
15
+ A library is untyped: the same library may be imported by both database and
16
+ file discovery configs, and its name is unique within a namespace.
18
17
  """
19
18
 
20
19
  model_config = ConfigDict(extra="allow", populate_by_name=True)
21
20
 
22
21
  name: str
23
- config_type: DiscoveryConfigType
24
22
  namespace: str = ""
25
23
  yaml: Optional[str] = Field(default=None, alias="config_yaml")
26
24
  # Server-populated read-only fields, excluded from request bodies.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "datamasque-python"
3
- version = "1.1.8"
3
+ version = "1.2.0"
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.1.8
2
+ current_version = 1.2.0
3
3
  commit = True
4
4
  tag = True
5
5
 
@@ -5,13 +5,11 @@ from typing import Any
5
5
 
6
6
  import pytest
7
7
  import requests_mock
8
- from pydantic import ValidationError
9
8
 
10
9
  from datamasque.client import (
11
10
  DataMasqueClient,
12
11
  DiscoveryConfigLibrary,
13
12
  DiscoveryConfigLibraryId,
14
- DiscoveryConfigType,
15
13
  )
16
14
  from datamasque.client.exceptions import DataMasqueApiError
17
15
  from datamasque.client.models.status import ValidationStatus
@@ -28,7 +26,6 @@ def sample_library_list_response() -> list[dict[str, Any]]:
28
26
  "id": LIBRARY_ID_1,
29
27
  "name": "my_library",
30
28
  "namespace": "org",
31
- "config_type": "database",
32
29
  "is_valid": "valid",
33
30
  "validation_error": None,
34
31
  "usage_count": 0,
@@ -39,7 +36,6 @@ def sample_library_list_response() -> list[dict[str, Any]]:
39
36
  "id": LIBRARY_ID_2,
40
37
  "name": "another_library",
41
38
  "namespace": "",
42
- "config_type": "file",
43
39
  "is_valid": "invalid",
44
40
  "validation_error": "bad yaml",
45
41
  "usage_count": 2,
@@ -56,7 +52,6 @@ def sample_library_detail_response() -> dict[str, Any]:
56
52
  "id": LIBRARY_ID_1,
57
53
  "name": "my_library",
58
54
  "namespace": "org",
59
- "config_type": "database",
60
55
  "config_yaml": "labels: []\nmetadata_rules: []\nidd_rules: []\n",
61
56
  "is_valid": "valid",
62
57
  "validation_error": None,
@@ -66,44 +61,19 @@ def sample_library_detail_response() -> dict[str, Any]:
66
61
  }
67
62
 
68
63
 
69
- @pytest.fixture
70
- def same_name_both_config_types() -> list[dict[str, Any]]:
71
- """Two libraries sharing (name, namespace) but with different config types, as the server allows."""
72
- return [
73
- {
74
- "id": LIBRARY_ID_1,
75
- "name": "my_library",
76
- "namespace": "",
77
- "config_type": "database",
78
- "is_valid": "valid",
79
- "created": "2025-01-01T12:00:00Z",
80
- "modified": "2025-01-02T12:00:00Z",
81
- },
82
- {
83
- "id": LIBRARY_ID_2,
84
- "name": "my_library",
85
- "namespace": "",
86
- "config_type": "file",
87
- "is_valid": "valid",
88
- "created": "2025-01-01T12:00:00Z",
89
- "modified": "2025-01-02T12:00:00Z",
90
- },
91
- ]
92
-
93
-
94
64
  @pytest.fixture
95
65
  def config_library() -> DiscoveryConfigLibrary:
96
66
  return DiscoveryConfigLibrary(
97
67
  name="test_library",
98
68
  namespace="test_ns",
99
- config_type=DiscoveryConfigType.database,
100
69
  yaml="labels: []\nmetadata_rules: []\nidd_rules: []\n",
101
70
  )
102
71
 
103
72
 
104
- def test_config_type_is_required_on_the_model() -> None:
105
- with pytest.raises(ValidationError, match="config_type"):
106
- DiscoveryConfigLibrary(name="test_library", yaml="labels: []\n")
73
+ def test_library_is_untyped() -> None:
74
+ """A library carries no `config_type`; the same library serves both config types."""
75
+ library = DiscoveryConfigLibrary(name="test_library", yaml="labels: []\n")
76
+ assert "config_type" not in library.model_dump(by_alias=True)
107
77
 
108
78
 
109
79
  def test_list_discovery_config_libraries(
@@ -121,12 +91,10 @@ def test_list_discovery_config_libraries(
121
91
  assert libraries[0].id == DiscoveryConfigLibraryId(LIBRARY_ID_1)
122
92
  assert libraries[0].name == "my_library"
123
93
  assert libraries[0].namespace == "org"
124
- assert libraries[0].config_type is DiscoveryConfigType.database
125
94
  assert libraries[0].yaml is None
126
95
  assert libraries[0].is_valid is ValidationStatus.valid
127
96
  assert libraries[1].id == DiscoveryConfigLibraryId(LIBRARY_ID_2)
128
97
  assert libraries[1].name == "another_library"
129
- assert libraries[1].config_type is DiscoveryConfigType.file
130
98
  assert libraries[1].is_valid is ValidationStatus.invalid
131
99
  assert libraries[1].validation_error == "bad yaml"
132
100
 
@@ -155,7 +123,6 @@ def test_get_discovery_config_library(client: DataMasqueClient, sample_library_d
155
123
  assert library.id == DiscoveryConfigLibraryId(LIBRARY_ID_1)
156
124
  assert library.name == "my_library"
157
125
  assert library.namespace == "org"
158
- assert library.config_type is DiscoveryConfigType.database
159
126
  assert library.yaml == "labels: []\nmetadata_rules: []\nidd_rules: []\n"
160
127
  assert library.is_valid is ValidationStatus.valid
161
128
 
@@ -176,7 +143,7 @@ def test_get_discovery_config_library_by_name_found(
176
143
  json=sample_library_detail_response,
177
144
  status_code=200,
178
145
  )
179
- library = client.get_discovery_config_library_by_name("my_library", DiscoveryConfigType.database, "org")
146
+ library = client.get_discovery_config_library_by_name("my_library", "org")
180
147
 
181
148
  assert library is not None
182
149
  assert library.name == "my_library"
@@ -193,7 +160,6 @@ def test_get_discovery_config_library_by_name_matches_namespace_client_side(
193
160
  "id": LIBRARY_ID_1,
194
161
  "name": "my_library",
195
162
  "namespace": "org",
196
- "config_type": "database",
197
163
  "is_valid": "valid",
198
164
  "created": "2025-01-01T12:00:00Z",
199
165
  "modified": "2025-01-02T12:00:00Z",
@@ -202,7 +168,6 @@ def test_get_discovery_config_library_by_name_matches_namespace_client_side(
202
168
  "id": LIBRARY_ID_2,
203
169
  "name": "my_library",
204
170
  "namespace": "",
205
- "config_type": "database",
206
171
  "is_valid": "valid",
207
172
  "created": "2025-01-01T12:00:00Z",
208
173
  "modified": "2025-01-02T12:00:00Z",
@@ -220,7 +185,7 @@ def test_get_discovery_config_library_by_name_matches_namespace_client_side(
220
185
  json=sample_library_detail_response,
221
186
  status_code=200,
222
187
  )
223
- library = client.get_discovery_config_library_by_name("my_library", DiscoveryConfigType.database, "org")
188
+ library = client.get_discovery_config_library_by_name("my_library", "org")
224
189
 
225
190
  assert library is not None
226
191
  assert library.id == DiscoveryConfigLibraryId(LIBRARY_ID_1)
@@ -235,7 +200,7 @@ def test_get_discovery_config_library_by_name_default_namespace_does_not_match_o
235
200
  json=[sample_library_list_response[0]],
236
201
  status_code=200,
237
202
  )
238
- library = client.get_discovery_config_library_by_name("my_library", DiscoveryConfigType.database)
203
+ library = client.get_discovery_config_library_by_name("my_library")
239
204
 
240
205
  assert library is None
241
206
  assert m.call_count == 1
@@ -248,50 +213,17 @@ def test_get_discovery_config_library_by_name_not_found(client: DataMasqueClient
248
213
  json=[],
249
214
  status_code=200,
250
215
  )
251
- library = client.get_discovery_config_library_by_name("nonexistent", DiscoveryConfigType.database)
216
+ library = client.get_discovery_config_library_by_name("nonexistent")
252
217
 
253
218
  assert library is None
254
219
 
255
220
 
256
- def test_get_discovery_config_library_by_name_selects_matching_config_type(
257
- client: DataMasqueClient, same_name_both_config_types: list[dict[str, Any]]
258
- ) -> None:
259
- detail_response = {
260
- "id": LIBRARY_ID_2,
261
- "name": "my_library",
262
- "namespace": "",
263
- "config_type": "file",
264
- "config_yaml": "labels: []\n",
265
- "is_valid": "valid",
266
- "created": "2025-01-01T12:00:00Z",
267
- "modified": "2025-01-02T12:00:00Z",
268
- }
269
-
270
- with requests_mock.Mocker() as m:
271
- m.get(
272
- "http://test-server/api/discovery/config-libraries/",
273
- json=same_name_both_config_types,
274
- status_code=200,
275
- )
276
- m.get(
277
- f"http://test-server/api/discovery/config-libraries/{LIBRARY_ID_2}/",
278
- json=detail_response,
279
- status_code=200,
280
- )
281
- library = client.get_discovery_config_library_by_name("my_library", DiscoveryConfigType.file)
282
-
283
- assert library is not None
284
- assert library.id == DiscoveryConfigLibraryId(LIBRARY_ID_2)
285
- assert library.config_type is DiscoveryConfigType.file
286
-
287
-
288
221
  def test_get_discovery_config_library_by_name_raises_when_server_omits_id(client: DataMasqueClient) -> None:
289
222
  """If the server returns a list entry without `id`, the by-name lookup surfaces a typed API error."""
290
223
  list_response_without_id = [
291
224
  {
292
225
  "name": "my_library",
293
226
  "namespace": "org",
294
- "config_type": "database",
295
227
  "is_valid": "valid",
296
228
  "created": "2025-01-01T12:00:00Z",
297
229
  "modified": "2025-01-02T12:00:00Z",
@@ -305,7 +237,7 @@ def test_get_discovery_config_library_by_name_raises_when_server_omits_id(client
305
237
  status_code=200,
306
238
  )
307
239
  with pytest.raises(DataMasqueApiError, match="without an `id`"):
308
- client.get_discovery_config_library_by_name("my_library", DiscoveryConfigType.database, "org")
240
+ client.get_discovery_config_library_by_name("my_library", "org")
309
241
 
310
242
 
311
243
  def test_create_discovery_config_library(client: DataMasqueClient, config_library: DiscoveryConfigLibrary) -> None:
@@ -313,7 +245,6 @@ def test_create_discovery_config_library(client: DataMasqueClient, config_librar
313
245
  "id": LIBRARY_ID_1,
314
246
  "name": "test_library",
315
247
  "namespace": "test_ns",
316
- "config_type": "database",
317
248
  "config_yaml": "labels: []\nmetadata_rules: []\nidd_rules: []\n",
318
249
  "is_valid": "valid",
319
250
  "validation_error": None,
@@ -338,7 +269,7 @@ def test_create_discovery_config_library(client: DataMasqueClient, config_librar
338
269
  request_body = m.last_request.json()
339
270
  assert request_body["name"] == "test_library"
340
271
  assert request_body["namespace"] == "test_ns"
341
- assert request_body["config_type"] == "database"
272
+ assert "config_type" not in request_body
342
273
  assert request_body["config_yaml"] == "labels: []\nmetadata_rules: []\nidd_rules: []\n"
343
274
  read_only_fields = {"id", "is_valid", "validation_error", "created", "modified"}
344
275
  assert not read_only_fields & request_body.keys()
@@ -351,7 +282,6 @@ def test_create_discovery_config_library_reports_validation_error(
351
282
  "id": LIBRARY_ID_1,
352
283
  "name": "test_library",
353
284
  "namespace": "test_ns",
354
- "config_type": "database",
355
285
  "config_yaml": "labels: []\nmetadata_rules: []\nidd_rules: []\n",
356
286
  "is_valid": "invalid",
357
287
  "validation_error": "metadata_rules is not a list",
@@ -379,7 +309,6 @@ def test_update_discovery_config_library(client: DataMasqueClient, config_librar
379
309
  "id": LIBRARY_ID_1,
380
310
  "name": "test_library",
381
311
  "namespace": "test_ns",
382
- "config_type": "database",
383
312
  "config_yaml": "labels: []\nmetadata_rules: []\nidd_rules: []\n",
384
313
  "is_valid": "valid",
385
314
  "validation_error": None,
@@ -431,7 +360,6 @@ def test_create_or_update_discovery_config_library_create(
431
360
  "id": LIBRARY_ID_1,
432
361
  "name": "test_library",
433
362
  "namespace": "test_ns",
434
- "config_type": "database",
435
363
  "config_yaml": "labels: []\nmetadata_rules: []\nidd_rules: []\n",
436
364
  "is_valid": "valid",
437
365
  "validation_error": None,
@@ -466,7 +394,6 @@ def test_create_or_update_discovery_config_library_update(
466
394
  "id": LIBRARY_ID_1,
467
395
  "name": "test_library",
468
396
  "namespace": "test_ns",
469
- "config_type": "database",
470
397
  "is_valid": "valid",
471
398
  "created": "2025-06-01T10:00:00Z",
472
399
  "modified": "2025-06-01T10:00:00Z",
@@ -476,7 +403,6 @@ def test_create_or_update_discovery_config_library_update(
476
403
  "id": LIBRARY_ID_1,
477
404
  "name": "test_library",
478
405
  "namespace": "test_ns",
479
- "config_type": "database",
480
406
  "config_yaml": "labels: []\nmetadata_rules: []\nidd_rules: []\n",
481
407
  "is_valid": "valid",
482
408
  "validation_error": None,
@@ -503,42 +429,6 @@ def test_create_or_update_discovery_config_library_update(
503
429
  assert m.request_history[1].method == "PUT"
504
430
 
505
431
 
506
- def test_create_or_update_discovery_config_library_matches_config_type(
507
- client: DataMasqueClient, same_name_both_config_types: list[dict[str, Any]]
508
- ) -> None:
509
- file_library = DiscoveryConfigLibrary(
510
- name="my_library",
511
- config_type=DiscoveryConfigType.file,
512
- yaml="labels: []\n",
513
- )
514
- update_response = {
515
- "id": LIBRARY_ID_2,
516
- "name": "my_library",
517
- "namespace": "",
518
- "config_type": "file",
519
- "config_yaml": "labels: []\n",
520
- "is_valid": "valid",
521
- "validation_error": None,
522
- "created": "2025-01-01T12:00:00Z",
523
- "modified": "2025-01-03T12:00:00Z",
524
- }
525
-
526
- with requests_mock.Mocker() as m:
527
- m.get(
528
- "http://test-server/api/discovery/config-libraries/",
529
- json=same_name_both_config_types,
530
- status_code=200,
531
- )
532
- m.put(
533
- f"http://test-server/api/discovery/config-libraries/{LIBRARY_ID_2}/",
534
- json=update_response,
535
- status_code=200,
536
- )
537
- result = client.create_or_update_discovery_config_library(file_library)
538
-
539
- assert result.id == DiscoveryConfigLibraryId(LIBRARY_ID_2)
540
-
541
-
542
432
  def test_delete_discovery_config_library_by_id(client: DataMasqueClient) -> None:
543
433
  with requests_mock.Mocker() as m:
544
434
  m.delete(
@@ -583,33 +473,13 @@ def test_delete_discovery_config_library_by_name(
583
473
  f"http://test-server/api/discovery/config-libraries/{LIBRARY_ID_1}/",
584
474
  status_code=204,
585
475
  )
586
- client.delete_discovery_config_library_by_name_if_exists("my_library", DiscoveryConfigType.database, "org")
476
+ client.delete_discovery_config_library_by_name_if_exists("my_library", "org")
587
477
 
588
478
  assert m.request_history[0].method == "GET"
589
479
  assert "name_exact=my_library" in m.request_history[0].url
590
480
  assert m.request_history[1].method == "DELETE"
591
481
 
592
482
 
593
- def test_delete_discovery_config_library_by_name_deletes_only_matching_config_type(
594
- client: DataMasqueClient, same_name_both_config_types: list[dict[str, Any]]
595
- ) -> None:
596
- with requests_mock.Mocker() as m:
597
- m.get(
598
- "http://test-server/api/discovery/config-libraries/",
599
- json=same_name_both_config_types,
600
- status_code=200,
601
- )
602
- m.delete(
603
- f"http://test-server/api/discovery/config-libraries/{LIBRARY_ID_2}/",
604
- status_code=204,
605
- )
606
- client.delete_discovery_config_library_by_name_if_exists("my_library", DiscoveryConfigType.file)
607
-
608
- assert m.call_count == 2
609
- assert m.request_history[1].method == "DELETE"
610
- assert LIBRARY_ID_2 in m.request_history[1].url
611
-
612
-
613
483
  def test_delete_discovery_config_library_by_name_not_found(
614
484
  client: DataMasqueClient, sample_library_list_response: list[dict[str, Any]]
615
485
  ) -> None:
@@ -619,7 +489,7 @@ def test_delete_discovery_config_library_by_name_not_found(
619
489
  json=sample_library_list_response,
620
490
  status_code=200,
621
491
  )
622
- client.delete_discovery_config_library_by_name_if_exists("nonexistent", DiscoveryConfigType.database)
492
+ client.delete_discovery_config_library_by_name_if_exists("nonexistent")
623
493
 
624
494
  assert m.call_count == 1
625
495
  assert m.request_history[0].method == "GET"
@@ -428,7 +428,7 @@ toml = [
428
428
 
429
429
  [[package]]
430
430
  name = "datamasque-python"
431
- version = "1.1.8"
431
+ version = "1.2.0"
432
432
  source = { editable = "." }
433
433
  dependencies = [
434
434
  { name = "pydantic" },