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.
@@ -0,0 +1,487 @@
1
+ """
2
+ This module contains model classes of objects, which are commonly used in E-PIX and gPAS.
3
+ """
4
+
5
+ from dataclasses import dataclass, field
6
+ from datetime import datetime
7
+ from enum import StrEnum
8
+ from typing import Any, Literal, TypedDict
9
+
10
+ MatchingMode = Literal["MATCHING_IDENTITIES", "NO_DECISION"]
11
+ PersistMode = Literal["IDENTIFYING", "PRIVACY_PRESERVING"]
12
+ HashingAlgorithm = Literal["RandomHashingStrategy", "DoubleHashingStrategy", "DoubleHashingStrategyFaster"]
13
+ UpdateBehaviour = Literal["DEFAULT", "OVERWRITE_ALL", "UPDATE_ALL_ADD_MISSING"]
14
+ ValidatorOperator = Literal["ALL", "ALL_OR_NONE", "AT_LEAST_ONE", "EXACT_ONE"]
15
+ MatchingAlgorithm = Literal[
16
+ "org.emau.icmvc.ttp.deduplication.impl.LevenshteinAlgorithm",
17
+ "org.emau.icmvc.ttp.deduplication.impl.ColognePhoneticAlgorithm",
18
+ "org.emau.icmvc.ttp.deduplication.impl.DeterministicAlgorithm",
19
+ "org.emau.icmvc.ttp.deduplication.impl.SorensenDiceCoefficientAlgorithmCoded",
20
+ "org.emau.icmvc.ttp.deduplication.impl.JaccardSimilarityAlgorithmCoded",
21
+ "org.emau.icmvc.ttp.deduplication.impl.SorensenDiceCoefficient",
22
+ "org.emau.icmvc.ttp.deduplication.impl.JaccardSimilarityAlgorithm",
23
+ ]
24
+ BlockingMode = Literal["NUMBERS", "TEXT"]
25
+ MPIGenerator = Literal["org.emau.icmvc.ttp.epix.gen.impl.EAN13Generator"]
26
+
27
+
28
+ class EntryType(TypedDict):
29
+ entry: list[dict[Any, Any]]
30
+
31
+
32
+ class FieldName(StrEnum):
33
+ birth_date = "birthDate"
34
+ birth_place = "birthPlace"
35
+ civil_status = "civilStatus"
36
+ death_date = "dateOfDeath"
37
+ degree = "degree"
38
+ external_date = "externalDate"
39
+ first_name = "firstName"
40
+ gender = "gender"
41
+ last_name = "lastName"
42
+ middle_name = "middleName"
43
+ mothers_maiden_name = "mothersMaidenName"
44
+ mother_tongue = "motherTongue"
45
+ nationality = "nationality"
46
+ prefix = "prefix"
47
+ race = "race"
48
+ religion = "religion"
49
+ suffix = "suffix"
50
+ value_1 = "value1"
51
+ value_2 = "value2"
52
+ value_3 = "value3"
53
+ value_4 = "value4"
54
+ value_5 = "value5"
55
+ value_6 = "value6"
56
+ value_7 = "value7"
57
+ value_8 = "value8"
58
+ value_9 = "value9"
59
+ value_10 = "value10"
60
+ vital_status = "vitalStatus"
61
+
62
+
63
+ @dataclass(frozen=True)
64
+ class IdentifierDomain:
65
+ """
66
+ Describes a value domain used to generate identifiers.
67
+ """
68
+
69
+ name: str
70
+ label: str
71
+ oid: str | None = None
72
+ description: str | None = None
73
+ entry_date: datetime | None = None
74
+ update_date: datetime | None = None
75
+
76
+
77
+ @dataclass(frozen=True)
78
+ class Identifier:
79
+ """
80
+ Represents an identifier sourced from a specific value domain.
81
+ """
82
+
83
+ value: str
84
+ identifier_domain: IdentifierDomain
85
+ entry_date: datetime | None = None
86
+ description: str | None = None
87
+ fresh: bool | None = None
88
+
89
+
90
+ @dataclass(frozen=True)
91
+ class Contact:
92
+ """
93
+ Assigned to an identity to designate contact details.
94
+ """
95
+
96
+ city: str | None = None
97
+ country: str | None = None
98
+ country_code: str | None = None
99
+ district: str | None = None
100
+ email: str | None = None
101
+ external_date: datetime | None = None
102
+ municipality_key: str | None = None
103
+ phone: str | None = None
104
+ state: str | None = None
105
+ street: str | None = None
106
+ zip_code: str | None = None
107
+
108
+
109
+ @dataclass(frozen=True)
110
+ class FullContact(Contact):
111
+ """
112
+ Contact with additional metadata.
113
+ """
114
+
115
+ contact_created: datetime | None = None
116
+ contact_id: int | None = None
117
+ contact_last_edited: datetime | None = None
118
+ contact_version: int | None = None
119
+ deactivated: bool | None = None
120
+ identity_id: int | None = None
121
+
122
+
123
+ @dataclass(frozen=True)
124
+ class Identity:
125
+ """
126
+ Identifying information about a real-world entity.
127
+ """
128
+
129
+ birth_date: datetime | None = None
130
+ birth_place: str | None = None
131
+ civil_status: str | None = None
132
+ degree: str | None = None
133
+ external_date: datetime | None = None
134
+ first_name: str | None = None
135
+ gender: str | None = None
136
+ identifiers: list[Identifier] = field(default_factory=list)
137
+ last_name: str | None = None
138
+ middle_name: str | None = None
139
+ mother_tongue: str | None = None
140
+ mothers_maiden_name: str | None = None
141
+ nationality: str | None = None
142
+ vital_status: str | None = None
143
+ death_date: datetime | None = None
144
+ prefix: str | None = None
145
+ race: str | None = None
146
+ religion: str | None = None
147
+ suffix: str | None = None
148
+ value_1: str | None = None
149
+ value_2: str | None = None
150
+ value_3: str | None = None
151
+ value_4: str | None = None
152
+ value_5: str | None = None
153
+ value_6: str | None = None
154
+ value_7: str | None = None
155
+ value_8: str | None = None
156
+ value_9: str | None = None
157
+ value_10: str | None = None
158
+ contacts: list[Contact] = field(default_factory=list)
159
+
160
+
161
+ @dataclass(frozen=True)
162
+ class Source:
163
+ """
164
+ Data source from which information is gathered.
165
+ """
166
+
167
+ name: str
168
+ description: str | None = None
169
+ label: str | None = None
170
+ entry_date: datetime | None = None
171
+ update_date: datetime | None = None
172
+
173
+
174
+ @dataclass(frozen=True)
175
+ class FullIdentity(Identity):
176
+ """
177
+ Identity with additional metadata.
178
+ """
179
+
180
+ deactivated: bool | None = None
181
+ identity_created: datetime | None = None
182
+ identity_id: int | None = None
183
+ identity_last_edited: datetime | None = None
184
+ identity_version: int | None = None
185
+ person_id: int | None = None
186
+ source: Source | None = None
187
+ contacts: list[FullContact] = field(default_factory=list)
188
+
189
+
190
+ @dataclass(frozen=True)
191
+ class Person:
192
+ """
193
+ State of an identity inside a data source.
194
+ """
195
+
196
+ deactivated: bool
197
+ mpi_id: Identifier
198
+ person_created: datetime
199
+ person_id: int
200
+ person_last_edited: datetime
201
+ other_identities: list[FullIdentity]
202
+ reference_identity: FullIdentity
203
+ domain_name: str
204
+
205
+ def mpi(self) -> str:
206
+ """
207
+ Convenience function to quickly obtain the MPI of this person.
208
+
209
+ :return: MPI associated to this person
210
+ """
211
+ return self.mpi_id.value
212
+
213
+ def identity_id(self) -> int | None:
214
+ """
215
+ Convenience function to quickly obtain the identity ID of this person.
216
+
217
+ :return: Identity ID associated to this person
218
+ """
219
+ return self.reference_identity.identity_id
220
+
221
+
222
+ @dataclass(frozen=True)
223
+ class ResponseEntry:
224
+ """
225
+ Response sent back by E-PIX on an MPI request. Contains information on whether the requested
226
+ identity was already found in the data source.
227
+ """
228
+
229
+ match_status: str
230
+ person: Person
231
+ mpi_error_code: str | None
232
+
233
+
234
+ @dataclass(frozen=True)
235
+ class BatchResponseEntry(ResponseEntry):
236
+ """
237
+ Response sent back by E-PIX on a batch MPI request. Contains the same info as a normal
238
+ MPI request, but also includes the request identity.
239
+ """
240
+
241
+ identity: Identity
242
+
243
+
244
+ @dataclass(frozen=True)
245
+ class BatchRequestConfig:
246
+ """
247
+ Configuration on how a batch request should be handled.
248
+ """
249
+
250
+ force_reference_update: bool
251
+ save_action: str
252
+
253
+
254
+ @dataclass(frozen=True)
255
+ class Reason:
256
+ """
257
+ Reason for resolving a possible match. Gets used for the configuration of a domain.
258
+ """
259
+
260
+ name: str
261
+ description: str | None = None
262
+
263
+
264
+ @dataclass(frozen=True)
265
+ class Deduplication:
266
+ """
267
+ List of reasons for resolving a possible match. Gets used for the configuration of a domain.
268
+ """
269
+
270
+ reasons: list[Reason] = field(default_factory=list)
271
+
272
+
273
+ @dataclass(frozen=True)
274
+ class SourceField:
275
+ """
276
+ Source fields that are hashed into Bloom filters.
277
+ """
278
+
279
+ name: FieldName
280
+ seed: int
281
+
282
+
283
+ @dataclass(frozen=True)
284
+ class Balanced:
285
+ """
286
+ Indicates and seeds the balancing of Bloom filters.
287
+ """
288
+
289
+ seed: int
290
+
291
+
292
+ @dataclass(frozen=True)
293
+ class BloomFilterConfig:
294
+ """
295
+ Configuration on how Bloom filters should be generated.
296
+ """
297
+
298
+ storing_field: FieldName
299
+ algorithm: HashingAlgorithm | str = "RandomHashingStrategy"
300
+ alphabet: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ .-0123456789mfoux"
301
+ balanced: Balanced | None = None
302
+ bits_per_ngram: int = 15
303
+ fold: int = 0
304
+ length: int = 1_000
305
+ ngrams: int = 2
306
+ source_fields: list[SourceField] = field(default_factory=list)
307
+
308
+
309
+ @dataclass(frozen=True)
310
+ class Privacy:
311
+ """
312
+ Container for storing all Bloom filter configurations.
313
+ """
314
+
315
+ bloom_filter_configs: list[BloomFilterConfig] = field(default_factory=list)
316
+
317
+
318
+ @dataclass(frozen=True)
319
+ class Validator:
320
+ """
321
+ Defines the name of Java validator class and suitable criterion for that validator. Validators are part of a
322
+ validation config which is part of the domain config.
323
+ """
324
+
325
+ qualified_class_name: str
326
+ criterion: str
327
+
328
+
329
+ @dataclass(frozen=True)
330
+ class ValidatorGroup:
331
+ """
332
+ Groups validators and combines their result through a logical operator. Validator groups can be nested.
333
+ """
334
+
335
+ operator: ValidatorOperator
336
+ validators: list[Validator] = field(default_factory=list)
337
+ validator_groups: list["ValidatorGroup"] = field(default_factory=list)
338
+
339
+
340
+ @dataclass(frozen=True)
341
+ class ValidatorConfig:
342
+ """
343
+ Container of the configuration for a validator.
344
+ """
345
+
346
+ field_name: FieldName
347
+ validator: Validator
348
+ validator_group: ValidatorGroup | None = None
349
+
350
+
351
+ @dataclass(frozen=True)
352
+ class Validation:
353
+ """
354
+ Container for all validator configs.
355
+ """
356
+
357
+ validation_configs: list[ValidatorConfig] = field(default_factory=list)
358
+
359
+
360
+ @dataclass(frozen=True)
361
+ class PreprocessingField:
362
+ """
363
+ Defines preprocessing transformations and filers for a specific field.
364
+ """
365
+
366
+ field_name: FieldName
367
+ complex_transformation_classes: list[str] = field(default_factory=list)
368
+ simple_filter_types: EntryType | None = None
369
+ simple_transformation_types: EntryType | None = None
370
+
371
+
372
+ @dataclass(frozen=True)
373
+ class FieldMatchingConfig:
374
+ """
375
+ Container for a matching configuration per field.
376
+ """
377
+
378
+ name: FieldName
379
+ algorithm: MatchingAlgorithm | str
380
+ blocking_mode: BlockingMode
381
+ blocking_threshold: float
382
+ matching_threshold: float
383
+ weight: float
384
+ multiple_values_separator: int = 0 # ASCII-value of a character.
385
+ penalty_both_short: float = 0.0
386
+ penalty_not_a_perfect_match: float = 0.0
387
+ penalty_one_short: float = 0.0
388
+
389
+
390
+ def _default_field_matching_configs() -> list[FieldMatchingConfig]:
391
+ """
392
+ Field matching config defaults that are used in the E-PIX web UI.
393
+
394
+ :return: list of default field matching configs
395
+ """
396
+ return [
397
+ FieldMatchingConfig(
398
+ name=FieldName.first_name,
399
+ algorithm="org.emau.icmvc.ttp.deduplication.impl.LevenshteinAlgorithm",
400
+ blocking_mode="TEXT",
401
+ blocking_threshold=0.4,
402
+ matching_threshold=0.8,
403
+ weight=8.0,
404
+ ),
405
+ FieldMatchingConfig(
406
+ name=FieldName.last_name,
407
+ algorithm="org.emau.icmvc.ttp.deduplication.impl.LevenshteinAlgorithm",
408
+ blocking_mode="TEXT",
409
+ blocking_threshold=0.0,
410
+ matching_threshold=0.8,
411
+ weight=6.0,
412
+ ),
413
+ FieldMatchingConfig(
414
+ name=FieldName.gender,
415
+ algorithm="org.emau.icmvc.ttp.deduplication.impl.LevenshteinAlgorithm",
416
+ blocking_mode="TEXT",
417
+ blocking_threshold=0.0,
418
+ matching_threshold=0.75,
419
+ weight=3.0,
420
+ ),
421
+ FieldMatchingConfig(
422
+ name=FieldName.birth_date,
423
+ algorithm="org.emau.icmvc.ttp.deduplication.impl.LevenshteinAlgorithm",
424
+ blocking_mode="NUMBERS",
425
+ blocking_threshold=0.6,
426
+ matching_threshold=1.0,
427
+ weight=9.0,
428
+ ),
429
+ ]
430
+
431
+
432
+ @dataclass(frozen=True)
433
+ class MatchingConfig:
434
+ """
435
+ Container for the matching config for all fields of a specific domain.
436
+ """
437
+
438
+ fields: list[FieldMatchingConfig] = field(default_factory=_default_field_matching_configs)
439
+ number_of_threads: int = 16
440
+ parallel_matching_after: int = 1_000
441
+ threshold_automatic_match: float = 1001.0
442
+ threshold_possible_match: float = 1001.0
443
+ use_cemfim: bool = False
444
+
445
+
446
+ @dataclass(frozen=True)
447
+ class DomainConfiguration:
448
+ """
449
+ Container for all configurations of a domain.
450
+ """
451
+
452
+ mpi_generator: MPIGenerator | str = "org.emau.icmvc.ttp.epix.gen.impl.EAN13Generator"
453
+ mpi_prefix: str = "1001"
454
+ persist_mode: PersistMode = "IDENTIFYING"
455
+ deduplication: Deduplication | None = None
456
+ privacy: Privacy | None = None
457
+ update_behaviour: UpdateBehaviour = "DEFAULT"
458
+ validation: Validation | None = None
459
+ required_fields: list[FieldName] = field(
460
+ default_factory=lambda: [FieldName.first_name, FieldName.last_name, FieldName.gender, FieldName.birth_date]
461
+ )
462
+ use_notifications: bool = False
463
+ limit_search_for_low_memory: bool = False
464
+ value_field_mapping: EntryType | None = field(default_factory=lambda: EntryType(entry=[]))
465
+ preprocessing_fields: list[PreprocessingField] = field(default_factory=list)
466
+ matching_config: MatchingConfig = field(default_factory=MatchingConfig)
467
+ matching_mode: MatchingMode = "MATCHING_IDENTITIES"
468
+
469
+
470
+ @dataclass(frozen=True)
471
+ class Domain:
472
+ """
473
+ Describes an E-PIX domain.
474
+ """
475
+
476
+ name: str
477
+ label: str
478
+ mpi_domain: IdentifierDomain
479
+ safe_source: Source
480
+ config_objects: DomainConfiguration = field(default_factory=DomainConfiguration)
481
+ description: str | None = ""
482
+ in_use: bool = True
483
+ matching_mode: MatchingMode = "MATCHING_IDENTITIES"
484
+ entry_date: datetime | None = None
485
+ update_date: datetime | None = None
486
+ person_count: int = -1
487
+ config: str | None = None