dapla-toolbelt-metadata 0.3.0__py3-none-any.whl → 0.4.1__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 +1 -0
- dapla_metadata/_shared/__init__.py +1 -0
- dapla_metadata/{datasets → _shared}/config.py +39 -13
- dapla_metadata/_shared/enums.py +28 -0
- dapla_metadata/{datasets → _shared}/user_info.py +4 -4
- dapla_metadata/datasets/core.py +6 -3
- dapla_metadata/datasets/utility/enums.py +0 -19
- dapla_metadata/datasets/utility/utils.py +1 -1
- dapla_metadata/variable_definitions/__init__.py +7 -0
- dapla_metadata/variable_definitions/_client.py +30 -0
- dapla_metadata/variable_definitions/config.py +49 -0
- dapla_metadata/variable_definitions/exceptions.py +66 -0
- dapla_metadata/variable_definitions/generated/.openapi-generator/FILES +22 -0
- dapla_metadata/variable_definitions/generated/.openapi-generator/VERSION +1 -0
- dapla_metadata/variable_definitions/generated/.openapi-generator-ignore +6 -0
- dapla_metadata/variable_definitions/generated/README.md +148 -0
- dapla_metadata/variable_definitions/generated/__init__.py +0 -0
- dapla_metadata/variable_definitions/generated/vardef_client/__init__.py +52 -0
- dapla_metadata/variable_definitions/generated/vardef_client/api/__init__.py +9 -0
- dapla_metadata/variable_definitions/generated/vardef_client/api/data_migration_api.py +313 -0
- dapla_metadata/variable_definitions/generated/vardef_client/api/draft_variable_definitions_api.py +919 -0
- dapla_metadata/variable_definitions/generated/vardef_client/api/patches_api.py +919 -0
- dapla_metadata/variable_definitions/generated/vardef_client/api/public_api.py +915 -0
- dapla_metadata/variable_definitions/generated/vardef_client/api/validity_periods_api.py +876 -0
- dapla_metadata/variable_definitions/generated/vardef_client/api/variable_definitions_api.py +1205 -0
- dapla_metadata/variable_definitions/generated/vardef_client/api_client.py +779 -0
- dapla_metadata/variable_definitions/generated/vardef_client/api_response.py +27 -0
- dapla_metadata/variable_definitions/generated/vardef_client/configuration.py +474 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/CompleteResponse.md +51 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/Contact.md +30 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/DataMigrationApi.md +90 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/Draft.md +42 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/DraftVariableDefinitionsApi.md +259 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/LanguageStringType.md +31 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/Owner.md +31 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/Patch.md +43 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/PatchesApi.md +249 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/PublicApi.md +218 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/SupportedLanguages.md +15 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/UpdateDraft.md +44 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/ValidityPeriod.md +42 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/ValidityPeriodsApi.md +236 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/VariableDefinitionsApi.md +304 -0
- dapla_metadata/variable_definitions/generated/vardef_client/docs/VariableStatus.md +17 -0
- dapla_metadata/variable_definitions/generated/vardef_client/exceptions.py +193 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/__init__.py +30 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/complete_response.py +284 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/contact.py +94 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/draft.py +243 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/klass_reference.py +99 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/language_string_type.py +104 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/owner.py +90 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/patch.py +289 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/problem.py +118 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/rendered_contact.py +92 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/rendered_variable_definition.py +235 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/supported_languages.py +33 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/update_draft.py +307 -0
- dapla_metadata/variable_definitions/generated/vardef_client/models/validity_period.py +259 -0
- 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/generated/vardef_client/rest.py +249 -0
- dapla_metadata/variable_definitions/vardef.py +173 -0
- dapla_metadata/variable_definitions/variable_definition.py +212 -0
- {dapla_toolbelt_metadata-0.3.0.dist-info → dapla_toolbelt_metadata-0.4.1.dist-info}/METADATA +1 -1
- dapla_toolbelt_metadata-0.4.1.dist-info/RECORD +80 -0
- dapla_toolbelt_metadata-0.3.0.dist-info/RECORD +0 -22
- {dapla_toolbelt_metadata-0.3.0.dist-info → dapla_toolbelt_metadata-0.4.1.dist-info}/LICENSE +0 -0
- {dapla_toolbelt_metadata-0.3.0.dist-info → dapla_toolbelt_metadata-0.4.1.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"""Variable Definitions
|
|
2
|
+
|
|
3
|
+
## Introduction Variable Definitions are centralized definitions of concrete variables which are typically present in multiple datasets. Variable Definitions support standardization of data and metadata and facilitate sharing and joining of data by clarifying when variables have an identical definition. ## Maintenance of Variable Definitions This API allows for creation, maintenance and access of Variable Definitions. ### Ownership Creation and maintenance of variables may only be performed by Statistics Norway employees representing a specific Dapla team, who are defined as the owners of a given Variable Definition. The team an owner represents must be specified when making a request through the `active_group` query parameter. All maintenance is to be performed by the owners, with no intervention from administrators. ### Status All Variable Definitions have an associated status. The possible values for status are `DRAFT`, `PUBLISHED_INTERNAL` and `PUBLISHED_EXTERNAL`. #### Draft When a Variable Definition is created it is assigned the status `DRAFT`. Under this status the Variable Definition is: - Only visible to Statistics Norway employees. - Mutable (it may be changed directly without need for versioning). - Not suitable to refer to from other systems. This status may be changed to `PUBLISHED_INTERNAL` or `PUBLISHED_EXTERNAL` with a direct update. #### Published Internal Under this status the Variable Definition is: - Only visible to Statistics Norway employees. - Immutable (all changes are versioned). - Suitable to refer to in internal systems for statistics production. - Not suitable to refer to for external use (for example in Statistikkbanken). This status may be changed to `PUBLISHED_EXTERNAL` by creating a Patch version. #### Published External Under this status the Variable Definition is: - Visible to the general public. - Immutable (all changes are versioned). - Suitable to refer to from any system. This status may not be changed as it would break immutability. If a Variable Definition is no longer relevant then its period of validity should be ended by specifying a `valid_until` date in a Patch version. ### Immutability Variable Definitions are immutable. This means that any changes must be performed in a strict versioning system. Consumers can avoid being exposed to breaking changes by specifying a `date_of_validity` when they request a Variable Definition. #### Patches Patches are for changes which do not affect the fundamental meaning of the Variable Definition. #### Validity Periods Validity Periods are versions with a period defined by a `valid_from` date and optionally a `valid_until` date. If the fundamental meaning of a Variable Definition is to be changed, it should be done by creating a new Validity Period.
|
|
4
|
+
|
|
5
|
+
The version of the OpenAPI document: 0.1
|
|
6
|
+
Contact: metadata@ssb.no
|
|
7
|
+
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
8
|
+
|
|
9
|
+
Do not edit the class manually.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import io
|
|
13
|
+
import json
|
|
14
|
+
import re
|
|
15
|
+
import ssl
|
|
16
|
+
|
|
17
|
+
import urllib3
|
|
18
|
+
|
|
19
|
+
from .exceptions import ApiException
|
|
20
|
+
from .exceptions import ApiValueError
|
|
21
|
+
|
|
22
|
+
SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"}
|
|
23
|
+
RESTResponseType = urllib3.HTTPResponse
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def is_socks_proxy_url(url):
|
|
27
|
+
if url is None:
|
|
28
|
+
return False
|
|
29
|
+
split_section = url.split("://")
|
|
30
|
+
if len(split_section) < 2:
|
|
31
|
+
return False
|
|
32
|
+
return split_section[0].lower() in SUPPORTED_SOCKS_PROXIES
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class RESTResponse(io.IOBase):
|
|
36
|
+
def __init__(self, resp) -> None:
|
|
37
|
+
self.response = resp
|
|
38
|
+
self.status = resp.status
|
|
39
|
+
self.reason = resp.reason
|
|
40
|
+
self.data = None
|
|
41
|
+
|
|
42
|
+
def read(self):
|
|
43
|
+
if self.data is None:
|
|
44
|
+
self.data = self.response.data
|
|
45
|
+
return self.data
|
|
46
|
+
|
|
47
|
+
def getheaders(self):
|
|
48
|
+
"""Returns a dictionary of the response headers."""
|
|
49
|
+
return self.response.headers
|
|
50
|
+
|
|
51
|
+
def getheader(self, name, default=None):
|
|
52
|
+
"""Returns a given response header."""
|
|
53
|
+
return self.response.headers.get(name, default)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class RESTClientObject:
|
|
57
|
+
def __init__(self, configuration) -> None:
|
|
58
|
+
# urllib3.PoolManager will pass all kw parameters to connectionpool
|
|
59
|
+
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75
|
|
60
|
+
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680
|
|
61
|
+
# Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html
|
|
62
|
+
|
|
63
|
+
# cert_reqs
|
|
64
|
+
if configuration.verify_ssl:
|
|
65
|
+
cert_reqs = ssl.CERT_REQUIRED
|
|
66
|
+
else:
|
|
67
|
+
cert_reqs = ssl.CERT_NONE
|
|
68
|
+
|
|
69
|
+
pool_args = {
|
|
70
|
+
"cert_reqs": cert_reqs,
|
|
71
|
+
"ca_certs": configuration.ssl_ca_cert,
|
|
72
|
+
"cert_file": configuration.cert_file,
|
|
73
|
+
"key_file": configuration.key_file,
|
|
74
|
+
}
|
|
75
|
+
if configuration.assert_hostname is not None:
|
|
76
|
+
pool_args["assert_hostname"] = configuration.assert_hostname
|
|
77
|
+
|
|
78
|
+
if configuration.retries is not None:
|
|
79
|
+
pool_args["retries"] = configuration.retries
|
|
80
|
+
|
|
81
|
+
if configuration.tls_server_name:
|
|
82
|
+
pool_args["server_hostname"] = configuration.tls_server_name
|
|
83
|
+
|
|
84
|
+
if configuration.socket_options is not None:
|
|
85
|
+
pool_args["socket_options"] = configuration.socket_options
|
|
86
|
+
|
|
87
|
+
if configuration.connection_pool_maxsize is not None:
|
|
88
|
+
pool_args["maxsize"] = configuration.connection_pool_maxsize
|
|
89
|
+
|
|
90
|
+
# https pool manager
|
|
91
|
+
self.pool_manager: urllib3.PoolManager
|
|
92
|
+
|
|
93
|
+
if configuration.proxy:
|
|
94
|
+
if is_socks_proxy_url(configuration.proxy):
|
|
95
|
+
from urllib3.contrib.socks import SOCKSProxyManager
|
|
96
|
+
|
|
97
|
+
pool_args["proxy_url"] = configuration.proxy
|
|
98
|
+
pool_args["headers"] = configuration.proxy_headers
|
|
99
|
+
self.pool_manager = SOCKSProxyManager(**pool_args)
|
|
100
|
+
else:
|
|
101
|
+
pool_args["proxy_url"] = configuration.proxy
|
|
102
|
+
pool_args["proxy_headers"] = configuration.proxy_headers
|
|
103
|
+
self.pool_manager = urllib3.ProxyManager(**pool_args)
|
|
104
|
+
else:
|
|
105
|
+
self.pool_manager = urllib3.PoolManager(**pool_args)
|
|
106
|
+
|
|
107
|
+
def request(
|
|
108
|
+
self,
|
|
109
|
+
method,
|
|
110
|
+
url,
|
|
111
|
+
headers=None,
|
|
112
|
+
body=None,
|
|
113
|
+
post_params=None,
|
|
114
|
+
_request_timeout=None,
|
|
115
|
+
):
|
|
116
|
+
"""Perform requests.
|
|
117
|
+
|
|
118
|
+
:param method: http request method
|
|
119
|
+
:param url: http request url
|
|
120
|
+
:param headers: http request headers
|
|
121
|
+
:param body: request json body, for `application/json`
|
|
122
|
+
:param post_params: request post parameters,
|
|
123
|
+
`application/x-www-form-urlencoded`
|
|
124
|
+
and `multipart/form-data`
|
|
125
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
126
|
+
number provided, it will be total request
|
|
127
|
+
timeout. It can also be a pair (tuple) of
|
|
128
|
+
(connection, read) timeouts.
|
|
129
|
+
"""
|
|
130
|
+
method = method.upper()
|
|
131
|
+
assert method in [
|
|
132
|
+
"GET",
|
|
133
|
+
"HEAD",
|
|
134
|
+
"DELETE",
|
|
135
|
+
"POST",
|
|
136
|
+
"PUT",
|
|
137
|
+
"PATCH",
|
|
138
|
+
"OPTIONS",
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
if post_params and body:
|
|
142
|
+
raise ApiValueError(
|
|
143
|
+
"body parameter cannot be used with post_params parameter.",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
post_params = post_params or {}
|
|
147
|
+
headers = headers or {}
|
|
148
|
+
|
|
149
|
+
timeout = None
|
|
150
|
+
if _request_timeout:
|
|
151
|
+
if isinstance(_request_timeout, (int, float)):
|
|
152
|
+
timeout = urllib3.Timeout(total=_request_timeout)
|
|
153
|
+
elif isinstance(_request_timeout, tuple) and len(_request_timeout) == 2:
|
|
154
|
+
timeout = urllib3.Timeout(
|
|
155
|
+
connect=_request_timeout[0],
|
|
156
|
+
read=_request_timeout[1],
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
try:
|
|
160
|
+
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
|
|
161
|
+
if method in ["POST", "PUT", "PATCH", "OPTIONS", "DELETE"]:
|
|
162
|
+
# no content type provided or payload is json
|
|
163
|
+
content_type = headers.get("Content-Type")
|
|
164
|
+
if not content_type or re.search("json", content_type, re.IGNORECASE):
|
|
165
|
+
request_body = None
|
|
166
|
+
if body is not None:
|
|
167
|
+
request_body = json.dumps(body)
|
|
168
|
+
r = self.pool_manager.request(
|
|
169
|
+
method,
|
|
170
|
+
url,
|
|
171
|
+
body=request_body,
|
|
172
|
+
timeout=timeout,
|
|
173
|
+
headers=headers,
|
|
174
|
+
preload_content=False,
|
|
175
|
+
)
|
|
176
|
+
elif content_type == "application/x-www-form-urlencoded":
|
|
177
|
+
r = self.pool_manager.request(
|
|
178
|
+
method,
|
|
179
|
+
url,
|
|
180
|
+
fields=post_params,
|
|
181
|
+
encode_multipart=False,
|
|
182
|
+
timeout=timeout,
|
|
183
|
+
headers=headers,
|
|
184
|
+
preload_content=False,
|
|
185
|
+
)
|
|
186
|
+
elif content_type == "multipart/form-data":
|
|
187
|
+
# must del headers['Content-Type'], or the correct
|
|
188
|
+
# Content-Type which generated by urllib3 will be
|
|
189
|
+
# overwritten.
|
|
190
|
+
del headers["Content-Type"]
|
|
191
|
+
# Ensures that dict objects are serialized
|
|
192
|
+
post_params = [
|
|
193
|
+
(a, json.dumps(b)) if isinstance(b, dict) else (a, b)
|
|
194
|
+
for a, b in post_params
|
|
195
|
+
]
|
|
196
|
+
r = self.pool_manager.request(
|
|
197
|
+
method,
|
|
198
|
+
url,
|
|
199
|
+
fields=post_params,
|
|
200
|
+
encode_multipart=True,
|
|
201
|
+
timeout=timeout,
|
|
202
|
+
headers=headers,
|
|
203
|
+
preload_content=False,
|
|
204
|
+
)
|
|
205
|
+
# Pass a `string` parameter directly in the body to support
|
|
206
|
+
# other content types than JSON when `body` argument is
|
|
207
|
+
# provided in serialized form.
|
|
208
|
+
elif isinstance(body, str) or isinstance(body, bytes):
|
|
209
|
+
r = self.pool_manager.request(
|
|
210
|
+
method,
|
|
211
|
+
url,
|
|
212
|
+
body=body,
|
|
213
|
+
timeout=timeout,
|
|
214
|
+
headers=headers,
|
|
215
|
+
preload_content=False,
|
|
216
|
+
)
|
|
217
|
+
elif headers["Content-Type"].startswith("text/") and isinstance(
|
|
218
|
+
body, bool
|
|
219
|
+
):
|
|
220
|
+
request_body = "true" if body else "false"
|
|
221
|
+
r = self.pool_manager.request(
|
|
222
|
+
method,
|
|
223
|
+
url,
|
|
224
|
+
body=request_body,
|
|
225
|
+
preload_content=False,
|
|
226
|
+
timeout=timeout,
|
|
227
|
+
headers=headers,
|
|
228
|
+
)
|
|
229
|
+
else:
|
|
230
|
+
# Cannot generate the request from given parameters
|
|
231
|
+
msg = """Cannot prepare a request message for provided
|
|
232
|
+
arguments. Please check that your arguments match
|
|
233
|
+
declared content type."""
|
|
234
|
+
raise ApiException(status=0, reason=msg)
|
|
235
|
+
# For `GET`, `HEAD`
|
|
236
|
+
else:
|
|
237
|
+
r = self.pool_manager.request(
|
|
238
|
+
method,
|
|
239
|
+
url,
|
|
240
|
+
fields={},
|
|
241
|
+
timeout=timeout,
|
|
242
|
+
headers=headers,
|
|
243
|
+
preload_content=False,
|
|
244
|
+
)
|
|
245
|
+
except urllib3.exceptions.SSLError as e:
|
|
246
|
+
msg = "\n".join([type(e).__name__, str(e)])
|
|
247
|
+
raise ApiException(status=0, reason=msg)
|
|
248
|
+
|
|
249
|
+
return RESTResponse(r)
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
|
|
3
|
+
from dapla_metadata.variable_definitions import config
|
|
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 (
|
|
7
|
+
DataMigrationApi,
|
|
8
|
+
)
|
|
9
|
+
from dapla_metadata.variable_definitions.generated.vardef_client.api.draft_variable_definitions_api import (
|
|
10
|
+
DraftVariableDefinitionsApi,
|
|
11
|
+
)
|
|
12
|
+
from dapla_metadata.variable_definitions.generated.vardef_client.api.variable_definitions_api import (
|
|
13
|
+
VariableDefinitionsApi,
|
|
14
|
+
)
|
|
15
|
+
from dapla_metadata.variable_definitions.generated.vardef_client.models.draft import (
|
|
16
|
+
Draft,
|
|
17
|
+
)
|
|
18
|
+
from dapla_metadata.variable_definitions.variable_definition import VariableDefinition
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Vardef:
|
|
22
|
+
"""Create, maintain and read Variable Definitions.
|
|
23
|
+
|
|
24
|
+
====================
|
|
25
|
+
Variable Definitions
|
|
26
|
+
====================
|
|
27
|
+
|
|
28
|
+
Variable Definitions are centralized definitions of concrete variables which are typically present in multiple datasets. Variable Definitions
|
|
29
|
+
support standardization of data and metadata and facilitate sharing and joining of data by clarifying when variables have an identical
|
|
30
|
+
definition.
|
|
31
|
+
|
|
32
|
+
The methods in this class allow for creation, maintenance and access of Variable Definitions.
|
|
33
|
+
|
|
34
|
+
Creation and maintenance of variables may only be performed by Statistics Norway employees representing a specific Dapla team, who are defined
|
|
35
|
+
as the owners of a given Variable Definition. The group a user represents is chosen when starting a service in Dapla Lab. This class will
|
|
36
|
+
seamlessly detect this and send it to the API. All maintenance is to be performed by the owners, with no intervention from administrators.
|
|
37
|
+
|
|
38
|
+
======
|
|
39
|
+
Status
|
|
40
|
+
======
|
|
41
|
+
All Variable Definitions have an associated status. The possible values for status are `DRAFT`, `PUBLISHED_INTERNAL` and `PUBLISHED_EXTERNAL`.
|
|
42
|
+
|
|
43
|
+
-----
|
|
44
|
+
Draft
|
|
45
|
+
-----
|
|
46
|
+
When a Variable Definition is created it is assigned the status `DRAFT`. Under this status the Variable Definition is:
|
|
47
|
+
* Only visible to Statistics Norway employees.
|
|
48
|
+
* Mutable (it may be changed directly without need for versioning).
|
|
49
|
+
* Not suitable to refer to from other systems.
|
|
50
|
+
This status may be changed to `PUBLISHED_INTERNAL` or `PUBLISHED_EXTERNAL` with a direct update.
|
|
51
|
+
|
|
52
|
+
------------------
|
|
53
|
+
Published Internal
|
|
54
|
+
------------------
|
|
55
|
+
Under this status the Variable Definition is:
|
|
56
|
+
* Only visible to Statistics Norway employees.
|
|
57
|
+
* Immutable (all changes are versioned).
|
|
58
|
+
* Suitable to refer to in internal systems for statistics production.
|
|
59
|
+
* Not suitable to refer to for external use (for example in Statistikkbanken).
|
|
60
|
+
|
|
61
|
+
This status may be changed to `PUBLISHED_EXTERNAL` by creating a Patch version.
|
|
62
|
+
|
|
63
|
+
------------------
|
|
64
|
+
Published External
|
|
65
|
+
------------------
|
|
66
|
+
Under this status the Variable Definition is:
|
|
67
|
+
* Visible to the general public.
|
|
68
|
+
* Immutable (all changes are versioned).
|
|
69
|
+
* Suitable to refer to from any system.
|
|
70
|
+
|
|
71
|
+
This status may not be changed as it would break immutability. If a Variable Definition is no longer relevant then its period of validity
|
|
72
|
+
should be ended by specifying a `valid_until` date in a Patch version.
|
|
73
|
+
|
|
74
|
+
============
|
|
75
|
+
Immutability
|
|
76
|
+
============
|
|
77
|
+
Variable Definitions are immutable. This means that any changes must be performed in a strict versioning system. Consumers can avoid
|
|
78
|
+
being exposed to breaking changes by specifying a `date_of_validity` when they request a Variable Definition.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
@vardef_exception_handler
|
|
83
|
+
def create_draft(cls, draft: Draft) -> VariableDefinition:
|
|
84
|
+
"""Create a Draft Variable Definition."""
|
|
85
|
+
return VariableDefinition.from_model(
|
|
86
|
+
DraftVariableDefinitionsApi(
|
|
87
|
+
VardefClient.get_client(),
|
|
88
|
+
).create_variable_definition(
|
|
89
|
+
active_group=config.get_active_group(),
|
|
90
|
+
draft=draft,
|
|
91
|
+
),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
@classmethod
|
|
95
|
+
@vardef_exception_handler
|
|
96
|
+
def migrate_from_vardok(cls, vardok_id: str) -> VariableDefinition:
|
|
97
|
+
"""Migrate a Variable Definition from Vardok to Vardef.
|
|
98
|
+
|
|
99
|
+
- Each Vardok Variable Definition may only be migrated once.
|
|
100
|
+
- The Dapla team of the person who performs the migration will be set as the owner.
|
|
101
|
+
- All metadata should be checked for correctness before publication.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
vardok_id (str): The ID of a Variable Definition in Vardok.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
VariableDefinition: The migrated Variable Definition in Vardef.
|
|
108
|
+
"""
|
|
109
|
+
return VariableDefinition.from_model(
|
|
110
|
+
DataMigrationApi(
|
|
111
|
+
VardefClient.get_client(),
|
|
112
|
+
).create_variable_definition_from_var_dok(
|
|
113
|
+
active_group=config.get_active_group(),
|
|
114
|
+
vardok_id=vardok_id,
|
|
115
|
+
),
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
@classmethod
|
|
119
|
+
@vardef_exception_handler
|
|
120
|
+
def list_variable_definitions(
|
|
121
|
+
cls,
|
|
122
|
+
date_of_validity: date | None = None,
|
|
123
|
+
) -> list[VariableDefinition]:
|
|
124
|
+
"""List variable definitions.
|
|
125
|
+
|
|
126
|
+
---------
|
|
127
|
+
Filtering
|
|
128
|
+
---------
|
|
129
|
+
If no filter arguments are provided then all Variable Definitions are returned. See the documentation for the
|
|
130
|
+
individual arguments to understand their effect. Filter arguments are combined with AND logic.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
date_of_validity (date | None, optional): List only variable definitions which are valid on this date. Defaults to None.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
list[VariableDefinition]: The list of Variable Definitions.
|
|
137
|
+
"""
|
|
138
|
+
return [
|
|
139
|
+
VariableDefinition.from_model(definition)
|
|
140
|
+
for definition in VariableDefinitionsApi(
|
|
141
|
+
VardefClient.get_client(),
|
|
142
|
+
).list_variable_definitions(
|
|
143
|
+
date_of_validity=date_of_validity,
|
|
144
|
+
)
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
@classmethod
|
|
148
|
+
@vardef_exception_handler
|
|
149
|
+
def get_variable_definition(
|
|
150
|
+
cls,
|
|
151
|
+
variable_definition_id: str,
|
|
152
|
+
date_of_validity: date | None = None,
|
|
153
|
+
) -> VariableDefinition:
|
|
154
|
+
"""Get a Variable Definition by ID.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
variable_definition_id (str): The ID of the desired Variable Definition
|
|
158
|
+
date_of_validity (date | None, optional): List only variable definitions which are valid on this date. Defaults to None.
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
VariableDefinition: The Variable Definition.
|
|
162
|
+
|
|
163
|
+
Raises:
|
|
164
|
+
NotFoundException when the given ID is not found
|
|
165
|
+
"""
|
|
166
|
+
return VariableDefinition.from_model(
|
|
167
|
+
VariableDefinitionsApi(
|
|
168
|
+
VardefClient.get_client(),
|
|
169
|
+
).get_variable_definition_by_id(
|
|
170
|
+
variable_definition_id=variable_definition_id,
|
|
171
|
+
date_of_validity=date_of_validity,
|
|
172
|
+
),
|
|
173
|
+
)
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
|
|
3
|
+
from dapla_metadata.variable_definitions import config
|
|
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.draft_variable_definitions_api import (
|
|
7
|
+
DraftVariableDefinitionsApi,
|
|
8
|
+
)
|
|
9
|
+
from dapla_metadata.variable_definitions.generated.vardef_client.api.patches_api import (
|
|
10
|
+
PatchesApi,
|
|
11
|
+
)
|
|
12
|
+
from dapla_metadata.variable_definitions.generated.vardef_client.api.validity_periods_api import (
|
|
13
|
+
ValidityPeriodsApi,
|
|
14
|
+
)
|
|
15
|
+
from dapla_metadata.variable_definitions.generated.vardef_client.models.complete_response import (
|
|
16
|
+
CompleteResponse,
|
|
17
|
+
)
|
|
18
|
+
from dapla_metadata.variable_definitions.generated.vardef_client.models.patch import (
|
|
19
|
+
Patch,
|
|
20
|
+
)
|
|
21
|
+
from dapla_metadata.variable_definitions.generated.vardef_client.models.update_draft import (
|
|
22
|
+
UpdateDraft,
|
|
23
|
+
)
|
|
24
|
+
from dapla_metadata.variable_definitions.generated.vardef_client.models.validity_period import (
|
|
25
|
+
ValidityPeriod,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
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
|
+
|
|
43
|
+
|
|
44
|
+
class VariableDefinition(CompletePatchOutput):
|
|
45
|
+
"""A Variable Definition.
|
|
46
|
+
|
|
47
|
+
- Provides access to the fields of the specific Variable Definition.
|
|
48
|
+
- Provides methods to access Patches and Validity Periods of this Variable Definition.
|
|
49
|
+
- Provides methods allowing maintenance of this Variable Definition.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
CompletePatchOutput: The Pydantic model superclass, representing a Variable Definition.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
@staticmethod
|
|
56
|
+
def from_model(
|
|
57
|
+
model: CompleteResponse,
|
|
58
|
+
) -> "VariableDefinition":
|
|
59
|
+
"""Create a VariableDefinition instance from a CompletePatchOutput or CompletePatchOutput."""
|
|
60
|
+
return VariableDefinition.model_construct(**model.model_dump())
|
|
61
|
+
|
|
62
|
+
@vardef_exception_handler
|
|
63
|
+
def list_validity_periods(self) -> list[CompletePatchOutput]:
|
|
64
|
+
"""List all Validity Periods for this Variable Definition."""
|
|
65
|
+
return [
|
|
66
|
+
CompletePatchOutput.from_model(validity_period)
|
|
67
|
+
for validity_period in ValidityPeriodsApi(
|
|
68
|
+
VardefClient.get_client(),
|
|
69
|
+
).list_validity_periods(
|
|
70
|
+
variable_definition_id=self.id,
|
|
71
|
+
)
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
@vardef_exception_handler
|
|
75
|
+
def list_patches(self) -> list[CompletePatchOutput]:
|
|
76
|
+
"""List all Patches for this Variable Definition."""
|
|
77
|
+
return [
|
|
78
|
+
CompletePatchOutput.from_model(patch)
|
|
79
|
+
for patch in PatchesApi(VardefClient.get_client()).list_patches(
|
|
80
|
+
variable_definition_id=self.id,
|
|
81
|
+
)
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
@vardef_exception_handler
|
|
85
|
+
def update_draft(
|
|
86
|
+
self,
|
|
87
|
+
update_draft: UpdateDraft,
|
|
88
|
+
) -> CompletePatchOutput:
|
|
89
|
+
"""Update this Variable Definition.
|
|
90
|
+
|
|
91
|
+
- Variable definition must have status 'DRAFT'.
|
|
92
|
+
- Supply only the fields to be changed. Other fields will retain their current values.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
update_draft: The input with updated values.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
CompletePatchOutput: Updated Variable definition with all details.
|
|
99
|
+
"""
|
|
100
|
+
return CompletePatchOutput.from_model(
|
|
101
|
+
DraftVariableDefinitionsApi(
|
|
102
|
+
VardefClient.get_client(),
|
|
103
|
+
).update_variable_definition_by_id(
|
|
104
|
+
variable_definition_id=self.id,
|
|
105
|
+
active_group=config.get_active_group(),
|
|
106
|
+
update_draft=update_draft,
|
|
107
|
+
),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
@vardef_exception_handler
|
|
111
|
+
def delete_draft(
|
|
112
|
+
self,
|
|
113
|
+
) -> str:
|
|
114
|
+
"""Delete this Variable definition.
|
|
115
|
+
|
|
116
|
+
Variable definition must have status 'DRAFT'.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
str: A message if the operation was succsessful.
|
|
120
|
+
|
|
121
|
+
"""
|
|
122
|
+
DraftVariableDefinitionsApi(
|
|
123
|
+
VardefClient.get_client(),
|
|
124
|
+
).delete_variable_definition_by_id(
|
|
125
|
+
variable_definition_id=self.id,
|
|
126
|
+
active_group=config.get_active_group(),
|
|
127
|
+
)
|
|
128
|
+
return f"Variable {self.id} safely deleted"
|
|
129
|
+
|
|
130
|
+
@vardef_exception_handler
|
|
131
|
+
def get_patch(self, patch_id: int) -> CompletePatchOutput:
|
|
132
|
+
"""Get a single Patch by ID.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
patch_id (int): The ID of the patch.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
CompletePatchOutput: The desired patch.
|
|
139
|
+
"""
|
|
140
|
+
return CompletePatchOutput.from_model(
|
|
141
|
+
PatchesApi(VardefClient.get_client()).get_patch(
|
|
142
|
+
variable_definition_id=self.id,
|
|
143
|
+
patch_id=patch_id,
|
|
144
|
+
),
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
@vardef_exception_handler
|
|
148
|
+
def create_patch(
|
|
149
|
+
self,
|
|
150
|
+
patch: Patch,
|
|
151
|
+
valid_from: date | None = None,
|
|
152
|
+
) -> CompletePatchOutput:
|
|
153
|
+
"""Create a new Patch for this Variable Definition.
|
|
154
|
+
|
|
155
|
+
Patches are to be used for minor changes which don't require a new Validity Period.
|
|
156
|
+
Examples of reasons for creating a new Patch:
|
|
157
|
+
- Correcting a typo
|
|
158
|
+
- Adding a translation
|
|
159
|
+
- Adding a subject field
|
|
160
|
+
|
|
161
|
+
Supply only the fields to be changed. Other fields will retain their current values.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
patch: The input for a new patch.
|
|
165
|
+
valid_from: Optional date for selecting a Validity Period to create patch in. The date must
|
|
166
|
+
exactly match the Validity Period `valid_from`. If value is None the patch is
|
|
167
|
+
created in the last validity period.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
CompletePatchOutput: Variable Definition with all details.
|
|
171
|
+
|
|
172
|
+
"""
|
|
173
|
+
return CompletePatchOutput.from_model(
|
|
174
|
+
PatchesApi(
|
|
175
|
+
VardefClient.get_client(),
|
|
176
|
+
).create_patch(
|
|
177
|
+
variable_definition_id=self.id,
|
|
178
|
+
active_group=config.get_active_group(),
|
|
179
|
+
patch=patch,
|
|
180
|
+
valid_from=valid_from,
|
|
181
|
+
),
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
@vardef_exception_handler
|
|
185
|
+
def create_validity_period(
|
|
186
|
+
self,
|
|
187
|
+
validity_period: ValidityPeriod,
|
|
188
|
+
) -> CompletePatchOutput:
|
|
189
|
+
"""Create a new Validity Period for this Variable Definition.
|
|
190
|
+
|
|
191
|
+
In order to create a new Validity Period input must contain updated
|
|
192
|
+
'definition' text for all present languages and a new valid from.
|
|
193
|
+
|
|
194
|
+
A new Validity Period should be created only when the fundamental definition
|
|
195
|
+
of the variable has changed. This way the previous definition can be preserved
|
|
196
|
+
for use in historical data.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
validity_period: The input for new Validity Period
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
CompletePatchOutput: Variable Definition with all details.
|
|
203
|
+
"""
|
|
204
|
+
return CompletePatchOutput.from_model(
|
|
205
|
+
ValidityPeriodsApi(
|
|
206
|
+
VardefClient.get_client(),
|
|
207
|
+
).create_validity_period(
|
|
208
|
+
variable_definition_id=self.id,
|
|
209
|
+
active_group=config.get_active_group(),
|
|
210
|
+
validity_period=validity_period,
|
|
211
|
+
),
|
|
212
|
+
)
|