Skip to content
43 changes: 21 additions & 22 deletions dataretrieval/wqp.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def get_results(
response = query(url, kwargs, delimiter=";", ssl_check=ssl_check)

df = pd.read_csv(StringIO(response.text), delimiter=",", low_memory=False)
return df, WQP_Metadata(response)
return df, WQP_Metadata(response, **kwargs)


def what_sites(
Expand Down Expand Up @@ -210,7 +210,7 @@ def what_sites(

df = pd.read_csv(StringIO(response.text), delimiter=",", low_memory=False)

return df, WQP_Metadata(response)
return df, WQP_Metadata(response, **kwargs)


def what_organizations(
Expand Down Expand Up @@ -265,7 +265,7 @@ def what_organizations(

df = pd.read_csv(StringIO(response.text), delimiter=",", low_memory=False)

return df, WQP_Metadata(response)
return df, WQP_Metadata(response, **kwargs)


def what_projects(ssl_check=True, legacy=True, **kwargs):
Expand Down Expand Up @@ -316,7 +316,7 @@ def what_projects(ssl_check=True, legacy=True, **kwargs):

df = pd.read_csv(StringIO(response.text), delimiter=",", low_memory=False)

return df, WQP_Metadata(response)
return df, WQP_Metadata(response, **kwargs)


def what_activities(
Expand Down Expand Up @@ -380,7 +380,7 @@ def what_activities(

df = pd.read_csv(StringIO(response.text), delimiter=",", low_memory=False)

return df, WQP_Metadata(response)
return df, WQP_Metadata(response, **kwargs)


def what_detection_limits(
Expand Down Expand Up @@ -442,7 +442,7 @@ def what_detection_limits(

df = pd.read_csv(StringIO(response.text), delimiter=",", low_memory=False)

return df, WQP_Metadata(response)
return df, WQP_Metadata(response, **kwargs)


def what_habitat_metrics(
Expand Down Expand Up @@ -497,7 +497,7 @@ def what_habitat_metrics(

df = pd.read_csv(StringIO(response.text), delimiter=",", low_memory=False)

return df, WQP_Metadata(response)
return df, WQP_Metadata(response, **kwargs)


def what_project_weights(ssl_check=True, legacy=True, **kwargs):
Expand Down Expand Up @@ -553,7 +553,7 @@ def what_project_weights(ssl_check=True, legacy=True, **kwargs):

df = pd.read_csv(StringIO(response.text), delimiter=",", low_memory=False)

return df, WQP_Metadata(response)
return df, WQP_Metadata(response, **kwargs)


def what_activity_metrics(ssl_check=True, legacy=True, **kwargs):
Expand Down Expand Up @@ -609,7 +609,7 @@ def what_activity_metrics(ssl_check=True, legacy=True, **kwargs):

df = pd.read_csv(StringIO(response.text), delimiter=",")

return df, WQP_Metadata(response)
return df, WQP_Metadata(response, **kwargs)


def wqp_url(service):
Expand Down Expand Up @@ -649,14 +649,15 @@ class WQP_Metadata(BaseMetadata):
----------
url : str
Response url
query_time : datetme.timedelta
query_time : datetime.timedelta
Response elapsed time
header : requests.structures.CaseInsensitiveDict
Response headers
comments : None
Metadata comments. WQP does not return comments.
site_info : tuple[pd.DataFrame, NWIS_Metadata] | None
Site information if the query included `sites`, `site` or `site_no`.
comment : None
Metadata comment. WQP does not return comments.
site_info : tuple[pd.DataFrame, WQP_Metadata] | None
Site information if the query included a site filter (`siteid`,
`sites`, `site`, or `site_no`).
"""

def __init__(self, response, **parameters) -> None:
Expand All @@ -682,14 +683,12 @@ def __init__(self, response, **parameters) -> None:

self._parameters = parameters

@property
def site_info(self):
if "sites" in self._parameters:
return what_sites(sites=parameters["sites"])
elif "site" in self._parameters:
return what_sites(sites=parameters["site"])
elif "site_no" in self._parameters:
return what_sites(sites=parameters["site_no"])
@property
def site_info(self):
for key in ("siteid", "sites", "site", "site_no"):
if key in self._parameters:
return what_sites(siteid=self._parameters[key])
return None


def _check_kwargs(kwargs):
Expand Down
39 changes: 39 additions & 0 deletions tests/wqp_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,42 @@ def test_check_kwargs():
kwargs = {"mimeType": "foo"}
with pytest.raises(ValueError):
kwargs = _check_kwargs(kwargs)


def test_wqp_metadata_site_info_property_resolves(requests_mock):
"""`site_info` must be a real property bound to the class.

Regression: previously `site_info` was defined as a closure inside
`__init__`, so `md.site_info` fell through to `BaseMetadata.site_info`
and raised `NotImplementedError`. Also verify the parameters are
threaded through from `get_results`.
"""
results_url = (
"https://www.waterqualitydata.us/data/Result/Search?"
"siteid=WIDNR_WQX-10032762&mimeType=csv"
)
sites_url = (
"https://www.waterqualitydata.us/data/Station/Search?"
"siteid=WIDNR_WQX-10032762&mimeType=csv"
)
mock_request(requests_mock, results_url, "tests/data/wqp_results.txt")
mock_request(requests_mock, sites_url, "tests/data/wqp_sites.txt")

_df, md = get_results(siteid="WIDNR_WQX-10032762")

# site_info must be a bound property — accessing it should return the
# what_sites() tuple, not raise NotImplementedError.
site_df, site_md = md.site_info
assert isinstance(site_df, DataFrame)
assert site_md.url == sites_url


def test_wqp_metadata_site_info_returns_none_without_site_filter(requests_mock):
"""`site_info` returns None when no site filter was supplied."""
results_url = (
"https://www.waterqualitydata.us/data/Result/Search?"
"characteristicName=Chloride&mimeType=csv"
)
mock_request(requests_mock, results_url, "tests/data/wqp_results.txt")
_df, md = get_results(characteristicName="Chloride")
assert md.site_info is None
Loading