Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 77 additions & 7 deletions cwms/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
API_ROOT = "https://cwms-data.usace.army.mil/cwms-data/"
API_VERSION = 2

# Specify whether LRTS will use new ID format
USE_NEW_LRTS_IDS = False

# Initialize a non-authenticated session with the default root URL and set default pool connections.

retry_strategy = Retry(
Expand Down Expand Up @@ -168,6 +171,7 @@ def init_session(
api_key: Optional[str] = None,
token: Optional[str] = None,
pool_connections: int = 100,
use_new_lrts_format: bool = False,
) -> BaseUrlSession:
"""Specify a root URL and authentication credentials for the CWMS Data API.

Expand All @@ -186,7 +190,7 @@ def init_session(
Returns the updated session object.
"""

global SESSION
global SESSION, USE_NEW_LRTS_IDS
if api_root:
# Ensure the API_ROOT ends with a single slash
api_root = api_root.rstrip("/") + "/"
Expand All @@ -206,11 +210,23 @@ def init_session(
# Ensure we don't provide the bearer text twice
if token.lower().startswith("bearer "):
token = token[7:]
SESSION.headers.update({"Authorization": "Bearer " + token})
SESSION.headers.update(
{
"Authorization": "Bearer " + token,
"X-CWMS-LRTS-Formatting": str(USE_NEW_LRTS_IDS).lower(),
}
)
elif api_key:
if api_key.startswith("apikey "):
api_key = api_key.replace("apikey ", "")
SESSION.headers.update({"Authorization": "apikey " + api_key})
SESSION.headers.update(
{
"Authorization": "apikey " + api_key,
"X-CWMS-LRTS-Formatting": str(USE_NEW_LRTS_IDS).lower(),
}
)

USE_NEW_LRTS_IDS = use_new_lrts_format

return SESSION

Expand All @@ -225,6 +241,46 @@ def return_base_url() -> str:
return str(SESSION.base_url)


def set_use_new_lrts_ids(state: bool) -> None:
"""Sets whether the new LRTS identifer format is used for subsequent operations.

The old Local Regular Time Series (LRTS) identifier format is the same as the
Pseudo-Regular Time Series (PRTS) identifier format, where both prepend a tilde
character ('~') to valid Regular Time Series (RTS) interval identifiers (e.g.,
~6Hours, ~1Day).

The new LRTS identifiers instead append "Local" to valid RTS interval identifiers
(e.g., 6HoursLocal, 1DayLocal), leaving the old format to specify only PRTS.

Args:
state: Whether the new LRTS identifier format is used
"""

global USE_NEW_LRTS_IDS

USE_NEW_LRTS_IDS = state


def get_use_new_lrts_ids() -> bool:
"""Gets whether the new LRTS identifer format is used for subsequent operations.

The old Local Regular Time Series (LRTS) identifier format is the same as the
Pseudo-Regular Time Series (PRTS) identifier format, where both prepend a tilde
character ('~') to valid Regular Time Series (RTS) interval identifiers (e.g.,
~6Hours, ~1Day).

The new LRTS identifiers instead append "Local" to valid RTS interval identifiers
(e.g., 6HoursLocal, 1DayLocal), leaving the old format to specify only PRTS.

Returns:
Whether the new LRTS identifier format is used
"""

global USE_NEW_LRTS_IDS

return USE_NEW_LRTS_IDS


def api_version_text(api_version: int) -> str:
"""Initialize CDA request headers.

Expand Down Expand Up @@ -329,7 +385,10 @@ def get(
ApiError: If an error response is return by the API.
"""

headers = {"Accept": api_version_text(api_version)}
headers = {
"Accept": api_version_text(api_version),
"X-CWMS-LRTS-Formatting": str(USE_NEW_LRTS_IDS).lower(),
}
try:
with SESSION.get(endpoint, params=params, headers=headers) as response:
if not response.ok:
Expand Down Expand Up @@ -389,7 +448,11 @@ def _post_function(
) -> Any:

# post requires different headers than get for
headers = {"accept": "*/*", "Content-Type": api_version_text(api_version)}
headers = {
"accept": "*/*",
"Content-Type": api_version_text(api_version),
"X-CWMS-LRTS-Formatting": str(USE_NEW_LRTS_IDS).lower(),
}
if isinstance(data, dict) or isinstance(data, list):
data = json.dumps(data)
try:
Expand Down Expand Up @@ -487,7 +550,11 @@ def patch(
ApiError: If an error response is return by the API.
"""

headers = {"accept": "*/*", "Content-Type": api_version_text(api_version)}
headers = {
"accept": "*/*",
"Content-Type": api_version_text(api_version),
"X-CWMS-LRTS-Formatting": str(USE_NEW_LRTS_IDS).lower(),
}

if data and isinstance(data, dict) or isinstance(data, list):
data = json.dumps(data)
Expand Down Expand Up @@ -522,7 +589,10 @@ def delete(
ApiError: If an error response is return by the API.
"""

headers = {"Accept": api_version_text(api_version)}
headers = {
"Accept": api_version_text(api_version),
"X-CWMS-LRTS-Formatting": str(USE_NEW_LRTS_IDS).lower(),
}
try:
with SESSION.delete(endpoint, params=params, headers=headers) as response:
if not response.ok:
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "cwms-python"
repository = "https://github.com/HydrologicEngineeringCenter/cwms-python"

version = "1.0.8"
version = "1.0.9"

packages = [
{ include = "cwms" },
Expand Down Expand Up @@ -43,3 +43,4 @@ comments_min_spaces_from_content = 1
whitelines = 1
explicit_start = false
preserve_quotes = true

Loading