Skip to main content
Archived

This project has been archived by its maintainers, and is no longer receiving any updates.

NWIS Data Downloader

PyPI version License: MIT Python Versions

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=200 for thousands of sites.
  • Error Handling: Wrap fetches in try/except for production pipelines.

Contributing

  1. Fork the repo
  2. Create a feature branch:
    git checkout -b feature/amazing-feature
    
  3. Commit changes:
    git commit -m "Add amazing feature"
    
  4. Push:
    git push origin feature/amazing-feature
    
  5. 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)

Source distribution for nwis-data-downloader 0.1.2
File Size Uploaded
nwis_data_downloader-0.1.2.tar.gz 8.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nwis-data-downloader 0.1.2
File Interpreter ABI Platform
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

Release history Release notifications | RSS feed

This release

0.1.2 This release

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