Skip to main content

CWMSpy

CWMS REST API for Data Retrieval

Requirements.

Python 3.9+

Installation & Usage

pip install

pip install cwms-python

For users on Python 3.11+ who want the pandas 3.x stack, install into a fresh virtual environment and upgrade pandas explicitly:

python3.11 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
pip install cwms-python "pandas>=3,<4"

This keeps the default package install stable while allowing a modern Python environment to use pandas 3.x.

Then import the package:

import cwms

Authentication

cwms.init_session() supports both CDA API keys and Keycloak access tokens. Use api_key= for the headless CDA API key flow, or token= for an OIDC access token such as one saved by cwms-cli login.

import cwms

cwms.init_session(
    api_root="https://cwms-data.usace.army.mil/cwms-data/",
    token="ACCESS_TOKEN",
)

If both token and api_key are provided, cwms-python will use the token and log a warning.

HTTP connection pools

Sessions created with cwms.init_session(api_root=..., pool_connections=100) configure the same connection pool size and retry policy for HTTP and HTTPS. This includes unencrypted internal HTTP CDA roots used by Batch jobs. The default pool retains up to 100 connections per host for reuse; it does not cap concurrent requests. Set pool_connections when creating the session to size that pool for your workload. A Connection pool is full, discarding connection warning means an extra connection is being closed instead of retained, not that a response or its data was discarded. Check raised exceptions for actual request failures.

Errors and debugging

Failed HTTP requests raise cwms.api.ApiError. Its message includes the HTTP status, method, URL, and CDA response body (including incident details when provided). The original response is available as error.response. Custom user-management errors retain these details too. Network exceptions propagate with their original type. Invalid JSON responses raise ApiError with the decoding exception as the cause; empty response bodies return an empty dictionary.

Concurrent time-series reads and writes raise cwms.api.BatchError if any series or chunk fails. It subclasses RuntimeError, and error.failures contains (series_or_chunk, original_exception) pairs for every failure. Reads do not return incomplete results as success. Successful writes are not rolled back. Failures while looking up time-series extents also propagate. Chunk retries are limited to connection errors, timeouts, and HTTP 429/500/502/503/504; validation and other permanent errors fail immediately at the chunk layer. The shared HTTP adapter retains its existing retry policy.

Enable request outcome and chunk diagnostics with Python logging:

import logging

logging.basicConfig(level=logging.WARNING)
logging.getLogger("cwms").setLevel(logging.DEBUG)

Request diagnostics include the method, endpoint, and response status, without request bodies or authentication headers.

Getting Started

import cwms
from datetime import datetime, timedelta

end = datetime.now()
begin = end - timedelta(days = 10)
data = cwms.get_timeseries(ts_id='Some.Fully.Qualified.Ts.Id',office_id='OFFICE1' , begin = begin, end = end)

#a cwms data object will be provided this object containes both the JSON as well
#as the values converted into a dataframe

#display the dataframe

df = data.df
print(df)
     date-time 	value 	quality-code
0 	2024-04-23 08:15:00 	86.57 	3
1 	2024-04-23 08:30:00 	86.57 	3
2 	2024-04-23 08:45:00 	86.58 	3
3 	2024-04-23 09:00:00 	86.58 	3
4 	2024-04-23 09:15:00 	86.58 	3
5 	2024-04-23 09:30:00 	86.58 	3
6 	2024-04-23 09:45:00 	86.59 	3
7 	2024-04-23 10:00:00 	86.58 	3
#display JSON
json = data.JSON
print(json)
{'name': 'Some.Fully.Qualified.Ts.Id',
 'office-id': 'MVP',
 'units': 'ft',
 'values': [['2024-04-23T08:15:00', 86.57, 3],
  ['2024-04-23T08:30:00', 86.57, 3],
  ['2024-04-23T08:45:00', 86.57999999999997, 3],
  ['2024-04-23T09:00:00', 86.57999999999997, 3],
  ['2024-04-23T09:15:00', 86.57999999999997, 3],
  ['2024-04-23T09:30:00', 86.57999999999997, 3],
  ['2024-04-23T09:45:00', 86.59, 3],
  ['2024-04-23T10:00:00', 86.57999999999997, 3]],
 'version-date': None}

TimeSeries Profile API Compatibility Warning

Currently, the TimeSeries Profile API may not be fully supported until a new version of cwms-data-access is released with the updated endpoint implementation.

Contributing

Please view the contribution documentation here: [CONTRIBUTING.md]

Contributing and releases

See CONTRIBUTING.md for development checks, PR title conventions, and the Release Please publishing workflow.

Metadata

Release files for cwms-python 1.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cwms-python 1.1.4
File Size Uploaded
cwms_python-1.1.4.tar.gz 51.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cwms-python 1.1.4
File Interpreter ABI Platform
cwms_python-1.1.4-py3-none-any.whl Python 3 none any Details

Total release size: 131.1 kB

Release files / cwms_python-1.1.4.tar.gz

Download URL cwms_python-1.1.4.tar.gz
Size 51.9 kB
Tags Source
SHA-256 checksum
How to use checksums
3e471bda1b2749cfd356427c4f935629fde4df58f6060f0328e5b2d9e3e81d22
BLAKE2b-256 checksum
How to use checksums
d93905dce768695750b5b86b6933f29562d4cf7220374f5e927d5ec0fd8b372f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / cwms_python-1.1.4-py3-none-any.whl

Download URL cwms_python-1.1.4-py3-none-any.whl
Size 79.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
679898d9f796406f6b59d441ccf79e2602465792128d7b0dd404a25e7bcfc2b2
BLAKE2b-256 checksum
How to use checksums
8aa9f565047978985a4d18e7eb4bf9225863ae9a3caebc6d60db7821c53dc5f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.4 This release

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.10

2 release files

1.0.9

2 release files

1.0.8

2 release files

1.0.7

2 release files

1.0.3

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.4

2 release files

0.3.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page