diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d98b9d..65e8c07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog for oda_reader +## 1.4.3 (2026-04-09) +- Fixes DAC1 query filter dimension order to match the current DSD schema, which added SECTOR at position 2. +- Bumps DAC1 dataflow version from 1.7 to 1.8. + ## 1.4.2 (2026-01-23) - Updates DAC1 dataflow version from 1.5 to 1.7. - Updates DAC2a dataflow version from 1.6 to 1.4. diff --git a/docs/docs/advanced.md b/docs/docs/advanced.md index 4aad386..0f5287f 100644 --- a/docs/docs/advanced.md +++ b/docs/docs/advanced.md @@ -19,7 +19,7 @@ filter_string = qb.build_dac1_filter( ) print(filter_string) -# Output: "USA.....1010.1140..." +# Output: "USA..1010..1140.." ``` This filter string can be used to manually construct API URLs. @@ -30,7 +30,7 @@ This filter string can be used to manually construct API URLs. - Understanding dimension order for a dataset **Methods available**: -- `build_dac1_filter(donor, recipient, flow_type, measure, unit_measure, price_base)` +- `build_dac1_filter(donor, sector, measure, flow_type, unit_measure, price_base)` - `build_dac2a_filter(donor, recipient, measure, price_base, ...)` - `build_crs_filter(donor, recipient, sector, channel, modality, microdata, ...)` - `build_multisystem_filter(donor, channel, flow_type, ...)` diff --git a/pyproject.toml b/pyproject.toml index 37a28c5..fb3c2db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "oda_reader" -version = "1.4.2" +version = "1.4.3" description = "A simple package to import ODA data from the OECD's API and AidData's database" readme = "README.md" license = "MIT" diff --git a/src/oda_reader/dac1.py b/src/oda_reader/dac1.py index 7a67a0a..4672301 100644 --- a/src/oda_reader/dac1.py +++ b/src/oda_reader/dac1.py @@ -4,7 +4,7 @@ from oda_reader.download.download_tools import download DATAFLOW_ID: str = "DSD_DAC1@DF_DAC1" -DATAFLOW_VERSION: str = "1.7" +DATAFLOW_VERSION: str = "1.8" @cache_info diff --git a/src/oda_reader/download/query_builder.py b/src/oda_reader/download/query_builder.py index 96f8674..a2af202 100644 --- a/src/oda_reader/download/query_builder.py +++ b/src/oda_reader/download/query_builder.py @@ -128,6 +128,7 @@ def set_time_period( def build_dac1_filter( self, donor: str | list[str] | None = None, + sector: str | list[str] | None = None, measure: str | list[str] | None = None, flow_type: str | list[str] | None = None, unit_measure: str | list[str] | None = None, @@ -136,10 +137,11 @@ def build_dac1_filter( """Build the filter string for the DAC1 dataflow. The allowed filter follows the pattern: - {donor}.{measure}.{untied}.{flow_type}.{unit_measure}.{price_base}.{period} + {donor}.{sector}.{measure}.{tying_status}.{flow_type}.{unit_measure}.{price_base} Args: donor (str | list[str] | None): The donor country code(s). + sector (str | list[str] | None): The sector code(s). measure (str | list[str] | None): The measure code(s). flow_type (str | list[str] | None): The flow type code(s). unit_measure (str | list[str] | None): The unit of measure code(s). @@ -149,17 +151,16 @@ def build_dac1_filter( str: The filter string for the query. """ - # if any of the parameters are None, set them to the default value donor = self._to_filter_str(donor) + sector = self._to_filter_str(sector) measure = self._to_filter_str(measure) - untied = self._to_filter_str(None) + tying_status = self._to_filter_str(None) flow_type = self._to_filter_str(flow_type) unit_measure = self._to_filter_str(unit_measure) price_base = self._to_filter_str(price_base) - period = self._to_filter_str(None) return ".".join( - [donor, measure, untied, flow_type, unit_measure, price_base, period] + [donor, sector, measure, tying_status, flow_type, unit_measure, price_base] ) def build_dac2a_filter( diff --git a/tests/download/unit/test_query_builder.py b/tests/download/unit/test_query_builder.py index e5a9589..a6f1d8d 100644 --- a/tests/download/unit/test_query_builder.py +++ b/tests/download/unit/test_query_builder.py @@ -18,22 +18,23 @@ def test_dac1_filter_basic(self): flow_type="1140", ) - # Should have donor.measure.untied.flow_type.unit_measure.price_base.period + # Should have donor.sector.measure.tying_status.flow_type.unit_measure.price_base # With None values as empty strings for API v1 - assert result == "1.2010..1140..." + assert result == "1..2010..1140.." def test_dac1_filter_all_parameters(self): """Test DAC1 filter with all parameters specified.""" qb = QueryBuilder(dataflow_id="DF_DAC1", api_version=1) result = qb.build_dac1_filter( donor="1", + sector="_Z", measure="2010", flow_type="1140", unit_measure="USD", price_base="V", ) - assert result == "1.2010..1140.USD.V." + assert result == "1._Z.2010..1140.USD.V" def test_dac1_filter_no_parameters(self): """Test DAC1 filter with no parameters (all dimensions).""" @@ -128,7 +129,7 @@ def test_build_query_api_v1(self): dataflow_version="1.0", api_version=1, ) - qb.set_filter("1.2010..1140...") + qb.set_filter("1..2010..1140..") qb.set_time_period(start=2020, end=2023) url = qb.build_query() @@ -136,7 +137,7 @@ def test_build_query_api_v1(self): assert "https://sdmx.oecd.org/public/rest/data/" in url assert "OECD.DCD.FSD" in url assert "DF_DAC1,1.0/" in url - assert "1.2010..1140..." in url + assert "1..2010..1140.." in url assert "startPeriod=2020" in url assert "endPeriod=2023" in url assert "format=csvfilewithlabels" in url diff --git a/uv.lock b/uv.lock index 41eae9f..684a3c6 100644 --- a/uv.lock +++ b/uv.lock @@ -789,7 +789,7 @@ wheels = [ [[package]] name = "oda-reader" -version = "1.4.1" +version = "1.4.3" source = { editable = "." } dependencies = [ { name = "filelock" },