mosaic-python-client 0.2.0__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.
- mosaic_client/__init__.py +17 -0
- mosaic_client/epix/__init__.py +115 -0
- mosaic_client/epix/client.py +772 -0
- mosaic_client/epix/models.py +487 -0
- mosaic_client/epix/schemas.py +379 -0
- mosaic_client/gpas/__init__.py +13 -0
- mosaic_client/gpas/client.py +342 -0
- mosaic_client/gpas/models.py +70 -0
- mosaic_client/gpas/schemas.py +53 -0
- mosaic_client/helpers.py +115 -0
- mosaic_python_client-0.2.0.dist-info/METADATA +290 -0
- mosaic_python_client-0.2.0.dist-info/RECORD +14 -0
- mosaic_python_client-0.2.0.dist-info/WHEEL +4 -0
- mosaic_python_client-0.2.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains functions for interacting with the gPAS SOAP interface.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from zeep import Client
|
|
6
|
+
|
|
7
|
+
from mosaic_client.gpas.models import Domain, DomainResponse
|
|
8
|
+
from mosaic_client.gpas.schemas import DomainResponseSchema, DomainSchema
|
|
9
|
+
from mosaic_client.helpers import WSDLClient, _cast_client, _read_key_value_list, _serialize_dict
|
|
10
|
+
|
|
11
|
+
KeyValueTuple = tuple[str, str]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def delete_entry(client: Client, domain_name: str, value: str) -> None:
|
|
15
|
+
"""
|
|
16
|
+
Deletes a value and its associated pseudonym from the specified data domain.
|
|
17
|
+
|
|
18
|
+
:param client: Zeep client with gPAS service definitions
|
|
19
|
+
:param domain_name: name of the domain where the value is present
|
|
20
|
+
:param value: value to remove
|
|
21
|
+
"""
|
|
22
|
+
client.service.deleteEntry(domainName=domain_name, value=value)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def delete_entries(client: Client, domain_name: str, values: list[str]) -> list[KeyValueTuple]:
|
|
26
|
+
"""
|
|
27
|
+
Deletes a list of values and their associated pseudonyms from the specified data domain.
|
|
28
|
+
|
|
29
|
+
:param client: Zeep client with gPAS service definitions
|
|
30
|
+
:param domain_name: name of the domain where the value is present
|
|
31
|
+
:param values: list of values to remove
|
|
32
|
+
:return: list of key-value pairs where the key is the value that was requested to be deleted, and the value is
|
|
33
|
+
an indicator whether deletion was successful or not
|
|
34
|
+
"""
|
|
35
|
+
response = client.service.deleteEntries(domainName=domain_name, values=values)
|
|
36
|
+
return _read_key_value_list(_serialize_dict(response))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_or_create_pseudonym_for(client: Client, domain_name: str, value: str) -> str:
|
|
40
|
+
"""
|
|
41
|
+
Requests a new pseudonym for a value in the specified data domain.
|
|
42
|
+
|
|
43
|
+
:param client: Zeep client with gPAS service definitions
|
|
44
|
+
:param domain_name: name of the domain where the value is supposed to be inserted
|
|
45
|
+
:param value: value to insert
|
|
46
|
+
:return: pseudonym that is assigned to the value
|
|
47
|
+
"""
|
|
48
|
+
return client.service.getOrCreatePseudonymFor(domainName=domain_name, value=value)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_or_create_pseudonym_for_list(client: Client, domain_name: str, values: list[str]) -> list[KeyValueTuple]:
|
|
52
|
+
"""
|
|
53
|
+
Request new pseudonyms for a list of values in the specified data domain.
|
|
54
|
+
|
|
55
|
+
:param client: Zeep client with gPAS service definitions
|
|
56
|
+
:param domain_name: name of the domain where the value is supposed to be inserted
|
|
57
|
+
:param values: list of values to insert
|
|
58
|
+
:return: list of key-value pairs where the key is the original value that is supposed to be pseudonymized,
|
|
59
|
+
and the value is the assigned pseudonym
|
|
60
|
+
"""
|
|
61
|
+
response = client.service.getOrCreatePseudonymForList(domainName=domain_name, values=values)
|
|
62
|
+
return _read_key_value_list(_serialize_dict(response))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def get_value_for(client: Client, domain_name: str, pseudonym: str) -> str:
|
|
66
|
+
"""
|
|
67
|
+
Gets the value for a pseudonym in the specified data domain.
|
|
68
|
+
|
|
69
|
+
:param client: Zeep client with gPAS service definitions
|
|
70
|
+
:param domain_name: name of the domain where the pseudonym is present
|
|
71
|
+
:param pseudonym: pseudonym to resolve
|
|
72
|
+
:return: value assigned to the pseudonym
|
|
73
|
+
"""
|
|
74
|
+
return client.service.getValueFor(domainName=domain_name, psn=pseudonym)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_value_for_list(client: Client, domain_name: str, pseudonyms: list[str]) -> list[KeyValueTuple]:
|
|
78
|
+
"""
|
|
79
|
+
Gets the values for a list of pseudonyms in the specified data domain.
|
|
80
|
+
|
|
81
|
+
:param client: Zeep client with gPAS service definitions
|
|
82
|
+
:param domain_name: name of the domain where the pseudonyms are present
|
|
83
|
+
:param pseudonyms: pseudonyms to resolve
|
|
84
|
+
:return: list of key-value pairs, structured as { pseudonym => value }
|
|
85
|
+
"""
|
|
86
|
+
response = client.service.getValueForList(domainName=domain_name, psnList=pseudonyms)
|
|
87
|
+
return _read_key_value_list(_serialize_dict(response))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def get_pseudonym_for(client: Client, domain_name: str, value: str) -> str:
|
|
91
|
+
"""
|
|
92
|
+
Gets the pseudonym for a value in the specified data domain.
|
|
93
|
+
|
|
94
|
+
:param client: Zeep client with gPAS service definitions
|
|
95
|
+
:param domain_name: name of the domain where the value is present
|
|
96
|
+
:param value: value to resolve
|
|
97
|
+
:return: pseudonym assigned to the value
|
|
98
|
+
"""
|
|
99
|
+
return client.service.getPseudonymFor(domainName=domain_name, value=value)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def get_pseudonym_for_list(client: Client, domain_name: str, values: list[str]) -> list[KeyValueTuple]:
|
|
103
|
+
"""
|
|
104
|
+
Gets the pseudonyms for a list of values in the specified data domain.
|
|
105
|
+
|
|
106
|
+
:param client: Zeep client with gPAS service definitions
|
|
107
|
+
:param domain_name: name of the domain where the values are present
|
|
108
|
+
:param values: values to resolve
|
|
109
|
+
:return: list of key-value pairs, structured as { value => pseudonym }
|
|
110
|
+
"""
|
|
111
|
+
response = client.service.getPseudonymForList(domainName=domain_name, values=values)
|
|
112
|
+
return _read_key_value_list(_serialize_dict(response))
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def insert_value_pseudonym_pair(client: Client, domain_name: str, value: str, pseudonym: str) -> None:
|
|
116
|
+
"""
|
|
117
|
+
Manually inserts a value and a pseudonym into the specified data domain.
|
|
118
|
+
|
|
119
|
+
:param client: Zeep client with gPAS service definitions
|
|
120
|
+
:param domain_name: name of the domain to insert the pair into
|
|
121
|
+
:param value: value to add
|
|
122
|
+
:param pseudonym: pseudonym to assign to the value
|
|
123
|
+
"""
|
|
124
|
+
client.service.insertValuePseudonymPair(domainName=domain_name, value=value, pseudonym=pseudonym)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def insert_value_pseudonym_pairs(client: Client, domain_name: str, pairs: list[KeyValueTuple]) -> None:
|
|
128
|
+
"""
|
|
129
|
+
Manually inserts a list of values and pseudonyms into the specified data domain.
|
|
130
|
+
|
|
131
|
+
:param client: Zeep client with gPAS service definitions
|
|
132
|
+
:param domain_name: name of the domain to insert the pairs into
|
|
133
|
+
:param pairs: list of key-value pairs, structured as { value => pseudonym }
|
|
134
|
+
"""
|
|
135
|
+
# for some reason this is the only case where the "entry" key is mandatory. it is not returned by any other
|
|
136
|
+
# endpoints where there's supposedly an "entry" key, e.g. deleteEntries (???)
|
|
137
|
+
client.service.insertValuePseudonymPairs(
|
|
138
|
+
domainName=domain_name,
|
|
139
|
+
pairs={
|
|
140
|
+
"entry": [
|
|
141
|
+
{
|
|
142
|
+
"key": kv_tuple[0],
|
|
143
|
+
"value": kv_tuple[1],
|
|
144
|
+
}
|
|
145
|
+
for kv_tuple in pairs
|
|
146
|
+
]
|
|
147
|
+
},
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def add_domain(client: Client, domain: Domain) -> None:
|
|
152
|
+
"""
|
|
153
|
+
Adds a new domain.
|
|
154
|
+
|
|
155
|
+
:param client: Zeep client with gPAS domain service definitions
|
|
156
|
+
:param domain: domain data class to create
|
|
157
|
+
"""
|
|
158
|
+
domain_soap = DomainSchema().dump(domain)
|
|
159
|
+
client.service.addDomain(domainDTO=domain_soap)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def get_domain(client: Client, domain_name: str) -> DomainResponse:
|
|
163
|
+
"""
|
|
164
|
+
Gets a domain that matches the specified name. Raises a Fault if there is no domain with such a name.
|
|
165
|
+
|
|
166
|
+
:param client: Zeep client with gPAS domain service definitions
|
|
167
|
+
:param domain_name: name of the domain to get
|
|
168
|
+
:return: domain response instance
|
|
169
|
+
"""
|
|
170
|
+
domain_soap = client.service.getDomain(domainName=domain_name)
|
|
171
|
+
return DomainResponseSchema().load(_serialize_dict(domain_soap))
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def list_domains(client: Client) -> list[DomainResponse]:
|
|
175
|
+
"""
|
|
176
|
+
Lists all available domains in the gPAS instance.
|
|
177
|
+
|
|
178
|
+
:param client: Zeep client with gPAS domain service definitions
|
|
179
|
+
:return: list of all available domains as domain response instances
|
|
180
|
+
"""
|
|
181
|
+
domains = _serialize_dict(client.service.listDomains())
|
|
182
|
+
return [DomainResponseSchema().load(domain) for domain in domains]
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def delete_domain(client: Client, domain_name: str) -> None:
|
|
186
|
+
"""
|
|
187
|
+
Deletes a domain that matches the specified name. Raises a Fault if there is no domain with such a name.
|
|
188
|
+
|
|
189
|
+
:param client: Zeep client with gPAS domain service definitions
|
|
190
|
+
:param domain_name: name of the domain to delete
|
|
191
|
+
"""
|
|
192
|
+
client.service.deleteDomainWithPSNs(domainName=domain_name)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class GPASClient(WSDLClient):
|
|
196
|
+
"""
|
|
197
|
+
This class is a wrapper around the gPAS service functions.
|
|
198
|
+
"""
|
|
199
|
+
|
|
200
|
+
def __init__(self, client: Client | str, domain_client: Client | str):
|
|
201
|
+
"""
|
|
202
|
+
Constructs a new SOAP client for gPAS service definitions.
|
|
203
|
+
|
|
204
|
+
:param client: URL to WSDL endpoint or zeep instance with WSDL information for the gPAS service
|
|
205
|
+
:param domain_client: URL to WSDL endpoint or zeep instance with WSDL information for the gPAS management
|
|
206
|
+
service
|
|
207
|
+
"""
|
|
208
|
+
super().__init__(client)
|
|
209
|
+
self._domain_client = _cast_client(domain_client)
|
|
210
|
+
|
|
211
|
+
def delete_entry(self, domain_name: str, value: str) -> None:
|
|
212
|
+
"""
|
|
213
|
+
Deletes a value and its associated pseudonym from the specified data domain.
|
|
214
|
+
|
|
215
|
+
:param domain_name: name of the domain where the value is present
|
|
216
|
+
:param value: value to remove
|
|
217
|
+
"""
|
|
218
|
+
delete_entry(self._client, domain_name, value)
|
|
219
|
+
|
|
220
|
+
def delete_entries(self, domain_name: str, values: list[str]) -> list[KeyValueTuple]:
|
|
221
|
+
"""
|
|
222
|
+
Deletes a list of values and their associated pseudonyms from the specified data domain.
|
|
223
|
+
|
|
224
|
+
:param domain_name: name of the domain where the value is present
|
|
225
|
+
:param values: list of values to remove
|
|
226
|
+
:return: list of key-value pairs where the key is the value that was requested to be deleted, and the value is
|
|
227
|
+
an indicator whether deletion was successful or not
|
|
228
|
+
"""
|
|
229
|
+
return delete_entries(self._client, domain_name, values)
|
|
230
|
+
|
|
231
|
+
def get_or_create_pseudonym_for(self, domain_name: str, value: str) -> str:
|
|
232
|
+
"""
|
|
233
|
+
Requests a new pseudonym for a value in the specified data domain.
|
|
234
|
+
|
|
235
|
+
:param domain_name: name of the domain where the value is supposed to be inserted
|
|
236
|
+
:param value: value to insert
|
|
237
|
+
:return: pseudonym that is assigned to the value
|
|
238
|
+
"""
|
|
239
|
+
return get_or_create_pseudonym_for(self._client, domain_name, value)
|
|
240
|
+
|
|
241
|
+
def get_or_create_pseudonym_for_list(self, domain_name: str, values: list[str]) -> list[KeyValueTuple]:
|
|
242
|
+
"""
|
|
243
|
+
Request new pseudonyms for a list of values in the specified data domain.
|
|
244
|
+
|
|
245
|
+
:param domain_name: name of the domain where the value is supposed to be inserted
|
|
246
|
+
:param values: list of values to insert
|
|
247
|
+
:return: list of key-value pairs where the key is the original value that is supposed to be pseudonymized,
|
|
248
|
+
and the value is the assigned pseudonym
|
|
249
|
+
"""
|
|
250
|
+
return get_or_create_pseudonym_for_list(self._client, domain_name, values)
|
|
251
|
+
|
|
252
|
+
def get_value_for(self, domain_name: str, pseudonym: str) -> str:
|
|
253
|
+
"""
|
|
254
|
+
Gets the value for a pseudonym in the specified data domain.
|
|
255
|
+
|
|
256
|
+
:param domain_name: name of the domain where the pseudonym is present
|
|
257
|
+
:param pseudonym: pseudonym to resolve
|
|
258
|
+
:return: value assigned to the pseudonym
|
|
259
|
+
"""
|
|
260
|
+
return get_value_for(self._client, domain_name, pseudonym)
|
|
261
|
+
|
|
262
|
+
def get_value_for_list(self, domain_name: str, pseudonyms: list[str]) -> list[KeyValueTuple]:
|
|
263
|
+
"""
|
|
264
|
+
Gets the values for a list of pseudonyms in the specified data domain.
|
|
265
|
+
|
|
266
|
+
:param domain_name: name of the domain where the pseudonyms are present
|
|
267
|
+
:param pseudonyms: pseudonyms to resolve
|
|
268
|
+
:return: list of key-value pairs, structured as { pseudonym => value }
|
|
269
|
+
"""
|
|
270
|
+
return get_value_for_list(self._client, domain_name, pseudonyms)
|
|
271
|
+
|
|
272
|
+
def get_pseudonym_for(self, domain_name: str, value: str) -> str:
|
|
273
|
+
"""
|
|
274
|
+
Gets the pseudonym for a value in the specified data domain.
|
|
275
|
+
|
|
276
|
+
:param domain_name: name of the domain where the value is present
|
|
277
|
+
:param value: value to resolve
|
|
278
|
+
:return: pseudonym assigned to the value
|
|
279
|
+
"""
|
|
280
|
+
return get_pseudonym_for(self._client, domain_name, value)
|
|
281
|
+
|
|
282
|
+
def get_pseudonym_for_list(self, domain_name: str, values: list[str]) -> list[KeyValueTuple]:
|
|
283
|
+
"""
|
|
284
|
+
Gets the pseudonyms for a list of values in the specified data domain.
|
|
285
|
+
|
|
286
|
+
:param domain_name: name of the domain where the values are present
|
|
287
|
+
:param values: values to resolve
|
|
288
|
+
:return: list of key-value pairs, structured as { value => pseudonym }
|
|
289
|
+
"""
|
|
290
|
+
return get_pseudonym_for_list(self._client, domain_name, values)
|
|
291
|
+
|
|
292
|
+
def insert_value_pseudonym_pair(self, domain_name: str, value: str, pseudonym: str) -> None:
|
|
293
|
+
"""
|
|
294
|
+
Manually inserts a value and a pseudonym into the specified data domain.
|
|
295
|
+
|
|
296
|
+
:param domain_name: name of the domain to insert the pair into
|
|
297
|
+
:param value: value to add
|
|
298
|
+
:param pseudonym: pseudonym to assign to the value
|
|
299
|
+
"""
|
|
300
|
+
insert_value_pseudonym_pair(self._client, domain_name, value, pseudonym)
|
|
301
|
+
|
|
302
|
+
def insert_value_pseudonym_pairs(self, domain_name: str, pairs: list[KeyValueTuple]) -> None:
|
|
303
|
+
"""
|
|
304
|
+
Manually inserts a list of values and pseudonyms into the specified data domain.
|
|
305
|
+
|
|
306
|
+
:param domain_name: name of the domain to insert the pairs into
|
|
307
|
+
:param pairs: list of key-value pairs, structured as { value => pseudonym }
|
|
308
|
+
"""
|
|
309
|
+
insert_value_pseudonym_pairs(self._client, domain_name, pairs)
|
|
310
|
+
|
|
311
|
+
def add_domain(self, domain: Domain) -> None:
|
|
312
|
+
"""
|
|
313
|
+
Adds a new domain.
|
|
314
|
+
|
|
315
|
+
:param domain: domain data class to create
|
|
316
|
+
"""
|
|
317
|
+
add_domain(self._domain_client, domain)
|
|
318
|
+
|
|
319
|
+
def get_domain(self, domain_name: str) -> DomainResponse:
|
|
320
|
+
"""
|
|
321
|
+
Gets a domain that matches the specified name. Raises a Fault if there is no domain with such a name.
|
|
322
|
+
|
|
323
|
+
:param domain_name: name of the domain to get
|
|
324
|
+
:return: domain response instance
|
|
325
|
+
"""
|
|
326
|
+
return get_domain(self._domain_client, domain_name)
|
|
327
|
+
|
|
328
|
+
def list_domains(self) -> list[DomainResponse]:
|
|
329
|
+
"""
|
|
330
|
+
Lists all available domains in the gPAS instance.
|
|
331
|
+
|
|
332
|
+
:return: list of all available domains as domain response instances
|
|
333
|
+
"""
|
|
334
|
+
return list_domains(self._domain_client)
|
|
335
|
+
|
|
336
|
+
def delete_domain(self, domain_name: str) -> None:
|
|
337
|
+
"""
|
|
338
|
+
Deletes a domain that matches the specified name. Raises a Fault if there is no domain with such a name.
|
|
339
|
+
|
|
340
|
+
:param domain_name: name of the domain to delete
|
|
341
|
+
"""
|
|
342
|
+
delete_domain(self._domain_client, domain_name)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
Alphabet = (
|
|
6
|
+
Literal[
|
|
7
|
+
"org.emau.icmvc.ganimed.ttp.psn.alphabets.Hex",
|
|
8
|
+
"org.emau.icmvc.ganimed.ttp.psn.alphabets.Numbers",
|
|
9
|
+
"org.emau.icmvc.ganimed.ttp.psn.alphabets.NumbersWithoutZero",
|
|
10
|
+
"org.emau.icmvc.ganimed.ttp.psn.alphabets.NumbersX",
|
|
11
|
+
"org.emau.icmvc.ganimed.ttp.psn.alphabets.Symbol31",
|
|
12
|
+
"org.emau.icmvc.ganimed.ttp.psn.alphabets.Symbol32",
|
|
13
|
+
]
|
|
14
|
+
| str
|
|
15
|
+
)
|
|
16
|
+
ForceCache = Literal["DEFAULT", "OFF", "ON"]
|
|
17
|
+
ValidateViaParents = Literal["CASCADE_DELETE", "ENSURE_EXISTS", "OFF", "VALIDATE"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass(frozen=True)
|
|
21
|
+
class DomainConfig:
|
|
22
|
+
"""
|
|
23
|
+
Configuration settings for gPAS domains.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
psn_prefix: str | None = None
|
|
27
|
+
psn_suffix: str | None = None
|
|
28
|
+
include_prefix_in_check_digit_calculation: bool = False
|
|
29
|
+
include_suffix_in_check_digit_calculation: bool = False
|
|
30
|
+
max_detected_errors: int = 2
|
|
31
|
+
multi_psn_domain: bool = False
|
|
32
|
+
psn_length: int = 8
|
|
33
|
+
psns_deletable: bool = False
|
|
34
|
+
send_notifications_web: bool = False
|
|
35
|
+
use_last_char_as_delimiter_after_x_chars: int = 0
|
|
36
|
+
force_cache: ForceCache = "DEFAULT"
|
|
37
|
+
validate_values_via_parents: ValidateViaParents = "OFF"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(frozen=True)
|
|
41
|
+
class Domain:
|
|
42
|
+
"""
|
|
43
|
+
Describes a gPAS domain.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
label: str
|
|
47
|
+
name: str
|
|
48
|
+
config: DomainConfig = field(default_factory=DomainConfig)
|
|
49
|
+
alphabet: Alphabet = "org.emau.icmvc.ganimed.ttp.psn.alphabets.Numbers"
|
|
50
|
+
check_digit_class: str = "org.emau.icmvc.ganimed.ttp.psn.generator.Verhoeff"
|
|
51
|
+
comment: str | None = None
|
|
52
|
+
parent_domain_names: list[str] = field(default_factory=list)
|
|
53
|
+
expiration_properties: None = None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass(frozen=True, kw_only=True)
|
|
57
|
+
class DomainResponse(Domain):
|
|
58
|
+
"""
|
|
59
|
+
Further information about a domain that are available after a domain was created.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
child_domain_names: list[str]
|
|
63
|
+
number_of_pseudonyms: int
|
|
64
|
+
number_of_anonyms: int
|
|
65
|
+
cache_used: bool
|
|
66
|
+
percent_psns_used: float
|
|
67
|
+
create_date: datetime
|
|
68
|
+
update_date: datetime
|
|
69
|
+
create_date_string: str
|
|
70
|
+
update_date_string: str
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from marshmallow import Schema, fields, post_load
|
|
2
|
+
|
|
3
|
+
from mosaic_client.gpas.models import Domain, DomainConfig, DomainResponse
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DomainConfigSchema(Schema):
|
|
7
|
+
psn_prefix = fields.Str(data_key="psnPrefix", allow_none=True)
|
|
8
|
+
psn_suffix = fields.Str(data_key="psnSuffix", allow_none=True)
|
|
9
|
+
include_prefix_in_check_digit_calculation = fields.Bool(data_key="includePrefixInCheckDigitCalculation")
|
|
10
|
+
include_suffix_in_check_digit_calculation = fields.Bool(data_key="includeSuffixInCheckDigitCalculation")
|
|
11
|
+
max_detected_errors = fields.Int(data_key="maxDetectedErrors")
|
|
12
|
+
multi_psn_domain = fields.Bool(data_key="multiPsnDomain")
|
|
13
|
+
psn_length = fields.Int(data_key="psnLength")
|
|
14
|
+
psns_deletable = fields.Bool(data_key="psnsDeletable")
|
|
15
|
+
send_notifications_web = fields.Bool(data_key="sendNotificationsWeb")
|
|
16
|
+
use_last_char_as_delimiter_after_x_chars = fields.Int(data_key="useLastCharAsDelimiterAfterXChars")
|
|
17
|
+
validate_values_via_parents = fields.Str(data_key="validateValuesViaParents")
|
|
18
|
+
force_cache = fields.Str(data_key="forceCache")
|
|
19
|
+
|
|
20
|
+
@post_load
|
|
21
|
+
def make_domain_config(self, data, **kwargs) -> DomainConfig:
|
|
22
|
+
return DomainConfig(**data)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DomainSchema(Schema):
|
|
26
|
+
label = fields.Str(required=True)
|
|
27
|
+
name = fields.Str(required=True)
|
|
28
|
+
config = fields.Nested(DomainConfigSchema())
|
|
29
|
+
alphabet = fields.Str()
|
|
30
|
+
check_digit_class = fields.Str(data_key="checkDigitClass")
|
|
31
|
+
comment = fields.Str(allow_none=True)
|
|
32
|
+
parent_domain_names = fields.List(fields.Str(), data_key="parentDomainNames")
|
|
33
|
+
expiration_properties = fields.Constant(None, data_key="expirationProperties")
|
|
34
|
+
|
|
35
|
+
@post_load
|
|
36
|
+
def make_domain(self, data, **kwargs) -> Domain:
|
|
37
|
+
return Domain(**data)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DomainResponseSchema(DomainSchema):
|
|
41
|
+
child_domain_names = fields.List(fields.Str(), data_key="childDomainNames")
|
|
42
|
+
number_of_pseudonyms = fields.Int(data_key="numberOfPseudonyms")
|
|
43
|
+
number_of_anonyms = fields.Int(data_key="numberOfAnonyms")
|
|
44
|
+
cache_used = fields.Bool(data_key="cacheUsed")
|
|
45
|
+
percent_psns_used = fields.Float(data_key="percentPsnsUsed")
|
|
46
|
+
create_date = fields.DateTime(data_key="createDate")
|
|
47
|
+
update_date = fields.DateTime(data_key="updateDate")
|
|
48
|
+
create_date_string = fields.Str(data_key="createDateString")
|
|
49
|
+
update_date_string = fields.Str(data_key="updateDateString")
|
|
50
|
+
|
|
51
|
+
@post_load
|
|
52
|
+
def make_domain(self, data, **kwargs) -> DomainResponse:
|
|
53
|
+
return DomainResponse(**data)
|
mosaic_client/helpers.py
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains helper functions that are used all throughout the mosaic_client library.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
import zeep.helpers
|
|
8
|
+
from zeep import Client
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _serialize_dict(obj: Any) -> Any:
|
|
12
|
+
"""
|
|
13
|
+
Converts a zeep response object into a dict or list, depending on the structure of the
|
|
14
|
+
response data.
|
|
15
|
+
|
|
16
|
+
:param obj: object to convert
|
|
17
|
+
:return: object as dict or list
|
|
18
|
+
"""
|
|
19
|
+
return zeep.helpers.serialize_object(obj, dict)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _malformed_key_value_response(reason: str) -> ValueError:
|
|
23
|
+
"""
|
|
24
|
+
Returns a ValueError informing about an incorrectly structured key-value response.
|
|
25
|
+
|
|
26
|
+
:param reason: reason for error
|
|
27
|
+
:return: ValueError with specified reason
|
|
28
|
+
"""
|
|
29
|
+
return ValueError(f"key-value response is malformed: {reason}")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _read_key_value_list(entry_list: list) -> list[tuple[Any, Any]]:
|
|
33
|
+
"""
|
|
34
|
+
Reads a list of objects structured as [{ "key", "value" }] into a list of tuples
|
|
35
|
+
where the first value of the tuple is the key and the second is the value. This function
|
|
36
|
+
will throw a ValueError if the list passed into this function is malformed.
|
|
37
|
+
|
|
38
|
+
:param entry_list: list of objects to parse
|
|
39
|
+
:return: list of key-value tuples
|
|
40
|
+
"""
|
|
41
|
+
key_value_lst: list[tuple[Any, Any]] = []
|
|
42
|
+
|
|
43
|
+
for i in range(len(entry_list)):
|
|
44
|
+
entry = entry_list[i]
|
|
45
|
+
|
|
46
|
+
# check for "key" key
|
|
47
|
+
if "key" not in entry:
|
|
48
|
+
raise _malformed_key_value_response(f"'entry[{i}]' is missing 'key' attribute")
|
|
49
|
+
|
|
50
|
+
# check for "value" key
|
|
51
|
+
if "value" not in entry:
|
|
52
|
+
raise _malformed_key_value_response(f"'entry[{i}]' is missing 'value' attribute")
|
|
53
|
+
|
|
54
|
+
key_value_lst.append((entry["key"], entry["value"]))
|
|
55
|
+
|
|
56
|
+
return key_value_lst
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _read_key_value_entry_response(response: Any) -> list[tuple[Any, Any]]:
|
|
60
|
+
"""
|
|
61
|
+
Reads an object structured as { "entry": [{ "key", "value" }] } into a list of tuples
|
|
62
|
+
where the first value of the tuple is the key and the second is the value. This function
|
|
63
|
+
will throw a ValueError if the object passed into this function is malformed.
|
|
64
|
+
|
|
65
|
+
:param response: object to parse
|
|
66
|
+
:return: list of key-value tuples
|
|
67
|
+
"""
|
|
68
|
+
# check that it's actually a dict
|
|
69
|
+
if type(response) != dict:
|
|
70
|
+
raise _malformed_key_value_response("not an object")
|
|
71
|
+
|
|
72
|
+
# check for "entry" key
|
|
73
|
+
if "entry" not in response:
|
|
74
|
+
raise _malformed_key_value_response("'entry' attribute is missing")
|
|
75
|
+
|
|
76
|
+
# "entry" key should hold list of key-value entries
|
|
77
|
+
response_entry_lst = response["entry"]
|
|
78
|
+
|
|
79
|
+
# check that it's actually a list
|
|
80
|
+
if type(response_entry_lst) != list:
|
|
81
|
+
raise _malformed_key_value_response("'entry' value is not a list")
|
|
82
|
+
|
|
83
|
+
return _read_key_value_list(response_entry_lst)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _cast_client(client: Client | str) -> Client:
|
|
87
|
+
"""
|
|
88
|
+
Takes zeep client instances or wsdl urls as strings and either just returns the given client instance or creates
|
|
89
|
+
one if a string was given. Raises a TypeError if the given client is neither a zeep client nor a string.
|
|
90
|
+
|
|
91
|
+
:param client: client instance or wsdl url as a string
|
|
92
|
+
:return: zeep client instance
|
|
93
|
+
"""
|
|
94
|
+
if isinstance(client, Client):
|
|
95
|
+
pass
|
|
96
|
+
elif isinstance(client, str):
|
|
97
|
+
client = Client(client)
|
|
98
|
+
else:
|
|
99
|
+
raise TypeError(f"unsupported constructor argument type: {type(client)}")
|
|
100
|
+
|
|
101
|
+
return client
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class WSDLClient:
|
|
105
|
+
"""
|
|
106
|
+
Generic SOAP client base.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
def __init__(self, client: Client | str):
|
|
110
|
+
"""
|
|
111
|
+
Constructs a new SOAP client.
|
|
112
|
+
|
|
113
|
+
:param client: URL to WSDL endpoint or zeep instance with WSDL information
|
|
114
|
+
"""
|
|
115
|
+
self._client = _cast_client(client)
|