A FastAPI service that wraps the OpenWeatherMap API, providing a simplified, well-documented interface for retrieving current weather and 5-day forecast data by city.
🔗 Live Demo: https://weather-api-59gn.onrender.com/docs (Note: hosted on Render's free tier — the first request after inactivity may take up to ~50 seconds while the service wakes up)
GET /weather/{city}— returns current weather for a city in a clean, simplified formatGET /weather/{city}/forecast— returns a 5-day forecast with one summary per day- In-memory caching (5-minute TTL) to reduce redundant OpenWeatherMap calls
- Rate limiting (10 requests/minute per IP) to protect against abuse
- Input validation (empty names, overly long names)
- Proper error handling with meaningful HTTP status codes (404 for unknown cities, 502 for upstream failures, 429 for rate limits)
- Structured logging
- Automated test suite (pytest)
- Interactive API documentation via Swagger UI
- Dockerized for consistent, portable deployment
- FastAPI — web framework
- httpx — async HTTP client for calling OpenWeatherMap
- Pydantic — data validation and response schemas
- cachetools — in-memory TTL caching
- slowapi — rate limiting
- pytest — testing framework
- python-dotenv — environment variable management
- Docker — containerization
Client → FastAPI (rate limit check) → Cache lookup → OpenWeatherMap API (on cache miss) → Response reshaping → Client
Our service validates input, checks the cache, calls OpenWeatherMap only when needed, and transforms their raw response into a simplified schema — rather than exposing OpenWeatherMap's format directly.
- Python 3.10+ (tested with 3.14)
- An OpenWeatherMap API key (sign up free)
- Docker Desktop (optional, for containerized runs)
- Clone the repository:
git clone <your-repo-url>
cd weather-api- Create and activate a virtual environment:
python -m venv venv
venv\Scripts\activate # Windows
source venv/bin/activate # Mac/Linux- Install dependencies:
pip install -r requirements.txt- Set up environment variables:
cp .env.example .envThen edit .env and add your OpenWeatherMap API key.
- Run the server:
uvicorn app.main:app --reload- Open the interactive docs:
http://127.0.0.1:8000/docs
- Build the image:
docker build -t weather-api .- Run the container:
docker run -p 8000:8000 --env-file .env weather-api- Visit
http://127.0.0.1:8000/docsas above.
Returns current weather for the given city.
Example request:
GET /weather/London
Example response:
{
"city": "London",
"country": "GB",
"temperature_celsius": 15.2,
"feels_like_celsius": 14.6,
"humidity_percent": 60,
"condition": "few clouds",
"wind_speed_mps": 3.1
}Returns a 5-day forecast (one entry per day, midday reading).
Example request:
GET /weather/London/forecast
Example response:
{
"city": "London",
"forecast": [
{"date": "2026-08-17", "temperature_celsius": 16.4, "condition": "light rain", "humidity_percent": 72},
{"date": "2026-08-18", "temperature_celsius": 18.1, "condition": "clear sky", "humidity_percent": 55}
]
}Error responses:
| Status | Meaning |
|---|---|
| 422 | Invalid input (empty or overly long city name) |
| 404 | City not found |
| 429 | Too many requests (rate limit exceeded — 10/minute per IP) |
| 502 | OpenWeatherMap unavailable or misconfigured |
python -m pytestapp/
├── main.py # FastAPI app and routes
├── models/ # Pydantic response schemas
└── services/ # External API client logic (with caching)
tests/ # Automated test suite
Dockerfile # Container build instructions
- In-memory cache resets on server restart and doesn't share state across multiple instances (Redis would solve this)
- Rate limiting is per-IP, so multiple users behind the same network share a limit
- Free-tier hosting (Render) may have a cold-start delay after inactivity
- Multi-city comparison endpoint
- Redis-based caching (for multi-instance deployments)
- Authentication / API key system for consumers of this API
MIT