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.
Files changed (38) hide show
  1. pysdmx/__init__.py +1 -1
  2. pysdmx/api/fmr/maintenance.py +10 -5
  3. pysdmx/io/input_processor.py +4 -0
  4. pysdmx/io/json/fusion/messages/constraint.py +22 -1
  5. pysdmx/io/json/fusion/messages/dsd.py +20 -14
  6. pysdmx/io/json/fusion/messages/msd.py +6 -9
  7. pysdmx/io/json/fusion/messages/schema.py +20 -1
  8. pysdmx/io/json/sdmxjson2/messages/core.py +12 -5
  9. pysdmx/io/json/sdmxjson2/messages/dsd.py +11 -17
  10. pysdmx/io/json/sdmxjson2/messages/msd.py +2 -5
  11. pysdmx/io/json/sdmxjson2/messages/report.py +7 -3
  12. pysdmx/io/json/sdmxjson2/messages/schema.py +38 -5
  13. pysdmx/io/json/sdmxjson2/messages/structure.py +7 -3
  14. pysdmx/io/json/sdmxjson2/reader/metadata.py +3 -3
  15. pysdmx/io/json/sdmxjson2/reader/structure.py +3 -3
  16. pysdmx/io/json/sdmxjson2/writer/_helper.py +118 -0
  17. pysdmx/io/json/sdmxjson2/writer/v2_0/__init__.py +1 -0
  18. pysdmx/io/json/sdmxjson2/writer/v2_0/metadata.py +33 -0
  19. pysdmx/io/json/sdmxjson2/writer/v2_0/structure.py +33 -0
  20. pysdmx/io/json/sdmxjson2/writer/v2_1/__init__.py +1 -0
  21. pysdmx/io/json/sdmxjson2/writer/v2_1/metadata.py +31 -0
  22. pysdmx/io/json/sdmxjson2/writer/v2_1/structure.py +33 -0
  23. pysdmx/io/reader.py +12 -3
  24. pysdmx/io/writer.py +13 -3
  25. pysdmx/io/xml/__ss_aux_reader.py +39 -17
  26. pysdmx/io/xml/__structure_aux_reader.py +221 -33
  27. pysdmx/io/xml/__structure_aux_writer.py +304 -5
  28. pysdmx/io/xml/__tokens.py +12 -0
  29. pysdmx/io/xml/__write_aux.py +9 -0
  30. pysdmx/io/xml/sdmx21/writer/generic.py +2 -2
  31. pysdmx/model/dataflow.py +11 -2
  32. pysdmx/toolkit/pd/_data_utils.py +1 -1
  33. {pysdmx-1.10.1.dist-info → pysdmx-1.12.0.dist-info}/METADATA +7 -1
  34. {pysdmx-1.10.1.dist-info → pysdmx-1.12.0.dist-info}/RECORD +36 -31
  35. {pysdmx-1.10.1.dist-info → pysdmx-1.12.0.dist-info}/WHEEL +1 -1
  36. pysdmx/io/json/sdmxjson2/writer/metadata.py +0 -60
  37. pysdmx/io/json/sdmxjson2/writer/structure.py +0 -61
  38. {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
- for comp_name in comps_to_relate:
568
- outfile += (
569
- f"{add_indent(indent)}<{ABBR_STR}:{DIM}>"
570
- f"{comp_name}</{ABBR_STR}:{DIM}>"
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
- ref = parse_item_urn(identity.urn) # type: ignore[arg-type]
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"
@@ -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 *codes* field indicates the expected (i.e. allowed) set of values a
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."""
@@ -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.10.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)