pysdmx 1.10.1__py3-none-any.whl → 1.12.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pysdmx/__init__.py +1 -1
- pysdmx/api/fmr/maintenance.py +10 -5
- pysdmx/io/input_processor.py +4 -0
- pysdmx/io/json/fusion/messages/constraint.py +22 -1
- pysdmx/io/json/fusion/messages/dsd.py +20 -14
- pysdmx/io/json/fusion/messages/msd.py +6 -9
- pysdmx/io/json/fusion/messages/schema.py +20 -1
- pysdmx/io/json/sdmxjson2/messages/core.py +12 -5
- pysdmx/io/json/sdmxjson2/messages/dsd.py +11 -17
- pysdmx/io/json/sdmxjson2/messages/msd.py +2 -5
- pysdmx/io/json/sdmxjson2/messages/report.py +7 -3
- pysdmx/io/json/sdmxjson2/messages/schema.py +38 -5
- pysdmx/io/json/sdmxjson2/messages/structure.py +7 -3
- pysdmx/io/json/sdmxjson2/reader/metadata.py +3 -3
- pysdmx/io/json/sdmxjson2/reader/structure.py +3 -3
- pysdmx/io/json/sdmxjson2/writer/_helper.py +118 -0
- pysdmx/io/json/sdmxjson2/writer/v2_0/__init__.py +1 -0
- pysdmx/io/json/sdmxjson2/writer/v2_0/metadata.py +33 -0
- pysdmx/io/json/sdmxjson2/writer/v2_0/structure.py +33 -0
- pysdmx/io/json/sdmxjson2/writer/v2_1/__init__.py +1 -0
- pysdmx/io/json/sdmxjson2/writer/v2_1/metadata.py +31 -0
- pysdmx/io/json/sdmxjson2/writer/v2_1/structure.py +33 -0
- pysdmx/io/reader.py +12 -3
- pysdmx/io/writer.py +13 -3
- pysdmx/io/xml/__ss_aux_reader.py +39 -17
- pysdmx/io/xml/__structure_aux_reader.py +221 -33
- pysdmx/io/xml/__structure_aux_writer.py +304 -5
- pysdmx/io/xml/__tokens.py +12 -0
- pysdmx/io/xml/__write_aux.py +9 -0
- pysdmx/io/xml/sdmx21/writer/generic.py +2 -2
- pysdmx/model/dataflow.py +11 -2
- pysdmx/toolkit/pd/_data_utils.py +1 -1
- {pysdmx-1.10.1.dist-info → pysdmx-1.12.0.dist-info}/METADATA +7 -1
- {pysdmx-1.10.1.dist-info → pysdmx-1.12.0.dist-info}/RECORD +36 -31
- {pysdmx-1.10.1.dist-info → pysdmx-1.12.0.dist-info}/WHEEL +1 -1
- pysdmx/io/json/sdmxjson2/writer/metadata.py +0 -60
- pysdmx/io/json/sdmxjson2/writer/structure.py +0 -61
- {pysdmx-1.10.1.dist-info → pysdmx-1.12.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -14,6 +14,7 @@ from pysdmx.io.xml.__tokens import (
|
|
|
14
14
|
CL,
|
|
15
15
|
CL_LOW,
|
|
16
16
|
CLASS,
|
|
17
|
+
COMPONENT_MAP,
|
|
17
18
|
CON,
|
|
18
19
|
CON_ID,
|
|
19
20
|
CONDITIONAL,
|
|
@@ -52,10 +53,12 @@ from pysdmx.io.xml.__tokens import (
|
|
|
52
53
|
POSITION,
|
|
53
54
|
PROV_AGREEMENT,
|
|
54
55
|
REF,
|
|
56
|
+
REPRESENTATION_MAP,
|
|
55
57
|
ROLE,
|
|
56
58
|
RULE,
|
|
57
59
|
RULE_SCHEME,
|
|
58
60
|
STR_USAGE,
|
|
61
|
+
STRUCTURE_MAP,
|
|
59
62
|
TELEPHONE,
|
|
60
63
|
TEXT_FORMAT,
|
|
61
64
|
TEXT_TYPE,
|
|
@@ -89,21 +92,30 @@ from pysdmx.io.xml.__write_aux import (
|
|
|
89
92
|
from pysdmx.model import (
|
|
90
93
|
AgencyScheme,
|
|
91
94
|
Codelist,
|
|
95
|
+
ComponentMap,
|
|
92
96
|
Concept,
|
|
93
97
|
ConceptScheme,
|
|
94
98
|
CustomType,
|
|
95
99
|
CustomTypeScheme,
|
|
96
100
|
DataType,
|
|
101
|
+
DatePatternMap,
|
|
97
102
|
Facets,
|
|
103
|
+
FixedValueMap,
|
|
98
104
|
Hierarchy,
|
|
105
|
+
ImplicitComponentMap,
|
|
106
|
+
MultiComponentMap,
|
|
107
|
+
MultiValueMap,
|
|
99
108
|
NamePersonalisation,
|
|
100
109
|
NamePersonalisationScheme,
|
|
110
|
+
RepresentationMap,
|
|
101
111
|
Ruleset,
|
|
102
112
|
RulesetScheme,
|
|
113
|
+
StructureMap,
|
|
103
114
|
Transformation,
|
|
104
115
|
TransformationScheme,
|
|
105
116
|
UserDefinedOperator,
|
|
106
117
|
UserDefinedOperatorScheme,
|
|
118
|
+
ValueMap,
|
|
107
119
|
VtlCodelistMapping,
|
|
108
120
|
VtlConceptMapping,
|
|
109
121
|
VtlDataflowMapping,
|
|
@@ -173,6 +185,9 @@ STR_DICT_TYPE_LIST_21 = {
|
|
|
173
185
|
ConceptScheme: "Concepts",
|
|
174
186
|
DataStructureDefinition: "DataStructures",
|
|
175
187
|
Dataflow: "Dataflows",
|
|
188
|
+
RepresentationMap: "RepresentationMaps",
|
|
189
|
+
StructureMap: "StructureMaps",
|
|
190
|
+
DatePatternMap: "DatePatternMaps",
|
|
176
191
|
CustomTypeScheme: "CustomTypes",
|
|
177
192
|
VtlMappingScheme: "VtlMappings",
|
|
178
193
|
NamePersonalisationScheme: "NamePersonalisations",
|
|
@@ -189,6 +204,9 @@ STR_DICT_TYPE_LIST_30 = {
|
|
|
189
204
|
ConceptScheme: "ConceptSchemes",
|
|
190
205
|
DataStructureDefinition: "DataStructures",
|
|
191
206
|
Dataflow: "Dataflows",
|
|
207
|
+
RepresentationMap: "RepresentationMaps",
|
|
208
|
+
StructureMap: "StructureMaps",
|
|
209
|
+
DatePatternMap: "DatePatternMaps",
|
|
192
210
|
CustomTypeScheme: "CustomTypeSchemes",
|
|
193
211
|
VtlMappingScheme: "VtlMappingSchemes",
|
|
194
212
|
NamePersonalisationScheme: "NamePersonalisationSchemes",
|
|
@@ -564,10 +582,25 @@ def __write_attribute_relation( # noqa: C901
|
|
|
564
582
|
f"{group_id}</{ABBR_STR}:{GROUP}>"
|
|
565
583
|
)
|
|
566
584
|
else:
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
585
|
+
is_dimension = comps_to_relate[0] in dim_names
|
|
586
|
+
if is_dimension:
|
|
587
|
+
for comp_name in comps_to_relate:
|
|
588
|
+
outfile += (
|
|
589
|
+
f"{add_indent(indent)}<{ABBR_STR}:{DIM}>"
|
|
590
|
+
f"{comp_name}</{ABBR_STR}:{DIM}>"
|
|
591
|
+
)
|
|
592
|
+
else:
|
|
593
|
+
outfile += f"{add_indent(indent)}<{ABBR_STR}:Observation/>"
|
|
594
|
+
measure_relationship += (
|
|
595
|
+
f"{indent}<{ABBR_STR}:{MEASURE_RELATIONSHIP}>"
|
|
596
|
+
)
|
|
597
|
+
for comp_name in comps_to_relate:
|
|
598
|
+
measure_relationship += (
|
|
599
|
+
f"{add_indent(indent)}<{ABBR_STR}:{MSR}>"
|
|
600
|
+
f"{comp_name}</{ABBR_STR}:{MSR}>"
|
|
601
|
+
)
|
|
602
|
+
measure_relationship += (
|
|
603
|
+
f"{indent}</{ABBR_STR}:{MEASURE_RELATIONSHIP}>"
|
|
571
604
|
)
|
|
572
605
|
|
|
573
606
|
else:
|
|
@@ -675,8 +708,13 @@ def __write_concept_identity(
|
|
|
675
708
|
) -> str:
|
|
676
709
|
if isinstance(identity, ItemReference):
|
|
677
710
|
ref = identity
|
|
711
|
+
elif identity.urn is not None:
|
|
712
|
+
ref = parse_item_urn(identity.urn)
|
|
678
713
|
else:
|
|
679
|
-
|
|
714
|
+
raise Invalid(
|
|
715
|
+
f"Cannot select concept identity without URN. "
|
|
716
|
+
f"Concept id={identity.id!r}"
|
|
717
|
+
)
|
|
680
718
|
|
|
681
719
|
outfile = f"{indent}<{ABBR_STR}:{CON_ID}>"
|
|
682
720
|
if references_30:
|
|
@@ -841,12 +879,273 @@ def __write_prov_agreement(
|
|
|
841
879
|
return outfile
|
|
842
880
|
|
|
843
881
|
|
|
882
|
+
def __write_value_map(
|
|
883
|
+
value_map: Union[ValueMap, MultiValueMap], indent: str
|
|
884
|
+
) -> str:
|
|
885
|
+
"""Writes a ValueMap or MultiValueMap (RepresentationMapping)."""
|
|
886
|
+
outfile = f"{indent}<{ABBR_STR}:RepresentationMapping>"
|
|
887
|
+
|
|
888
|
+
# MultiValueMap
|
|
889
|
+
if isinstance(value_map, MultiValueMap):
|
|
890
|
+
for s in value_map.source:
|
|
891
|
+
outfile += (
|
|
892
|
+
f"{add_indent(indent)}<{ABBR_STR}:SourceValue>"
|
|
893
|
+
f"{__escape_xml(str(s))}"
|
|
894
|
+
f"</{ABBR_STR}:SourceValue>"
|
|
895
|
+
)
|
|
896
|
+
for t in value_map.target:
|
|
897
|
+
outfile += (
|
|
898
|
+
f"{add_indent(indent)}<{ABBR_STR}:TargetValue>"
|
|
899
|
+
f"{__escape_xml(str(t))}"
|
|
900
|
+
f"</{ABBR_STR}:TargetValue>"
|
|
901
|
+
)
|
|
902
|
+
outfile += f"{indent}</{ABBR_STR}:RepresentationMapping>"
|
|
903
|
+
return outfile
|
|
904
|
+
|
|
905
|
+
# ValueMap
|
|
906
|
+
outfile += (
|
|
907
|
+
f"{add_indent(indent)}<{ABBR_STR}:SourceValue>"
|
|
908
|
+
f"{__escape_xml(str(value_map.source))}"
|
|
909
|
+
f"</{ABBR_STR}:SourceValue>"
|
|
910
|
+
)
|
|
911
|
+
outfile += (
|
|
912
|
+
f"{add_indent(indent)}<{ABBR_STR}:TargetValue>"
|
|
913
|
+
f"{__escape_xml(str(value_map.target))}"
|
|
914
|
+
f"</{ABBR_STR}:TargetValue>"
|
|
915
|
+
)
|
|
916
|
+
outfile += f"{indent}</{ABBR_STR}:RepresentationMapping>"
|
|
917
|
+
return outfile
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
def __write_multi_component_map(
|
|
921
|
+
comp_map: MultiComponentMap, indent: str
|
|
922
|
+
) -> str:
|
|
923
|
+
"""Writes a MultiComponentMap (1-n, n-1, n-n) to the XML file."""
|
|
924
|
+
outfile = f"{indent}<{ABBR_STR}:{COMPONENT_MAP}>"
|
|
925
|
+
|
|
926
|
+
for s in comp_map.source:
|
|
927
|
+
outfile += (
|
|
928
|
+
f"{add_indent(indent)}<{ABBR_STR}:Source>"
|
|
929
|
+
f"{__escape_xml(str(s))}"
|
|
930
|
+
f"</{ABBR_STR}:Source>"
|
|
931
|
+
)
|
|
932
|
+
|
|
933
|
+
for t in comp_map.target:
|
|
934
|
+
outfile += (
|
|
935
|
+
f"{add_indent(indent)}<{ABBR_STR}:Target>"
|
|
936
|
+
f"{__escape_xml(str(t))}"
|
|
937
|
+
f"</{ABBR_STR}:Target>"
|
|
938
|
+
)
|
|
939
|
+
|
|
940
|
+
outfile += (
|
|
941
|
+
f"{add_indent(indent)}<{ABBR_STR}:RepresentationMap>"
|
|
942
|
+
f"{__escape_xml(str(comp_map.values))}"
|
|
943
|
+
f"</{ABBR_STR}:RepresentationMap>"
|
|
944
|
+
)
|
|
945
|
+
|
|
946
|
+
outfile += f"{indent}</{ABBR_STR}:{COMPONENT_MAP}>"
|
|
947
|
+
return outfile
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
def __write_representation_map(
|
|
951
|
+
rep_map: RepresentationMap, indent: str, references_30: bool = False
|
|
952
|
+
) -> str:
|
|
953
|
+
"""Writes a RepresentationMap to the XML file."""
|
|
954
|
+
data = __write_maintainable(rep_map, indent, references_30)
|
|
955
|
+
|
|
956
|
+
label = f"{ABBR_STR}:{REPRESENTATION_MAP}"
|
|
957
|
+
attributes = data.get("Attributes") or ""
|
|
958
|
+
attributes = attributes.replace("'", '"')
|
|
959
|
+
|
|
960
|
+
outfile = f"{indent}<{label}{attributes}>"
|
|
961
|
+
outfile += __export_intern_data(data)
|
|
962
|
+
|
|
963
|
+
# Write Source and Target references
|
|
964
|
+
outfile += (
|
|
965
|
+
f"{add_indent(indent)}<{ABBR_STR}:SourceCodelist>"
|
|
966
|
+
f"{rep_map.source}"
|
|
967
|
+
f"</{ABBR_STR}:SourceCodelist>"
|
|
968
|
+
)
|
|
969
|
+
outfile += (
|
|
970
|
+
f"{add_indent(indent)}<{ABBR_STR}:TargetCodelist>"
|
|
971
|
+
f"{rep_map.target}"
|
|
972
|
+
f"</{ABBR_STR}:TargetCodelist>"
|
|
973
|
+
)
|
|
974
|
+
|
|
975
|
+
# Write ValueMaps
|
|
976
|
+
for value_map in rep_map.maps:
|
|
977
|
+
outfile += __write_value_map(value_map, add_indent(indent))
|
|
978
|
+
|
|
979
|
+
outfile += f"{indent}</{label}>"
|
|
980
|
+
|
|
981
|
+
return outfile
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
def __write_component_map(
|
|
985
|
+
comp_map: ComponentMap, indent: str, references_30: bool = False
|
|
986
|
+
) -> str:
|
|
987
|
+
"""Writes a ComponentMap to the XML file."""
|
|
988
|
+
outfile = f"{indent}<{ABBR_STR}:{COMPONENT_MAP}>"
|
|
989
|
+
outfile += (
|
|
990
|
+
f"{add_indent(indent)}<{ABBR_STR}:Source>"
|
|
991
|
+
f"{comp_map.source}"
|
|
992
|
+
f"</{ABBR_STR}:Source>"
|
|
993
|
+
)
|
|
994
|
+
outfile += (
|
|
995
|
+
f"{add_indent(indent)}<{ABBR_STR}:Target>"
|
|
996
|
+
f"{comp_map.target}"
|
|
997
|
+
f"</{ABBR_STR}:Target>"
|
|
998
|
+
)
|
|
999
|
+
|
|
1000
|
+
# Write the RepresentationMap reference
|
|
1001
|
+
outfile += (
|
|
1002
|
+
f"{add_indent(indent)}<{ABBR_STR}:RepresentationMap>"
|
|
1003
|
+
f"{comp_map.values}"
|
|
1004
|
+
f"</{ABBR_STR}:RepresentationMap>"
|
|
1005
|
+
)
|
|
1006
|
+
|
|
1007
|
+
outfile += f"{indent}</{ABBR_STR}:{COMPONENT_MAP}>"
|
|
1008
|
+
return outfile
|
|
1009
|
+
|
|
1010
|
+
|
|
1011
|
+
def __write_implicit_component_map(
|
|
1012
|
+
imp_comp_map: ImplicitComponentMap, indent: str
|
|
1013
|
+
) -> str:
|
|
1014
|
+
"""Writes an ImplicitComponentMap (no RepresentationMap)."""
|
|
1015
|
+
outfile = f"{indent}<{ABBR_STR}:ComponentMap>"
|
|
1016
|
+
outfile += (
|
|
1017
|
+
f"{add_indent(indent)}<{ABBR_STR}:Source>"
|
|
1018
|
+
f"{imp_comp_map.source}"
|
|
1019
|
+
f"</{ABBR_STR}:Source>"
|
|
1020
|
+
)
|
|
1021
|
+
outfile += (
|
|
1022
|
+
f"{add_indent(indent)}<{ABBR_STR}:Target>"
|
|
1023
|
+
f"{imp_comp_map.target}"
|
|
1024
|
+
f"</{ABBR_STR}:Target>"
|
|
1025
|
+
)
|
|
1026
|
+
outfile += f"{indent}</{ABBR_STR}:ComponentMap>"
|
|
1027
|
+
return outfile
|
|
1028
|
+
|
|
1029
|
+
|
|
1030
|
+
def __write_fixed_value_map(fixed_map: FixedValueMap, indent: str) -> str:
|
|
1031
|
+
"""Writes a FixedValueMap to the XML file."""
|
|
1032
|
+
outfile = f"{indent}<{ABBR_STR}:FixedValueMap>"
|
|
1033
|
+
outfile += (
|
|
1034
|
+
f"{add_indent(indent)}<{ABBR_STR}:Target>"
|
|
1035
|
+
f"{fixed_map.target}"
|
|
1036
|
+
f"</{ABBR_STR}:Target>"
|
|
1037
|
+
)
|
|
1038
|
+
outfile += (
|
|
1039
|
+
f"{add_indent(indent)}<{ABBR_STR}:Value>"
|
|
1040
|
+
f"{__escape_xml(str(fixed_map.value))}"
|
|
1041
|
+
f"</{ABBR_STR}:Value>"
|
|
1042
|
+
)
|
|
1043
|
+
outfile += f"{indent}</{ABBR_STR}:FixedValueMap>"
|
|
1044
|
+
return outfile
|
|
1045
|
+
|
|
1046
|
+
|
|
1047
|
+
def __write_date_pattern_map(date_map: DatePatternMap, indent: str) -> str:
|
|
1048
|
+
"""Writes a DatePatternMap to the XML file."""
|
|
1049
|
+
attrs = ""
|
|
1050
|
+
if date_map.id is not None:
|
|
1051
|
+
attrs += f' id="{__escape_xml(date_map.id)}"'
|
|
1052
|
+
if date_map.resolve_period is not None:
|
|
1053
|
+
attrs += f' resolvePeriod="{__escape_xml(date_map.resolve_period)}"'
|
|
1054
|
+
|
|
1055
|
+
attrs += f' sourcePattern="{__escape_xml(date_map.pattern)}"'
|
|
1056
|
+
attrs += f' locale="{__escape_xml(date_map.locale)}"'
|
|
1057
|
+
|
|
1058
|
+
outfile = f"{indent}<{ABBR_STR}:DatePatternMap{attrs}>"
|
|
1059
|
+
outfile += (
|
|
1060
|
+
f"{add_indent(indent)}<{ABBR_STR}:Source>"
|
|
1061
|
+
f"{__escape_xml(date_map.source)}"
|
|
1062
|
+
f"</{ABBR_STR}:Source>"
|
|
1063
|
+
)
|
|
1064
|
+
outfile += (
|
|
1065
|
+
f"{add_indent(indent)}<{ABBR_STR}:Target>"
|
|
1066
|
+
f"{__escape_xml(date_map.target)}"
|
|
1067
|
+
f"</{ABBR_STR}:Target>"
|
|
1068
|
+
)
|
|
1069
|
+
|
|
1070
|
+
if date_map.pattern_type == "variable":
|
|
1071
|
+
outfile += (
|
|
1072
|
+
f"{add_indent(indent)}<{ABBR_STR}:FrequencyDimension>"
|
|
1073
|
+
f"{__escape_xml(date_map.frequency)}"
|
|
1074
|
+
f"</{ABBR_STR}:FrequencyDimension>"
|
|
1075
|
+
)
|
|
1076
|
+
else:
|
|
1077
|
+
outfile += (
|
|
1078
|
+
f"{add_indent(indent)}<{ABBR_STR}:TargetFrequencyID>"
|
|
1079
|
+
f"{__escape_xml(date_map.frequency)}"
|
|
1080
|
+
f"</{ABBR_STR}:TargetFrequencyID>"
|
|
1081
|
+
)
|
|
1082
|
+
|
|
1083
|
+
outfile += f"{indent}</{ABBR_STR}:DatePatternMap>"
|
|
1084
|
+
return outfile
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
def __write_structure_map(
|
|
1088
|
+
struct_map: StructureMap, indent: str, references_30: bool = False
|
|
1089
|
+
) -> str:
|
|
1090
|
+
"""Writes a StructureMap to the XML file."""
|
|
1091
|
+
data = __write_maintainable(struct_map, indent, references_30)
|
|
1092
|
+
|
|
1093
|
+
label = f"{ABBR_STR}:{STRUCTURE_MAP}"
|
|
1094
|
+
attributes = data.get("Attributes") or ""
|
|
1095
|
+
attributes = attributes.replace("'", '"')
|
|
1096
|
+
|
|
1097
|
+
outfile = f"{indent}<{label}{attributes}>"
|
|
1098
|
+
outfile += __export_intern_data(data)
|
|
1099
|
+
|
|
1100
|
+
# Write Source and Target references
|
|
1101
|
+
outfile += (
|
|
1102
|
+
f"{add_indent(indent)}<{ABBR_STR}:Source>"
|
|
1103
|
+
f"{struct_map.source}"
|
|
1104
|
+
f"</{ABBR_STR}:Source>"
|
|
1105
|
+
)
|
|
1106
|
+
outfile += (
|
|
1107
|
+
f"{add_indent(indent)}<{ABBR_STR}:Target>"
|
|
1108
|
+
f"{struct_map.target}"
|
|
1109
|
+
f"</{ABBR_STR}:Target>"
|
|
1110
|
+
)
|
|
1111
|
+
|
|
1112
|
+
# Write component maps and fixed value maps
|
|
1113
|
+
for map_item in struct_map.maps:
|
|
1114
|
+
if isinstance(map_item, DatePatternMap):
|
|
1115
|
+
outfile += __write_date_pattern_map(map_item, add_indent(indent))
|
|
1116
|
+
for map_item in struct_map.maps:
|
|
1117
|
+
if isinstance(map_item, MultiComponentMap):
|
|
1118
|
+
outfile += __write_multi_component_map(
|
|
1119
|
+
map_item, add_indent(indent)
|
|
1120
|
+
)
|
|
1121
|
+
elif isinstance(map_item, ComponentMap):
|
|
1122
|
+
outfile += __write_component_map(
|
|
1123
|
+
map_item, add_indent(indent), references_30
|
|
1124
|
+
)
|
|
1125
|
+
elif isinstance(map_item, ImplicitComponentMap):
|
|
1126
|
+
outfile += __write_implicit_component_map(
|
|
1127
|
+
map_item, add_indent(indent)
|
|
1128
|
+
)
|
|
1129
|
+
if isinstance(map_item, FixedValueMap):
|
|
1130
|
+
outfile += __write_fixed_value_map(map_item, add_indent(indent))
|
|
1131
|
+
|
|
1132
|
+
outfile += f"{indent}</{label}>"
|
|
1133
|
+
|
|
1134
|
+
return outfile
|
|
1135
|
+
|
|
1136
|
+
|
|
844
1137
|
def __write_scheme( # noqa: C901
|
|
845
1138
|
item_scheme: Any, indent: str, scheme: str, references_30: bool = False
|
|
846
1139
|
) -> str:
|
|
847
1140
|
"""Writes the scheme to the XML file."""
|
|
848
1141
|
if getattr(item_scheme, "sdmx_type", None) == "valuelist":
|
|
849
1142
|
scheme = VALUE_LIST
|
|
1143
|
+
|
|
1144
|
+
if scheme == REPRESENTATION_MAP:
|
|
1145
|
+
return __write_representation_map(item_scheme, indent, references_30)
|
|
1146
|
+
if scheme == STRUCTURE_MAP:
|
|
1147
|
+
return __write_structure_map(item_scheme, indent, references_30)
|
|
1148
|
+
|
|
850
1149
|
label = f"{ABBR_STR}:{scheme}"
|
|
851
1150
|
components = ""
|
|
852
1151
|
data = __write_maintainable(item_scheme, indent, references_30)
|
pysdmx/io/xml/__tokens.py
CHANGED
|
@@ -297,3 +297,15 @@ VALUE_LISTS = "ValueLists"
|
|
|
297
297
|
VALUE_LIST = "ValueList"
|
|
298
298
|
VALUE_LIST_LOW = "valuelist"
|
|
299
299
|
VALUE_ITEM = "ValueItem"
|
|
300
|
+
|
|
301
|
+
# Mapping
|
|
302
|
+
STRUCTURE_MAPS = "StructureMaps"
|
|
303
|
+
STRUCTURE_MAP = "StructureMap"
|
|
304
|
+
REPRESENTATION_MAPS = "RepresentationMaps"
|
|
305
|
+
REPRESENTATION_MAP = "RepresentationMap"
|
|
306
|
+
COMPONENT_MAPS = "ComponentMaps"
|
|
307
|
+
COMPONENT_MAP = "ComponentMap"
|
|
308
|
+
FIXED_VALUE_MAPS = "FixedValueMaps"
|
|
309
|
+
FIXED_VALUE_MAP = "FixedValueMap"
|
|
310
|
+
DATE_PATTERN_MAP = "DatePatternMap"
|
|
311
|
+
DATE_PATTERN_MAPS = "DatePatternMaps"
|
pysdmx/io/xml/__write_aux.py
CHANGED
|
@@ -22,10 +22,12 @@ from pysdmx.io.xml.__tokens import (
|
|
|
22
22
|
NAME_PERS,
|
|
23
23
|
PROV_AGREEMENT,
|
|
24
24
|
PROV_AGREMENT,
|
|
25
|
+
REPRESENTATION_MAPS,
|
|
25
26
|
RULE_SCHEMES,
|
|
26
27
|
RULESETS,
|
|
27
28
|
STR_USAGE,
|
|
28
29
|
STRUCTURE,
|
|
30
|
+
STRUCTURE_MAPS,
|
|
29
31
|
TRANS_SCHEMES,
|
|
30
32
|
TRANSFORMATIONS,
|
|
31
33
|
UDO_SCHEMES,
|
|
@@ -70,6 +72,9 @@ DSDS = "DataStructures"
|
|
|
70
72
|
DATAFLOWS = "Dataflows"
|
|
71
73
|
CONSTRAINTS = "Constraints"
|
|
72
74
|
PROV_AGREEMENTS = "ProvisionAgreements"
|
|
75
|
+
REPRESENTATION_MAPS_KEY = "RepresentationMaps"
|
|
76
|
+
STRUCTURE_MAPS_KEY = "StructureMaps"
|
|
77
|
+
DATE_PATTERN_MAP_KEY = "DatePatternMaps"
|
|
73
78
|
ALL_DIM = "AllDimensions"
|
|
74
79
|
|
|
75
80
|
BASE_URL_21 = "http://www.sdmx.org/resources/sdmxml/schemas/v2_1"
|
|
@@ -205,6 +210,8 @@ MSG_CONTENT_PKG_21 = OrderedDict(
|
|
|
205
210
|
(CONCEPTS, "Concepts"),
|
|
206
211
|
(DSDS, "DataStructures"),
|
|
207
212
|
(CONSTRAINTS, "ContentConstraints"),
|
|
213
|
+
(REPRESENTATION_MAPS, "RepresentationMaps"),
|
|
214
|
+
(STRUCTURE_MAPS, "StructureMaps"),
|
|
208
215
|
(CUSTOM_TYPES, "CustomTypes"),
|
|
209
216
|
(VTLMAPPINGS, "VtlMappings"),
|
|
210
217
|
(NAME_PERS, "NamePersonalisations"),
|
|
@@ -224,6 +231,8 @@ MSG_CONTENT_PKG_30 = OrderedDict(
|
|
|
224
231
|
(CONCEPTS_SCHEMES, "ConceptSchemes"),
|
|
225
232
|
(DSDS, "DataStructures"),
|
|
226
233
|
(CONSTRAINTS, "ContentConstraints"),
|
|
234
|
+
(REPRESENTATION_MAPS, "RepresentationMaps"),
|
|
235
|
+
(STRUCTURE_MAPS, "StructureMaps"),
|
|
227
236
|
(CUSTOM_TYPE_SCHEMES, "CustomTypeSchemes"),
|
|
228
237
|
(VTLMAPPING_SCHEMES, "VtlMappingSchemes"),
|
|
229
238
|
(NAME_PER_SCHEMES, "NamePersonalisationSchemes"),
|
|
@@ -379,9 +379,9 @@ def __series_processing(
|
|
|
379
379
|
del data_dict["Series"][0]
|
|
380
380
|
|
|
381
381
|
# Getting each datapoint from data and creating dict
|
|
382
|
-
data = data.sort_values(series_codes, axis=0)
|
|
382
|
+
data = data.sort_values(series_codes + series_att_codes, axis=0)
|
|
383
383
|
data_dict = {
|
|
384
|
-
"Series": data[series_codes]
|
|
384
|
+
"Series": data[series_codes + series_att_codes]
|
|
385
385
|
.drop_duplicates()
|
|
386
386
|
.reset_index(drop=True)
|
|
387
387
|
.to_dict(orient="records")
|
pysdmx/model/dataflow.py
CHANGED
|
@@ -107,8 +107,8 @@ class Component(
|
|
|
107
107
|
statistical domain, i.e. a component attached to a series in a particular
|
|
108
108
|
domain may be attached to, say, the dataset in another domain.
|
|
109
109
|
|
|
110
|
-
The *
|
|
111
|
-
component can take within a particular domain. In addition to
|
|
110
|
+
The *enumeration* field indicates the expected (i.e. allowed) set of
|
|
111
|
+
codes a component can take within a particular domain. In addition to
|
|
112
112
|
(or instead of) a set of codes, additional details about the expected
|
|
113
113
|
format may be found in the *facets* and *dtype* fields.
|
|
114
114
|
|
|
@@ -487,6 +487,14 @@ class Schema(Struct, frozen=True, omit_defaults=True, repr_omit_defaults=True):
|
|
|
487
487
|
if any of the artefacts listed under the artefacts
|
|
488
488
|
property has been updated after the schema was
|
|
489
489
|
generated, you might want to regenerate the schema.
|
|
490
|
+
name: The schema name.
|
|
491
|
+
groups: The list of groups defined in the data structure.
|
|
492
|
+
keys: The list of allowed series. This is the equivalent
|
|
493
|
+
of an SDMX KeySet. KeySets allow finer
|
|
494
|
+
restrictions than when components only (i.e. SDMX
|
|
495
|
+
CubeRegions). The values in the sequence follow
|
|
496
|
+
the SDMX-REST conventions for series wildcarding
|
|
497
|
+
(e.g. *.USD.CHF.*).
|
|
490
498
|
"""
|
|
491
499
|
|
|
492
500
|
context: Literal["datastructure", "dataflow", "provisionagreement"]
|
|
@@ -498,6 +506,7 @@ class Schema(Struct, frozen=True, omit_defaults=True, repr_omit_defaults=True):
|
|
|
498
506
|
generated: datetime = datetime.now(timezone.utc)
|
|
499
507
|
name: Optional[str] = None
|
|
500
508
|
groups: Optional[Sequence[Group]] = None
|
|
509
|
+
keys: Optional[Sequence[str]] = None
|
|
501
510
|
|
|
502
511
|
def __str__(self) -> str:
|
|
503
512
|
"""Custom string representation without the class name."""
|
pysdmx/toolkit/pd/_data_utils.py
CHANGED
|
@@ -25,7 +25,7 @@ def format_labels( # noqa: C901
|
|
|
25
25
|
for k in df.columns:
|
|
26
26
|
for component in components:
|
|
27
27
|
if component.id == k:
|
|
28
|
-
df.rename(
|
|
28
|
+
df.rename( # type: ignore[call-overload, unused-ignore]
|
|
29
29
|
columns={k: component.concept.name}, # type: ignore[union-attr]
|
|
30
30
|
inplace=True,
|
|
31
31
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pysdmx
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.12.0
|
|
4
4
|
Summary: Your opinionated Python SDMX library
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
License-File: LICENSE
|
|
@@ -24,6 +24,12 @@ Requires-Dist: jsonschema (>=4.10) ; extra == "json"
|
|
|
24
24
|
Requires-Dist: lxml (>=5.2) ; extra == "all"
|
|
25
25
|
Requires-Dist: lxml (>=5.2) ; extra == "xml"
|
|
26
26
|
Requires-Dist: msgspec (>=0)
|
|
27
|
+
Requires-Dist: numpy (>=2.0.2,<2.1) ; (python_version < "3.13") and (extra == "all")
|
|
28
|
+
Requires-Dist: numpy (>=2.0.2,<2.1) ; (python_version < "3.13") and (extra == "data")
|
|
29
|
+
Requires-Dist: numpy (>=2.0.2,<2.1) ; (python_version < "3.13") and (extra == "vtl")
|
|
30
|
+
Requires-Dist: numpy (>=2.1.0,<2.3) ; (python_version >= "3.13") and (extra == "all")
|
|
31
|
+
Requires-Dist: numpy (>=2.1.0,<2.3) ; (python_version >= "3.13") and (extra == "data")
|
|
32
|
+
Requires-Dist: numpy (>=2.1.0,<2.3) ; (python_version >= "3.13") and (extra == "vtl")
|
|
27
33
|
Requires-Dist: pandas (>=2.1.4) ; extra == "all"
|
|
28
34
|
Requires-Dist: pandas (>=2.1.4) ; extra == "data"
|
|
29
35
|
Requires-Dist: parsy (>=2.1)
|