khaeru / sdmx

SDMX information model and client in Python
https://sdmx1.readthedocs.io
Apache License 2.0
23 stars 18 forks source link

XMLParseError: KeyError: 'BS_REP_SECTOR' when parsing ECB constraints #114

Open zymon opened 1 year ago

zymon commented 1 year ago

Hello, Here's simple code snippet to reproduce the problem:

import sdmx import logging

logging.basicConfig() logging.root.setLevel(logging.NOTSET)

client = sdmx.Client('ECB') c=client.contentconstraint('BSI_CONSTRAINTS')

Result:

> Traceback (most recent call last):
File "r:\SharedLocal\ECFIN-DEV\fastop\python\.venv\Lib\site-packages\sdmx\reader\xml.py", line 254, in read_message
result = func(self, element)
^^^^^^^^^^^^^^^^^^^
File "r:\SharedLocal\ECFIN-DEV\fastop\python\.venv\Lib\site-packages\sdmx\reader\xml.py", line 1171, in _ms
cl, values_for = _ms_component(reader, elem, kind)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "r:\SharedLocal\ECFIN-DEV\fastop\python\.venv\Lib\site-packages\sdmx\reader\xml.py", line 1141, in _ms_component
return cl, cl.get(elem.attrib["id"])
^^^^^^^^^^^^^^^^^^^^^^^^^
File "r:\SharedLocal\ECFIN-DEV\fastop\python\.venv\Lib\site-packages\sdmx\model.py", line 879, in get
raise KeyError(id)
KeyError: 'BS_REP_SECTOR'

> The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "r:\SharedLocal\ECFIN-DEV\fastop\python\.venv\Lib\site-packages\sdmx\client.py", line 485, in get
msg = reader.read_message(response_content, dsd=kwargs.get("dsd", None))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "r:\SharedLocal\ECFIN-DEV\fastop\python\.venv\Lib\site-packages\sdmx\reader\xml.py", line 271, in read_message
raise XMLParseError from exc
sdmx.exceptions.XMLParseError: KeyError: 'BS_REP_SECTOR'

sdmx1 version: 2.7.0 python: 3.11.2

khaeru commented 1 year ago

Confirmed. This occurs because the reader is trying to actually look up the corresponding DataflowDefinition, DSD, dimension, and associated Codelist. Handy when those objects are present in the message, but we have no fallback behaviour when they're not.

Giving references=all seems to be a workaround:

import sdmx

ECB = sdmx.Client("ECB")
msg = ECB.contentconstraint("BSI_CONSTRAINTS", params={"references": "all"})
cc = msg.constraint["BSI_CONSTRAINT"]
cc.data_content_region[0]

gives output like:

<CubeRegion include
  <MemberSelection BS_REP_SECTOR in {'P', 'A', 'R', 'B', 'C', 'E', 'U', 'V', 'F', 'L', 'N'}>
  <MemberSelection BS_COUNT_SECTOR in {'2240Z', '1000', '1220', '2210', '2110', '2253', '3000', '2230', '2250', '2272', '2240LMN', '2271', '2270', '00NR', '2240F', '2240G', '2240HJ', '2240I', '0000', '2300', '1211', '2240DE', '2200', '1210', '2222', '2123', '2240A', '2240B', '00BK', '2240C', '00NB', '2100', '2221', '2122', '2000', '2220', '2121', '2120', '2240', '2260', '1200', '1100'}>
  <MemberSelection BS_ITEM in {'A20EST', 'L61', 'L60', 'A23DASZ5', 'A21DAXZ5', 'LRAE', 'L21T', 'A21T', 'A20YZ', 'A20RASU2', 'LRAU', 'A20DAXZ5', 'A10', 'A20YC', 'A20YB', 'A22DASZ5', 'L70', 'L71', 'L74', 'A20YA', 'M10', 'R31', 'R31A', 'LXG', 'A20', 'A21', 'A22', 'A23', 'A23DANZ5', 'A25', 'A20CP', 'A20TA', 'IRR', 'A23YZ', 'M20', 'A21DASZ5', 'L24A', 'T00', 'AT0', 'A30', 'AT2', 'A23YA', 'L90', 'AT9', 'A20SA', 'A22DAXZ5', 'A23YC', 'L10', 'LR0', 'M30', 'A20DASU2', 'A41', 'LRE', 'A42', 'LRD', 'A20DANZ5', 'LREE', 'A22YZ', 'L21', 'L20', 'L23', 'LREN', 'L22', 'LRR', 'L24', 'A21DANZ5', 'A20NB', 'A20NA', 'L2A', 'A50', 'L2C', 'L2B', 'A22YC', 'A22YA', 'L30', 'LT3', 'A20RAXZ5', 'LT2', 'A5A', 'LT4', 'LT6', 'A60', 'LTD', 'L41', 'L40', 'A21YZ', 'N00', 'LE0', 'A70', 'A20DASZ5', 'A71', 'A23DAXZ5', 'L20G', 'A74', 'A20DAWZ5', 'A20NZ', 'A21YC', 'A21YA', 'A20S', 'A20T', 'A7C', 'A20R', 'A20RASZ5', 'AXG', 'A2Z3', 'A20G', 'A2Z1', 'A2Z2', 'A22DANZ5', 'A80', 'A20D', 'A20A'}>
  <MemberSelection DATA_TYPE in {'1', 'A', 'Q', 'S', '4', '5', '6', '7', 'X', 'I', 'Y'}>
  <MemberSelection BS_SUFFIX in {'P', 'A', '3', 'E', 'V', '6', 'F', 'I', 'Z', 'P10'}>
  <MemberSelection REF_AREA in {'U5', 'DE', 'BE', 'FI', 'PT', 'BG', 'DK', 'LT', 'LU', 'HR', 'LV', 'FR', 'HU', '4F', 'SE', 'SI', 'SK', 'GB', 'IE', 'EE', 'MT', 'GR', 'IT', 'ES', 'AT', 'CY', 'CZ', 'PL', 'U2', 'RO', 'NL'}>
  <MemberSelection MATURITY_ORIG in {'A', 'D', 'HL', 'E', 'F', 'G', 'KKF', 'H', 'I', 'J', 'K', 'L', 'M', 'HHL', 'X', 'KF'}>
  <MemberSelection ADJUSTMENT in {'Y', 'N'}>
  <MemberSelection COUNT_AREA in {'U5', 'U6', 'DE', 'BE', 'FI', 'U8', 'PT', 'U9', 'BG', 'DK', 'LT', 'LU', 'HR', 'LV', 'FR', 'HU', 'A1', 'SE', 'SI', 'SK', 'Z5', 'GB', 'IE', 'Z9', 'EE', 'MT', 'GR', 'IT', 'ES', 'AT', 'CY', 'CZ', 'PL', 'U2', 'RO', 'NL', 'U3', 'U4'}>
  <MemberSelection CURRENCY_TRANS in {'Z07', 'CHF', 'Z06', 'EUR', 'DKK', 'Z0Z', 'USD', 'BGN', 'RON', 'JPY', 'PLN', 'GBP', 'CZK', 'Z41', 'HUF', 'SEK', 'Z42', 'Z01', 'Z03', 'Z05', 'Z04'}>
  <MemberSelection FREQ in {'A', 'Q', 'M'}>
>