Skip to main content

NOAA Climate Data Online API Client

PyPI version GitHub Actions License Documentation Ruff uv

An asynchronous Python client for the NOAA National Centers for Environmental Information (NCEI) Climate Data Online (CDO) Web Services API v2. Features automatic rate limiting, connection pooling, and comprehensive type safety.

Features

  • ⚡ Asynchronous API: Built with aiohttp for high-performance async I/O
  • 🚦 Automatic Rate Limiting: Enforces NOAA's limits (5 req/sec, 10,000 req/day)
  • 🔄 Connection Pooling: Efficient TCP connection reuse
  • 📝 Type Safety: Full type hints and runtime validation
  • 🎨 Beautiful Documentation: Color-formatted docstrings with pdoc
  • 🛡️ Resource Management: Proper async context management
  • 📊 Complete Coverage: All documented NOAA CDO v2 endpoints supported

Installation

pip install noaa-cdo-api

API Documentation

Full API documentation with colored formatting is available at https://fxf8.github.io/noaa-cdo-api/.

Quick Start

import asyncio
from noaa_cdo_api import NOAAClient, Extent

async def main():
    # Best Practice: Use async context manager for automatic cleanup
    async with NOAAClient(token="YOUR_TOKEN_HERE") as client:
        # Query available datasets
        datasets = await client.get_datasets(limit=10)

        # Query stations in a geographic region
        stations = await client.get_stations(
            extent=Extent(40.0, -80.0, 45.0, -75.0), # latitude_min, longitude_min, latitude_max, longitude_max
            datasetid="GHCND",
            limit=5
        )

        # Get climate data with unit conversion
        data = await client.get_data(
            datasetid="GHCND",
            startdate="2022-01-01",
            enddate="2022-01-31",
            stationid="GHCND:USW00094728",
            units="metric",
            limit=100,
        )

if __name__ == "__main__":
    asyncio.run(main())

Important Implementation Notes

Event Loop Management

# ❌ BAD: Creating multiple event loops
client1 = await NOAAClient(token="TOKEN1")
client2 = await NOAAClient(token="TOKEN2")

results = [*asyncio.run(client1.get_datasets(...)), *asyncio.run(client2.get_datasets(...))]

# ✅ GOOD: Share the same event loop (note that rate limits apply **per token**)
async with NOAAClient(token="TOKEN1") as client1, \
         NOAAClient(token="TOKEN2") as client2:
    await asyncio.gather(
        client1.get_datasets(),
        client2.get_datasets()
    )

Resource Management

# ❌ Less ideal but functional: Manual cleanup
client = NOAAClient(token="TOKEN")
try:
    await client.get_datasets()
finally:
    await client.close()

# ✅ Better: Use async context manager
async with NOAAClient(token="TOKEN") as client:
    await client.get_datasets()

Rate Limiting

# ✅ Good: Use only a single client
async def parallel_with():
    async with NOAAClient(token="TOKEN") as client:
        tasks = [client.get_datasets() for _ in range(20)]
        return await asyncio.gather(*tasks)  # Rate limits respected


# ❌ Bad: Each client has separate rate limits
async def parallel_separate():
    tasks = []
    for i in range(20):
        client = NOAAClient(token="TOKEN")  # Each has separate limiter
        tasks.append(client.get_datasets())
    return await asyncio.gather(*tasks)  # May exceed rate limits

Tips

  1. Connection Pooling

    • Reuse the same client instance
    • Default connection limit is 10
    • Adjust with tcp_connector_limit parameter
  2. Pagination

    • Use limit and offset for large result sets
    • Process data in chunks for memory efficiency
  3. Data Volume

    • Limit date ranges (1 year for daily, 10 years for monthly)
    • Use specific station IDs when possible
    • Set includemetadata=False if not needed
  4. Caching

    • Cache frequently accessed metadata
    • Implement local caching for historical data

Available Endpoints

  • /datasets: Query available datasets
  • /datacategories: Query data categories
  • /datatypes: Query data types
  • /locationcategories: Query location categories
  • /locations: Query locations
  • /stations: Query weather stations
  • /data: Query actual climate data

Type Safety

The library provides comprehensive type checking through:

  • TypedDict schemas for all parameters
  • Runtime validation of parameter values
  • Proper enum types for constrained fields

Example with type checking:

from noaa_cdo_api import parameter_schemas

params: parameter_schemas.StationsParameters = {
    "extent": "42.0,-90.0,40.0,-88.0",
    "datasetid": "GHCND",
    "limit": 100
}

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • NOAA's National Centers for Environmental Information (NCEI)
  • The aiohttp team for their excellent HTTP client
  • Contributors to the project

Getting Help

Metadata

Release files for noaa-cdo-api 0.1.0

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

Source distribution (sdist)

Source distribution for noaa-cdo-api 0.1.0
File Size Uploaded
noaa_cdo_api-0.1.0.tar.gz 27.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for noaa-cdo-api 0.1.0
File Interpreter ABI Platform
noaa_cdo_api-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 59.4 kB

Release files / noaa_cdo_api-0.1.0.tar.gz

Download URL noaa_cdo_api-0.1.0.tar.gz
Size 27.4 kB
Tags Source
SHA-256 checksum
How to use checksums
6d2e3ac0a72c96bd7b099004dedc8b4ec01b96b4ef85010d80601e0675002329
BLAKE2b-256 checksum
How to use checksums
1b8a9b908a035ffae28820ecfcdb397c26a36fbe26b9b47875969af1e233ac3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.9

Release files / noaa_cdo_api-0.1.0-py3-none-any.whl

Download URL noaa_cdo_api-0.1.0-py3-none-any.whl
Size 32.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8b1b5ed48249fa751b47dc334e36d24dbf66000b4491625cae3a3cb228e05362
BLAKE2b-256 checksum
How to use checksums
17a00fadf16e0bee0cee22bbd912d6b2eed1e4dfb126f3561a575b689aed0290
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.9

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

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