def test_request(): # Constructor r = sdmx.Request(log_level=logging.ERROR) # Invalid source name raise an exception with pytest.raises(ValueError): sdmx.Request("noagency") # Regular methods r.clear_cache() r.timeout = 300 assert r.timeout == 300 # dir() includes convenience methods for resource endpoints expected = { "cache", "clear_cache", "get", "preview_data", "series_keys", "session", "source", "timeout", } expected |= set(ep.name for ep in sdmx.Resource) assert set(filter(lambda s: not s.startswith("_"), dir(r))) == expected
def get_sdmx(source=None, **args): """Retrieve data from *source* using :mod:`sdmx`. Arguments --------- source : str Name of a data source recognized by ``sdmx1``, e.g. 'OECD'. args Other arguments to :meth:`sdmx.Request.get`. Returns ------- pandas.DataFrame """ # SDMX client for the data source req = sdmx.Request(source=source) # commented: for debugging # args.setdefault('tofile', 'debug.json') # Retrieve the data msg = req.get(resource_type="data", **args) # Convert to pd.DataFrame, preserving attributes df = sdmx.to_pandas(msg, attributes="dgso") index_cols = df.index.names # Reset index, use categoricals return df.reset_index().astype({c: "category" for c in index_cols})
def test_doc_example(): """Code from example.rst.""" import sdmx estat = sdmx.Request("ESTAT") metadata = estat.datastructure("DSD_une_rt_a") for cl in "CL_AGE", "CL_UNIT": print(sdmx.to_pandas(metadata.codelist[cl])) resp = estat.data("une_rt_a", key={"GEO": "EL+ES+IE"}, params={"startPeriod": "2007"}) data = sdmx.to_pandas(resp).xs("Y15-74", level="AGE", drop_level=False) data.loc[("A", "Y15-74", "PC_ACT", "T")] # Further checks per https://github.com/dr-leo/pandaSDMX/issues/157 # DimensionDescriptor for the structure message dd1 = metadata.structure.DSD_une_rt_a.dimensions # DimensionDescriptor retrieved whilst validating the data message dd2 = resp.data[0].structured_by.dimensions # DimensionDescriptors have same ID, components and order assert dd1 == dd2 # One SeriesKey from the data message sk = list(resp.data[0].series.keys())[0] # Key values have same order as in the DSD assert dd1.order_key(sk) == sk
def test_request_get_args(): req = sdmx.Request("ESTAT") # Request._make_key accepts '+'-separated values args = dict( resource_id="une_rt_a", key={"GEO": "EL+ES+IE"}, params={"startPeriod": "2007"}, dry_run=True, use_cache=True, ) # Store the URL url = req.data(**args).url # Using an iterable of key values gives the same URL args["key"] = {"GEO": ["EL", "ES", "IE"]} assert req.data(**args).url == url # Using a direct string for a key gives the same URL args["key"] = "....EL+ES+IE" # No specified values for first 4 dimensions assert req.data(**args).url == url # Giving 'provider' is redundant for a data request, causes a warning with pytest.warns(UserWarning, match="'provider' argument is redundant"): req.data( "une_rt_a", key={"GEO": "EL+ES+IE"}, params={"startPeriod": "2007"}, provider="ESTAT", ) # Using an unknown endpoint is an exception with pytest.raises(ValueError): req.get("badendpoint", "id")
def test_write_constraint(): """'constraint' argument to writer.write_dataset.""" with specimen("ng-ts.xml") as f: msg = sdmx.read_sdmx(f) # Fetch the message's DSD assert msg.structure.is_external_reference # NB the speciment included in tests/data has 'ECB_EXR_NG' as the # data structure ID; but a query against the web service gives # 'ECB_EXR1' for the same data structure. id = "ECB_EXR1" dsd = (sdmx.Request(msg.structure.maintainer.id).get("datastructure", id).structure[id]) # Create a ContentConstraint cc = dsd.make_constraint({"CURRENCY": "JPY+USD"}) # Write the message without constraint s1 = sdmx.to_pandas(msg) assert len(s1) == 12 assert set(s1.index.to_frame()["CURRENCY"]) == {"CHF", "GBP", "JPY", "USD"} # Writing using constraint produces a fewer items; only those matching the # constraint s2 = sdmx.to_pandas(msg, constraint=cc) assert len(s2) == 6 assert set(s2.index.to_frame()["CURRENCY"]) == {"JPY", "USD"}
def test_request_get_exceptions(): """Tests of Request.get() that don't require remote data.""" req = sdmx.Request("ESTAT") # Exception is raised on unrecognized arguments exc = "unrecognized arguments: {'foo': 'bar'}" with pytest.raises(ValueError, match=exc): req.get("datastructure", foo="bar") exc = r"{'foo': 'bar'} supplied with get\(url=...\)" with pytest.raises(ValueError, match=exc): sdmx.read_url("https://example.com", foo="bar")
def test_request_preview_data(): req = sdmx.Request("ECB") # List of keys can be retrieved keys = req.preview_data("EXR") assert isinstance(keys, list) # Count of keys can be determined assert len(keys) > 1000 # A filter can be provided, resulting in fewer keys keys = req.preview_data("EXR", {"CURRENCY": "CAD+CHF+CNY"}) assert len(keys) == 24 # Result can be converted to pandas object keys_pd = sdmx.to_pandas(keys) assert isinstance(keys_pd, pd.DataFrame) assert len(keys_pd) == 24
def test_deprecated_request(caplog): message = "Request class will be removed in v3.0; use Client(…)" with pytest.warns(DeprecationWarning, match=re.escape(message)): sdmx.Request("ECB") assert caplog.record_tuples == [("sdmx.client", logging.WARNING, message)]