dapla-toolbelt-metadata 0.4.1__py3-none-any.whl → 0.5.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.
Potentially problematic release.
This version of dapla-toolbelt-metadata might be problematic. Click here for more details.
- dapla_metadata/__init__.py +7 -0
- dapla_metadata/dapla/__init__.py +1 -0
- dapla_metadata/{_shared → dapla}/user_info.py +55 -8
- dapla_metadata/datasets/code_list.py +1 -1
- dapla_metadata/datasets/core.py +1 -1
- dapla_metadata/datasets/dataset_parser.py +1 -1
- dapla_metadata/datasets/model_backwards_compatibility.py +6 -6
- dapla_metadata/datasets/model_validation.py +2 -2
- dapla_metadata/datasets/utility/constants.py +1 -0
- dapla_metadata/datasets/utility/enums.py +1 -1
- dapla_metadata/datasets/utility/utils.py +7 -11
- dapla_metadata/variable_definitions/__init__.py +5 -3
- dapla_metadata/variable_definitions/{generated → _generated}/.openapi-generator/FILES +0 -5
- dapla_metadata/variable_definitions/_generated/.openapi-generator/VERSION +1 -0
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/__init__.py +0 -5
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/api/__init__.py +0 -1
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/api/data_migration_api.py +2 -2
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/api/draft_variable_definitions_api.py +14 -14
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/api/patches_api.py +15 -15
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/api/validity_periods_api.py +8 -281
- dapla_metadata/variable_definitions/{generated/vardef_client/api/public_api.py → _generated/vardef_client/api/variable_definitions_api.py} +73 -358
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/__init__.py +2 -6
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/complete_response.py +8 -32
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/contact.py +2 -2
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/draft.py +8 -23
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/language_string_type.py +7 -6
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/owner.py +2 -2
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/patch.py +16 -61
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/problem.py +2 -2
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/update_draft.py +22 -55
- dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/models/validity_period.py +14 -48
- dapla_metadata/variable_definitions/_generated/vardef_client/models/variable_status.py +33 -0
- dapla_metadata/variable_definitions/_generated/vardef_client/py.typed +0 -0
- dapla_metadata/variable_definitions/_utils/__init__.py +1 -0
- dapla_metadata/variable_definitions/{_client.py → _utils/_client.py} +5 -3
- dapla_metadata/variable_definitions/{config.py → _utils/config.py} +25 -1
- dapla_metadata/variable_definitions/_utils/constants.py +41 -0
- dapla_metadata/variable_definitions/_utils/descriptions.py +86 -0
- dapla_metadata/variable_definitions/_utils/files.py +273 -0
- dapla_metadata/variable_definitions/_utils/template_files.py +112 -0
- dapla_metadata/variable_definitions/_utils/variable_definition_files.py +93 -0
- dapla_metadata/variable_definitions/exceptions.py +141 -11
- dapla_metadata/variable_definitions/resources/vardef_model_descriptions_nb.yaml +63 -0
- dapla_metadata/variable_definitions/vardef.py +131 -10
- dapla_metadata/variable_definitions/variable_definition.py +241 -43
- {dapla_toolbelt_metadata-0.4.1.dist-info → dapla_toolbelt_metadata-0.5.0.dist-info}/METADATA +5 -7
- dapla_toolbelt_metadata-0.5.0.dist-info/RECORD +84 -0
- {dapla_toolbelt_metadata-0.4.1.dist-info → dapla_toolbelt_metadata-0.5.0.dist-info}/WHEEL +1 -1
- dapla_metadata/variable_definitions/generated/.openapi-generator/VERSION +0 -1
- dapla_metadata/variable_definitions/generated/vardef_client/api/variable_definitions_api.py +0 -1205
- dapla_metadata/variable_definitions/generated/vardef_client/models/klass_reference.py +0 -99
- dapla_metadata/variable_definitions/generated/vardef_client/models/rendered_contact.py +0 -92
- dapla_metadata/variable_definitions/generated/vardef_client/models/rendered_variable_definition.py +0 -235
- dapla_metadata/variable_definitions/generated/vardef_client/models/supported_languages.py +0 -33
- dapla_metadata/variable_definitions/generated/vardef_client/models/variable_status.py +0 -33
- dapla_toolbelt_metadata-0.4.1.dist-info/RECORD +0 -80
- /dapla_metadata/{variable_definitions/generated/vardef_client → _shared}/py.typed +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/.openapi-generator-ignore +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/README.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/__init__.py +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/api_client.py +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/api_response.py +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/configuration.py +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/CompleteResponse.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/Contact.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/DataMigrationApi.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/Draft.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/DraftVariableDefinitionsApi.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/LanguageStringType.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/Owner.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/Patch.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/PatchesApi.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/PublicApi.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/SupportedLanguages.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/UpdateDraft.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/ValidityPeriod.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/ValidityPeriodsApi.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/VariableDefinitionsApi.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/docs/VariableStatus.md +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/exceptions.py +0 -0
- /dapla_metadata/variable_definitions/{generated → _generated}/vardef_client/rest.py +0 -0
- {dapla_toolbelt_metadata-0.4.1.dist-info → dapla_toolbelt_metadata-0.5.0.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# --- Variabel definisjoner ---
|
|
2
|
+
# ref: https://statistics-norway.atlassian.net/wiki/spaces/MPD/pages/3009839199/VarDef+-+Krav+til+dokumentasjon+av+variabler
|
|
3
|
+
name: |
|
|
4
|
+
Variabelens navn. Dette skal ikke være en mer “teknisk” forkortelse, men et navn som er forståelig for mennesker, f.eks. “Lønnsinntekter”.
|
|
5
|
+
short_name: |
|
|
6
|
+
Dette er variabelens kortnavn, som kan være en mer “teknisk” forkortelse, f.eks. wlonn (kortnavnet til Lønnsinntekter). Kortnavnet til en variabel i Vardef skal være unikt.
|
|
7
|
+
Kravet til kortnavnet er at det kan inneholde a-z (kun små bokstaver), 0-9 og _ (understrek). Minimumslengden på kortnavnet er 2 tegn. Bokstavene “æ”, “ø” og “å” kan ikke brukes. Disse anbefales erstattet med hhv. “ae”, “oe” og “aa"
|
|
8
|
+
definition: |
|
|
9
|
+
En definisjon skal beskrive hva variabelen betyr og være så kort og presis som mulig. Mer utfyllende opplysninger kan legges i Merknad-feltet.
|
|
10
|
+
classification_reference: |
|
|
11
|
+
Lenke (URI) til kodeverk (klassifikasjon eller kodeliste) i KLASS som beskriver verdiene variabelen kan anta. F.eks. vil variabelen “Sivilstand” ha kodeverks-URI Standard for [sivilstand](https://www.ssb.no/klass/klassifikasjoner/19).
|
|
12
|
+
unit_types: |
|
|
13
|
+
Enhetstype(r) - enheten(e) som beskrives av denne variabelen. Variabelen “sivilstand” vil f.eks. ha enhetstypen person, mens f.eks. “Produsentpris for tjenester” vil ha både foretak og bedrift som enhetstyper siden variabelen kan beskrive begge.
|
|
14
|
+
ref: https://www.ssb.no/klass/klassifikasjoner/702.
|
|
15
|
+
subject_fields: |
|
|
16
|
+
Statistikkområde(r) som variabelen brukes innenfor, hentet fra [Kodeliste for statistikkområder i Statistikkbanken](https://www.ssb.no/klass/klassifikasjoner/618).
|
|
17
|
+
F.eks. tilhører variabelen “Sivilstand” statistikkområdet “Befolkning”.
|
|
18
|
+
contains_special_categories_of_personal_data: |
|
|
19
|
+
Viser om variabelen inneholder spesielt sensitive personopplysninger [Lov om behandling av personopplysninger(personopplysningsloven)-KAPITTEL || Prinsipper - Lovdata](https://lovdata.no/dokument/NL/lov/2018-06-15-38/KAPITTEL_gdpr-2#gdpr/a9)
|
|
20
|
+
- opplysninger om etnisk opprinnelse
|
|
21
|
+
- opplysninger om politisk oppfatning
|
|
22
|
+
- opplysninger om religion
|
|
23
|
+
- opplysninger om filosofisk overbevisning
|
|
24
|
+
- opplysninger om fagforeningsmedlemskap
|
|
25
|
+
- genetiske opplysninger
|
|
26
|
+
- biometriske opplysninger med det formål å entydig identifisere noen
|
|
27
|
+
- helseopplysninger
|
|
28
|
+
- opplysninger om seksuelle forhold
|
|
29
|
+
- opplysninger om seksuell legning
|
|
30
|
+
measurement_type: |
|
|
31
|
+
Måletype som en kvantitativ variabelen tilhører, f.eks. valuta, areal osv. Disse ligger i kodeverket [SSB måletyper/måleenheter](https://www.ssb.no/klass/klassifikasjoner/303/koder)
|
|
32
|
+
valid_from: |
|
|
33
|
+
Datoen variabeldefinisjonen er gyldig f.o.m.
|
|
34
|
+
valid_until: |
|
|
35
|
+
Datoen variabeldefinisjonens var gyldig t.o.m. Settes hvis definisjonen skal erstattet av en ny definisjon (med en ny gyldighetsperiode), eller variabelen ikke lenger skal brukes.
|
|
36
|
+
external_reference_uri: |
|
|
37
|
+
En peker (URI) til ekstern definisjon/dokumentasjon, f.eks. ei webside som er relevant for variabelen.
|
|
38
|
+
comment: |
|
|
39
|
+
Her kan en sette inn eventuelle tilleggsopplysninger som ikke hører hjemme i selve definisjonen. Variabelen “Landbakgrunn” har f.eks. merknaden “Fra og med 1.1.2003 ble definisjon endret til også å trekke inn besteforeldrenes fødeland”.
|
|
40
|
+
related_variable_definition_uris: |
|
|
41
|
+
Her kan en legge inn URI(er) til andre variabler som er relevante. Eksempelvis er variabelen “Inntekt etter skatt” en beregnet variabel der “Yrkesinntekter” og “Kapitalinntekter” inngår i beregningen. En kan da legge inn deres URI-er i dette feltet.
|
|
42
|
+
contact: |
|
|
43
|
+
Her dokumenterer en navn og epost for person eller gruppe som kan svare på spørsmål.
|
|
44
|
+
variable_status: |
|
|
45
|
+
Livssyklus for variabelen. Denne har tre kategorier: Utkast, Publisert internt og Publisert eksternt.
|
|
46
|
+
id: |
|
|
47
|
+
Unik SSB identifikator for variabeldefinisjonen. Denne blir maskingenerert.
|
|
48
|
+
Variabeldefinisjoner med ulike gyldighetsperioder har samme ID (og samme kortnavn).
|
|
49
|
+
patch_id: |
|
|
50
|
+
Løpenummer som identifiserer en patch, endring, for en variabeldefinisjon.
|
|
51
|
+
owner: |
|
|
52
|
+
Eier av variabelen dvs. ansvarlig Dapla-team (statistikk-team) og informasjon om tilgangsstyringsgrupper. Team-tilhørighet settes automatisk til det samme som teamtilhørigheten til den som oppretter variabelen.
|
|
53
|
+
Eksempel:
|
|
54
|
+
team: ledstil
|
|
55
|
+
groups: [developers]
|
|
56
|
+
created_at: |
|
|
57
|
+
Datoen variabelen ble opprettet. Denne er maskingenerert.
|
|
58
|
+
created_by: |
|
|
59
|
+
Personen som har opprettet variabelen (initialer). Dette er maskingenerert.
|
|
60
|
+
last_updated_at: |
|
|
61
|
+
Dato da variabelen sist ble oppdatert. Denne er maskingenerert.
|
|
62
|
+
last_updated_by: |
|
|
63
|
+
Personen (initialer) som sist utførte en endring i variabelen. Denne er maskingenerert.
|
|
@@ -1,22 +1,38 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from datetime import date
|
|
3
|
+
from os import PathLike
|
|
4
|
+
from pathlib import Path
|
|
2
5
|
|
|
3
|
-
from dapla_metadata.variable_definitions import
|
|
4
|
-
from dapla_metadata.variable_definitions._client import VardefClient
|
|
5
|
-
from dapla_metadata.variable_definitions.exceptions import vardef_exception_handler
|
|
6
|
-
from dapla_metadata.variable_definitions.generated.vardef_client.api.data_migration_api import (
|
|
6
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.api.data_migration_api import (
|
|
7
7
|
DataMigrationApi,
|
|
8
8
|
)
|
|
9
|
-
from dapla_metadata.variable_definitions.
|
|
9
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.api.draft_variable_definitions_api import (
|
|
10
10
|
DraftVariableDefinitionsApi,
|
|
11
11
|
)
|
|
12
|
-
from dapla_metadata.variable_definitions.
|
|
12
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.api.variable_definitions_api import (
|
|
13
13
|
VariableDefinitionsApi,
|
|
14
14
|
)
|
|
15
|
-
from dapla_metadata.variable_definitions.
|
|
15
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.models.draft import (
|
|
16
16
|
Draft,
|
|
17
17
|
)
|
|
18
|
+
from dapla_metadata.variable_definitions._utils import config
|
|
19
|
+
from dapla_metadata.variable_definitions._utils._client import VardefClient
|
|
20
|
+
from dapla_metadata.variable_definitions._utils.template_files import (
|
|
21
|
+
_find_latest_template_file,
|
|
22
|
+
)
|
|
23
|
+
from dapla_metadata.variable_definitions._utils.template_files import (
|
|
24
|
+
create_template_yaml,
|
|
25
|
+
)
|
|
26
|
+
from dapla_metadata.variable_definitions._utils.variable_definition_files import (
|
|
27
|
+
_read_file_to_model,
|
|
28
|
+
)
|
|
29
|
+
from dapla_metadata.variable_definitions.exceptions import VariableNotFoundError
|
|
30
|
+
from dapla_metadata.variable_definitions.exceptions import vardef_exception_handler
|
|
31
|
+
from dapla_metadata.variable_definitions.exceptions import vardef_file_error_handler
|
|
18
32
|
from dapla_metadata.variable_definitions.variable_definition import VariableDefinition
|
|
19
33
|
|
|
34
|
+
logger = logging.getLogger(__name__)
|
|
35
|
+
|
|
20
36
|
|
|
21
37
|
class Vardef:
|
|
22
38
|
"""Create, maintain and read Variable Definitions.
|
|
@@ -82,7 +98,7 @@ class Vardef:
|
|
|
82
98
|
@vardef_exception_handler
|
|
83
99
|
def create_draft(cls, draft: Draft) -> VariableDefinition:
|
|
84
100
|
"""Create a Draft Variable Definition."""
|
|
85
|
-
|
|
101
|
+
new_variable = VariableDefinition.from_model(
|
|
86
102
|
DraftVariableDefinitionsApi(
|
|
87
103
|
VardefClient.get_client(),
|
|
88
104
|
).create_variable_definition(
|
|
@@ -91,6 +107,39 @@ class Vardef:
|
|
|
91
107
|
),
|
|
92
108
|
)
|
|
93
109
|
|
|
110
|
+
logger.info(
|
|
111
|
+
"Successfully created variable definition '%s' with ID '%s'",
|
|
112
|
+
new_variable.short_name,
|
|
113
|
+
new_variable.id,
|
|
114
|
+
)
|
|
115
|
+
return new_variable
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
@vardef_file_error_handler
|
|
119
|
+
def create_draft_from_file(
|
|
120
|
+
cls,
|
|
121
|
+
file_path: PathLike[str] | None = None,
|
|
122
|
+
) -> VariableDefinition:
|
|
123
|
+
"""Create a Draft Variable Definition from a stored yaml file.
|
|
124
|
+
|
|
125
|
+
By default the latest template file in the default directory is chosen, this may be overridden by providing a value for the optional `file_path` parameter.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
file_path (PathLike[str], optional): Supply a file path to override the automatic one. Defaults to None.
|
|
129
|
+
|
|
130
|
+
Raises:
|
|
131
|
+
FileNotFoundError: When a file can't be found.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
VariableDefinition: The created draft variable definition.
|
|
135
|
+
"""
|
|
136
|
+
return cls.create_draft(
|
|
137
|
+
_read_file_to_model(
|
|
138
|
+
file_path or _find_latest_template_file(),
|
|
139
|
+
Draft,
|
|
140
|
+
),
|
|
141
|
+
)
|
|
142
|
+
|
|
94
143
|
@classmethod
|
|
95
144
|
@vardef_exception_handler
|
|
96
145
|
def migrate_from_vardok(cls, vardok_id: str) -> VariableDefinition:
|
|
@@ -106,7 +155,7 @@ class Vardef:
|
|
|
106
155
|
Returns:
|
|
107
156
|
VariableDefinition: The migrated Variable Definition in Vardef.
|
|
108
157
|
"""
|
|
109
|
-
|
|
158
|
+
migrated_variable = VariableDefinition.from_model(
|
|
110
159
|
DataMigrationApi(
|
|
111
160
|
VardefClient.get_client(),
|
|
112
161
|
).create_variable_definition_from_var_dok(
|
|
@@ -115,6 +164,13 @@ class Vardef:
|
|
|
115
164
|
),
|
|
116
165
|
)
|
|
117
166
|
|
|
167
|
+
logger.info(
|
|
168
|
+
"Successfully migrated variable definition '%s' with ID '%s'",
|
|
169
|
+
migrated_variable.short_name,
|
|
170
|
+
migrated_variable.id,
|
|
171
|
+
)
|
|
172
|
+
return migrated_variable
|
|
173
|
+
|
|
118
174
|
@classmethod
|
|
119
175
|
@vardef_exception_handler
|
|
120
176
|
def list_variable_definitions(
|
|
@@ -146,7 +202,7 @@ class Vardef:
|
|
|
146
202
|
|
|
147
203
|
@classmethod
|
|
148
204
|
@vardef_exception_handler
|
|
149
|
-
def
|
|
205
|
+
def get_variable_definition_by_id(
|
|
150
206
|
cls,
|
|
151
207
|
variable_definition_id: str,
|
|
152
208
|
date_of_validity: date | None = None,
|
|
@@ -171,3 +227,68 @@ class Vardef:
|
|
|
171
227
|
date_of_validity=date_of_validity,
|
|
172
228
|
),
|
|
173
229
|
)
|
|
230
|
+
|
|
231
|
+
@classmethod
|
|
232
|
+
@vardef_exception_handler
|
|
233
|
+
def get_variable_definition_by_shortname(
|
|
234
|
+
cls,
|
|
235
|
+
short_name: str,
|
|
236
|
+
date_of_validity: date | None = None,
|
|
237
|
+
) -> VariableDefinition:
|
|
238
|
+
"""Retrieve a Variable Definition by ID or short name.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
short_name (str): The short name of the Variable Definition.
|
|
242
|
+
date_of_validity (date | None, optional): Filter by validity date. Defaults to None.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
VariableDefinition: The retrieved Variable Definition.
|
|
246
|
+
|
|
247
|
+
Raises:
|
|
248
|
+
VariableNotFoundError: If no matching Variable Definition is found.
|
|
249
|
+
ValueError: If multiple variables with the same shortname is found.
|
|
250
|
+
"""
|
|
251
|
+
client = VardefClient.get_client()
|
|
252
|
+
api = VariableDefinitionsApi(client)
|
|
253
|
+
|
|
254
|
+
variable_definitions = api.list_variable_definitions(
|
|
255
|
+
short_name=short_name,
|
|
256
|
+
date_of_validity=date_of_validity,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
if not variable_definitions:
|
|
260
|
+
msg = f"Variable with short name {short_name} not found"
|
|
261
|
+
raise VariableNotFoundError(msg)
|
|
262
|
+
if len(variable_definitions) > 1:
|
|
263
|
+
msg = f"Lookup by short name {short_name} found multiple variables which should not be possible."
|
|
264
|
+
raise VariableNotFoundError(msg)
|
|
265
|
+
|
|
266
|
+
return VariableDefinition.from_model(variable_definitions[0])
|
|
267
|
+
|
|
268
|
+
@classmethod
|
|
269
|
+
@vardef_file_error_handler
|
|
270
|
+
def write_template_to_file(cls, custom_file_path: str | None = None) -> Path:
|
|
271
|
+
"""Write template with default values to a yaml file."""
|
|
272
|
+
file_path = create_template_yaml(
|
|
273
|
+
custom_directory=Path(custom_file_path) if custom_file_path else None,
|
|
274
|
+
)
|
|
275
|
+
logger.info(
|
|
276
|
+
f"Created editable variable definition template file at {file_path}", # noqa: G004
|
|
277
|
+
)
|
|
278
|
+
return file_path
|
|
279
|
+
|
|
280
|
+
@classmethod
|
|
281
|
+
@vardef_exception_handler
|
|
282
|
+
def does_short_name_exist(
|
|
283
|
+
cls,
|
|
284
|
+
short_name: str,
|
|
285
|
+
) -> bool:
|
|
286
|
+
"""Return True if the short name exists in Vardef, otherwise False."""
|
|
287
|
+
variable_definitions = Vardef.list_variable_definitions()
|
|
288
|
+
for variable in variable_definitions:
|
|
289
|
+
if short_name.strip() == variable.short_name:
|
|
290
|
+
logger.info(
|
|
291
|
+
f"Found duplicate short name {short_name}", # noqa: G004
|
|
292
|
+
)
|
|
293
|
+
return True
|
|
294
|
+
return False
|
|
@@ -1,47 +1,51 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from datetime import date
|
|
3
|
+
from os import PathLike
|
|
4
|
+
from pathlib import Path
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
from
|
|
5
|
-
from
|
|
6
|
-
|
|
6
|
+
import yaml
|
|
7
|
+
from pydantic import ConfigDict
|
|
8
|
+
from pydantic import PrivateAttr
|
|
9
|
+
|
|
10
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.api.draft_variable_definitions_api import (
|
|
7
11
|
DraftVariableDefinitionsApi,
|
|
8
12
|
)
|
|
9
|
-
from dapla_metadata.variable_definitions.
|
|
13
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.api.patches_api import (
|
|
10
14
|
PatchesApi,
|
|
11
15
|
)
|
|
12
|
-
from dapla_metadata.variable_definitions.
|
|
16
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.api.validity_periods_api import (
|
|
13
17
|
ValidityPeriodsApi,
|
|
14
18
|
)
|
|
15
|
-
from dapla_metadata.variable_definitions.
|
|
19
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.models.complete_response import (
|
|
16
20
|
CompleteResponse,
|
|
17
21
|
)
|
|
18
|
-
from dapla_metadata.variable_definitions.
|
|
22
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.models.patch import (
|
|
19
23
|
Patch,
|
|
20
24
|
)
|
|
21
|
-
from dapla_metadata.variable_definitions.
|
|
25
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.models.update_draft import (
|
|
22
26
|
UpdateDraft,
|
|
23
27
|
)
|
|
24
|
-
from dapla_metadata.variable_definitions.
|
|
28
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.models.validity_period import (
|
|
25
29
|
ValidityPeriod,
|
|
26
30
|
)
|
|
31
|
+
from dapla_metadata.variable_definitions._generated.vardef_client.models.variable_status import (
|
|
32
|
+
VariableStatus,
|
|
33
|
+
)
|
|
34
|
+
from dapla_metadata.variable_definitions._utils import config
|
|
35
|
+
from dapla_metadata.variable_definitions._utils._client import VardefClient
|
|
36
|
+
from dapla_metadata.variable_definitions._utils.variable_definition_files import (
|
|
37
|
+
_read_file_to_model,
|
|
38
|
+
)
|
|
39
|
+
from dapla_metadata.variable_definitions._utils.variable_definition_files import (
|
|
40
|
+
create_variable_yaml,
|
|
41
|
+
)
|
|
42
|
+
from dapla_metadata.variable_definitions.exceptions import vardef_exception_handler
|
|
43
|
+
from dapla_metadata.variable_definitions.exceptions import vardef_file_error_handler
|
|
27
44
|
|
|
45
|
+
logger = logging.getLogger(__name__)
|
|
28
46
|
|
|
29
|
-
class CompletePatchOutput(CompleteResponse):
|
|
30
|
-
"""Complete response For internal users who need all details while maintaining variable definitions."""
|
|
31
|
-
|
|
32
|
-
@staticmethod
|
|
33
|
-
def from_model(
|
|
34
|
-
model: CompleteResponse,
|
|
35
|
-
) -> "CompletePatchOutput":
|
|
36
|
-
"""Create a CompletePatchOutput instance from a CompletePatchOutput."""
|
|
37
|
-
return CompletePatchOutput.model_construct(**model.model_dump())
|
|
38
|
-
|
|
39
|
-
def __str__(self) -> str:
|
|
40
|
-
"""Format as indented JSON."""
|
|
41
|
-
return self.model_dump_json(indent=2, warnings=False)
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
class VariableDefinition(CompletePatchOutput):
|
|
48
|
+
class VariableDefinition(CompleteResponse):
|
|
45
49
|
"""A Variable Definition.
|
|
46
50
|
|
|
47
51
|
- Provides access to the fields of the specific Variable Definition.
|
|
@@ -49,21 +53,33 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
49
53
|
- Provides methods allowing maintenance of this Variable Definition.
|
|
50
54
|
|
|
51
55
|
Args:
|
|
52
|
-
|
|
56
|
+
CompleteResponse: The Pydantic model superclass, representing a Variable Definition.
|
|
53
57
|
"""
|
|
54
58
|
|
|
59
|
+
_file_path: Path | None = PrivateAttr(None)
|
|
60
|
+
|
|
61
|
+
model_config = ConfigDict(use_enum_values=True, str_strip_whitespace=True)
|
|
62
|
+
|
|
63
|
+
def get_file_path(self) -> Path | None:
|
|
64
|
+
"""Get the file path where the variable definition has been written to for editing."""
|
|
65
|
+
return self._file_path
|
|
66
|
+
|
|
67
|
+
def set_file_path(self, file_path: Path | None) -> None:
|
|
68
|
+
"""Set the file path where the variable definition has been written to for editing."""
|
|
69
|
+
self._file_path = file_path
|
|
70
|
+
|
|
55
71
|
@staticmethod
|
|
56
72
|
def from_model(
|
|
57
73
|
model: CompleteResponse,
|
|
58
74
|
) -> "VariableDefinition":
|
|
59
|
-
"""Create a VariableDefinition instance from a
|
|
75
|
+
"""Create a VariableDefinition instance from a CompleteResponse."""
|
|
60
76
|
return VariableDefinition.model_construct(**model.model_dump())
|
|
61
77
|
|
|
62
78
|
@vardef_exception_handler
|
|
63
|
-
def list_validity_periods(self) -> list[
|
|
79
|
+
def list_validity_periods(self) -> list["VariableDefinition"]:
|
|
64
80
|
"""List all Validity Periods for this Variable Definition."""
|
|
65
81
|
return [
|
|
66
|
-
|
|
82
|
+
VariableDefinition.from_model(validity_period)
|
|
67
83
|
for validity_period in ValidityPeriodsApi(
|
|
68
84
|
VardefClient.get_client(),
|
|
69
85
|
).list_validity_periods(
|
|
@@ -72,10 +88,10 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
72
88
|
]
|
|
73
89
|
|
|
74
90
|
@vardef_exception_handler
|
|
75
|
-
def list_patches(self) -> list[
|
|
91
|
+
def list_patches(self) -> list["VariableDefinition"]:
|
|
76
92
|
"""List all Patches for this Variable Definition."""
|
|
77
93
|
return [
|
|
78
|
-
|
|
94
|
+
VariableDefinition.from_model(patch)
|
|
79
95
|
for patch in PatchesApi(VardefClient.get_client()).list_patches(
|
|
80
96
|
variable_definition_id=self.id,
|
|
81
97
|
)
|
|
@@ -85,7 +101,7 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
85
101
|
def update_draft(
|
|
86
102
|
self,
|
|
87
103
|
update_draft: UpdateDraft,
|
|
88
|
-
) ->
|
|
104
|
+
) -> "VariableDefinition":
|
|
89
105
|
"""Update this Variable Definition.
|
|
90
106
|
|
|
91
107
|
- Variable definition must have status 'DRAFT'.
|
|
@@ -95,9 +111,9 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
95
111
|
update_draft: The input with updated values.
|
|
96
112
|
|
|
97
113
|
Returns:
|
|
98
|
-
|
|
114
|
+
VariableDefinition: Updated Variable definition with all details.
|
|
99
115
|
"""
|
|
100
|
-
|
|
116
|
+
updated = VariableDefinition.from_model(
|
|
101
117
|
DraftVariableDefinitionsApi(
|
|
102
118
|
VardefClient.get_client(),
|
|
103
119
|
).update_variable_definition_by_id(
|
|
@@ -106,6 +122,38 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
106
122
|
update_draft=update_draft,
|
|
107
123
|
),
|
|
108
124
|
)
|
|
125
|
+
logger.info(
|
|
126
|
+
"Successfully updated variable definition '%s' with ID '%s'",
|
|
127
|
+
updated.short_name,
|
|
128
|
+
updated.id,
|
|
129
|
+
)
|
|
130
|
+
return updated
|
|
131
|
+
|
|
132
|
+
@vardef_file_error_handler
|
|
133
|
+
def update_draft_from_file(
|
|
134
|
+
self,
|
|
135
|
+
file_path: PathLike | None = None,
|
|
136
|
+
) -> "VariableDefinition":
|
|
137
|
+
"""Update this Variable Definition.
|
|
138
|
+
|
|
139
|
+
Will automatically read the relevant file pertaining to this variable definition. Can
|
|
140
|
+
be overridden by specifying the file_path parameter.
|
|
141
|
+
|
|
142
|
+
- Variable definition must have status 'DRAFT'.
|
|
143
|
+
- Supply only the fields to be changed. Other fields will retain their current values.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
file_path: Optionally specify the path to read from.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
VariableDefinition: Updated Variable definition with all details.
|
|
150
|
+
"""
|
|
151
|
+
return self.update_draft(
|
|
152
|
+
_read_file_to_model(
|
|
153
|
+
file_path or self.get_file_path(),
|
|
154
|
+
UpdateDraft,
|
|
155
|
+
),
|
|
156
|
+
)
|
|
109
157
|
|
|
110
158
|
@vardef_exception_handler
|
|
111
159
|
def delete_draft(
|
|
@@ -128,16 +176,16 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
128
176
|
return f"Variable {self.id} safely deleted"
|
|
129
177
|
|
|
130
178
|
@vardef_exception_handler
|
|
131
|
-
def get_patch(self, patch_id: int) ->
|
|
179
|
+
def get_patch(self, patch_id: int) -> "VariableDefinition":
|
|
132
180
|
"""Get a single Patch by ID.
|
|
133
181
|
|
|
134
182
|
Args:
|
|
135
183
|
patch_id (int): The ID of the patch.
|
|
136
184
|
|
|
137
185
|
Returns:
|
|
138
|
-
|
|
186
|
+
VariableDefinition: The desired patch.
|
|
139
187
|
"""
|
|
140
|
-
return
|
|
188
|
+
return VariableDefinition.from_model(
|
|
141
189
|
PatchesApi(VardefClient.get_client()).get_patch(
|
|
142
190
|
variable_definition_id=self.id,
|
|
143
191
|
patch_id=patch_id,
|
|
@@ -149,7 +197,7 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
149
197
|
self,
|
|
150
198
|
patch: Patch,
|
|
151
199
|
valid_from: date | None = None,
|
|
152
|
-
) ->
|
|
200
|
+
) -> "VariableDefinition":
|
|
153
201
|
"""Create a new Patch for this Variable Definition.
|
|
154
202
|
|
|
155
203
|
Patches are to be used for minor changes which don't require a new Validity Period.
|
|
@@ -167,10 +215,10 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
167
215
|
created in the last validity period.
|
|
168
216
|
|
|
169
217
|
Returns:
|
|
170
|
-
|
|
218
|
+
VariableDefinition: Variable Definition with all details.
|
|
171
219
|
|
|
172
220
|
"""
|
|
173
|
-
|
|
221
|
+
new_patch = VariableDefinition.from_model(
|
|
174
222
|
PatchesApi(
|
|
175
223
|
VardefClient.get_client(),
|
|
176
224
|
).create_patch(
|
|
@@ -180,12 +228,55 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
180
228
|
valid_from=valid_from,
|
|
181
229
|
),
|
|
182
230
|
)
|
|
231
|
+
logger.info(
|
|
232
|
+
"Successfully created patch with patch ID '%s' for variable definition '%s' with ID '%s'",
|
|
233
|
+
new_patch.patch_id,
|
|
234
|
+
new_patch.short_name,
|
|
235
|
+
new_patch.id,
|
|
236
|
+
)
|
|
237
|
+
return new_patch
|
|
238
|
+
|
|
239
|
+
@vardef_file_error_handler
|
|
240
|
+
def create_patch_from_file(
|
|
241
|
+
self,
|
|
242
|
+
file_path: PathLike | None = None,
|
|
243
|
+
valid_from: date | None = None,
|
|
244
|
+
) -> "VariableDefinition":
|
|
245
|
+
"""Create a new Patch for this Variable Definition from a file.
|
|
246
|
+
|
|
247
|
+
Will automatically read the relevant file pertaining to this variable definition. Can
|
|
248
|
+
be overridden by specifying the file_path parameter.
|
|
249
|
+
|
|
250
|
+
Patches are to be used for minor changes which don't require a new Validity Period.
|
|
251
|
+
Examples of reasons for creating a new Patch:
|
|
252
|
+
- Correcting a typo
|
|
253
|
+
- Adding a translation
|
|
254
|
+
- Adding a subject field
|
|
255
|
+
|
|
256
|
+
Supply only the fields to be changed. Other fields will retain their current values.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
file_path: Optionally specify the path to read from.
|
|
260
|
+
valid_from: Optional date for selecting a Validity Period to create patch in. The date must
|
|
261
|
+
exactly match the Validity Period `valid_from`. If value is None the patch is
|
|
262
|
+
created in the last validity period.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
VariableDefinition: Variable Definition with all details.
|
|
266
|
+
"""
|
|
267
|
+
return self.create_patch(
|
|
268
|
+
patch=_read_file_to_model(
|
|
269
|
+
file_path or self.get_file_path(),
|
|
270
|
+
Patch,
|
|
271
|
+
),
|
|
272
|
+
valid_from=valid_from,
|
|
273
|
+
)
|
|
183
274
|
|
|
184
275
|
@vardef_exception_handler
|
|
185
276
|
def create_validity_period(
|
|
186
277
|
self,
|
|
187
278
|
validity_period: ValidityPeriod,
|
|
188
|
-
) ->
|
|
279
|
+
) -> "VariableDefinition":
|
|
189
280
|
"""Create a new Validity Period for this Variable Definition.
|
|
190
281
|
|
|
191
282
|
In order to create a new Validity Period input must contain updated
|
|
@@ -199,9 +290,9 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
199
290
|
validity_period: The input for new Validity Period
|
|
200
291
|
|
|
201
292
|
Returns:
|
|
202
|
-
|
|
293
|
+
VariableDefinition: Variable Definition with all details.
|
|
203
294
|
"""
|
|
204
|
-
|
|
295
|
+
new_validity_period = VariableDefinition.from_model(
|
|
205
296
|
ValidityPeriodsApi(
|
|
206
297
|
VardefClient.get_client(),
|
|
207
298
|
).create_validity_period(
|
|
@@ -210,3 +301,110 @@ class VariableDefinition(CompletePatchOutput):
|
|
|
210
301
|
validity_period=validity_period,
|
|
211
302
|
),
|
|
212
303
|
)
|
|
304
|
+
|
|
305
|
+
logger.info(
|
|
306
|
+
"Successfully created validity period that is valid from '%s' for variable definition '%s' with ID '%s'",
|
|
307
|
+
new_validity_period.valid_from,
|
|
308
|
+
new_validity_period.short_name,
|
|
309
|
+
new_validity_period.id,
|
|
310
|
+
)
|
|
311
|
+
return new_validity_period
|
|
312
|
+
|
|
313
|
+
@vardef_file_error_handler
|
|
314
|
+
def create_validity_period_from_file(
|
|
315
|
+
self,
|
|
316
|
+
file_path: PathLike | None = None,
|
|
317
|
+
) -> "VariableDefinition":
|
|
318
|
+
"""Create a new ValidityPeriod for this Variable Definition from a file.
|
|
319
|
+
|
|
320
|
+
In order to create a new Validity Period the input file must contain updated
|
|
321
|
+
'definition' text for all present languages and a new valid from.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
file_path: Optionally specify the path to read from.
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
VariableDefinition: Variable Definition with all details.
|
|
328
|
+
"""
|
|
329
|
+
return self.create_validity_period(
|
|
330
|
+
validity_period=_read_file_to_model(
|
|
331
|
+
file_path or self.get_file_path(),
|
|
332
|
+
ValidityPeriod,
|
|
333
|
+
),
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
def publish_internal(self) -> "VariableDefinition":
|
|
337
|
+
"""Publish this variable definition internally."""
|
|
338
|
+
if self.variable_status != VariableStatus.DRAFT.name:
|
|
339
|
+
msg = "That won't work here. Only variable definitions with status DRAFT may be published internally."
|
|
340
|
+
raise ValueError(
|
|
341
|
+
msg,
|
|
342
|
+
)
|
|
343
|
+
update = self.update_draft(
|
|
344
|
+
UpdateDraft(variable_status=VariableStatus.PUBLISHED_INTERNAL),
|
|
345
|
+
)
|
|
346
|
+
logger.info(
|
|
347
|
+
"Variable definition '%s' with ID '%s' successfully published, new status: %s",
|
|
348
|
+
update.short_name,
|
|
349
|
+
update.id,
|
|
350
|
+
update.variable_status,
|
|
351
|
+
)
|
|
352
|
+
return update
|
|
353
|
+
|
|
354
|
+
def publish_external(self) -> "VariableDefinition":
|
|
355
|
+
"""Publish this variable definition externally."""
|
|
356
|
+
if self.variable_status == VariableStatus.PUBLISHED_EXTERNAL.name:
|
|
357
|
+
msg = "That won't work here. The variable definition is already published."
|
|
358
|
+
raise ValueError(
|
|
359
|
+
msg,
|
|
360
|
+
)
|
|
361
|
+
if self.variable_status is VariableStatus.DRAFT:
|
|
362
|
+
update = self.update_draft(
|
|
363
|
+
UpdateDraft(variable_status=VariableStatus.PUBLISHED_EXTERNAL),
|
|
364
|
+
)
|
|
365
|
+
else:
|
|
366
|
+
update = self.create_patch(
|
|
367
|
+
Patch(variable_status=VariableStatus.PUBLISHED_EXTERNAL),
|
|
368
|
+
)
|
|
369
|
+
logger.info(
|
|
370
|
+
"Variable definition '%s' with ID '%s' successfully published, new status: %s",
|
|
371
|
+
update.short_name,
|
|
372
|
+
update.id,
|
|
373
|
+
update.variable_status,
|
|
374
|
+
)
|
|
375
|
+
return update
|
|
376
|
+
|
|
377
|
+
def to_file(self) -> "VariableDefinition":
|
|
378
|
+
"""Write this variable definition to file."""
|
|
379
|
+
file_path = create_variable_yaml(
|
|
380
|
+
model_instance=self,
|
|
381
|
+
)
|
|
382
|
+
self.set_file_path(file_path)
|
|
383
|
+
logger.info(
|
|
384
|
+
f"Created editable variable definition file at {file_path}", # noqa: G004
|
|
385
|
+
)
|
|
386
|
+
return self
|
|
387
|
+
|
|
388
|
+
def to_dict(self) -> dict:
|
|
389
|
+
"""Return as dictionary."""
|
|
390
|
+
return super().to_dict()
|
|
391
|
+
|
|
392
|
+
def __str__(self) -> str:
|
|
393
|
+
"""Format as indented YAML."""
|
|
394
|
+
return self._convert_to_yaml_output()
|
|
395
|
+
|
|
396
|
+
def __repr__(self) -> str:
|
|
397
|
+
"""Format as indented YAML."""
|
|
398
|
+
return self._convert_to_yaml_output()
|
|
399
|
+
|
|
400
|
+
def _convert_to_yaml_output(self) -> str:
|
|
401
|
+
return yaml.dump(
|
|
402
|
+
self.model_dump(
|
|
403
|
+
mode="json",
|
|
404
|
+
serialize_as_any=True,
|
|
405
|
+
warnings="error",
|
|
406
|
+
),
|
|
407
|
+
allow_unicode=True,
|
|
408
|
+
default_flow_style=False,
|
|
409
|
+
sort_keys=False,
|
|
410
|
+
)
|