datamasque-python 1.2.1__py3-none-any.whl → 1.2.2__py3-none-any.whl

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.
@@ -76,15 +76,19 @@ class DiscoveryConfigLibraryClient(BaseClient):
76
76
  Creates a new discovery config library on the server.
77
77
 
78
78
  Sets the library's server-assigned fields
79
- (`id`, `is_valid`, `validation_error`, `created`, `modified`) and returns the library.
79
+ (`id`, `is_valid`, `validation_error`, `usage_count`, `created`, `modified`) and returns the library.
80
80
  """
81
81
 
82
+ if not library.yaml:
83
+ raise ValueError("Cannot create a discovery config library without YAML content (yaml is empty)")
84
+
82
85
  data = library.model_dump(exclude_none=True, by_alias=True, mode="json")
83
86
  response = self.make_request("POST", "/api/discovery/config-libraries/", data=data)
84
87
  created = DiscoveryConfigLibrary.model_validate(response.json())
85
88
  library.id = created.id
86
89
  library.is_valid = created.is_valid
87
90
  library.validation_error = created.validation_error
91
+ library.usage_count = created.usage_count
88
92
  library.created = created.created
89
93
  library.modified = created.modified
90
94
  logger.info('Creation of discovery config library "%s" successful', library.name)
@@ -101,9 +105,9 @@ class DiscoveryConfigLibraryClient(BaseClient):
101
105
  if library.id is None:
102
106
  raise ValueError("Cannot update a discovery config library that has not been created yet (id is None)")
103
107
 
104
- if library.yaml is None:
108
+ if not library.yaml:
105
109
  raise ValueError(
106
- "Cannot update a discovery config library without YAML content (yaml is None); "
110
+ "Cannot update a discovery config library without YAML content (yaml is empty or unset); "
107
111
  "list results omit YAML, so fetch the full library with `get_discovery_config_library` first"
108
112
  )
109
113
 
@@ -112,6 +116,7 @@ class DiscoveryConfigLibraryClient(BaseClient):
112
116
  updated = DiscoveryConfigLibrary.model_validate(response.json())
113
117
  library.is_valid = updated.is_valid
114
118
  library.validation_error = updated.validation_error
119
+ library.usage_count = updated.usage_count
115
120
  library.modified = updated.modified
116
121
  logger.debug('Update of discovery config library "%s" successful', library.name)
117
122
  return library
@@ -75,15 +75,20 @@ class DiscoveryConfigClient(BaseClient):
75
75
  Creates a new discovery config on the server.
76
76
 
77
77
  Sets the config's server-assigned fields
78
- (`id`, `is_valid`, `validation_error`, `created`, `modified`) and returns the config.
78
+ (`id`, `is_valid`, `validation_error`, `validation_error_details`, `created`, `modified`)
79
+ and returns the config.
79
80
  """
80
81
 
82
+ if not config.yaml:
83
+ raise ValueError("Cannot create a discovery config without YAML content (yaml is empty)")
84
+
81
85
  data = config.model_dump(exclude_none=True, by_alias=True, mode="json")
82
86
  response = self.make_request("POST", "/api/discovery/configs/", data=data)
83
87
  created = DiscoveryConfig.model_validate(response.json())
84
88
  config.id = created.id
85
89
  config.is_valid = created.is_valid
86
90
  config.validation_error = created.validation_error
91
+ config.validation_error_details = created.validation_error_details
87
92
  config.created = created.created
88
93
  config.modified = created.modified
89
94
  logger.info('Creation of discovery config "%s" successful', config.name)
@@ -94,17 +99,24 @@ class DiscoveryConfigClient(BaseClient):
94
99
  Performs a full update of the discovery config.
95
100
 
96
101
  The config must have its `id` set
