Client#
SGUClient is the entry point for every request. Endpoints are grouped by domain
on its attributes:
Attribute |
Client |
|---|---|
|
|
|
|
|
See Getting started for an introduction.
SGUClient#
- class SGUClient(config=None, *, transport=None)[source]#
Main client for interacting with SGU API.
This is the primary interface users will interact with.
Use it as a context manager so the HTTP session is closed when you are done. If the client has to outlive a
withblock, callclose()yourself.Example
>>> with SGUClient() as client: ... stations = client.levels.observed.get_stations() ... measurements = client.levels.observed.get_measurements()
>>> # With custom config >>> config = SGUConfig(timeout=60, log_level="DEBUG") >>> with SGUClient(config=config) as client: ... stations = client.levels.observed.get_stations()
- __init__(config=None, *, transport=None)[source]#
Initialize the SGU client.
- Parameters:
config (
SGUConfig|None) – Configuration object. If None, uses default config.transport (
Transport|None) – Where requests go. If None, the client talks to SGU over the network with aRequestsTransportbuilt fromconfig, and closes it inclose(). A transport you pass in is yours to close, and the network settings inconfig(timeout,max_retries,user_agent) don’t apply to it.
- close()[source]#
Close the underlying HTTP session and its pooled connections.
Called automatically when the client is used as a context manager. Call it yourself when you create the client without a
withblock.- Return type:
LevelsClient#
- class LevelsClient(base_client)[source]#
Client for accessing groundwater level data.
Provides access to both observed and modeled groundwater levels through a hierarchical API structure.
Example
>>> with SGUClient() as client: ... stations = client.levels.observed.get_stations() ... areas = client.levels.modeled.get_areas() ... levels = client.levels.modeled.get_levels()
Transports#
Every request goes through a Transport. By default that’s a
RequestsTransport, which talks to SGU over the network using the timeout,
max_retries and user_agent from SGUConfig.
Pass your own transport to serve responses from somewhere else, for example canned
pages in your tests. A transport has one method, fetch, which returns the status and
body of one response; the client still handles errors, JSON and pagination:
import json
from sgu_client import SGUClient, TransportResponse
class CannedTransport:
def __init__(self, page: dict):
self.page = page
def fetch(self, url, params):
return TransportResponse(200, json.dumps(self.page))
client = SGUClient(transport=CannedTransport(my_station_page))
stations = client.levels.observed.get_stations()
A transport you pass in is yours to close; SGUClient.close() only closes the
transport the client created.
- class Transport(*args, **kwargs)[source]#
Fetches one response from SGU.
The client builds the URL and query params, then decides what the response means: it turns error statuses into
SGUAPIError, parses the JSON and requests further pages.A transport raises
SGUTimeoutErrororSGUConnectionErrorwhen it can’t get a response at all.
- class TransportResponse(status_code, text)[source]#
What SGU sent back for one request.
- status_code#
HTTP status code, e.g.
200or404
- text#
Response body, usually JSON
- class RequestsTransport(config=None)[source]#
The default transport: GET requests to SGU with the
requestslibrary.Uses
timeout,max_retriesanduser_agentfrom the config. Retries on 429 and 5xx responses with exponential backoff.- fetch(url, params)[source]#
GET
urlwith queryparamsand return the response.- Raises:
SGUTimeoutError – If connecting or reading times out.
SGUConnectionError – If SGU can’t be reached.
SGUAPIError – If the request fails in any other way.
- Return type: