pysdmx 1.3.0__py3-none-any.whl → 1.4.0rc1__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 (100) hide show
  1. pysdmx/__extras_check.py +3 -2
  2. pysdmx/__init__.py +1 -1
  3. pysdmx/api/fmr/__init__.py +4 -4
  4. pysdmx/api/gds/__init__.py +328 -0
  5. pysdmx/api/qb/gds.py +153 -0
  6. pysdmx/api/qb/service.py +91 -3
  7. pysdmx/api/qb/structure.py +1 -0
  8. pysdmx/api/qb/util.py +1 -0
  9. pysdmx/io/__init__.py +2 -1
  10. pysdmx/io/csv/sdmx10/reader/__init__.py +4 -2
  11. pysdmx/io/csv/sdmx10/writer/__init__.py +15 -2
  12. pysdmx/io/csv/sdmx20/reader/__init__.py +5 -2
  13. pysdmx/io/csv/sdmx20/writer/__init__.py +13 -2
  14. pysdmx/io/format.py +4 -0
  15. pysdmx/io/input_processor.py +12 -3
  16. pysdmx/io/json/fusion/messages/core.py +2 -0
  17. pysdmx/io/json/fusion/messages/report.py +13 -7
  18. pysdmx/io/json/gds/messages/__init__.py +35 -0
  19. pysdmx/io/json/gds/messages/agencies.py +41 -0
  20. pysdmx/io/json/gds/messages/catalog.py +79 -0
  21. pysdmx/io/json/gds/messages/sdmx_api.py +23 -0
  22. pysdmx/io/json/gds/messages/services.py +49 -0
  23. pysdmx/io/json/gds/messages/urn_resolver.py +43 -0
  24. pysdmx/io/json/gds/reader/__init__.py +12 -0
  25. pysdmx/io/json/sdmxjson2/messages/__init__.py +12 -4
  26. pysdmx/io/json/sdmxjson2/messages/agency.py +72 -0
  27. pysdmx/io/json/sdmxjson2/messages/category.py +22 -29
  28. pysdmx/io/json/sdmxjson2/messages/code.py +68 -64
  29. pysdmx/io/json/sdmxjson2/messages/concept.py +9 -18
  30. pysdmx/io/json/sdmxjson2/messages/constraint.py +2 -13
  31. pysdmx/io/json/sdmxjson2/messages/core.py +113 -21
  32. pysdmx/io/json/sdmxjson2/messages/dataflow.py +51 -21
  33. pysdmx/io/json/sdmxjson2/messages/dsd.py +110 -36
  34. pysdmx/io/json/sdmxjson2/messages/map.py +61 -49
  35. pysdmx/io/json/sdmxjson2/messages/pa.py +9 -17
  36. pysdmx/io/json/sdmxjson2/messages/provider.py +88 -0
  37. pysdmx/io/json/sdmxjson2/messages/report.py +84 -14
  38. pysdmx/io/json/sdmxjson2/messages/schema.py +14 -5
  39. pysdmx/io/json/sdmxjson2/messages/structure.py +105 -36
  40. pysdmx/io/json/sdmxjson2/messages/vtl.py +42 -96
  41. pysdmx/io/pd.py +2 -9
  42. pysdmx/io/reader.py +72 -27
  43. pysdmx/io/serde.py +11 -0
  44. pysdmx/io/writer.py +134 -0
  45. pysdmx/io/xml/{sdmx21/reader/__data_aux.py → __data_aux.py} +9 -2
  46. pysdmx/io/xml/{sdmx21/reader/__parse_xml.py → __parse_xml.py} +30 -6
  47. pysdmx/io/xml/__ss_aux_reader.py +96 -0
  48. pysdmx/io/xml/__structure_aux_reader.py +1174 -0
  49. pysdmx/io/xml/__structure_aux_writer.py +1233 -0
  50. pysdmx/io/xml/{sdmx21/__tokens.py → __tokens.py} +33 -1
  51. pysdmx/io/xml/{sdmx21/writer/__write_aux.py → __write_aux.py} +129 -37
  52. pysdmx/io/xml/{sdmx21/writer/__write_data_aux.py → __write_data_aux.py} +1 -1
  53. pysdmx/io/xml/__write_structure_specific_aux.py +254 -0
  54. pysdmx/io/xml/{sdmx21/reader/doc_validation.py → doc_validation.py} +10 -2
  55. pysdmx/io/xml/{sdmx21/reader/header.py → header.py} +11 -3
  56. pysdmx/io/xml/sdmx21/reader/error.py +2 -2
  57. pysdmx/io/xml/sdmx21/reader/generic.py +12 -8
  58. pysdmx/io/xml/sdmx21/reader/structure.py +5 -840
  59. pysdmx/io/xml/sdmx21/reader/structure_specific.py +13 -97
  60. pysdmx/io/xml/sdmx21/reader/submission.py +2 -2
  61. pysdmx/io/xml/sdmx21/writer/error.py +1 -1
  62. pysdmx/io/xml/sdmx21/writer/generic.py +13 -7
  63. pysdmx/io/xml/sdmx21/writer/structure.py +16 -828
  64. pysdmx/io/xml/sdmx21/writer/structure_specific.py +13 -238
  65. pysdmx/io/xml/sdmx30/__init__.py +1 -0
  66. pysdmx/io/xml/sdmx30/reader/__init__.py +1 -0
  67. pysdmx/io/xml/sdmx30/reader/structure.py +39 -0
  68. pysdmx/io/xml/sdmx30/reader/structure_specific.py +39 -0
  69. pysdmx/io/xml/sdmx30/writer/__init__.py +1 -0
  70. pysdmx/io/xml/sdmx30/writer/structure.py +67 -0
  71. pysdmx/io/xml/sdmx30/writer/structure_specific.py +108 -0
  72. pysdmx/model/__base.py +99 -34
  73. pysdmx/model/__init__.py +4 -0
  74. pysdmx/model/category.py +20 -0
  75. pysdmx/model/code.py +29 -8
  76. pysdmx/model/concept.py +52 -11
  77. pysdmx/model/dataflow.py +117 -33
  78. pysdmx/model/dataset.py +66 -14
  79. pysdmx/model/gds.py +161 -0
  80. pysdmx/model/map.py +51 -8
  81. pysdmx/model/message.py +235 -55
  82. pysdmx/model/metadata.py +79 -16
  83. pysdmx/model/submission.py +12 -7
  84. pysdmx/model/vtl.py +30 -13
  85. pysdmx/toolkit/__init__.py +1 -1
  86. pysdmx/toolkit/pd/__init__.py +85 -0
  87. pysdmx/toolkit/vtl/__init__.py +2 -1
  88. pysdmx/toolkit/vtl/_validations.py +1 -1
  89. pysdmx/toolkit/vtl/{generate_vtl_script.py → script_generation.py} +30 -4
  90. pysdmx/toolkit/vtl/validation.py +119 -0
  91. pysdmx/util/_model_utils.py +1 -1
  92. pysdmx-1.4.0rc1.dist-info/METADATA +119 -0
  93. pysdmx-1.4.0rc1.dist-info/RECORD +140 -0
  94. pysdmx/io/json/sdmxjson2/messages/org.py +0 -140
  95. pysdmx/toolkit/vtl/model_validations.py +0 -50
  96. pysdmx-1.3.0.dist-info/METADATA +0 -76
  97. pysdmx-1.3.0.dist-info/RECORD +0 -116
  98. /pysdmx/io/xml/{sdmx21/writer/config.py → config.py} +0 -0
  99. {pysdmx-1.3.0.dist-info → pysdmx-1.4.0rc1.dist-info}/LICENSE +0 -0
  100. {pysdmx-1.3.0.dist-info → pysdmx-1.4.0rc1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,85 @@
1
+ """Utility functions to leverage the SDMX information model in Pandas."""
2
+
3
+ from typing import Dict, Iterable
4
+
5
+ from pysdmx.model import Component, DataType
6
+
7
+
8
+ def __get_pd_type(dt: DataType, required: bool) -> str: # noqa: C901
9
+ if dt == DataType.SHORT:
10
+ return "int16" if required else "Int16"
11
+ elif dt == DataType.INTEGER:
12
+ return "int32" if required else "Int32"
13
+ elif dt == DataType.LONG or dt == DataType.COUNT:
14
+ return "int64" if required else "Int64"
15
+ elif dt == DataType.BIG_INTEGER or dt == DataType.DECIMAL:
16
+ return "object"
17
+ elif dt == DataType.FLOAT:
18
+ return "float32" if required else "Float32"
19
+ elif dt == DataType.DOUBLE:
20
+ return "float64" if required else "Float64"
21
+ elif dt == DataType.BOOLEAN:
22
+ return "bool" if required else "boolean"
23
+ elif dt == DataType.MONTH:
24
+ return "int8" if required else "Int8"
25
+ elif dt == DataType.GREGORIAN_TIME_PERIOD:
26
+ return "object"
27
+ elif dt == DataType.DATE_TIME:
28
+ return "datetime64[ns]"
29
+ elif dt == DataType.YEAR:
30
+ return "datetime64[Y]"
31
+ elif dt == DataType.YEAR_MONTH:
32
+ return "datetime64[M]"
33
+ elif dt == DataType.DATE:
34
+ return "datetime64[D]"
35
+ else:
36
+ return "string"
37
+
38
+
39
+ def to_pandas_type(comp: Component) -> str:
40
+ """Determine the appropriate Pandas data type for the given component.
41
+
42
+ For enumerated components, returns 'category' as the Pandas data type.
43
+ For non-enumerated components, maps the SDMX data type to the corresponding
44
+ Pandas data type, taking into account whether the component is required.
45
+
46
+ Args:
47
+ comp (Component):
48
+ The SDMX component for which to determine the Pandas data type.
49
+
50
+ Returns:
51
+ The string representation of the corresponding Pandas data type.
52
+ Possible return values include:
53
+
54
+ - 'category' (for enumerated components)
55
+ - Numeric types ('int16', 'Int16', 'float32', 'Float32', etc.)
56
+ - 'object' (for complex numeric types and time periods)
57
+ - Datetime types ('datetime64[ns]', 'datetime64[Y]', etc.)
58
+ - 'string' (default for unhandled types)
59
+ - 'bool' or 'boolean' (for boolean values)
60
+ """
61
+ if comp.enumeration:
62
+ return "category"
63
+ else:
64
+ return __get_pd_type(comp.dtype, comp.required)
65
+
66
+
67
+ def to_pandas_schema(components: Iterable[Component]) -> Dict[str, str]:
68
+ """Infer the schema of a Pandas Data Frame from a list of components.
69
+
70
+ This function generates a dictionary mapping component IDs to their
71
+ corresponding Pandas data types. The resulting dictionary can be used
72
+ as input to the Pandas `astype` method to cast DataFrame columns
73
+ to the desired types.
74
+
75
+ Args:
76
+ components (Iterable[Component]):
77
+ A collection of SDMX components from which the schema for
78
+ the Pandas DataFrame will be inferred.
79
+
80
+ Returns:
81
+ Dict[str, str]:
82
+ A dictionary where keys are the component IDs (field names)
83
+ and values are their corresponding Pandas data types.
84
+ """
85
+ return {c.id: to_pandas_type(c) for c in components}
@@ -1,5 +1,6 @@
1
1
  """VTL toolkit for PySDMX."""
2
2
 
3
- from pysdmx.toolkit.vtl import generate_vtl_script, model_validations
3
+ from pysdmx.toolkit.vtl.script_generation import generate_vtl_script
4
+ from pysdmx.toolkit.vtl.validation import model_validations
4
5
 
5
6
  __all__ = ["model_validations", "generate_vtl_script"]
@@ -10,7 +10,7 @@ from vtlengine.AST import (
10
10
  )
11
11
 
12
12
  from pysdmx.errors import Invalid
13
- from pysdmx.io.xml.sdmx21.__tokens import RULE_SCHEME, UDO_SCHEME
13
+ from pysdmx.io.xml.__tokens import RULE_SCHEME, UDO_SCHEME
14
14
  from pysdmx.model import Reference
15
15
  from pysdmx.model.vtl import (
16
16
  Ruleset,
@@ -2,6 +2,7 @@
2
2
 
3
3
  from typing import Sequence, Union
4
4
 
5
+ from pysdmx.__extras_check import __check_vtl_extra
5
6
  from pysdmx.model import (
6
7
  Reference,
7
8
  RulesetScheme,
@@ -9,7 +10,6 @@ from pysdmx.model import (
9
10
  TransformationScheme,
10
11
  UserDefinedOperatorScheme,
11
12
  )
12
- from pysdmx.toolkit.vtl.model_validations import model_validations
13
13
 
14
14
 
15
15
  def _process_ruleset_scheme(
@@ -48,21 +48,41 @@ def _process_transformation(transformations: Sequence[Transformation]) -> str:
48
48
 
49
49
 
50
50
  def generate_vtl_script(
51
- transformation_scheme: TransformationScheme, model_validation: bool = True
51
+ transformation_scheme: TransformationScheme,
52
+ model_validation: bool = False,
53
+ prettyprint: bool = False,
52
54
  ) -> str:
53
- """Generates the full VTL Transformation Scheme script.
55
+ """Generates the VTL script from a TransformationScheme.
56
+
57
+ This method iterates over the TransformationScheme object and its referred
58
+ RulesetSchemes and UserDefinedOperatorSchemes to generate the VTL script
59
+ as string
60
+
61
+ The model_validation feature checks if the model object is valid by
62
+ parsing the VTL code inside the definitions.
63
+
64
+ The prettyprint feature formats the VTL script in a user-friendly way.
65
+
66
+ .. important::
67
+ The prettyprint and model_validation features require
68
+ the pysdmx[vtl] extra.
54
69
 
55
70
  Args:
56
71
  transformation_scheme: A TransformationScheme object.
57
72
  model_validation: A boolean value to check if the model
58
73
  object is valid.
59
74
  if True, the model object is validated.
75
+ prettyprint: A boolean value to check if the generated script
76
+ is returned formatted.
60
77
 
61
- returns:
78
+ Returns:
62
79
  A string containing the full VTL Transformation Scheme script.
63
80
 
64
81
  """
65
82
  if model_validation:
83
+ __check_vtl_extra()
84
+ from pysdmx.toolkit.vtl.validation import model_validations
85
+
66
86
  model_validations(transformation_scheme)
67
87
 
68
88
  vtl_script = ""
@@ -75,4 +95,10 @@ def generate_vtl_script(
75
95
  )
76
96
  vtl_script += _process_transformation(transformation_scheme.items)
77
97
 
98
+ if prettyprint:
99
+ __check_vtl_extra()
100
+ from vtlengine import prettify # type: ignore[import-untyped]
101
+
102
+ return prettify(vtl_script)
103
+
78
104
  return vtl_script
@@ -0,0 +1,119 @@
1
+ """Model validations for VTL models."""
2
+
3
+ from typing import Union
4
+
5
+ from pysdmx.__extras_check import __check_vtl_extra
6
+ from pysdmx.errors import Invalid
7
+ from pysdmx.model import (
8
+ Ruleset,
9
+ RulesetScheme,
10
+ Transformation,
11
+ TransformationScheme,
12
+ UserDefinedOperator,
13
+ UserDefinedOperatorScheme,
14
+ VtlScheme,
15
+ )
16
+ from pysdmx.model.__base import Item
17
+
18
+
19
+ def model_validations(model_obj: Union[VtlScheme, Item]) -> None:
20
+ """Validation checks for VTL objects.
21
+
22
+ This method performs validation checks on VTLScheme objects ,
23
+ such as TransformationScheme, RulesetScheme,
24
+ UserDefinedOperatorScheme, etc. or its items,
25
+ like Ruleset, Transformation, UserDefinedOperator, etc.
26
+
27
+ It raises an Invalid exception if the model object is not valid.
28
+
29
+ The model validation checks on items:
30
+
31
+ * Ruleset validation
32
+
33
+ * A single RulesetDefinition (define ...) is valid in a Ruleset
34
+
35
+ * Ruleset type matches the definition (hierarchical or datapoint)
36
+
37
+ * Ruleset scope matches the signature (variable or valuedomain)
38
+
39
+ * User Defined Operator validation
40
+
41
+ * A single OperatorDefinition (define operator ...)
42
+ is valid in a User Defined Operator
43
+
44
+ * Transformation validation
45
+
46
+ * Checks if the transformation is valid
47
+
48
+ * Checks a single assignment is present in the expression
49
+
50
+ The model validation checks on VTLScheme:
51
+
52
+ * RulesetScheme validation
53
+
54
+ * Checks if it contains at least one Ruleset
55
+
56
+ * Checks if all items in the scheme are Ruleset
57
+
58
+ * UserDefinedOperatorScheme validation
59
+
60
+ * Checks if it contains at least one UserDefinedOperator
61
+
62
+ * Checks if all items in the scheme are UserDefinedOperator
63
+
64
+ * TransformationScheme validation
65
+
66
+ * Checks if it contains at least one Transformation
67
+
68
+ * Checks if all items in the scheme are Transformation
69
+
70
+ * Checks the referenced RulesetSchemes (if any)
71
+ and UserDefinedOperatorSchemes (if any)
72
+
73
+ Args:
74
+ model_obj: A VTLScheme or Item object.
75
+ raises:
76
+ Invalid: Invalid model object if the model object is not valid.
77
+ """
78
+ # We add here the check for vtl extra and add the local imports to
79
+ # prevent unhandled ImportError
80
+ __check_vtl_extra()
81
+
82
+ if isinstance(model_obj, Ruleset):
83
+ from pysdmx.toolkit.vtl._validations import (
84
+ _ruleset_validation,
85
+ )
86
+
87
+ _ruleset_validation(model_obj)
88
+ elif isinstance(model_obj, RulesetScheme):
89
+ from pysdmx.toolkit.vtl._validations import (
90
+ _ruleset_scheme_validations,
91
+ )
92
+
93
+ _ruleset_scheme_validations(model_obj)
94
+ elif isinstance(model_obj, UserDefinedOperator):
95
+ from pysdmx.toolkit.vtl._validations import (
96
+ _user_defined_operator_validation,
97
+ )
98
+
99
+ _user_defined_operator_validation(model_obj)
100
+ elif isinstance(model_obj, UserDefinedOperatorScheme):
101
+ from pysdmx.toolkit.vtl._validations import (
102
+ _user_defined_operator_scheme_validations,
103
+ )
104
+
105
+ _user_defined_operator_scheme_validations(model_obj)
106
+ elif isinstance(model_obj, Transformation):
107
+ from pysdmx.toolkit.vtl._validations import (
108
+ _transformation_validations,
109
+ )
110
+
111
+ _transformation_validations(model_obj)
112
+ elif isinstance(model_obj, TransformationScheme):
113
+ from pysdmx.toolkit.vtl._validations import (
114
+ _transformation_scheme_validations,
115
+ )
116
+
117
+ _transformation_scheme_validations(model_obj)
118
+ else:
119
+ raise Invalid("Invalid model object")
@@ -27,7 +27,7 @@ def schema_generator(message: Message, dataset_ref: Reference) -> Schema:
27
27
  raise Invalid(
28
28
  f"Dataflow {dataset_ref} does not have a structure defined.",
29
29
  )
30
- dsd_ref = parse_urn(dataflow.structure)
30
+ dsd_ref = parse_urn(dataflow.structure) # type: ignore[arg-type]
31
31
  try:
32
32
  dsd = message.get_data_structure_definition(str(dsd_ref))
33
33
  except NotFound:
@@ -0,0 +1,119 @@
1
+ Metadata-Version: 2.3
2
+ Name: pysdmx
3
+ Version: 1.4.0rc1
4
+ Summary: Your opinionated Python SDMX library
5
+ License: Apache-2.0
6
+ Keywords: sdmx,data discovery,data retrieval,metadata,fmr
7
+ Author: Xavier Sosnovsky
8
+ Author-email: <xavier.sosnovsky@bis.org>
9
+ Requires-Python: >=3.9
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: License :: OSI Approved :: Apache Software License
14
+ Classifier: Typing :: Typed
15
+ Provides-Extra: all
16
+ Provides-Extra: data
17
+ Provides-Extra: dc
18
+ Provides-Extra: vtl
19
+ Provides-Extra: xml
20
+ Requires-Dist: httpx (>=0)
21
+ Requires-Dist: lxml (>=5.2) ; extra == "all"
22
+ Requires-Dist: lxml (>=5.2) ; extra == "xml"
23
+ Requires-Dist: msgspec (>=0)
24
+ Requires-Dist: pandas (>=2.1.4) ; extra == "all"
25
+ Requires-Dist: pandas (>=2.1.4) ; extra == "data"
26
+ Requires-Dist: parsy (>=2.1)
27
+ Requires-Dist: python-dateutil (>=2.8.2) ; extra == "all"
28
+ Requires-Dist: python-dateutil (>=2.8.2) ; extra == "dc"
29
+ Requires-Dist: sdmxschemas (>=0.2.0) ; extra == "all"
30
+ Requires-Dist: sdmxschemas (>=0.2.0) ; extra == "xml"
31
+ Requires-Dist: vtlengine (>=1.1,<2.0) ; extra == "all"
32
+ Requires-Dist: vtlengine (>=1.1,<2.0) ; extra == "vtl"
33
+ Requires-Dist: xmltodict (>=0.13) ; extra == "all"
34
+ Requires-Dist: xmltodict (>=0.13) ; extra == "xml"
35
+ Project-URL: Bug Tracker, https://bis-med-it.github.io/pysdmx/issues
36
+ Project-URL: Documentation, https://bis-med-it.github.io/pysdmx
37
+ Project-URL: Homepage, https://sdmx.io/tools/pysdmx
38
+ Project-URL: Repository, https://github.com/bis-med-it/pysdmx
39
+ Description-Content-Type: text/x-rst
40
+
41
+ .. |pypi badge| image:: https://img.shields.io/pypi/v/pysdmx.svg
42
+ :target: https://pypi.org/project/pysdmx/
43
+
44
+ .. |awesome badge| image:: https://awesome.re/mentioned-badge.svg
45
+ :target: http://www.awesomeofficialstatistics.org
46
+
47
+ |pypi badge| |awesome badge|
48
+
49
+ ``pysdmx`` in a nutshell
50
+ ************************
51
+
52
+ What is pysdmx?
53
+ ===============
54
+
55
+ ``pysdmx`` is a **pragmatic** and **opinionated** SDMX library written in
56
+ **Python**. It focuses on **simplicity**, providing a subset of SDMX functionalities
57
+ without requiring advanced knowledge of SDMX. ``pysdmx`` is developed as part of
58
+ the `sdmx.io <http://sdmx.io/>`_ project under the **BIS Open Tech initiative**.
59
+
60
+ What does it do?
61
+ ================
62
+
63
+ ``pysdmx`` aspires to be a versatile SDMX toolbox for Python, covering various
64
+ use cases. Here are some highlights:
65
+
66
+ SDMX information model in Python
67
+ --------------------------------
68
+
69
+ ``pysdmx`` offers Python classes representing a **simplified subset of the SDMX
70
+ information model**, enabling a domain-driven development of SDMX processes in
71
+ Python. The model classes support serialization in formats like JSON, YAML, or
72
+ MessagePack. This functionality relies on the
73
+ `msgspec library <https://jcristharif.com/msgspec/>`_.
74
+
75
+ Metadata in action
76
+ ------------------
77
+
78
+ SDMX metadata are very useful for documenting statistical processes. For example,
79
+ they can define the structure we expect for a data collection process and share
80
+ it with the organizations providing data so that they know what to send.
81
+
82
+ However, metadata can do so much more than that, i.e., they can be “active” and
83
+ **drive various types of statistical processes**, such as generating the filesystem
84
+ layout, creating the physical data model, validating data, mapping data, and
85
+ configuring processes. To drive such processes, ``pysdmx`` supports retrieving
86
+ metadata from an SDMX Registry or any service compliant with the SDMX-REST 2.0.0 (or
87
+ above) API. Use these metadata to power your own statistical processes!
88
+
89
+ Reading and writing SDMX files
90
+ ------------------------------
91
+
92
+ ``pysdmx`` supports reading and writing SDMX data and structure messages, in various
93
+ formats, such as SDMX-CSV, SDMX-JSON, and SDMX-ML.
94
+
95
+ Data discovery and data retrieval
96
+ ---------------------------------
97
+
98
+ This functionality is under development. Once ready, ``pysdmx`` will allow:
99
+
100
+ - **Listing public SDMX services**.
101
+ - **Discovering data** available in these services.
102
+ - **Retrieving data** from these services.
103
+
104
+ This functionality is based on the **SDMX Global Discovery Service initiative**.
105
+
106
+ Integration with the ecosystem
107
+ ------------------------------
108
+
109
+ ``pysdmx`` integrates nicely with other standards, like the `Validation and
110
+ Transformation Language (VTL) <https://sdmx.org/about-sdmx/about-vtl/>`_,
111
+ and major Python libraries like `Pandas <https://pandas.pydata.org/>`_.
112
+ Take a look at the ``pysdmx`` toolkit module to learn more.
113
+
114
+ ``pysdmx`` is available on `PyPI <https://pypi.org/>`_ and can be
115
+ installed using options such as pip, pipx, poetry, etc.
116
+
117
+ For more details, check the `project documentation
118
+ <https://py.sdmx.io>`_.
119
+
@@ -0,0 +1,140 @@
1
+ pysdmx/__extras_check.py,sha256=I39OaM1lAPBnyzHVJ7kA_ZA_tMeDAQLr6ZKqEQ9MK1Q,1659
2
+ pysdmx/__init__.py,sha256=pbr9sYLtXXLshnGSuTBilBjXhge-z5bRG99UVZMOw30,70
3
+ pysdmx/api/__init__.py,sha256=8lRaF6kEO51ehl0fmW_pHLvkN_34TtEhqhr3oKo6E6g,26
4
+ pysdmx/api/dc/__init__.py,sha256=oPU32X8CRZy4T1to9mO5KMqMwxQsVI424dPqai-I8zI,121
5
+ pysdmx/api/dc/_api.py,sha256=poy1FYFXnF6maBGy5lpOodf32-7QQjH8PCBNDkuOXxQ,7747
6
+ pysdmx/api/dc/query/__init__.py,sha256=wcgbCaULRRixC1S9KjQrwHnaM3gwIGIZw8W1JwrZCQY,459
7
+ pysdmx/api/dc/query/_model.py,sha256=PsKXQbAk5_iT-jRukiCuWjoGaStAOyRBtAPewz0C6WM,2910
8
+ pysdmx/api/dc/query/_parsing_model.py,sha256=89UMQVExPC7ebYZRX6o7gwYLhlzhwK8X02lZxHv6P0U,1200
9
+ pysdmx/api/dc/query/_parsing_util.py,sha256=pUc5z6sijGmJZsLilAxiPsCSRIO7l2iznzL3oE24eU8,2391
10
+ pysdmx/api/dc/query/_py_parser.py,sha256=_kVUk6Xu5jZdclng1F6eDSZS2-ok_yncI1y1q5lYpBU,1502
11
+ pysdmx/api/dc/query/_sql_parser.py,sha256=vQjhSyt6qA4jAHchkq4XXVhNPtKjKSVLzhoPkUyhJKk,1561
12
+ pysdmx/api/dc/query/util.py,sha256=9HALmvlgVCckaMTVG7sEFbAw_mBwfbL4K-Pac2KPSYw,915
13
+ pysdmx/api/fmr/__init__.py,sha256=04PEKA7fW9hKBUr2QQSO6lzYSY9kjNu0ddL1P4CF-Jw,40811
14
+ pysdmx/api/gds/__init__.py,sha256=BBl75wEdcz9zPMfk6kAGHitRW39S774VL9xifMZ_uHs,11560
15
+ pysdmx/api/qb/__init__.py,sha256=vxdMJFFg4J_KWADrnzj_8KcU0UlwpJPdx0yiW3QJo9Y,1498
16
+ pysdmx/api/qb/availability.py,sha256=2yPHnTXu_jACNKNhhtXMkxVkfLK1Ewa5ucGAbRxvC5o,10181
17
+ pysdmx/api/qb/data.py,sha256=RUcSQBZYkqlrD2ehrGxUWUEAyjbfl5CSgjQ6BwN3hus,22049
18
+ pysdmx/api/qb/gds.py,sha256=Z2KhP6m09_oWI2CbYRhlTsx8VLC-_UZaQEOEqX94SOw,4975
19
+ pysdmx/api/qb/refmeta.py,sha256=rWhMcUkcQ0zYoiEVAVFOnykLLhMWFFZssFZh8z3kRng,10677
20
+ pysdmx/api/qb/registration.py,sha256=IURlmXcXQi8e-w5YXCgRNs07EQJZJ2bOdZb7M_k5iZ8,7132
21
+ pysdmx/api/qb/schema.py,sha256=f0V-fQl9GQ2YWhnZqUF_wogB2L9dRIdY_vT4XvYkqoI,5747
22
+ pysdmx/api/qb/service.py,sha256=PyhzVw3X9tupUOrSstwMZm2WeK-PMVeXE1e2XBZjFp4,15274
23
+ pysdmx/api/qb/structure.py,sha256=NA4-Xlnj55xNLFlAC2qmaSRgKYbzFjQTKXA5G-SYlBo,17783
24
+ pysdmx/api/qb/util.py,sha256=Meysdjad-ZyE2WZ1xwMGYrVQPapCKG5QdT4LkdF5CSw,3651
25
+ pysdmx/errors.py,sha256=9bfujYykzfGMa1TuUOmH9QqghnZGOo556fvbKH2jFa8,3295
26
+ pysdmx/io/__init__.py,sha256=96ZCY1PfcWp_q2Nlo2tHJAK31sH_b05v9UkbR0vGdg0,180
27
+ pysdmx/io/csv/__init__.py,sha256=53f2rPkwILigOqArgRQOOwLk-ha6zVTe4EypIsR7K6I,107
28
+ pysdmx/io/csv/sdmx10/__init__.py,sha256=NAAm_yodK-gzkuzewGQeYpF3f5nZmDA4vWGfT2KGTWc,38
29
+ pysdmx/io/csv/sdmx10/reader/__init__.py,sha256=13TXdR7aqw1RxPnYuq6OG7Uz7a9eIzfDRi_wNMRaG54,2877
30
+ pysdmx/io/csv/sdmx10/writer/__init__.py,sha256=c7WvEufF8UBu6Lf417a4ujY8cQ7QOiQ9_cu_MIej0Gg,1648
31
+ pysdmx/io/csv/sdmx20/__init__.py,sha256=mNfMJKSpmMfk4CbbHhjnBOTQ2IZFY15cNUhHtJPcs90,231
32
+ pysdmx/io/csv/sdmx20/reader/__init__.py,sha256=HSSUE3iL9g2Bzb_vKw97-Uw_3H3yUQxN8ssAyr1EJkI,4925
33
+ pysdmx/io/csv/sdmx20/writer/__init__.py,sha256=xqNg2L2BdCkKVIkMrBpkbR6wq2gZ3r1K7oZRkZ1aBoU,2062
34
+ pysdmx/io/format.py,sha256=f8bhh3KgEAbR3LligcalaXwdFxMjBP0VPXkrxX_ajno,4117
35
+ pysdmx/io/input_processor.py,sha256=HN6GFK3pgdPcTkgmoBIBHzw9ypao_xedOnjGlVxHMOc,5122
36
+ pysdmx/io/json/fusion/messages/__init__.py,sha256=C0LAG6UfIZcQdlCv5d_D1ZNIcCq04RxZYLAp6tLDqwY,1573
37
+ pysdmx/io/json/fusion/messages/category.py,sha256=E9jrzXenEpqDNUhT1JJLYxty37PSGegRtx45mB3-COg,4589
38
+ pysdmx/io/json/fusion/messages/code.py,sha256=kB3RJiSA75G4IJYObYR0hdiXYcRs-vNMKqUeA6F4SSo,7529
39
+ pysdmx/io/json/fusion/messages/concept.py,sha256=aOfJxQSC3b1cgDdxZNFUcab3mpPEvtnXIbNjbIwPIog,2750
40
+ pysdmx/io/json/fusion/messages/constraint.py,sha256=dPkzhCWN49Y9ReSZPRFTdM6GWc0rU2BZTyFfWsqlX34,615
41
+ pysdmx/io/json/fusion/messages/core.py,sha256=GdzF3TNUGrB0gxuaaSpk9LaYqcdy_M6L2azExZQfM0Q,4843
42
+ pysdmx/io/json/fusion/messages/dataflow.py,sha256=oxocZAdl_uMroO6Msu6k7lEz_tGLvj3oKeDhH_IMb7E,2833
43
+ pysdmx/io/json/fusion/messages/dsd.py,sha256=ccNKx3RlWNkIDMpDJ036mxzkNy8-ZFSOBGfZyjEOths,7755
44
+ pysdmx/io/json/fusion/messages/map.py,sha256=TPsCFuUfk5Jhhe7CNvEoHuFNZFpHhvNiYFWeIEUx-sc,7695
45
+ pysdmx/io/json/fusion/messages/org.py,sha256=9gZpHg6o4fPGY9fUIDUCyKQCCLL6NYFHnQJkxdXD8v8,6264
46
+ pysdmx/io/json/fusion/messages/pa.py,sha256=6zN8Qxj5bdf5zo2N9TwYlSLyGxokvsELtk1--1cMbxw,1393
47
+ pysdmx/io/json/fusion/messages/report.py,sha256=ZE62ZmHlCXk3TxRTRWCDCKVMhnN0J5UjMEzrsnD5I3E,1551
48
+ pysdmx/io/json/fusion/messages/schema.py,sha256=47uiSD5GSrd6TCnDFeg10SztP3vNuzKbYSvvKNK4wB0,2371
49
+ pysdmx/io/json/fusion/messages/vtl.py,sha256=7VGjDRWzKMO6WT4CnGvGBKinhX06DzrJmDRudnvN4XM,16092
50
+ pysdmx/io/json/fusion/reader/__init__.py,sha256=fpya2W7YJ6lcdupAybBawMtJI7PT0gy48gLkDbuPTWU,1295
51
+ pysdmx/io/json/gds/messages/__init__.py,sha256=5LqGtO3GDi2B6HM2eDGCSJCncLS8C4MQ7vd5YBvCRok,885
52
+ pysdmx/io/json/gds/messages/agencies.py,sha256=C_2viUTW5FTLxMV0dtqPUQEs9tgjjsFxE44mHJ6aXp0,986
53
+ pysdmx/io/json/gds/messages/catalog.py,sha256=-Y7j8rFA0PcS3AVT6X9_8VAw_eHCPLDtZxUqy1TLx4U,2280
54
+ pysdmx/io/json/gds/messages/sdmx_api.py,sha256=RIjNQr6ZZXCFGRBpGPKoLaxD9UilVDNyHC1G6XmMs9k,566
55
+ pysdmx/io/json/gds/messages/services.py,sha256=OUFmYK4XkNMoaw70n4QabyxzdRDh-0XeYxBJtVezxMs,1259
56
+ pysdmx/io/json/gds/messages/urn_resolver.py,sha256=w_wRRAwjaBw_yooSda1MXcD_aN63FdpFE7WFvcjHSeQ,1209
57
+ pysdmx/io/json/gds/reader/__init__.py,sha256=cXQvjSzRe4lTsGmru6qMYE_HU2DEccJSYKsQ5ayIpxw,373
58
+ pysdmx/io/json/sdmxjson2/messages/__init__.py,sha256=pqLbzZf-FkuSJWy8DLxtCXIu-Si2Mm-vDTzCqnJDNVA,1984
59
+ pysdmx/io/json/sdmxjson2/messages/agency.py,sha256=m8ltYpMfAzNllM2sd9K4BskS1_nF-gByXmjAizRwlBM,2478
60
+ pysdmx/io/json/sdmxjson2/messages/category.py,sha256=cqBjFm6o7XrhWWAjdR2lTbfOCJJWa6DlfAKjnQUq7uk,4737
61
+ pysdmx/io/json/sdmxjson2/messages/code.py,sha256=yo1-bx2brHfhPjymsj71SHz_PyOWJODBNa7oiMIAcDc,9381
62
+ pysdmx/io/json/sdmxjson2/messages/concept.py,sha256=fvwnfaBh10AtvCXkQuHbeYu5C7Fvn7wsg2zdBOV1kWc,3086
63
+ pysdmx/io/json/sdmxjson2/messages/constraint.py,sha256=XJsf7O8LBROOy8uyHzdBXyUUpOCUn46IrzuhETSF4_g,1636
64
+ pysdmx/io/json/sdmxjson2/messages/core.py,sha256=lMrlWg1Qbrj5ZG3duewr94YFmyiEu0jgnUHFL0f41T0,6381
65
+ pysdmx/io/json/sdmxjson2/messages/dataflow.py,sha256=EylbN2s7fz-rH5F0D5wtomJYX3DhNnWd0lbIMBXizjw,4506
66
+ pysdmx/io/json/sdmxjson2/messages/dsd.py,sha256=8rEqsZ_oHcAhtbWsGgKc_VUqUYgWmWC0Aj5-X7bZ2y8,11518
67
+ pysdmx/io/json/sdmxjson2/messages/map.py,sha256=VBsCO9QE_vItWZSPqySUU0W1r7qcc-2LNDZxqusFqcc,9891
68
+ pysdmx/io/json/sdmxjson2/messages/pa.py,sha256=vmL47EVrdbw3YhyH3ZJB6_EEaLAwULQv5Bfd4qVrzx0,1665
69
+ pysdmx/io/json/sdmxjson2/messages/provider.py,sha256=d2_UbNlgLLWqR9JCIBFwI7qswMaFuWKoSPc2bsnL23c,3165
70
+ pysdmx/io/json/sdmxjson2/messages/report.py,sha256=E4Xo3CcUPf_ihF5bTSczBXhupYLjtOdMH6XQh5eunhA,3508
71
+ pysdmx/io/json/sdmxjson2/messages/schema.py,sha256=hGEqEnNJ2LKnDTanVSPoF82ZsFvMWqZmYdzYEA--FaA,2634
72
+ pysdmx/io/json/sdmxjson2/messages/structure.py,sha256=WpQttjSdGK1AuWfR69gpe4E7HP9zkG6TWOvFhIpbis4,5446
73
+ pysdmx/io/json/sdmxjson2/messages/vtl.py,sha256=UrcNP5p_R2R_bFrY-vbOKCGYXkD5N4yBAwZlCWetDMQ,14700
74
+ pysdmx/io/json/sdmxjson2/reader/__init__.py,sha256=f9vTKscFIAQpAKh3pZ4ZKlZSKyGfj1yaZS9w7S0_hIc,1264
75
+ pysdmx/io/pd.py,sha256=1C5UnAT25EADOpNsRBooEdWNaJEGdmcwh6_R9O5MOrc,464
76
+ pysdmx/io/reader.py,sha256=Ejy9YW9QjuwfSKSHmB9EkCVGEKYPvpX5UEesgXE1_FU,8334
77
+ pysdmx/io/serde.py,sha256=l8z9qulrUkRNZq63YOUqTTs7zpl1hdYZe3UAZW1aEpM,1062
78
+ pysdmx/io/writer.py,sha256=h_2JSaOHSCHjOOIROXNnAakPD2FkSsJ1x42rpK7q7Ag,4564
79
+ pysdmx/io/xml/__allowed_lxml_errors.py,sha256=PdIK2i6JwwGRh1Ogc5JA0hRySO7QXJKN-DI8EYtdjA0,225
80
+ pysdmx/io/xml/__data_aux.py,sha256=ztivjZANN1PJ63IvoMfx-5TA2AiPQTVPC_0YYHOT9Ns,4069
81
+ pysdmx/io/xml/__init__.py,sha256=tcUsSEiM3nBA7lDbZPwGZ7Vu_K9gQd8oliASUMTGjFE,105
82
+ pysdmx/io/xml/__parse_xml.py,sha256=mGJMd_e2KWr-X8OtE1dB_CHBtqhMIuMpJwtvUmEX9dk,2137
83
+ pysdmx/io/xml/__ss_aux_reader.py,sha256=Tfp7oSb_0-AVEVdu7YFtj-SlBuEKp7fpg3-SxCmOHW0,2868
84
+ pysdmx/io/xml/__structure_aux_reader.py,sha256=zCe6-tjNxsTneQcPLodHC91AbLF7wj1CFdRkVRhyPrY,37837
85
+ pysdmx/io/xml/__structure_aux_writer.py,sha256=UbTMG3dwFYBdpSxykSOtuQidsTFioZ19izfBp_kjQr8,40162
86
+ pysdmx/io/xml/__tokens.py,sha256=5r2GnXX4M43Z33OEV9LwNLafTJ_T6zwZBxmzaqgG1TE,6700
87
+ pysdmx/io/xml/__write_aux.py,sha256=hgts820JRF87T28J8mCHp4qpDPwCuEi5izDti1mvnOo,14109
88
+ pysdmx/io/xml/__write_data_aux.py,sha256=ypq0SO_bFio5YWIsjIEfXwLU36mGHjAbRZJltVRD8lU,4277
89
+ pysdmx/io/xml/__write_structure_specific_aux.py,sha256=gj-q7NjsInV6-3vos2tDQyb9hG5WZGhYqLGiZ5cQu2E,7605
90
+ pysdmx/io/xml/config.py,sha256=R24cczVkzkhjVLXpv-qfEm88W3_QTqVt2Qofi8IvJ5Y,93
91
+ pysdmx/io/xml/doc_validation.py,sha256=O5p5J9o-41I245JR91fzG6k_tI-8Y9EuIwdVluFms3s,1624
92
+ pysdmx/io/xml/header.py,sha256=_XiruPAfMtr4wudCpiuhFXDvRgWITGQ9GZVG3lMvWcc,5535
93
+ pysdmx/io/xml/sdmx21/__init__.py,sha256=_rh_dz1d-LmUw4iVbsZQkTXANTJeR8ov8z_4jNRGhtg,38
94
+ pysdmx/io/xml/sdmx21/reader/__init__.py,sha256=2jMsySFbbq-So3ymqzKVi5gOPRwO0qasBBwntD03rTw,34
95
+ pysdmx/io/xml/sdmx21/reader/error.py,sha256=ySY3dBPcOaF_lm8yX1Khc92R5XgyD1u-djjiOrgZJP8,885
96
+ pysdmx/io/xml/sdmx21/reader/generic.py,sha256=uGZtqf44NqsZj7vjoE-eE5GBNJKEPmE9i72E9Ihu8Y4,5073
97
+ pysdmx/io/xml/sdmx21/reader/structure.py,sha256=bR3rCfY4x5xxkcyLhDSI-6Vw7b52RJY2qCcqr5MBuD4,1088
98
+ pysdmx/io/xml/sdmx21/reader/structure_specific.py,sha256=S3-gLmaBFjBRIr25qQtlraonKm9XAlvHgUVtdFHEFdM,1158
99
+ pysdmx/io/xml/sdmx21/reader/submission.py,sha256=8daiBW-sIVGaB6lYwHqJNkLI7IixMSydCK-0ZO8ri4I,1711
100
+ pysdmx/io/xml/sdmx21/writer/__init__.py,sha256=QQGFAss26njCC4eKYxhBcI9LYm5NHuJaAJGKCrIrL80,31
101
+ pysdmx/io/xml/sdmx21/writer/error.py,sha256=0wkX7K_n2oZNkOKg_zpl9Id82qP72Lqof-T-ZLGoZ1M,353
102
+ pysdmx/io/xml/sdmx21/writer/generic.py,sha256=cnzuawsb5SvzFZZmhiJb8DQPV8tNiH2UowWYGN0DZgc,13750
103
+ pysdmx/io/xml/sdmx21/writer/structure.py,sha256=S3qoNgXxrakn2V4NLdL5U5mAA16XisI0PpJDuxqalFE,2084
104
+ pysdmx/io/xml/sdmx21/writer/structure_specific.py,sha256=iXc1J-RzoKyRznvgGgdTSeUfyqZLouI8CtSq2YhGBWI,2877
105
+ pysdmx/io/xml/sdmx30/__init__.py,sha256=8BScJFEgLy8DoUreu2RBUtxjGjKyClkKBI_Qtarbk-Y,38
106
+ pysdmx/io/xml/sdmx30/reader/__init__.py,sha256=zxxRIIDA48SSENoFW8A09jSvQ0F1xQwIDkIBmTAxJSk,34
107
+ pysdmx/io/xml/sdmx30/reader/structure.py,sha256=dRkbW8M69gENhBP6LxntX-jDP1LBExz7hxUqocLnyOo,1103
108
+ pysdmx/io/xml/sdmx30/reader/structure_specific.py,sha256=BYZmNjGKGTMZLoE28XuYof8kIQ77WSrFv1-a2iV4TN0,1158
109
+ pysdmx/io/xml/sdmx30/writer/__init__.py,sha256=cfCVmf82PNRe9A5RYmuKfvxDTSNcsySlJwCBbKfY_O0,31
110
+ pysdmx/io/xml/sdmx30/writer/structure.py,sha256=T4Ety741N0P648lSN0WszhX9CztboAnWTtahSaeBts4,2105
111
+ pysdmx/io/xml/sdmx30/writer/structure_specific.py,sha256=ftNFO4RIJnyC-ZmU7SrIhjbJUJPzebDHMUMKyw9QPc4,3236
112
+ pysdmx/io/xml/utils.py,sha256=ljrocQwPTYycg3I68sqYI5pF8qukNccSCMM9Xf_Tag0,583
113
+ pysdmx/model/__base.py,sha256=H5OpCpi6fGxB30vFn-lCstTczSdOB4YJiBynThovQs4,13810
114
+ pysdmx/model/__init__.py,sha256=gmY8uGK0_SK9Ca5TqtYJqPSXvO9godlDKu2rhYouPSU,4984
115
+ pysdmx/model/category.py,sha256=WWWysaTdlcU8KZpQyZgbZkrOelNVCGOfVUk_APJxm-w,6031
116
+ pysdmx/model/code.py,sha256=otfn9WwSE6bBQeHia9T0A5WOQ6N37K3s4DbnZ5hywVM,11950
117
+ pysdmx/model/concept.py,sha256=mQfqJdtWc10WdTKX_Mw7Znw65cN3QO-kCar9MWYeWO4,9645
118
+ pysdmx/model/dataflow.py,sha256=Cqi_dJ-Mba0s24Dj8tAsQApcezf6kpomI1KMyX_8kgg,22633
119
+ pysdmx/model/dataset.py,sha256=Lbr7tYonGHD3NZUD-M9hK2puaEAluOVPG2DbkOohzMM,4861
120
+ pysdmx/model/gds.py,sha256=QrnmI8Hn--C95gGXCeUeWwhn-Ur7DuT08Cg7oPJIEVI,4976
121
+ pysdmx/model/map.py,sha256=IYoxKYpt0-9kYAgU24wryrSchR-lrc3NMacI5Vt5las,17213
122
+ pysdmx/model/message.py,sha256=hO-kxYTxt19lhx4xIIQE8RiLjz6peZK6CabFzlo5DRs,14469
123
+ pysdmx/model/metadata.py,sha256=EwElZZ8oewpuaEDDWM9ZV95Xvklcq333qxqPwoUqmXU,7653
124
+ pysdmx/model/organisation.py,sha256=k6ZQ_O4l7174Y8tr-nnMnsUL0q0O8Rw3q4mIWmJUh2A,4706
125
+ pysdmx/model/submission.py,sha256=iMQSvt-BYuDrqPEBcjw_wWNp74Vsx2OnEj3tnkth0Z8,833
126
+ pysdmx/model/vtl.py,sha256=k7WIb89876xKlf7k0R9sgZ1VVlRrIkbV7FzvMFZn8e0,6985
127
+ pysdmx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
+ pysdmx/toolkit/__init__.py,sha256=yBRw4FXQH_RUJgF6vwZscNwCVBt-FMwslJEfDKa7eXo,26
129
+ pysdmx/toolkit/pd/__init__.py,sha256=3JoCZHamJR4mZfLt9GmaznLlG_YilmY0hAhuW5COQC8,3138
130
+ pysdmx/toolkit/vtl/__init__.py,sha256=nVwtISeFiT4tr2gNjb2A-P_IRAdqv6Mn7EOgFkaRleg,216
131
+ pysdmx/toolkit/vtl/_validations.py,sha256=seDf83sodg9Jn7Y-L4vo2Zmfqyh_ivBLdH7tz1DjyO4,5677
132
+ pysdmx/toolkit/vtl/script_generation.py,sha256=YOP_-MMcIdDIHYa8HIMuVCN9N-S9CQD8bH5xpF1kc2E,3235
133
+ pysdmx/toolkit/vtl/validation.py,sha256=UieJUYwxkw9McHZwixKFQdgYKFsgFwFo5XCLIIDcr7Q,3594
134
+ pysdmx/util/__init__.py,sha256=6sSo9wq6BQIrCV1aaeNj8AWztxqsEkDZA-pRAFzwmUQ,3921
135
+ pysdmx/util/_date_pattern_map.py,sha256=IS1qONwVHbTBNIFCT0Rqbijj2a9mYvs7onXSK6GeQAQ,1620
136
+ pysdmx/util/_model_utils.py,sha256=gczmenZBkcCTYMOUI4HQeKxodVFcD_RFZEoEYC05XRc,2304
137
+ pysdmx-1.4.0rc1.dist-info/LICENSE,sha256=3XTNDPtv2RxDUNkQzn9MIWit2u7_Ob5daMLEq-4pBJs,649
138
+ pysdmx-1.4.0rc1.dist-info/METADATA,sha256=pSA1Qo5hZUv1fbM7tk02cWZorUp1byuhTMjFd1bxt5s,4693
139
+ pysdmx-1.4.0rc1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
140
+ pysdmx-1.4.0rc1.dist-info/RECORD,,