sdmxlib 0.43.0__tar.gz → 0.44.0__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.
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/PKG-INFO +1 -1
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/pyproject.toml +1 -1
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/__init__.py +2 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/local/registry.py +166 -1
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/__init__.py +2 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/metadataset.py +24 -1
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/README.md +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/_duckdb.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/api/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/api/client.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/api/federated.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/api/filters.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/api/policy.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/api/providers.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/api/query.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/api/registry.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/api/session.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/builders/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/builders/contentconstraint.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/catalog.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/data_store.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_csv/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_csv/reader.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_csv/writer.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json/_data_common.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json/data_v1.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json/data_v2.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json/metadata.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json/reader.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json/structure_values.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json/writer.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json_1_0/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_json_1_0/writer.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml/_common.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml21/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml21/namespaces.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml21/reader.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml21/writer.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml30/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml30/metadata.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml30/namespaces.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml30/reader.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml30/writer.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml31/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml31/namespaces.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml31/reader.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/formats/sdmx_ml31/writer.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/local/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/local/data_store.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/annotations.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/base.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/binding.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/category.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/code_query.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/codelist.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/collections.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/concept.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/constraint.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/convert.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/dataflow.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/dataset.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/datastructure.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/expr.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/hierarchy.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/hierarchy_query.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/in_memory_registry.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/istring.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/mapping.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/message.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/metadataflow.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/metadatastructure.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/organisation.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/provision.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/ref.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/registry.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/representation.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/urn.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/model/validation.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/polars.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/py.typed +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/rest.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/sql.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/storage/__init__.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/storage/_kinds.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/storage/lazy.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/storage/readers.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/storage/schema.py +0 -0
- {sdmxlib-0.43.0 → sdmxlib-0.44.0}/src/sdmxlib/storage/writers.py +0 -0
|
@@ -90,6 +90,7 @@ from sdmxlib.model import (
|
|
|
90
90
|
MeasureDimension,
|
|
91
91
|
MetadataAttribute,
|
|
92
92
|
MetadataMessage,
|
|
93
|
+
MetadataSection,
|
|
93
94
|
MetadataSet,
|
|
94
95
|
MetadataStructure,
|
|
95
96
|
Metadataflow,
|
|
@@ -198,6 +199,7 @@ __all__ = [
|
|
|
198
199
|
"MemberValue",
|
|
199
200
|
"MetadataAttribute",
|
|
200
201
|
"MetadataMessage",
|
|
202
|
+
"MetadataSection",
|
|
201
203
|
"MetadataSet",
|
|
202
204
|
"MetadataStructure",
|
|
203
205
|
"Metadataflow",
|
|
@@ -36,13 +36,14 @@ import time
|
|
|
36
36
|
from collections.abc import Iterable, Iterator
|
|
37
37
|
from contextlib import contextmanager
|
|
38
38
|
from pathlib import Path
|
|
39
|
-
from typing import TYPE_CHECKING, Any, Self
|
|
39
|
+
from typing import TYPE_CHECKING, Any, Self, cast
|
|
40
40
|
|
|
41
41
|
import attrs
|
|
42
42
|
import duckdb
|
|
43
43
|
|
|
44
44
|
from sdmxlib._duckdb import scalar
|
|
45
45
|
from sdmxlib.model.collections import ItemList
|
|
46
|
+
from sdmxlib.model.istring import InternationalString
|
|
46
47
|
from sdmxlib.model.ref import Ref
|
|
47
48
|
from sdmxlib.model.registry import InMemoryRegistry, artefact_urn
|
|
48
49
|
from sdmxlib.model.urn import SdmxUrn
|
|
@@ -60,6 +61,19 @@ if TYPE_CHECKING:
|
|
|
60
61
|
from sdmxlib.model.binding import DataflowBinding, DriftIssue
|
|
61
62
|
from sdmxlib.model.dataflow import Dataflow
|
|
62
63
|
from sdmxlib.model.hierarchy import Hierarchy
|
|
64
|
+
from sdmxlib.model.metadataset import MetadataSection, MetadataSet
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _leaf_attribute_id(attribute_path: str) -> str:
|
|
68
|
+
"""Leaf attribute id from a dotted ``attribute_path``.
|
|
69
|
+
|
|
70
|
+
Strips the parent path and any ``[n]`` sibling suffix, e.g.
|
|
71
|
+
``"QUALITY.COVERAGE[1]"`` -> ``"COVERAGE"``.
|
|
72
|
+
"""
|
|
73
|
+
leaf = attribute_path.rsplit(".", 1)[-1]
|
|
74
|
+
bracket = leaf.find("[")
|
|
75
|
+
return leaf[:bracket] if bracket != -1 else leaf
|
|
76
|
+
|
|
63
77
|
|
|
64
78
|
# Map item-level artefact class -> (parent scheme type name, items attribute name)
|
|
65
79
|
_ITEM_TO_SCHEME: dict[str, tuple[str, str]] = {
|
|
@@ -657,6 +671,157 @@ class Registry:
|
|
|
657
671
|
if issues:
|
|
658
672
|
raise DriftError(issues)
|
|
659
673
|
|
|
674
|
+
# ── Reference-metadata queries ──────────────────────────────────────
|
|
675
|
+
|
|
676
|
+
def metadata_for_target(
|
|
677
|
+
self,
|
|
678
|
+
target_urn: "str | SdmxUrn[Any]",
|
|
679
|
+
*,
|
|
680
|
+
structure_urn: "str | SdmxUrn[Any] | None" = None,
|
|
681
|
+
) -> "list[MetadataSet]":
|
|
682
|
+
"""All MetadataSets whose targets include ``target_urn``.
|
|
683
|
+
|
|
684
|
+
The reverse of ``MetadataSet.targets`` — given any artefact URN
|
|
685
|
+
(a Code, Codelist, Concept, Dataflow, …), return every reported
|
|
686
|
+
MetadataSet attached to it. This is the SDMX 3.0
|
|
687
|
+
``/metadata/structure/{artefactType}/…`` by-target lookup realised
|
|
688
|
+
locally, and the primitive both the REST view and the search
|
|
689
|
+
indexer navigate.
|
|
690
|
+
|
|
691
|
+
Sets are returned without resolving their target/structure Refs
|
|
692
|
+
(the URNs are all present) — cheap even for sets with many
|
|
693
|
+
targets. Ordered by set URN for determinism.
|
|
694
|
+
|
|
695
|
+
Args:
|
|
696
|
+
target_urn: The artefact URN to find attached metadata for.
|
|
697
|
+
structure_urn: Optional MSD or Metadataflow URN to filter by,
|
|
698
|
+
e.g. return only reference-guide sets targeting the code.
|
|
699
|
+
|
|
700
|
+
Returns:
|
|
701
|
+
The matching MetadataSets (empty list if none).
|
|
702
|
+
"""
|
|
703
|
+
cur = self._read_cursor()
|
|
704
|
+
params: list[str] = [str(target_urn)]
|
|
705
|
+
sql = "SELECT DISTINCT t.set_urn FROM metadata_target t"
|
|
706
|
+
if structure_urn is not None:
|
|
707
|
+
sql += " JOIN metadata_set s ON s.urn = t.set_urn AND s.structure_urn = ?"
|
|
708
|
+
params.append(str(structure_urn))
|
|
709
|
+
sql += " WHERE t.target_urn = ? ORDER BY t.set_urn"
|
|
710
|
+
# target_urn is the last positional param; structure_urn (if any)
|
|
711
|
+
# precedes it in SQL text, so order params to match.
|
|
712
|
+
ordered = ([params[1]] if structure_urn is not None else []) + [params[0]]
|
|
713
|
+
rows = cur.execute(sql, ordered).fetchall()
|
|
714
|
+
|
|
715
|
+
sets: list[MetadataSet] = []
|
|
716
|
+
for (set_urn,) in rows:
|
|
717
|
+
artefact = readers.get_artefact(cur, set_urn, lazy_conn=self._conn)
|
|
718
|
+
if artefact is not None:
|
|
719
|
+
sets.append(cast("MetadataSet", artefact))
|
|
720
|
+
return sets
|
|
721
|
+
|
|
722
|
+
def metadata_report(
|
|
723
|
+
self,
|
|
724
|
+
set_urn: "str | SdmxUrn[Any]",
|
|
725
|
+
) -> "list[MetadataSection]":
|
|
726
|
+
"""Flattened, MSD-typed view of a MetadataSet's reported values.
|
|
727
|
+
|
|
728
|
+
Returns one ``MetadataSection`` per ``metadata_value`` row,
|
|
729
|
+
each carrying the leaf attribute's declared ``text_type`` (e.g.
|
|
730
|
+
``"String"`` / ``"XHTML"``) and ``is_presentational`` flag joined
|
|
731
|
+
from the MSD. Sections are ordered by ``(path, sibling_index)``.
|
|
732
|
+
|
|
733
|
+
This is the sectioned input a chunker / search indexer consumes —
|
|
734
|
+
it turns the reported tree + schema into a flat, typed list without
|
|
735
|
+
the caller re-joining the MSD. Returns an empty list if the set has
|
|
736
|
+
no values (or does not exist).
|
|
737
|
+
|
|
738
|
+
Args:
|
|
739
|
+
set_urn: The MetadataSet URN to project.
|
|
740
|
+
"""
|
|
741
|
+
from sdmxlib.model.metadataset import MetadataSection # noqa: PLC0415
|
|
742
|
+
|
|
743
|
+
cur = self._read_cursor()
|
|
744
|
+
type_by_id = self._msd_attribute_types(cur, str(set_urn))
|
|
745
|
+
|
|
746
|
+
rows = cur.execute(
|
|
747
|
+
"""
|
|
748
|
+
SELECT attribute_path, sibling_index, value_kind, scalar, i18n
|
|
749
|
+
FROM metadata_value
|
|
750
|
+
WHERE set_urn = ?
|
|
751
|
+
ORDER BY attribute_path, sibling_index
|
|
752
|
+
""",
|
|
753
|
+
[str(set_urn)],
|
|
754
|
+
).fetchall()
|
|
755
|
+
|
|
756
|
+
sections: list[MetadataSection] = []
|
|
757
|
+
for attribute_path, sibling_index, value_kind, scalar_val, i18n_val in rows:
|
|
758
|
+
leaf_id = _leaf_attribute_id(attribute_path)
|
|
759
|
+
text_type, is_pres = type_by_id.get(leaf_id, (None, False))
|
|
760
|
+
value: Any
|
|
761
|
+
if value_kind == "i18n":
|
|
762
|
+
value = InternationalString.of(dict(i18n_val)) if i18n_val else None
|
|
763
|
+
else:
|
|
764
|
+
value = scalar_val
|
|
765
|
+
sections.append(
|
|
766
|
+
MetadataSection(
|
|
767
|
+
path=attribute_path,
|
|
768
|
+
attribute_id=leaf_id,
|
|
769
|
+
sibling_index=sibling_index,
|
|
770
|
+
value=value,
|
|
771
|
+
text_type=text_type,
|
|
772
|
+
is_presentational=is_pres,
|
|
773
|
+
)
|
|
774
|
+
)
|
|
775
|
+
return sections
|
|
776
|
+
|
|
777
|
+
def _msd_attribute_types(
|
|
778
|
+
self,
|
|
779
|
+
cur: "duckdb.DuckDBPyConnection",
|
|
780
|
+
set_urn: str,
|
|
781
|
+
) -> "dict[str, tuple[str | None, bool]]":
|
|
782
|
+
"""Map ``attribute id → (text_type, is_presentational)`` for a set's MSD.
|
|
783
|
+
|
|
784
|
+
Resolves the set's structure (an MSD directly, or the MSD behind a
|
|
785
|
+
Metadataflow) and walks its attribute tree. Empty if the structure
|
|
786
|
+
is absent.
|
|
787
|
+
"""
|
|
788
|
+
from sdmxlib.model.metadatastructure import MetadataAttribute, MetadataStructure # noqa: PLC0415
|
|
789
|
+
from sdmxlib.model.representation import Facet # noqa: PLC0415
|
|
790
|
+
|
|
791
|
+
set_row = cur.execute(
|
|
792
|
+
"SELECT structure_urn, structure_kind FROM metadata_set WHERE urn = ?",
|
|
793
|
+
[set_urn],
|
|
794
|
+
).fetchone()
|
|
795
|
+
if set_row is None:
|
|
796
|
+
return {}
|
|
797
|
+
structure_urn, structure_kind = set_row
|
|
798
|
+
|
|
799
|
+
msd_urn = structure_urn
|
|
800
|
+
if structure_kind == "Metadataflow":
|
|
801
|
+
flow = readers.get_artefact(cur, structure_urn, lazy_conn=self._conn)
|
|
802
|
+
structure_ref = getattr(flow, "structure", None)
|
|
803
|
+
if structure_ref is None:
|
|
804
|
+
return {}
|
|
805
|
+
msd_urn = str(structure_ref.urn)
|
|
806
|
+
|
|
807
|
+
msd = readers.get_artefact(cur, msd_urn, lazy_conn=self._conn)
|
|
808
|
+
if not isinstance(msd, MetadataStructure):
|
|
809
|
+
return {}
|
|
810
|
+
|
|
811
|
+
out: dict[str, tuple[str | None, bool]] = {}
|
|
812
|
+
|
|
813
|
+
def _walk(attr: MetadataAttribute) -> None:
|
|
814
|
+
text_type: str | None = None
|
|
815
|
+
if isinstance(attr.representation, Facet) and attr.representation.type is not None:
|
|
816
|
+
text_type = str(attr.representation.type)
|
|
817
|
+
out[attr.id] = (text_type, attr.is_presentational)
|
|
818
|
+
for child in attr.children:
|
|
819
|
+
_walk(child)
|
|
820
|
+
|
|
821
|
+
for root in msd.attributes:
|
|
822
|
+
_walk(root)
|
|
823
|
+
return out
|
|
824
|
+
|
|
660
825
|
# ── Ref resolution ─────────────────────────────────────────────────
|
|
661
826
|
|
|
662
827
|
def _resolve_refs( # noqa: C901
|
|
@@ -78,6 +78,7 @@ from sdmxlib.model.message import MetadataMessage, StructureMessage
|
|
|
78
78
|
from sdmxlib.model.metadataflow import Metadataflow
|
|
79
79
|
from sdmxlib.model.metadatastructure import MetadataAttribute, MetadataStructure
|
|
80
80
|
from sdmxlib.model.metadataset import (
|
|
81
|
+
MetadataSection,
|
|
81
82
|
MetadataSet,
|
|
82
83
|
ReportedAttribute,
|
|
83
84
|
ReportedAttributeValue,
|
|
@@ -157,6 +158,7 @@ __all__ = [
|
|
|
157
158
|
"MemberValue",
|
|
158
159
|
"MetadataAttribute",
|
|
159
160
|
"MetadataMessage",
|
|
161
|
+
"MetadataSection",
|
|
160
162
|
"MetadataSet",
|
|
161
163
|
"MetadataStructure",
|
|
162
164
|
"Metadataflow",
|
|
@@ -19,7 +19,7 @@ from collections.abc import Sequence
|
|
|
19
19
|
from datetime import datetime
|
|
20
20
|
from typing import Any, ClassVar, cast
|
|
21
21
|
|
|
22
|
-
from attrs import define, evolve, field
|
|
22
|
+
from attrs import define, evolve, field, frozen
|
|
23
23
|
|
|
24
24
|
from sdmxlib.model.annotations import Annotations
|
|
25
25
|
from sdmxlib.model.base import MaintainableArtefact
|
|
@@ -70,6 +70,29 @@ class ReportedAttribute:
|
|
|
70
70
|
annotations: Annotations = field(factory=Annotations, converter=_to_annotations)
|
|
71
71
|
|
|
72
72
|
|
|
73
|
+
@frozen
|
|
74
|
+
class MetadataSection:
|
|
75
|
+
"""A flattened, MSD-typed view of one reported metadata value.
|
|
76
|
+
|
|
77
|
+
The retrieval projection of a MetadataSet: one ``MetadataSection`` per
|
|
78
|
+
``metadata_value`` row, with the leaf attribute's declared data type
|
|
79
|
+
(``text_type``, e.g. ``"String"`` / ``"XHTML"``) joined in from the
|
|
80
|
+
MSD. This is the sectioned input a chunker / search indexer wants —
|
|
81
|
+
``path`` gives the dotted hierarchical location (with ``[n]`` sibling
|
|
82
|
+
suffixes preserved), ``attribute_id`` the leaf id, and ``value`` the
|
|
83
|
+
scalar or ``InternationalString`` content.
|
|
84
|
+
|
|
85
|
+
Produced by ``Registry.metadata_report``.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
path: str
|
|
89
|
+
attribute_id: str
|
|
90
|
+
sibling_index: int
|
|
91
|
+
value: ReportedAttributeValue | None = None
|
|
92
|
+
text_type: str | None = None
|
|
93
|
+
is_presentational: bool = False
|
|
94
|
+
|
|
95
|
+
|
|
73
96
|
# ── MetadataSet ──────────────────────────────────────────────────────────
|
|
74
97
|
|
|
75
98
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|