97
- (i.e., it must have been previously created or retrieved from the server).
102
+ and its `yaml` content present.
98
103
  """
99
104
 
100
105
  if config.id is None:
101
106
  raise ValueError("Cannot update a discovery config that has not been created yet (id is None)")
102
107
 
108
+ if not config.yaml:
109
+ raise ValueError(
110
+ "Cannot update a discovery config without YAML content (yaml is empty or unset); "
111
+ "list results omit YAML, so fetch the full config with `get_discovery_config` first"
112
+ )
113
+
103
114
  data = config.model_dump(exclude_none=True, by_alias=True, mode="json")
104
115
  response = self.make_request("PUT", f"/api/discovery/configs/{config.id}/", data=data)
105
116
  updated = DiscoveryConfig.model_validate(response.json())
106
117
  config.is_valid = updated.is_valid
107
118
  config.validation_error = updated.validation_error
119
+ config.validation_error_details = updated.validation_error_details
108
120
  config.modified = updated.modified
109
121
  logger.debug('Update of discovery config "%s" successful', config.name)
110
122
  return config
@@ -2,9 +2,9 @@ import enum
2
2
  from datetime import datetime
3
3
  from typing import Any, NewType, Optional
4
4
 
5
- from pydantic import BaseModel, ConfigDict, Field
5
+ from pydantic import AliasChoices, AliasPath, BaseModel, ConfigDict, Field
6
6
 
7
- from datamasque.client.models.status import ValidationStatus
7
+ from datamasque.client.models.status import ValidationErrorDetails, ValidationStatus
8
8
 
9
9
  DiscoveryConfigId = NewType("DiscoveryConfigId", str)
10
10
 
@@ -49,5 +49,14 @@ class DiscoveryConfig(BaseModel):
49
49
  """Validation status; may be `in_progress` briefly after creating a large config."""
50
50
  validation_error: Optional[str] = Field(default=None, exclude=True)
51
51
  """Human-readable validation error, or `None` when valid."""
52
+ # Deliberately not `validation_errors`:
53
+ # this is a different shape to `Ruleset.validation_errors`,
54
+ # and would sit one character from `validation_error` above.
55
+ validation_error_details: list[ValidationErrorDetails] = Field(
56
+ default_factory=list,
57
+ exclude=True,
58
+ validation_alias=AliasChoices(AliasPath("errors", "config_yaml"), "validation_error_details"),
59
+ )
60
+ """Structured, positional validation errors."""
52
61
  created: Optional[datetime] = Field(default=None, exclude=True)
53
62
  modified: Optional[datetime] = Field(default=None, exclude=True)
@@ -27,5 +27,7 @@ class DiscoveryConfigLibrary(BaseModel):
27
27
  """Validation status; libraries are validated synchronously on create/update."""
28
28
  validation_error: Optional[str] = Field(default=None, exclude=True)
29
29
  """Human-readable validation error, or `None` when valid."""
30
+ usage_count: Optional[int] = Field(default=None, exclude=True)
31
+ """Number of active discovery configs that import this library."""
30
32
  created: Optional[datetime] = Field(default=None, exclude=True)
31
33
  modified: Optional[datetime] = Field(default=None, exclude=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datamasque-python
3
- Version: 1.2.1
3
+ Version: 1.2.2
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/
@@ -2,8 +2,8 @@ datamasque/client/__init__.py,sha256=2PVF5FrXkPAv51EMxSvfpYelJpbOg_Tlx-Wo7p2-0jo
2
2
  datamasque/client/base.py,sha256=cXU4dluL9e1N1F2pV48iIvebv6OHt7Kh4Ka2y9vkOPo,14296
3
3
  datamasque/client/connections.py,sha256=EFinx8fJRme0mTxuWY3d29UnmUFbsQhMaUQT0Ma2PK4,2885
4
4
  datamasque/client/discovery.py,sha256=xidiAj5LdVSGQy6pjta_2Z_aJmuPPohblyNDfua_Mxk,28859
5
- datamasque/client/discovery_config_libraries.py,sha256=bwuBTCnJUSnOyTz_I-_D6uS3wcRJh3ZRtfv2AOyMnmY,7024
6
- datamasque/client/discovery_configs.py,sha256=G-W-X_KizjjQLa-Rb6ixLjlkxbkCe4WGCOfYZrGtxIk,6420
5
+ datamasque/client/discovery_config_libraries.py,sha256=K6kFi7kL4SGIPKNIg1TBMIwHUeyfXI3Lyg5sknMMCD4,7285
6
+ datamasque/client/discovery_configs.py,sha256=-iSDi7g8PAYXJ8aGCusGOVtE1UWD4D_pNxf68IdRei4,6967
7
7
  datamasque/client/dmclient.py,sha256=0W6s26gUl9EZRL1kdk0R_7hgZSAOesY3H5wd-tN-QIE,1940
8
8
  datamasque/client/exceptions.py,sha256=3JI_LU8K3P2BCJDjGewzj3yg6oMd_7KuQ-zwSLR8Bfs,3956
9
9
  datamasque/client/files.py,sha256=vc2tZgT8RdwuCObIQ7H-Qjb80H1PBFqD0nG5Y1tOA_o,3503
@@ -22,8 +22,8 @@ datamasque/client/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
22
22
  datamasque/client/models/connection.py,sha256=loLy4RCiIfY9kvBFspSqJSRhHqhcJxm_mQzXwMRS4VU,17529
23
23
  datamasque/client/models/data_selection.py,sha256=406yyUZ5NmLBSql2lYM1gsTWY5GWmnutmF-DjznAoLc,1904
24
24
  datamasque/client/models/discovery.py,sha256=Ejtrmja_wjHRxCWZel5Q5nZz4M20F2zdtBsdhWI1BnA,16791
25
- datamasque/client/models/discovery_config.py,sha256=1CHMgSxMXuarPGfRcz9wX7jeZLn1SDw0UEe-L5naE54,1917
26
- datamasque/client/models/discovery_config_library.py,sha256=NW4bhrlpps_SyJcX07W-dfQ_i9C0OH3O0b9TQcXPl1w,1298
25
+ datamasque/client/models/discovery_config.py,sha256=8sqs9x_X0H_hR1fJDEFmOdJyGRDwgbdb3eddEAe98WE,2420
26
+ datamasque/client/models/discovery_config_library.py,sha256=m0wI51Q4aHysLNHyNTWH3KrDLV_rxtoLNeKQsF9RYFk,1436
27
27
  datamasque/client/models/dm_instance.py,sha256=6h0WNlI1qt6jkrYFapIvuSJFkhRCcwbpx0PLG5NsrGw,2219
28
28
  datamasque/client/models/files.py,sha256=7hG3Q1-XYb1PF88l3ppsmBp2tjNtvQvv-RNTrOa7Nts,2784
29
29
  datamasque/client/models/git.py,sha256=F0KdMFe2vMyL-9tp3SGKGeOlbD1gbcjQn0jpOzNzybc,1782
@@ -38,7 +38,7 @@ datamasque/client/models/safe_data_preview.py,sha256=BiI9d13KdQrTin2JfbjiRiODjns
38
38
  datamasque/client/models/status.py,sha256=WiSMEy_YxdcIA46ioYpAEu8OK8UNDoXpV1W7IUhhyVY,3219
39
39
  datamasque/client/models/table_reference.py,sha256=55fKdHjC2TQnUmbp0XiWqfeFGXqcq4wXjbWgMaN3p3c,3835
40
40
  datamasque/client/models/user.py,sha256=UGAUzgJkf78m24_zFXXoA99zdut48BXkX_ivV8yq1Vc,2043
41
- datamasque_python-1.2.1.dist-info/METADATA,sha256=zTFqfTv2d-IILIIaCglzlraCNgZ3wwHP95mpvK0AYnI,4497
42
- datamasque_python-1.2.1.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
43
- datamasque_python-1.2.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
44
- datamasque_python-1.2.1.dist-info/RECORD,,
41
+ datamasque_python-1.2.2.dist-info/METADATA,sha256=ir-yTNm-rFL887aT4tQN1iTe6Ll10VNBUvy2n7JTF3k,4497
42
+ datamasque_python-1.2.2.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
43
+ datamasque_python-1.2.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
44
+ datamasque_python-1.2.2.dist-info/RECORD,,