Skip to content

Commit b44dd2f

Browse files
thodson-usgsclaude
andcommitted
Switch WQP default profile from legacy to WQX3.0
Change all WQP functions from legacy=True to legacy=False so that get_results, what_sites, and what_activities route to WQX3.0 endpoints by default. Functions without a WQX3.0 equivalent now emit a UserWarning instead of silently returning legacy data. legacy=True still works but triggers a DeprecationWarning. Closes #121. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent c4d0f84 commit b44dd2f

2 files changed

Lines changed: 74 additions & 61 deletions

File tree

dataretrieval/wqp.py

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
def get_results(
4444
ssl_check=True,
45-
legacy=True,
45+
legacy=False,
4646
**kwargs,
4747
) -> tuple[DataFrame, WQP_Metadata]:
4848
"""Query the WQP for results.
@@ -160,7 +160,7 @@ def get_results(
160160

161161
def what_sites(
162162
ssl_check=True,
163-
legacy=True,
163+
legacy=False,
164164
**kwargs,
165165
) -> tuple[DataFrame, WQP_Metadata]:
166166
"""Search WQP for sites within a region with specific data.
@@ -215,7 +215,7 @@ def what_sites(
215215

216216
def what_organizations(
217217
ssl_check=True,
218-
legacy=True,
218+
legacy=False,
219219
**kwargs,
220220
) -> tuple[DataFrame, WQP_Metadata]:
221221
"""Search WQP for organizations within a region with specific data.
@@ -258,8 +258,12 @@ def what_organizations(
258258
if legacy is True:
259259
url = wqp_url("Organization")
260260
else:
261-
print("WQX3.0 profile not available, returning legacy profile.")
262-
url = wqp_url("Organization")
261+
warnings.warn(
262+
"No WQX3.0 equivalent exists for this function; returning legacy data.",
263+
UserWarning,
264+
stacklevel=2,
265+
)
266+
url = wqp_url("Organization", warn=False)
263267

264268
response = query(url, payload=kwargs, delimiter=";", ssl_check=ssl_check)
265269

@@ -268,7 +272,7 @@ def what_organizations(
268272
return df, WQP_Metadata(response)
269273

270274

271-
def what_projects(ssl_check=True, legacy=True, **kwargs):
275+
def what_projects(ssl_check=True, legacy=False, **kwargs):
272276
"""Search WQP for projects within a region with specific data.
273277
274278
Any WQP API parameter can be passed as a keyword argument to this function.
@@ -309,8 +313,12 @@ def what_projects(ssl_check=True, legacy=True, **kwargs):
309313
if legacy is True:
310314
url = wqp_url("Project")
311315
else:
312-
print("WQX3.0 profile not available, returning legacy profile.")
313-
url = wqp_url("Project")
316+
warnings.warn(
317+
"No WQX3.0 equivalent exists for this function; returning legacy data.",
318+
UserWarning,
319+
stacklevel=2,
320+
)
321+
url = wqp_url("Project", warn=False)
314322

315323
response = query(url, payload=kwargs, delimiter=";", ssl_check=ssl_check)
316324

@@ -321,7 +329,7 @@ def what_projects(ssl_check=True, legacy=True, **kwargs):
321329

322330
def what_activities(
323331
ssl_check=True,
324-
legacy=True,
332+
legacy=False,
325333
**kwargs,
326334
) -> tuple[DataFrame, WQP_Metadata]:
327335
"""Search WQP for activities within a region with specific data.
@@ -385,7 +393,7 @@ def what_activities(
385393

386394
def what_detection_limits(
387395
ssl_check=True,
388-
legacy=True,
396+
legacy=False,
389397
**kwargs,
390398
) -> tuple[DataFrame, WQP_Metadata]:
391399
"""Search WQP for result detection limits within a region with specific
@@ -435,8 +443,12 @@ def what_detection_limits(
435443
if legacy is True:
436444
url = wqp_url("ResultDetectionQuantitationLimit")
437445
else:
438-
print("WQX3.0 profile not available, returning legacy profile.")
439-
url = wqp_url("ResultDetectionQuantitationLimit")
446+
warnings.warn(
447+
"No WQX3.0 equivalent exists for this function; returning legacy data.",
448+
UserWarning,
449+
stacklevel=2,
450+
)
451+
url = wqp_url("ResultDetectionQuantitationLimit", warn=False)
440452

441453
response = query(url, payload=kwargs, delimiter=";", ssl_check=ssl_check)
442454

@@ -447,7 +459,7 @@ def what_detection_limits(
447459

448460
def what_habitat_metrics(
449461
ssl_check=True,
450-
legacy=True,
462+
legacy=False,
451463
**kwargs,
452464
) -> tuple[DataFrame, WQP_Metadata]:
453465
"""Search WQP for habitat metrics within a region with specific data.
@@ -490,8 +502,12 @@ def what_habitat_metrics(
490502
if legacy is True:
491503
url = wqp_url("BiologicalMetric")
492504
else:
493-
print("WQX3.0 profile not available, returning legacy profile.")
494-
url = wqp_url("BiologicalMetric")
505+
warnings.warn(
506+
"No WQX3.0 equivalent exists for this function; returning legacy data.",
507+
UserWarning,
508+
stacklevel=2,
509+
)
510+
url = wqp_url("BiologicalMetric", warn=False)
495511

496512
response = query(url, payload=kwargs, delimiter=";", ssl_check=ssl_check)
497513

@@ -500,7 +516,7 @@ def what_habitat_metrics(
500516
return df, WQP_Metadata(response)
501517

502518

503-
def what_project_weights(ssl_check=True, legacy=True, **kwargs):
519+
def what_project_weights(ssl_check=True, legacy=False, **kwargs):
504520
"""Search WQP for project weights within a region with specific data.
505521
506522
Any WQP API parameter can be passed as a keyword argument to this function.
@@ -546,8 +562,12 @@ def what_project_weights(ssl_check=True, legacy=True, **kwargs):
546562
if legacy is True:
547563
url = wqp_url("ProjectMonitoringLocationWeighting")
548564
else:
549-
print("WQX3.0 profile not available, returning legacy profile.")
550-
url = wqp_url("ProjectMonitoringLocationWeighting")
565+
warnings.warn(
566+
"No WQX3.0 equivalent exists for this function; returning legacy data.",
567+
UserWarning,
568+
stacklevel=2,
569+
)
570+
url = wqp_url("ProjectMonitoringLocationWeighting", warn=False)
551571

552572
response = query(url, payload=kwargs, delimiter=";", ssl_check=ssl_check)
553573

@@ -556,7 +576,7 @@ def what_project_weights(ssl_check=True, legacy=True, **kwargs):
556576
return df, WQP_Metadata(response)
557577

558578

559-
def what_activity_metrics(ssl_check=True, legacy=True, **kwargs):
579+
def what_activity_metrics(ssl_check=True, legacy=False, **kwargs):
560580
"""Search WQP for activity metrics within a region with specific data.
561581
562582
Any WQP API parameter can be passed as a keyword argument to this function.
@@ -602,8 +622,12 @@ def what_activity_metrics(ssl_check=True, legacy=True, **kwargs):
602622
if legacy is True:
603623
url = wqp_url("ActivityMetric")
604624
else:
605-
print("WQX3.0 profile not available, returning legacy profile.")
606-
url = wqp_url("ActivityMetric")
625+
warnings.warn(
626+
"No WQX3.0 equivalent exists for this function; returning legacy data.",
627+
UserWarning,
628+
stacklevel=2,
629+
)
630+
url = wqp_url("ActivityMetric", warn=False)
607631

608632
response = query(url, payload=kwargs, delimiter=";", ssl_check=ssl_check)
609633

@@ -612,11 +636,12 @@ def what_activity_metrics(ssl_check=True, legacy=True, **kwargs):
612636
return df, WQP_Metadata(response)
613637

614638

615-
def wqp_url(service):
639+
def wqp_url(service, warn=True):
616640
"""Construct the WQP URL for a given service."""
617641

618642
base_url = "https://www.waterqualitydata.us/data/"
619-
_warn_legacy_use()
643+
if warn:
644+
_warn_legacy_use()
620645

621646
if service not in services_legacy:
622647
raise TypeError(
@@ -631,7 +656,6 @@ def wqx3_url(service):
631656
"""Construct the WQP URL for a given WQX 3.0 service."""
632657

633658
base_url = "https://www.waterqualitydata.us/wqx3/"
634-
_warn_wqx3_use()
635659

636660
if service not in services_wqx3:
637661
raise TypeError(
@@ -705,20 +729,11 @@ def _check_kwargs(kwargs):
705729
return kwargs
706730

707731

708-
def _warn_wqx3_use():
709-
message = (
710-
"Support for the WQX3.0 profiles is experimental. "
711-
"Queries may be slow or fail intermitttently."
712-
)
713-
warnings.warn(message, UserWarning, stacklevel=2)
714-
715-
716732
def _warn_legacy_use():
717733
message = (
718-
"This function call will return the legacy WQX format, "
719-
"which means USGS data have not been updated since March 2024. "
720-
"Please review the dataretrieval-python documentation for more "
721-
"information on updated WQX3.0 profiles. Setting `legacy=False` "
722-
"will remove this warning."
734+
"You are explicitly requesting the legacy WQX format "
735+
"(legacy=True), which means USGS data have not been updated "
736+
"since March 2024. Remove legacy=True from your call to use "
737+
"the current WQX3.0 profiles."
723738
)
724739
warnings.warn(message, DeprecationWarning, stacklevel=2)

tests/wqp_test.py

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@
1818

1919

2020
def test_get_results(requests_mock):
21-
"""Tests water quality portal ratings query"""
21+
"""Tests water quality portal results query using the default WQX3.0 profile"""
2222
request_url = (
23-
"https://www.waterqualitydata.us/data/Result/Search?siteid=WIDNR_WQX-10032762"
23+
"https://www.waterqualitydata.us/wqx3/Result/search?siteid=WIDNR_WQX-10032762"
2424
"&characteristicName=Specific+conductance&startDateLo=05-01-2011&startDateHi=09-30-2011"
2525
"&mimeType=csv"
26+
"&dataProfile=fullPhysChem"
2627
)
27-
response_file_path = "tests/data/wqp_results.txt"
28+
response_file_path = "tests/data/wqp3_results.txt"
2829
mock_request(requests_mock, request_url, response_file_path)
2930
df, md = get_results(
3031
siteid="WIDNR_WQX-10032762",
@@ -33,42 +34,39 @@ def test_get_results(requests_mock):
3334
startDateHi="09-30-2011",
3435
)
3536
assert type(df) is DataFrame
36-
assert df.size == 315
37+
assert df.size == 900
3738
assert md.url == request_url
3839
assert isinstance(md.query_time, datetime.timedelta)
3940
assert md.header == {"mock_header": "value"}
4041
assert md.comment is None
4142

4243

43-
def test_get_results_WQX3(requests_mock):
44-
"""Tests water quality portal results query with new WQX3.0 profile"""
44+
def test_get_results_legacy(requests_mock):
45+
"""Tests water quality portal results query with explicit legacy=True"""
4546
request_url = (
46-
"https://www.waterqualitydata.us/wqx3/Result/search?siteid=WIDNR_WQX-10032762"
47+
"https://www.waterqualitydata.us/data/Result/Search?siteid=WIDNR_WQX-10032762"
4748
"&characteristicName=Specific+conductance&startDateLo=05-01-2011&startDateHi=09-30-2011"
4849
"&mimeType=csv"
49-
"&dataProfile=fullPhysChem"
5050
)
51-
response_file_path = "tests/data/wqp3_results.txt"
51+
response_file_path = "tests/data/wqp_results.txt"
5252
mock_request(requests_mock, request_url, response_file_path)
53-
df, md = get_results(
54-
legacy=False,
55-
siteid="WIDNR_WQX-10032762",
56-
characteristicName="Specific conductance",
57-
startDateLo="05-01-2011",
58-
startDateHi="09-30-2011",
59-
)
53+
with pytest.warns(DeprecationWarning, match="legacy=True"):
54+
df, md = get_results(
55+
legacy=True,
56+
siteid="WIDNR_WQX-10032762",
57+
characteristicName="Specific conductance",
58+
startDateLo="05-01-2011",
59+
startDateHi="09-30-2011",
60+
)
6061
assert type(df) is DataFrame
61-
assert df.size == 900
62+
assert df.size == 315
6263
assert md.url == request_url
63-
assert isinstance(md.query_time, datetime.timedelta)
64-
assert md.header == {"mock_header": "value"}
65-
assert md.comment is None
6664

6765

6866
def test_what_sites(requests_mock):
69-
"""Tests Water quality portal sites query"""
67+
"""Tests Water quality portal sites query using the default WQX3.0 profile"""
7068
request_url = (
71-
"https://www.waterqualitydata.us/data/Station/Search?statecode=US%3A34&characteristicName=Chloride"
69+
"https://www.waterqualitydata.us/wqx3/Station/search?statecode=US%3A34&characteristicName=Chloride"
7270
"&mimeType=csv"
7371
)
7472
response_file_path = "tests/data/wqp_sites.txt"
@@ -117,9 +115,9 @@ def test_what_projects(requests_mock):
117115

118116

119117
def test_what_activities(requests_mock):
120-
"""Tests Water quality portal activities query"""
118+
"""Tests Water quality portal activities query using the default WQX3.0 profile"""
121119
request_url = (
122-
"https://www.waterqualitydata.us/data/Activity/Search?statecode=US%3A34&characteristicName=Chloride"
120+
"https://www.waterqualitydata.us/wqx3/Activity/search?statecode=US%3A34&characteristicName=Chloride"
123121
"&mimeType=csv"
124122
)
125123
response_file_path = "tests/data/wqp_activities.txt"

0 commit comments

Comments
 (0)