11"""
2- Tool for downloading data from the Water Quality Portal (https://waterqualitydata.us)
2+ Tool for downloading data from the USGS Aquarius Samples database (https://waterqualitydata.us)
33
4- See https://waterqualitydata.us/webservices_documentation for API reference
5-
6- .. todo::
7-
8- - implement other services like Organization, Activity, etc.
4+ See https://api.waterdata.usgs.gov/samples-data/docs#/ for API reference
95
106"""
117
128from __future__ import annotations
139
1410import warnings
1511import requests
12+ from requests .models import PreparedRequest
1613from io import StringIO
1714from typing import TYPE_CHECKING
1815
1916import pandas as pd
2017
21- # from . utils import BaseMetadata, query
18+ from utils import BaseMetadata , query
2219
2320if TYPE_CHECKING :
2421 from pandas import DataFrame
@@ -68,31 +65,32 @@ def _check_profiles(
6865 )
6966
7067def get_USGS_samples (
71- service = "results" ,
72- profile = "fullphyschem" ,
73- activityMediaName = None ,
74- activityStartDateLower = None ,
75- activityStartDateUpper = None ,
76- activityTypeCode = None ,
77- characteristicGroup = None ,
78- characteristc = None ,
79- characteristicUserSupplied = None ,
80- boundingBox = None ,
81- countryFips = None ,
82- stateFips = None ,
83- countyFips = None ,
84- siteTypeCode = None ,
85- siteTypeName = None ,
86- usgsPCode = None ,
87- hydrologicUnit = None ,
88- monitoringLocationIdentifier = None ,
89- organizationIdentifier = None ,
90- pointLocationLatitude = None ,
91- pointLocationLongitude = None ,
92- pointLocationWithinMiles = None ,
93- projectIdentifier = None ,
94- recordIdentifierUserSupplied = None ,
95- mimeType = "text/csv"
68+ ssl_check = True ,
69+ service = "results" ,
70+ profile = "fullphyschem" ,
71+ activityMediaName = None ,
72+ activityStartDateLower = None ,
73+ activityStartDateUpper = None ,
74+ activityTypeCode = None ,
75+ characteristicGroup = None ,
76+ characteristc = None ,
77+ characteristicUserSupplied = None ,
78+ boundingBox = None ,
79+ countryFips = None ,
80+ stateFips = None ,
81+ countyFips = None ,
82+ siteTypeCode = None ,
83+ siteTypeName = None ,
84+ usgsPCode = None ,
85+ hydrologicUnit = None ,
86+ monitoringLocationIdentifier = None ,
87+ organizationIdentifier = None ,
88+ pointLocationLatitude = None ,
89+ pointLocationLongitude = None ,
90+ pointLocationWithinMiles = None ,
91+ projectIdentifier = None ,
92+ recordIdentifierUserSupplied = None ,
93+ mimeType = "text/csv"
9694):
9795 """Search Samples database for USGS water quality data.
9896 This is a wrapper function for the Samples database API. All potential
@@ -111,21 +109,23 @@ def get_USGS_samples(
111109
112110 Parameters
113111 ----------
112+ ssl_check : bool, optional
113+ Check the SSL certificate.
114114 service : string
115115 One of the available Samples services: "results", "locations", "activities",
116116 "projects", or "organizations". Defaults to "results".
117117 profile : string
118118 One of the available profiles associated with a service. Options for each
119119 service are:
120- " results" - "fullphyschem", "basicphyschem",
120+ results - "fullphyschem", "basicphyschem",
121121 "fullbio", "basicbio", "narrow",
122122 "resultdetectionquantitationlimit",
123123 "labsampleprep", "count"
124- " locations" - "site", "count"
125- " activities" - "sampact", "actmetric",
124+ locations - "site", "count"
125+ activities - "sampact", "actmetric",
126126 "actgroup", "count"
127- " projects" - "project", "projectmonitoringlocationweight"
128- " organizations" - "organization", "count"
127+ projects - "project", "projectmonitoringlocationweight"
128+ organizations - "organization", "count"
129129 activityMediaName : string or list of strings, optional
130130 Name or code indicating environmental medium sample was taken.
131131 Example: "Water".
@@ -150,7 +150,7 @@ def get_USGS_samples(
150150 Example: "Suspended Sediment Discharge"
151151 characteristicUserSupplied : string or list of strings, optional
152152 A user supplied characteristic name describing one or more results.
153- boundingBox: list of four floats, optional
153+ boundingBox: string of four floats, optional
154154 Filters on the the associated monitoring location's point location
155155 by checking if it is located within the specified geographic area.
156156 The logic is inclusive, i.e. it will include locations that overlap
@@ -162,7 +162,7 @@ def get_USGS_samples(
162162 - Southern-most latitude
163163 - Eastern-most longitude
164164 - Northern-most longitude
165- Example: [ -92.8,44.2,-88.9,46.0]
165+ Example: ' -92.8,44.2,-88.9,46.0'
166166 countryFips : string or list of strings, optional
167167 Example: "US" (United States)
168168 stateFips : string or list of strings, optional
@@ -210,19 +210,55 @@ def get_USGS_samples(
210210 Internal AQS record identifier that returns 1 entry. Only available
211211 for the "results" service.
212212 mimeType : string, optional
213+
214+ Returns
215+ -------
216+ df : ``pandas.DataFrame``
217+ Formatted data returned from the API query.
218+ md : :obj:`dataretrieval.utils.Metadata`
219+ Custom ``dataretrieval`` metadata object pertaining to the query.
220+
221+ Examples
222+ --------
223+ .. code::
224+
225+ >>> # Get PFAS results within a bounding box
226+ >>> df, md = dataretrieval.samples.get_USGS_samples(
227+ ... boundingBox="-90.2,42.6,-88.7,43.2",
228+ ... characteristicGroup="Organics, PFAS"
229+ ... )
213230
231+ >>> # Get all activities for the Commonwealth of Virginia over a date range
232+ >>> df, md = dataretrieval.samples.get_USGS_samples(
233+ ... service="activities",
234+ ... profile="sampact",
235+ ... activityStartDateLower="2023-10-01",
236+ ... activityStartDateUpper="2024-01-01",
237+ ... stateFips="US:51")
214238
215239 """
216240 _check_profiles (service , profile )
217241
218242 # Get all not-None inputs
219- params = {key : value for key , value in locals ().items () if value is not None and key not in ['service' , 'profile' ]}
243+ params = {key : value for key , value in locals ().items () if value is not None and key not in ['service' , 'profile' , 'ssl_check' ]}
244+
245+ if len (params ) == 1 and 'mimeType' in params :
246+ raise TypeError ("No filter parameters provided. You must add at least "
247+ "one filter parameter beyond a service, profile, and format argument." )
220248
221249 # Build URL with service and profile
222250 url = BASE_URL + service + "/" + profile
251+
252+ # Print URL
253+ req = PreparedRequest ()
254+ req .prepare_url (url , params = params )
255+ print (f"Request: { req .url } " )
256+
223257 # Make a GET request with the filtered parameters
224- response = requests .get (url , params = params )
258+ response = query (url , params , delimiter = ";" , ssl_check = ssl_check )
259+
260+ df = pd .read_csv (StringIO (response .text ), delimiter = "," )
225261
226- return response
262+ return df , BaseMetadata ( response )
227263
228264
0 commit comments