This project has been archived by its maintainers, and is no longer receiving any updates.
NWIS Data Downloader
A Python package to fetch and process daily USGS National Water Information System (NWIS) data. Supports batch downloading across many sites and parameters, dynamic parameter code discovery, and filtering for data quality.
Features
- Dynamic Parameter Discovery – Fetch and search all USGS parameter codes (e.g., discharge, sediment, temperature).
- Batch Fetching – Robust multi-site downloads with progress bars and retries.
- Data Processing – Convert NWIS JSON responses into tidy Pandas DataFrames.
- Filtering Tools – Keep only sites with sufficient data for desired variables.
- Robust & Safe – Handles rate limits, errors, and empty responses gracefully.
Installation
pip install nwis-data-downloader
Or install from source:
git clone https://github.com/bluerrror/NWIS_Data_Downloader.git
cd NWIS_Data_Downloader
pip install -e .
Requirements: Python ≥ 3.8, plus requests, pandas, tqdm.
Common Parameter Codes
Some frequently used USGS parameter codes (from USGS documentation):
| Parameter Code | Short Name | Description | Units |
|---|---|---|---|
| 00010 | Temperature | Water temperature | °C |
| 00060 | Discharge | Streamflow discharge | ft³/s |
| 00065 | Gage Height | Gage height | ft |
| 00045 | Precipitation | Precipitation depth | in |
| 00400 | pH | pH value | unitless |
| 00630 | Nitrate | Nitrogen, nitrate | mg/L as N |
| 00631 | Nitrate + Nitrite | Nitrate plus nitrite | mg/L as N |
| 80155 | Suspended Sediment | Suspended sediment concentration | mg/L |
For a complete list, call:
get_usgs_parameters()
Quickstart
1. Discover and Search Parameters
from usgs_data_fetcher import get_usgs_parameters, search_parameters
params_df = get_usgs_parameters()
print(f"Total parameters: {len(params_df)}")
# Search for discharge-related parameters
discharge_params = search_parameters(params_df, 'discharge')
print(discharge_params[['parm_cd', 'parameter_nm', 'parameter_unit']].head())
# Example: search for temperature or pH
wq_params = search_parameters(params_df, 'temperature OR pH', columns=['parameter_nm'])
print(f"Water Quality Matches: {len(wq_params)}")
2. Fetch Data for a Single Site
from usgs_data_fetcher import fetch_usgs_daily, usgs_json_to_df
site = '01491000'
json_data = fetch_usgs_daily(
sites=[site],
parameter_codes=['00060'], # Discharge
start='2024-01-01',
end='2025-01-01'
)
df = usgs_json_to_df(json_data)
print(df.head())
print(df.shape)
3. Batch Fetch with Filtering
from usgs_data_fetcher import fetch_batch_usgs_data
sites = [
'01491000',
'01646500',
'09522500'
]
selected_codes = ['00060', '80155'] # Discharge + Suspended Sediment
data_df = fetch_batch_usgs_data(
sites=sites,
parameter_codes=selected_codes,
start='2000-01-01',
end='2025-01-01',
required_params=['80155'],
min_records=100,
batch_size=10
)
print(data_df.shape)
print(data_df.describe())
4. Interactive Parameter Selection
import pandas as pd
from usgs_data_fetcher import get_usgs_parameters, search_parameters
params_df = get_usgs_parameters()
query = input("Enter search term (e.g., 'sediment'): ").strip()
matches = search_parameters(params_df, query)
if not matches.empty:
print(matches[['parm_cd', 'parameter_nm']].to_string(index=False))
codes = input("Enter comma-separated codes (or 'all'): ").strip()
selected_codes = matches['parm_cd'].tolist() if codes.lower() == 'all' else [c.strip() for c in codes.split(',')]
print(f"Selected: {selected_codes}")
else:
print("No matches found.")
selected_codes = ['00060'] # Default
5. Save & Visualize Data
import matplotlib.pyplot as plt
data_df.to_csv('usgs_hydrology_data.csv', index=False)
data_df['time'] = pd.to_datetime(data_df['time'])
plt.figure(figsize=(12, 6))
for site in data_df['site_no'].unique()[:2]:
site_data = data_df[data_df['site_no'] == site]
plt.plot(site_data['time'], site_data['00060'], label=f'Site {site}')
plt.xlabel('Date')
plt.ylabel('Discharge (cfs)')
plt.title('Daily Streamflow Trends')
plt.legend()
plt.savefig('discharge_plot.png')
plt.show()
API Reference
Core Functions
fetch_usgs_daily(sites, parameter_codes, ...)— Fetch raw NWIS daily JSON data.usgs_json_to_df(json_data)— Convert JSON to tidy DataFrame.fetch_batch_usgs_data(sites, parameter_codes, ...)— Multi-site batch fetch with filtering.
Parameter Utilities
get_usgs_parameters()— Download complete parameter catalog.search_parameters(params_df, query, ...)— Query parameters by keyword.
Full documentation can be found in fetcher.py and parameters.py.
Examples
- Water Quality Batch: Use
['00010', '00400']for temperature + pH. - Precipitation Analysis: Use
['00045']for precipitation depth. - Large-Scale Fetching: Set
batch_size=200for thousands of sites. - Error Handling: Wrap fetches in
try/exceptfor production pipelines.
Contributing
- Fork the repo
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit changes:
git commit -m "Add amazing feature"
- Push:
git push origin feature/amazing-feature
- Open a Pull Request
License
MIT License — see LICENSE for details.
Acknowledgments
Built on the excellent USGS NWIS API:
https://waterservices.usgs.gov
Release files for nwis-data-downloader 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nwis_data_downloader-0.1.2.tar.gz | 8.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nwis_data_downloader-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.4 kB
Release files / nwis_data_downloader-0.1.2.tar.gz
| Download URL | nwis_data_downloader-0.1.2.tar.gz |
|---|---|
| Size | 8.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
96c1b12be68f889c04b071482b7d3597d58eee2ac431a28944cf314da97691f1
|
|
BLAKE2b-256 checksum How to use checksums |
dbbb7f543a06cce1bd2aa5346b0e6b9c52fbb37b69b40a6305a203dfb67eeb95
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / nwis_data_downloader-0.1.2-py3-none-any.whl
| Download URL | nwis_data_downloader-0.1.2-py3-none-any.whl |
|---|---|
| Size | 9.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c416e9ebc5ac33e335ea104005e6976ae2bb86a260cbc40c562bcb80d94fad69
|
|
BLAKE2b-256 checksum How to use checksums |
d9a8a8603b19187f6f9b09edee775d0ec5aea545605616128ba5b87a64b07386
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|