Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/sources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,17 @@ SDMX-ML —
- This web service returns the non-standard HTTP content-type "application/force-download"; :mod:`sdmx` replaces it with "application/xml".


.. _LU1:

``LU1``: STATEC (Luxembourg)
----------------------------
Comment on lines +426 to +427

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point: the name does appear in slightly different forms across the registry, the test, and the docs. We've kept each as it is because they each follow the pattern the repo already uses. The documentation heading in particular has a fixed shape, so it can't simply mirror the others.

Detail: every source heading in doc/sources.rst uses the same form, namely the source ID followed by the office name and the country in parentheses. For example, NB is "Norges Bank (Norway)" and LSD is "National Institute of Statistics (Lithuania)". NB itself varies the same way across its registry name ("Norges Bank (NO)"), its test docstring ("Norges Bank.") and its heading. Happy to standardise on a specific form if you'd prefer one.


SDMX-ML —
`Website <https://lustat.statec.lu/>`__

- LUSTAT is the data dissemination platform of STATEC, the national statistical institute of Luxembourg.


.. _NB:

``NB``: Norges Bank (Norway)
Expand Down
6 changes: 4 additions & 2 deletions doc/whatsnew.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
What's new?
***********

.. Next release
.. ============
Next release
============

- Add :ref:`LU1` data source: Luxembourg STATEC (LUSTAT) (:pull:`283`).

v2.26.0 (2026-04-04)
====================
Expand Down
12 changes: 12 additions & 0 deletions sdmx/sources.json
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,18 @@
"structureset": false
}
},
{
"id": "LU1",
"name": "Luxembourg STATEC",
"url": "https://lustat.statec.lu/rest",
"supports": {
"agencyscheme": false,
"dataconsumerscheme": false,
"metadataflow": false,
"metadatastructure": false,
Comment on lines +351 to +353

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. This is deliberate, not an oversight. In sdmx1, the supports list and the test's xfail list look similar but mean different things, so endpoints aren't interchangeable between them.

supports is reserved for endpoints the server flatly doesn't have; sdmx1 then skips the request entirely. The endpoints flagged here fail in other ways. Two of them return different error responses, so sdmx1 should still try them and surface a normal, catchable error. The other two, metadata and registration, aren't a limitation of the Luxembourg service at all; they're simply not implemented in sdmx1 yet. All four belong in the test's xfail list, which is where they are.

Detail: per the source-policy in doc/sources.rst, supports: false is for HTTP 404 only. organisationscheme returns HTTP 400 (raising HTTPError) and structure returns HTTP 501 (raising NotImplementedError), so both go in xfail. metadata and registration are sdmx1-internal gaps, xfailed in every source's test (TestTEST, TestAR1, TestUY110). LU1's xfail set is identical to TestUY110's.

"structureset": false
}
},
{
"id": "NB",
"name": "Norges Bank (NO)",
Expand Down
2 changes: 1 addition & 1 deletion sdmx/tests/test_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def test_get_source(caplog):
def test_list_sources():
source_ids = list_sources()
# Correct number of sources, excluding those created for testing
assert 35 == len(set(source_ids) - {"MOCK", "TEST"})
assert 36 == len(set(source_ids) - {"MOCK", "TEST"})

# Listed alphabetically
assert "ABS" == source_ids[0]
Expand Down
17 changes: 17 additions & 0 deletions sdmx/tests/test_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,23 @@ class TestLSD(DataSourceTest):
}


class TestLU1(DataSourceTest):
"""Luxembourg STATEC (LUSTAT)."""

source_id = "LU1"

endpoint_args = {
"data": dict(resource_id="DF_A1100", params=dict(lastNObservations=1)),
}

xfail = {
"metadata": NotImplementedError, # Internal to sdmx1
"organisationscheme": HTTPError, # 400 Bad Request
"registration": ValueError, # Internal to sdmx1
"structure": NotImplementedError, # 501 Not Implemented

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct as written. sdmx1 deliberately turns an HTTP 501 ("not implemented") response into Python's built-in NotImplementedError, rather than a generic HTTP error, so that calling code can catch it cleanly. The test expects exactly what the library raises, and the # 501 comment describes the server response that triggers it.

Detail: doc/sources.rst's source-policy states this explicitly. A 501 response raises NotImplementedError; a 400 raises HTTPError. Verified live: probing LU1's structure endpoint raised NotImplementedError, and the DataSourceTest xfails cleanly (a wrong exception type would make it error rather than xfail). TestUY110 carries the identical structure: NotImplementedError # 501.

}


class TestNB(DataSourceTest):
"""Norges Bank.

Expand Down
Loading