https://github.com/fxf8/noaa-cdo-api
A modern api wrapper for NOAA NCEI Web Services
https://github.com/fxf8/noaa-cdo-api
aiohttp-client api-wrapper async asyncio historical modern noaa noaa-cdo noaa-cdo-api noaa-weather python typehints
Last synced: about 2 months ago
JSON representation
A modern api wrapper for NOAA NCEI Web Services
- Host: GitHub
- URL: https://github.com/fxf8/noaa-cdo-api
- Owner: fxf8
- License: mit
- Created: 2025-03-31T00:33:27.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-04-27T02:48:26.000Z (10 months ago)
- Last Synced: 2026-01-14T00:38:20.788Z (about 2 months ago)
- Topics: aiohttp-client, api-wrapper, async, asyncio, historical, modern, noaa, noaa-cdo, noaa-cdo-api, noaa-weather, python, typehints
- Language: Python
- Homepage: https://pypi.org/project/noaa-cdo-api/
- Size: 983 KB
- Stars: 8
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# NOAA Climate Data Online API Client
[](https://badge.fury.io/py/noaa-cdo-api)
[](https://github.com/fxf8/noaa-cdo-api/actions)
[](https://github.com/fxf8/noaa-cdo-api/blob/main/LICENSE)
[](https://fuexfollets.github.io/noaa-cdo-api)
[](https://github.com/astral-sh/ruff)
[](https://github.com/astral-sh/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
```bash
pip install noaa-cdo-api
```
## API Documentation
Full API documentation with colored formatting is available at [https://fxf8.github.io/noaa-cdo-api/](https://fxf8.github.io/noaa-cdo-api/).
## Quick Start
```python
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
```python
# ❌ 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
```python
# ❌ Less ideal but functional: Manual cleanup
client = NOAAClient(token="TOKEN")
try:
await client.get_datasets()
finally:
client.close() # Might miss resources (note: close does not need to be awaited)
# ✅ Better: Use async context manager
async with NOAAClient(token="TOKEN") as client:
await client.get_datasets()
```
### Rate Limiting
```python
# ✅ 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:
```python
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](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
- [Open an issue](https://github.com/fxf8/noaa-cdo-api/issues)
- [Read the docs](https://fuexfollets.github.io/noaa-cdo-api)
- [NOAA CDO API Documentation](https://www.ncdc.noaa.gov/cdo-web/webservices/v2)