def get_json(self, endpoint: str, kwds: Dict[str, str], request_method: str = "GET") -> gpd.GeoDataFrame: """Get the JSON response from the Water Quality Web Service. Parameters ---------- endpoint : str Endpoint of the Water Quality Web Service. kwds : dict Water Quality Web Service keyword arguments. request_method : str, optional HTTP request method. Default to GET. Returns ------- geopandas.GeoDataFrame The web service response as a GeoDataFrame. """ req_kwds = [{ "params": kwds }] if request_method == "GET" else [{ "data": kwds }] return geoutils.json2geodf( ar.retrieve_json( [self._base_url(endpoint)], req_kwds, request_method=request_method, expire_after=self.expire_after, disable=self.disable_caching, ))
def _get_streamflow(self, sids: Sequence[str], start_dt: str, end_dt: str, freq: str, kwargs: Dict[str, str]) -> pd.DataFrame: """Convert json to dataframe.""" payloads = [{ "sites": ",".join(s), "startDT": start_dt, "endDT": end_dt, **kwargs, } for s in tlz.partition_all(1500, sids)] resp = ar.retrieve_json( [f"{self.url}/{freq}"] * len(payloads), [{ "params": p } for p in payloads], expire_after=self.expire_after, disable=self.disable_caching, ) def get_site_id(site_cd: Dict[str, str]) -> str: """Get site id.""" return f"{site_cd['agencyCode']}-{site_cd['value']}" r_ts = { get_site_id(t["sourceInfo"]["siteCode"][0]): t["values"][0]["value"] for r in resp for t in r["value"]["timeSeries"] if len(t["values"][0]["value"]) > 0 } if len(r_ts) == 0: raise DataNotAvailable("discharge") def to_df(col: str, values: Dict[str, Any]) -> pd.DataFrame: discharge = pd.DataFrame.from_records(values, exclude=["qualifiers"], index=["dateTime"]) discharge.index = pd.to_datetime(discharge.index, infer_datetime_format=True) if discharge.index.tz is None: tz = resp[0]["value"]["timeSeries"][0]["sourceInfo"][ "timeZoneInfo"] tz_dict = { "CST": "US/Central", "MST": "US/Mountain", "PST": "US/Pacific", "EST": "US/Eastern", } time_zone = tz_dict.get( tz["defaultTimeZone"]["zoneAbbreviation"], tz["defaultTimeZone"]["zoneAbbreviation"], ) discharge.index = discharge.index.tz_localize(time_zone) discharge.index = discharge.index.tz_convert("UTC") discharge.columns = [col] return discharge qobs = pd.concat([to_df(s, t) for s, t in r_ts.items()], axis=1) # Convert cfs to cms return qobs.astype("float64") * 0.028316846592
def _get_json( self, urls: Sequence[str], params: Optional[List[Dict[str, str]]] = None) -> List[Dict[str, Any]]: """Get JSON response from NID web service. Parameters ---------- urls : list of str A list of query URLs. params : dict, optional A list of parameters to pass to the web service, defaults to ``None``. Returns ------- list of dict List of JSON responses from the web service. """ if not isinstance(urls, list): raise InvalidInputType("urls", "list or str") if params is None: kwds = None else: kwds = [{"params": {**p, "out": "json"}} for p in params] resp = ar.retrieve_json( urls, kwds, expire_after=self.expire_after, disable=self.disable_caching, ) if len(resp) == 0: raise ZeroMatched failed = [(i, f"Req_{i}: {r['message']}") for i, r in enumerate(resp) if "error" in r] if failed: idx, err_msgs = zip(*failed) errs = " service requests failed with the following messages:\n" errs += "\n".join(err_msgs) if len(failed) == len(urls): raise ZeroMatched(f"All{errs}") resp = [r for i, r in enumerate(resp) if i not in idx] logger.warning(f"Some{errs}") return resp
def __init__( self, expire_after: float = EXPIRE, disable_caching: bool = False, ) -> None: self.base_url = ServiceURL().restful.nid self.suggest_url = f"{self.base_url}/suggestions" self.expire_after = expire_after self.disable_caching = disable_caching self.fields_meta = pd.DataFrame( ar.retrieve_json( [f"{self.base_url}/advanced-fields"], expire_after=self.expire_after, disable=self.disable_caching, )[0]) self.valid_fields = self.fields_meta.name.to_list() self.dam_type = { -1: "N/A", 1: "Arch", 2: "Buttress", 3: "Concrete", 4: "Earth", 5: "Gravity", 6: "Masonry", 7: "Multi-Arch", 8: "Rockfill", 9: "Roller-Compacted Concrete", 10: "Stone", 11: "Timber Crib", 12: "Other", } self.dam_purpose = { -1: "N/A", 1: "Debris Control", 2: "Fire Protection, Stock, Or Small Farm Pond", 3: "Fish and Wildlife Pond", 4: "Flood Risk Reduction", 5: "Grade Stabilization", 6: "Hydroelectric", 7: "Irrigation", 8: "Navigation", 9: "Recreation", 10: "Tailings", 11: "Water Supply", 12: "Other", }
def lookup_domain_values(self, endpoint: str) -> List[str]: """Get the domain values for the target endpoint.""" valid_endpoints = [ "statecode", "countycode", "sitetype", "organization", "samplemedia", "characteristictype", "characteristicname", "providers", ] if endpoint.lower() not in valid_endpoints: raise InvalidInputValue("endpoint", valid_endpoints) resp = ar.retrieve_json( [f"{self.wq_url}/Codes/{endpoint}?mimeType=json"], expire_after=self.expire_after, disable=self.disable_caching, ) return [r["value"] for r in resp[0]["codes"]]