-
Notifications
You must be signed in to change notification settings - Fork 67
Description
Hi!
I've been using pandaSDMX (to great success) to fetch exchange rates and more from the ECBs statistical data warehouse "SDW".
Recently (around February 24th or 25th), something on the ECB API has changed, causing my regular data imports to fail.
(I've also reported that problem to them using their contact form. Waiting to see what'll happen.)
Here's what I have found out until now:
When fetching data without an Accept header, the API returns a Content-Type: application/vnd.sdmx.genericdata+xml;version=2.1 header.
When fetching data with an Accept: application/vnd.sdmx.genericdata+xml;version=2.1 header, the API returns no Content-Type header at all.
This triggers an error in pandaSDMX.
To reproduce:
# result includes Content-Type header
curl -I 'https://data-api.ecb.europa.eu/service/data/EXR/D.USD.EUR.SP00.A?startPeriod=2025-01-01'
# result is lacking Content-Type header
curl -I -H'Accept: application/vnd.sdmx.genericdata+xml;version=2.1' 'https://data-api.ecb.europa.eu/service/data/EXR/D.USD.EUR.SP00.A?startPeriod=2025-01-01'The pandaSDMX equivalent in python:
import pandasdmx as sdmx
ecb = sdmx.Request('ECB')
exr = ecb.dataflow('EXR')
# works, because it's not sending an Accept header due to not passing a data structure definition
data = ecb.data('EXR', key='D.USD.EUR.SP00.A', params={'startPeriod':'2025-01-01'})
# fails, because it's sending an Accept header
data = ecb.data('EXR', dsd=exr.structure.ECB_EXR1, key='D.USD.EUR.SP00.A', params={'startPeriod':'2025-01-01'})The error happens when get_reader_for_content_type(content_type) is called with None because of the missing Content-Type header.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/.../venv/lib/python3.11/site-packages/pandasdmx/api.py", line 498, in get
Reader = get_reader_for_content_type(content_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/.../venv/lib/python3.11/site-packages/pandasdmx/reader/__init__.py", line 45, in get_reader_for_content_type
if cls.supports_content_type(ctype):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/.../venv/lib/python3.11/site-packages/pandasdmx/reader/base.py", line 40, in supports_content_type
other = parse_content_type(value)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/.../venv/lib/python3.11/site-packages/pandasdmx/util.py", line 374, in parse_content_type
tokens = value.split(";")
^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'split'
I'm not 100% sure if this can be safely handled in pandaSDMX. Maybe have a default reader to use when no Content-Type header is returned? Maybe guess that Content-Type equals Accept if it's missing?
Both sound sub-optimal. I hope that ECB ship fix it on their end, but I don't know if that will happen, even though I asked very nicely.
Also, you're using ECB for some examples in the documentation. Those might fail because of this as well.