dapla-toolbelt-metadata 0.6.2__tar.gz → 0.6.4__tar.gz
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_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/PKG-INFO +3 -3
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/pyproject.toml +38 -51
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/core.py +110 -10
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/standards/name_validator.py +2 -2
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/standards/utils/constants.py +2 -2
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_utils/config.py +1 -2
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_utils/constants.py +23 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_utils/files.py +107 -11
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_utils/template_files.py +8 -15
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_utils/variable_definition_files.py +32 -5
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/resources/vardef_model_descriptions_nb.yaml +53 -17
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/vardef.py +3 -3
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/variable_definition.py +19 -21
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/LICENSE +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/README.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/_shared/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/_shared/config.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/_shared/enums.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/_shared/py.typed +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/dapla/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/dapla/user_info.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/code_list.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/dapla_dataset_path_info.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/dataset_parser.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/external_sources/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/external_sources/external_sources.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/model_backwards_compatibility.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/model_validation.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/py.typed +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/statistic_subject_mapping.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/utility/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/utility/constants.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/utility/enums.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/utility/utils.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/standards/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/standards/standard_validators.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/standards/utils/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/.openapi-generator/FILES +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/.openapi-generator/VERSION +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/.openapi-generator-ignore +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/README.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/api/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/api/data_migration_api.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/api/draft_variable_definitions_api.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/api/patches_api.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/api/validity_periods_api.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/api/variable_definitions_api.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/api_client.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/api_response.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/configuration.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/CompleteResponse.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/Contact.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/DataMigrationApi.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/Draft.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/DraftVariableDefinitionsApi.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/LanguageStringType.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/Owner.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/Patch.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/PatchesApi.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/PublicApi.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/SupportedLanguages.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/UpdateDraft.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/ValidityPeriod.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/ValidityPeriodsApi.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/VariableDefinitionsApi.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/docs/VariableStatus.md +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/exceptions.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/complete_response.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/contact.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/draft.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/language_string_type.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/owner.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/patch.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/problem.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/update_draft.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/validity_period.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/models/variable_status.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/py.typed +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_generated/vardef_client/rest.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_utils/__init__.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_utils/_client.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/_utils/descriptions.py +0 -0
- {dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/variable_definitions/exceptions.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: dapla-toolbelt-metadata
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.4
|
|
4
4
|
Summary: Dapla Toolbelt Metadata
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Team Metadata
|
|
7
7
|
Author-email: metadata@ssb.no
|
|
8
|
-
Requires-Python: >=3.10
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
9
|
Classifier: Development Status :: 4 - Beta
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -24,7 +24,7 @@ Requires-Dist: pyjwt (>=2.8.0)
|
|
|
24
24
|
Requires-Dist: python-dotenv (>=1.0.1)
|
|
25
25
|
Requires-Dist: requests (>=2.31.0)
|
|
26
26
|
Requires-Dist: ruamel-yaml (>=0.18.10)
|
|
27
|
-
Requires-Dist: ssb-datadoc-model (
|
|
27
|
+
Requires-Dist: ssb-datadoc-model (==6.0.0)
|
|
28
28
|
Requires-Dist: ssb-klass-python (>=1.0.1)
|
|
29
29
|
Requires-Dist: typing-extensions (>=4.12.2)
|
|
30
30
|
Project-URL: Changelog, https://github.com/statisticsnorway/dapla-toolbelt-metadata/releases
|
|
@@ -1,36 +1,45 @@
|
|
|
1
|
-
[
|
|
1
|
+
[project]
|
|
2
2
|
name = "dapla-toolbelt-metadata"
|
|
3
|
-
version = "0.6.2"
|
|
4
3
|
description = "Dapla Toolbelt Metadata"
|
|
5
|
-
authors = ["Team Metadata <metadata@ssb.no>"]
|
|
6
4
|
license = "MIT"
|
|
5
|
+
version = "0.6.4"
|
|
6
|
+
dynamic = ["classifiers"]
|
|
7
7
|
readme = "README.md"
|
|
8
|
+
authors = [{ name = "Team Metadata", email = "metadata@ssb.no" }]
|
|
9
|
+
requires-python = '>=3.10'
|
|
10
|
+
dependencies = [
|
|
11
|
+
'pyarrow >=8.0.0',
|
|
12
|
+
'pydantic >=2.5.2',
|
|
13
|
+
'arrow >=1.3.0',
|
|
14
|
+
'python-dotenv >=1.0.1',
|
|
15
|
+
'requests >=2.31.0',
|
|
16
|
+
'beautifulsoup4 >=4.12.3',
|
|
17
|
+
'cloudpathlib[gs] >=0.17.0',
|
|
18
|
+
'pyjwt >=2.8.0',
|
|
19
|
+
'ssb-klass-python >=1.0.1',
|
|
20
|
+
'ssb-datadoc-model ==6.0.0',
|
|
21
|
+
'typing-extensions >=4.12.2',
|
|
22
|
+
'ruamel-yaml >=0.18.10',
|
|
23
|
+
'google-auth >=2.38.0',
|
|
24
|
+
'lxml >=5.3.1',
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
8
28
|
homepage = "https://github.com/statisticsnorway/dapla-toolbelt-metadata"
|
|
9
29
|
repository = "https://github.com/statisticsnorway/dapla-toolbelt-metadata"
|
|
10
30
|
documentation = "https://statisticsnorway.github.io/dapla-toolbelt-metadata"
|
|
11
|
-
|
|
31
|
+
Changelog = "https://github.com/statisticsnorway/dapla-toolbelt-metadata/releases"
|
|
12
32
|
|
|
33
|
+
[tool.poetry]
|
|
34
|
+
requires-poetry = '>=2.0,<3.0'
|
|
13
35
|
packages = [{ include = "dapla_metadata", from = "src" }]
|
|
36
|
+
classifiers = ["Development Status :: 4 - Beta"]
|
|
14
37
|
|
|
15
|
-
[tool.poetry.
|
|
16
|
-
|
|
38
|
+
[tool.poetry.requires-plugins]
|
|
39
|
+
poetry-plugin-export = ">=1.9.0" # Used with nox
|
|
17
40
|
|
|
18
41
|
[tool.poetry.dependencies]
|
|
19
|
-
python = ">=3.10,<4.0"
|
|
20
|
-
pyarrow = ">=8.0.0"
|
|
21
|
-
pydantic = ">=2.5.2"
|
|
22
|
-
arrow = ">=1.3.0"
|
|
23
|
-
python-dotenv = ">=1.0.1"
|
|
24
|
-
requests = ">=2.31.0"
|
|
25
|
-
beautifulsoup4 = ">=4.12.3"
|
|
26
|
-
cloudpathlib = { extras = ["gs"], version = ">=0.17.0" }
|
|
27
|
-
pyjwt = ">=2.8.0"
|
|
28
|
-
ssb-klass-python = ">=1.0.1"
|
|
29
|
-
ssb-datadoc-model = "^6.0.0"
|
|
30
|
-
typing-extensions = ">=4.12.2"
|
|
31
|
-
ruamel-yaml = ">=0.18.10"
|
|
32
|
-
google-auth = ">=2.38.0"
|
|
33
|
-
lxml = ">=5.3.1"
|
|
42
|
+
python = ">=3.10,<4.0" # This is currently needed for compatibility with ssb-klass-python
|
|
34
43
|
|
|
35
44
|
[tool.poetry.group.dev.dependencies]
|
|
36
45
|
pygments = ">=2.18.0"
|
|
@@ -64,7 +73,7 @@ types-beautifulsoup4 = ">=4.12.0.20240511"
|
|
|
64
73
|
ipykernel = "^6.29.5"
|
|
65
74
|
rich = "^13.9.4"
|
|
66
75
|
bpython = "^0.24"
|
|
67
|
-
testcontainers = { version = "
|
|
76
|
+
testcontainers = { version = ">=4.8.2", extras = ["generic"] }
|
|
68
77
|
pytest-asyncio = "^0.26.0"
|
|
69
78
|
|
|
70
79
|
[tool.pytest.ini_options]
|
|
@@ -77,11 +86,7 @@ tests = ["tests", "*/tests", "*/test"]
|
|
|
77
86
|
[tool.coverage.run]
|
|
78
87
|
branch = true
|
|
79
88
|
source = ["dapla_metadata"]
|
|
80
|
-
omit = [
|
|
81
|
-
"tests/*",
|
|
82
|
-
"__init__.py",
|
|
83
|
-
"*/dapla_metadata/variable_definitions/_generated/*",
|
|
84
|
-
]
|
|
89
|
+
omit = ["tests/*", "__init__.py", "*/dapla_metadata/variable_definitions/_generated/*"]
|
|
85
90
|
relative_files = true
|
|
86
91
|
|
|
87
92
|
[tool.coverage.report]
|
|
@@ -105,7 +110,6 @@ warn_unreachable = false
|
|
|
105
110
|
ignore_errors = true
|
|
106
111
|
disable_error_code = ["unreachable"]
|
|
107
112
|
|
|
108
|
-
|
|
109
113
|
[[tool.mypy.overrides]]
|
|
110
114
|
# Allow missing type hints in third-party libraries without type information.
|
|
111
115
|
module = [
|
|
@@ -127,27 +131,15 @@ ignore_missing_imports = true
|
|
|
127
131
|
# Also don't require type annotations
|
|
128
132
|
[[tool.mypy.overrides]]
|
|
129
133
|
module = ["tests.*"]
|
|
130
|
-
disable_error_code = [
|
|
131
|
-
"var-annotated",
|
|
132
|
-
"has-type",
|
|
133
|
-
"no-any-return",
|
|
134
|
-
"no-untyped-def",
|
|
135
|
-
]
|
|
134
|
+
disable_error_code = ["var-annotated", "has-type", "no-any-return", "no-untyped-def"]
|
|
136
135
|
|
|
137
136
|
[tool.ruff]
|
|
138
|
-
force-exclude = true
|
|
137
|
+
force-exclude = true # Apply excludes to pre-commit
|
|
139
138
|
show-fixes = true
|
|
140
139
|
src = ["src", "tests"]
|
|
141
|
-
target-version = "py310"
|
|
140
|
+
target-version = "py310" # Minimum Python version supported
|
|
142
141
|
include = ["*.py", "*.pyi", "**/pyproject.toml", "*.ipynb"]
|
|
143
|
-
extend-exclude = [
|
|
144
|
-
"__pycache__",
|
|
145
|
-
"old",
|
|
146
|
-
".ipynb_checkpoints",
|
|
147
|
-
"noxfile.py",
|
|
148
|
-
"docs/conf.py",
|
|
149
|
-
"_generated/",
|
|
150
|
-
]
|
|
142
|
+
extend-exclude = ["__pycache__", "old", ".ipynb_checkpoints", "noxfile.py", "docs/conf.py", "_generated/"]
|
|
151
143
|
|
|
152
144
|
# Ruff rules may be customized as desired: https://docs.astral.sh/ruff/rules/
|
|
153
145
|
[tool.ruff.lint]
|
|
@@ -181,12 +173,7 @@ fixture-parentheses = false
|
|
|
181
173
|
max-args = 8
|
|
182
174
|
|
|
183
175
|
[tool.ruff.lint.pep8-naming]
|
|
184
|
-
classmethod-decorators = [
|
|
185
|
-
"classmethod",
|
|
186
|
-
"validator",
|
|
187
|
-
"root_validator",
|
|
188
|
-
"pydantic.validator",
|
|
189
|
-
]
|
|
176
|
+
classmethod-decorators = ["classmethod", "validator", "root_validator", "pydantic.validator"]
|
|
190
177
|
|
|
191
178
|
[tool.ruff.lint.per-file-ignores]
|
|
192
179
|
"*/__init__.py" = ["F401"]
|
|
@@ -206,5 +193,5 @@ classmethod-decorators = [
|
|
|
206
193
|
]
|
|
207
194
|
|
|
208
195
|
[build-system]
|
|
209
|
-
requires = ["poetry-core>=
|
|
196
|
+
requires = ["poetry-core>=2.0"]
|
|
210
197
|
build-backend = "poetry.core.masonry.api"
|
{dapla_toolbelt_metadata-0.6.2 → dapla_toolbelt_metadata-0.6.4}/src/dapla_metadata/datasets/core.py
RENAMED
|
@@ -109,8 +109,11 @@ class Datadoc:
|
|
|
109
109
|
self.dataset_path: pathlib.Path | CloudPath | None = None
|
|
110
110
|
self.dataset = model.Dataset()
|
|
111
111
|
self.variables: list = []
|
|
112
|
+
self.pseudo_variables: list[model.PseudoVariable] = []
|
|
112
113
|
self.variables_lookup: dict[str, model.Variable] = {}
|
|
114
|
+
self.pseudo_variables_lookup: dict[str, model.PseudoVariable] = {}
|
|
113
115
|
self.explicitly_defined_metadata_document = False
|
|
116
|
+
self.dataset_consistency_status: list = []
|
|
114
117
|
if metadata_document_path:
|
|
115
118
|
self.metadata_document = normalize_path(metadata_document_path)
|
|
116
119
|
self.explicitly_defined_metadata_document = True
|
|
@@ -148,11 +151,19 @@ class Datadoc:
|
|
|
148
151
|
"""
|
|
149
152
|
extracted_metadata: model.DatadocMetadata | None = None
|
|
150
153
|
existing_metadata: model.DatadocMetadata | None = None
|
|
154
|
+
existing_pseudonymization: model.PseudonymizationMetadata | None = None
|
|
155
|
+
|
|
151
156
|
if self.metadata_document and self.metadata_document.exists():
|
|
152
157
|
existing_metadata = self._extract_metadata_from_existing_document(
|
|
153
158
|
self.metadata_document,
|
|
154
159
|
)
|
|
155
160
|
|
|
161
|
+
existing_pseudonymization = (
|
|
162
|
+
self._extract_pseudonymization_from_existing_document(
|
|
163
|
+
self.metadata_document,
|
|
164
|
+
)
|
|
165
|
+
)
|
|
166
|
+
|
|
156
167
|
if (
|
|
157
168
|
self.dataset_path is not None
|
|
158
169
|
and self.dataset == model.Dataset()
|
|
@@ -169,11 +180,14 @@ class Datadoc:
|
|
|
169
180
|
and existing_metadata is not None
|
|
170
181
|
):
|
|
171
182
|
existing_file_path = self._get_existing_file_path(extracted_metadata)
|
|
172
|
-
self.
|
|
183
|
+
self.dataset_consistency_status = self._check_dataset_consistency(
|
|
173
184
|
self.dataset_path,
|
|
174
185
|
Path(existing_file_path),
|
|
175
186
|
extracted_metadata,
|
|
176
187
|
existing_metadata,
|
|
188
|
+
)
|
|
189
|
+
self._check_ready_to_merge(
|
|
190
|
+
self.dataset_consistency_status,
|
|
177
191
|
errors_as_warnings=self.errors_as_warnings,
|
|
178
192
|
)
|
|
179
193
|
merged_metadata = self._merge_metadata(
|
|
@@ -188,10 +202,15 @@ class Datadoc:
|
|
|
188
202
|
self._set_metadata(merged_metadata)
|
|
189
203
|
else:
|
|
190
204
|
self._set_metadata(existing_metadata or extracted_metadata)
|
|
205
|
+
|
|
206
|
+
if existing_pseudonymization:
|
|
207
|
+
self._set_pseudonymization_metadata(existing_pseudonymization)
|
|
208
|
+
|
|
191
209
|
set_default_values_variables(self.variables)
|
|
192
210
|
set_default_values_dataset(self.dataset)
|
|
193
211
|
set_dataset_owner(self.dataset)
|
|
194
212
|
self._create_variables_lookup()
|
|
213
|
+
self._create_pseudo_variables_lookup()
|
|
195
214
|
|
|
196
215
|
def _get_existing_file_path(
|
|
197
216
|
self,
|
|
@@ -218,35 +237,48 @@ class Datadoc:
|
|
|
218
237
|
self.dataset = merged_metadata.dataset
|
|
219
238
|
self.variables = merged_metadata.variables
|
|
220
239
|
|
|
240
|
+
def _set_pseudonymization_metadata(
|
|
241
|
+
self,
|
|
242
|
+
existing_pseudonymization: model.PseudonymizationMetadata | None,
|
|
243
|
+
) -> None:
|
|
244
|
+
if not existing_pseudonymization or not (
|
|
245
|
+
existing_pseudonymization.pseudo_variables
|
|
246
|
+
):
|
|
247
|
+
msg = "Could not read pseudonymization metadata"
|
|
248
|
+
raise ValueError(msg)
|
|
249
|
+
self.pseudo_variables = existing_pseudonymization.pseudo_variables
|
|
250
|
+
|
|
221
251
|
def _create_variables_lookup(self) -> None:
|
|
222
252
|
self.variables_lookup = {
|
|
223
253
|
v.short_name: v for v in self.variables if v.short_name
|
|
224
254
|
}
|
|
225
255
|
|
|
256
|
+
def _create_pseudo_variables_lookup(self) -> None:
|
|
257
|
+
self.pseudo_variables_lookup = {
|
|
258
|
+
v.short_name: v for v in self.pseudo_variables if v.short_name
|
|
259
|
+
}
|
|
260
|
+
|
|
226
261
|
@staticmethod
|
|
227
|
-
def
|
|
262
|
+
def _check_dataset_consistency(
|
|
228
263
|
new_dataset_path: Path | CloudPath,
|
|
229
264
|
existing_dataset_path: Path,
|
|
230
265
|
extracted_metadata: model.DatadocMetadata,
|
|
231
266
|
existing_metadata: model.DatadocMetadata,
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
) -> None:
|
|
235
|
-
"""Check if the datasets are consistent enough to make a successful merge of metadata.
|
|
267
|
+
) -> list[dict[str, object]]:
|
|
268
|
+
"""Run consistency tests.
|
|
236
269
|
|
|
237
270
|
Args:
|
|
238
271
|
new_dataset_path: Path to the dataset to be documented.
|
|
239
272
|
existing_dataset_path: Path stored in the existing metadata.
|
|
240
273
|
extracted_metadata: Metadata extracted from a physical dataset.
|
|
241
274
|
existing_metadata: Metadata from a previously created metadata document.
|
|
242
|
-
errors_as_warnings: True if failing checks should be raised as warnings, not errors.
|
|
243
275
|
|
|
244
|
-
|
|
245
|
-
|
|
276
|
+
Returns:
|
|
277
|
+
List if dict with property name and boolean success flag
|
|
246
278
|
"""
|
|
247
279
|
new_dataset_path_info = DaplaDatasetPathInfo(new_dataset_path)
|
|
248
280
|
existing_dataset_path_info = DaplaDatasetPathInfo(existing_dataset_path)
|
|
249
|
-
|
|
281
|
+
return [
|
|
250
282
|
{
|
|
251
283
|
"name": "Bucket name",
|
|
252
284
|
"success": (
|
|
@@ -290,6 +322,20 @@ class Datadoc:
|
|
|
290
322
|
),
|
|
291
323
|
},
|
|
292
324
|
]
|
|
325
|
+
|
|
326
|
+
@staticmethod
|
|
327
|
+
def _check_ready_to_merge(
|
|
328
|
+
results: list[dict[str, object]], *, errors_as_warnings: bool
|
|
329
|
+
) -> None:
|
|
330
|
+
"""Check if the datasets are consistent enough to make a successful merge of metadata.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
results: List if dict with property name and boolean success flag
|
|
334
|
+
errors_as_warnings: True if failing checks should be raised as warnings, not errors.
|
|
335
|
+
|
|
336
|
+
Raises:
|
|
337
|
+
InconsistentDatasetsError: If inconsistencies are found and `errors_as_warnings == False`
|
|
338
|
+
"""
|
|
293
339
|
if failures := [result for result in results if not result["success"]]:
|
|
294
340
|
msg = f"{INCONSISTENCIES_MESSAGE} {', '.join(str(f['name']) for f in failures)}"
|
|
295
341
|
if errors_as_warnings:
|
|
@@ -384,6 +430,42 @@ class Datadoc:
|
|
|
384
430
|
)
|
|
385
431
|
return None
|
|
386
432
|
|
|
433
|
+
def _extract_pseudonymization_from_existing_document(
|
|
434
|
+
self,
|
|
435
|
+
document: pathlib.Path | CloudPath,
|
|
436
|
+
) -> model.PseudonymizationMetadata | None:
|
|
437
|
+
"""Read pseudo metadata from an existing metadata document.
|
|
438
|
+
|
|
439
|
+
If there is pseudo metadata in the document supplied, the method validates and returns the pseudonymization structure.
|
|
440
|
+
|
|
441
|
+
Args:
|
|
442
|
+
document: A path to the existing metadata document.
|
|
443
|
+
|
|
444
|
+
Raises:
|
|
445
|
+
json.JSONDecodeError: If the metadata document cannot be parsed.
|
|
446
|
+
"""
|
|
447
|
+
try:
|
|
448
|
+
with document.open(mode="r", encoding="utf-8") as file:
|
|
449
|
+
fresh_metadata = json.load(file)
|
|
450
|
+
except json.JSONDecodeError:
|
|
451
|
+
logger.warning(
|
|
452
|
+
"Could not open existing metadata file %s.",
|
|
453
|
+
document,
|
|
454
|
+
exc_info=True,
|
|
455
|
+
)
|
|
456
|
+
return None
|
|
457
|
+
|
|
458
|
+
if not is_metadata_in_container_structure(fresh_metadata):
|
|
459
|
+
return None
|
|
460
|
+
|
|
461
|
+
pseudonymization_metadata = fresh_metadata.get("pseudonymization")
|
|
462
|
+
if pseudonymization_metadata is None:
|
|
463
|
+
return None
|
|
464
|
+
|
|
465
|
+
return model.PseudonymizationMetadata.model_validate_json(
|
|
466
|
+
json.dumps(pseudonymization_metadata),
|
|
467
|
+
)
|
|
468
|
+
|
|
387
469
|
def _extract_subject_field_from_path(
|
|
388
470
|
self,
|
|
389
471
|
dapla_dataset_path_info: DaplaDatasetPathInfo,
|
|
@@ -501,6 +583,11 @@ class Datadoc:
|
|
|
501
583
|
)
|
|
502
584
|
if self.container:
|
|
503
585
|
self.container.datadoc = datadoc
|
|
586
|
+
if not self.container.pseudonymization:
|
|
587
|
+
self.container.pseudonymization = model.PseudonymizationMetadata(
|
|
588
|
+
pseudo_dataset=model.PseudoDataset()
|
|
589
|
+
)
|
|
590
|
+
self.container.pseudonymization.pseudo_variables = self.pseudo_variables
|
|
504
591
|
else:
|
|
505
592
|
self.container = model.MetadataContainer(datadoc=datadoc)
|
|
506
593
|
if self.metadata_document:
|
|
@@ -530,3 +617,16 @@ class Datadoc:
|
|
|
530
617
|
self.dataset,
|
|
531
618
|
) + num_obligatory_variables_fields_completed(self.variables)
|
|
532
619
|
return calculate_percentage(num_set_fields, num_all_fields)
|
|
620
|
+
|
|
621
|
+
def add_pseudo_variable(self, variable_short_name: str) -> None:
|
|
622
|
+
"""Adds a new pseudo variable to the list of pseudonymized variables."""
|
|
623
|
+
if self.variables_lookup[variable_short_name] is not None:
|
|
624
|
+
pseudo_variable = model.PseudoVariable(short_name=variable_short_name)
|
|
625
|
+
self.pseudo_variables.append(pseudo_variable)
|
|
626
|
+
self.pseudo_variables_lookup[variable_short_name] = pseudo_variable
|
|
627
|
+
|
|
628
|
+
def get_pseudo_variable(
|
|
629
|
+
self, variable_short_name: str
|
|
630
|
+
) -> model.PseudoVariable | None:
|
|
631
|
+
"""Finds a pseudo variable by shortname."""
|
|
632
|
+
return self.pseudo_variables_lookup.get(variable_short_name)
|
|
@@ -128,9 +128,9 @@ class NamingStandardReport:
|
|
|
128
128
|
"""Returns an appropriate message based on the success rate."""
|
|
129
129
|
rate = self.success_rate()
|
|
130
130
|
if rate is not None:
|
|
131
|
-
if rate
|
|
131
|
+
if 95 <= rate <= 100:
|
|
132
132
|
return SSB_NAMING_STANDARD_REPORT_RESULT_BEST
|
|
133
|
-
if 70 < rate <
|
|
133
|
+
if 70 < rate < 95:
|
|
134
134
|
return SSB_NAMING_STANDARD_REPORT_RESULT_GOOD
|
|
135
135
|
if 40 <= rate <= 70:
|
|
136
136
|
return SSB_NAMING_STANDARD_REPORT_RESULT_AVERAGE
|
|
@@ -9,7 +9,7 @@ NAME_STANDARD_SUCCESS = "Filene dine er i samsvar med SSB-navnestandarden"
|
|
|
9
9
|
NAME_STANDARD_VIOLATION = "Det er oppdaget brudd på SSB-navnestandard:"
|
|
10
10
|
|
|
11
11
|
MISSING_BUCKET_NAME = "Filnavn mangler bøttenavn ref: https://manual.dapla.ssb.no/statistikkere/navnestandard.html#obligatoriske-mapper"
|
|
12
|
-
MISSING_VERSION = "Filnavn mangler versjon ref: https://manual.dapla.ssb.no/statistikkere/navnestandard.html#
|
|
12
|
+
MISSING_VERSION = "Filnavn mangler versjon, hvis ikke filen er nyeste versjon kan dette være brudd på navnestandarden ref: https://manual.dapla.ssb.no/statistikkere/navnestandard.html#versjonering-av-datasett"
|
|
13
13
|
MISSING_PERIOD = "Filnavn mangler gyldighetsperiode ref: https://manual.dapla.ssb.no/statistikkere/navnestandard.html#filnavn"
|
|
14
14
|
MISSING_SHORT_NAME = "Kortnavn for statistikk mangler ref: https://manual.dapla.ssb.no/statistikkere/navnestandard.html#obligatoriske-mapper"
|
|
15
15
|
MISSING_DATA_STATE = "Mappe for datatilstand mangler ref: https://manual.dapla.ssb.no/statistikkere/navnestandard.html#obligatoriske-mapper"
|
|
@@ -26,7 +26,7 @@ BUCKET_NAME_UNKNOWN = "Kan ikke validere bøttenavn"
|
|
|
26
26
|
|
|
27
27
|
SSB_NAMING_STANDARD_REPORT = "SSB navnestandard rapport"
|
|
28
28
|
SSB_NAMING_STANDARD_REPORT_SUCCESS_RATE = "Suksess rate"
|
|
29
|
-
SSB_NAMING_STANDARD_REPORT_RESULT_BEST = "🚀 Fantastisk!
|
|
29
|
+
SSB_NAMING_STANDARD_REPORT_RESULT_BEST = "🚀 Fantastisk! 🎉\n"
|
|
30
30
|
SSB_NAMING_STANDARD_REPORT_RESULT_GOOD = (
|
|
31
31
|
"✅ Bra jobba! Fortsatt litt rom for forbedring. 😊\n"
|
|
32
32
|
)
|
|
@@ -59,8 +59,7 @@ def get_vardef_host() -> str:
|
|
|
59
59
|
case DaplaEnvironment.TEST:
|
|
60
60
|
return VARDEF_HOST_TEST
|
|
61
61
|
case DaplaEnvironment.DEV:
|
|
62
|
-
|
|
63
|
-
raise NotImplementedError(msg)
|
|
62
|
+
return VARDEF_HOST_TEST
|
|
64
63
|
case _:
|
|
65
64
|
return get_config_item("VARDEF_HOST") or "http://localhost:8080"
|
|
66
65
|
|
|
@@ -39,3 +39,26 @@ MACHINE_GENERATED_FIELDS = [
|
|
|
39
39
|
|
|
40
40
|
OPTIONAL_FIELD = "~ Valgfritt felt ~"
|
|
41
41
|
REQUIRED_FIELD = "! Obligatorisk felt !"
|
|
42
|
+
|
|
43
|
+
YAML_STR_TAG = "tag:yaml.org,2002:str"
|
|
44
|
+
|
|
45
|
+
BLOCK_FIELDS = [
|
|
46
|
+
"definition",
|
|
47
|
+
"name",
|
|
48
|
+
"contact.title",
|
|
49
|
+
"comment",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
DOUBLE_QUOTE_FIELDS = [
|
|
53
|
+
"unit_types",
|
|
54
|
+
"subject_fields",
|
|
55
|
+
"related_variable_definition_uris",
|
|
56
|
+
"owner",
|
|
57
|
+
"short_name",
|
|
58
|
+
"classification_reference",
|
|
59
|
+
"measurement_type",
|
|
60
|
+
"external_reference_uri",
|
|
61
|
+
"created_by",
|
|
62
|
+
"id",
|
|
63
|
+
"last_updated_by",
|
|
64
|
+
]
|
|
@@ -4,12 +4,16 @@ import logging
|
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import TYPE_CHECKING
|
|
7
|
+
from typing import Any
|
|
7
8
|
from typing import cast
|
|
8
9
|
|
|
9
10
|
import pytz
|
|
10
11
|
from pydantic.config import JsonDict
|
|
11
12
|
from ruamel.yaml import YAML
|
|
12
13
|
from ruamel.yaml import CommentedMap
|
|
14
|
+
from ruamel.yaml import RoundTripRepresenter
|
|
15
|
+
from ruamel.yaml.scalarstring import DoubleQuotedScalarString
|
|
16
|
+
from ruamel.yaml.scalarstring import LiteralScalarString
|
|
13
17
|
|
|
14
18
|
from dapla_metadata.variable_definitions._generated.vardef_client.models.complete_response import (
|
|
15
19
|
CompleteResponse,
|
|
@@ -18,6 +22,8 @@ from dapla_metadata.variable_definitions._generated.vardef_client.models.variabl
|
|
|
18
22
|
VariableStatus,
|
|
19
23
|
)
|
|
20
24
|
from dapla_metadata.variable_definitions._utils import config
|
|
25
|
+
from dapla_metadata.variable_definitions._utils.constants import BLOCK_FIELDS
|
|
26
|
+
from dapla_metadata.variable_definitions._utils.constants import DOUBLE_QUOTE_FIELDS
|
|
21
27
|
from dapla_metadata.variable_definitions._utils.constants import (
|
|
22
28
|
MACHINE_GENERATED_FIELDS,
|
|
23
29
|
)
|
|
@@ -40,6 +46,7 @@ from dapla_metadata.variable_definitions._utils.constants import (
|
|
|
40
46
|
from dapla_metadata.variable_definitions._utils.constants import (
|
|
41
47
|
VARIABLE_STATUS_FIELD_NAME,
|
|
42
48
|
)
|
|
49
|
+
from dapla_metadata.variable_definitions._utils.constants import YAML_STR_TAG
|
|
43
50
|
from dapla_metadata.variable_definitions._utils.descriptions import (
|
|
44
51
|
apply_norwegian_descriptions_to_model,
|
|
45
52
|
)
|
|
@@ -112,6 +119,15 @@ def _get_variable_definitions_dir():
|
|
|
112
119
|
return folder_path
|
|
113
120
|
|
|
114
121
|
|
|
122
|
+
def _set_field_requirement(field_name: str, field: Any) -> str | None:
|
|
123
|
+
"""Determine the field requirement status."""
|
|
124
|
+
if field_name not in MACHINE_GENERATED_FIELDS:
|
|
125
|
+
if field.is_required() or field_name == VARIABLE_STATUS_FIELD_NAME:
|
|
126
|
+
return REQUIRED_FIELD
|
|
127
|
+
return OPTIONAL_FIELD
|
|
128
|
+
return None
|
|
129
|
+
|
|
130
|
+
|
|
115
131
|
def _populate_commented_map(
|
|
116
132
|
field_name: str,
|
|
117
133
|
value: str,
|
|
@@ -120,16 +136,17 @@ def _populate_commented_map(
|
|
|
120
136
|
) -> None:
|
|
121
137
|
"""Add data to a CommentedMap."""
|
|
122
138
|
commented_map[field_name] = value
|
|
123
|
-
field = model_instance.model_fields[field_name]
|
|
139
|
+
field = type(model_instance).model_fields[field_name]
|
|
124
140
|
description: JsonValue = cast(
|
|
125
141
|
JsonDict,
|
|
126
142
|
field.json_schema_extra,
|
|
127
143
|
)[NORWEGIAN_DESCRIPTIONS]
|
|
144
|
+
field_requirement: str | None = _set_field_requirement(field_name, field)
|
|
128
145
|
if description is not None:
|
|
129
146
|
new_description = (
|
|
130
|
-
(
|
|
131
|
-
|
|
132
|
-
+ str(description)
|
|
147
|
+
("\n" + field_requirement + "\n" + str(description))
|
|
148
|
+
if field_requirement
|
|
149
|
+
else ("\n" + str(description))
|
|
133
150
|
)
|
|
134
151
|
commented_map.yaml_set_comment_before_after_key(
|
|
135
152
|
field_name,
|
|
@@ -174,14 +191,22 @@ def _validate_and_create_directory(custom_directory: Path) -> Path:
|
|
|
174
191
|
return custom_directory
|
|
175
192
|
|
|
176
193
|
|
|
177
|
-
def
|
|
178
|
-
|
|
179
|
-
yaml.
|
|
180
|
-
|
|
194
|
+
def configure_yaml(yaml: YAML) -> YAML:
|
|
195
|
+
"""Common Yaml config for variable definitions."""
|
|
196
|
+
yaml.Representer = RoundTripRepresenter # Preserve the order of keys etc.
|
|
197
|
+
yaml.default_flow_style = False # Ensures pretty YAML formatting block style
|
|
198
|
+
yaml.allow_unicode = True # Support special characters
|
|
199
|
+
yaml.preserve_quotes = True
|
|
200
|
+
yaml.width = 4096 # prevent wrapping lines
|
|
201
|
+
yaml.indent(
|
|
202
|
+
mapping=4,
|
|
203
|
+
sequence=6,
|
|
204
|
+
offset=4,
|
|
205
|
+
) # Ensure indentation for nested keys and lists
|
|
181
206
|
yaml.representer.add_representer(
|
|
182
207
|
VariableStatus,
|
|
183
208
|
lambda dumper, data: dumper.represent_scalar(
|
|
184
|
-
|
|
209
|
+
YAML_STR_TAG,
|
|
185
210
|
data.value,
|
|
186
211
|
),
|
|
187
212
|
)
|
|
@@ -189,6 +214,76 @@ def _configure_yaml() -> YAML:
|
|
|
189
214
|
return yaml
|
|
190
215
|
|
|
191
216
|
|
|
217
|
+
def _safe_get(data: dict, keys: list):
|
|
218
|
+
"""Safely navigate nested dictionaries."""
|
|
219
|
+
for key in keys:
|
|
220
|
+
if not isinstance(data, dict) or key not in data or data[key] is None:
|
|
221
|
+
return None
|
|
222
|
+
data = data[key]
|
|
223
|
+
return data
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def _apply_literal_scalars(field: dict):
|
|
227
|
+
"""Helper function to wrap `LanguageStringType` values in `LiteralScalarString`.
|
|
228
|
+
|
|
229
|
+
This function wraps each non-`None` language value in a `LanguageStringType` field
|
|
230
|
+
in the `LiteralScalarString` YAML type, ensuring proper YAML formatting with block style.
|
|
231
|
+
"""
|
|
232
|
+
for lang, value in field.items():
|
|
233
|
+
if value is not None:
|
|
234
|
+
field[lang] = LiteralScalarString(value)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def _apply_double_quotes_to_dict_values(field: dict):
|
|
238
|
+
"""Helper function to wrap dictionary values in `DoubleQuotedScalarString`.
|
|
239
|
+
|
|
240
|
+
This function wraps each non-`None` value in a dictionary, including values inside lists,
|
|
241
|
+
in the `DoubleQuotedScalarString` YAML type, ensuring proper YAML formatting with double quotes.
|
|
242
|
+
"""
|
|
243
|
+
for sub_key, sub_value in field.items():
|
|
244
|
+
if isinstance(sub_value, list):
|
|
245
|
+
field[sub_key] = [
|
|
246
|
+
DoubleQuotedScalarString(item) for item in sub_value if item is not None
|
|
247
|
+
]
|
|
248
|
+
elif sub_value is not None:
|
|
249
|
+
field[sub_key] = DoubleQuotedScalarString(sub_value)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def pre_process_data(data: dict) -> dict:
|
|
253
|
+
"""Format variable definition model fields with ruamel YAML scalar string types.
|
|
254
|
+
|
|
255
|
+
This method sets the appropriate scalar string type (either `LiteralScalarString` or `DoubleQuotedScalarString`)
|
|
256
|
+
for fields of the variable definition model, based on predefined lists of fields.
|
|
257
|
+
|
|
258
|
+
It processes both nested dictionaries and lists, ensuring each element is formatted with the correct YAML string type.
|
|
259
|
+
|
|
260
|
+
Args:
|
|
261
|
+
data (dict): A dictionary containing the variable definition data.
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
dict: The updated dictionary with model fields formatted as ruamel.yaml scalar string types.
|
|
265
|
+
"""
|
|
266
|
+
for key in BLOCK_FIELDS:
|
|
267
|
+
keys = key.split(".")
|
|
268
|
+
field = _safe_get(data, keys)
|
|
269
|
+
if isinstance(field, dict):
|
|
270
|
+
_apply_literal_scalars(field)
|
|
271
|
+
|
|
272
|
+
for key in DOUBLE_QUOTE_FIELDS:
|
|
273
|
+
keys = key.split(".")
|
|
274
|
+
field = _safe_get(data, keys)
|
|
275
|
+
if isinstance(field, list):
|
|
276
|
+
data[key] = [
|
|
277
|
+
DoubleQuotedScalarString(item) for item in field if item is not None
|
|
278
|
+
]
|
|
279
|
+
elif isinstance(field, str):
|
|
280
|
+
data[key] = DoubleQuotedScalarString(data[key])
|
|
281
|
+
elif isinstance(field, dict):
|
|
282
|
+
_apply_double_quotes_to_dict_values(field)
|
|
283
|
+
|
|
284
|
+
return data
|
|
285
|
+
|
|
286
|
+
|
|
192
287
|
def _model_to_yaml_with_comments(
|
|
193
288
|
model_instance: CompleteResponse,
|
|
194
289
|
file_name: str,
|
|
@@ -209,7 +304,8 @@ def _model_to_yaml_with_comments(
|
|
|
209
304
|
Returns:
|
|
210
305
|
Path: The file path of the generated YAML file.
|
|
211
306
|
"""
|
|
212
|
-
yaml =
|
|
307
|
+
yaml = YAML()
|
|
308
|
+
configure_yaml(yaml)
|
|
213
309
|
|
|
214
310
|
from dapla_metadata.variable_definitions.variable_definition import (
|
|
215
311
|
VariableDefinition,
|
|
@@ -223,7 +319,7 @@ def _model_to_yaml_with_comments(
|
|
|
223
319
|
serialize_as_any=True,
|
|
224
320
|
warnings="error",
|
|
225
321
|
)
|
|
226
|
-
|
|
322
|
+
data = pre_process_data(data)
|
|
227
323
|
# One CommentMap for each section in the yaml file
|
|
228
324
|
machine_generated_map = CommentedMap()
|
|
229
325
|
commented_map = CommentedMap()
|