A reusable Python OOP library for weather data processing, multi-provider integration, severity analysis, and unit conversions.
Project description
☁️ cloudweatherlib
A powerful, reusable Python OOP library for weather data processing, multi-provider API integration, severity analysis, and unit conversions.
cloudweatherlib provides a clean, object-oriented interface for fetching and processing weather data from multiple providers (Google Weather API, OpenWeatherMap). It handles raw API responses, converts units, analyzes weather severity, and aggregates data across multiple cities — all through a simple Facade client.
🏗️ Architecture & OOP Principles
| OOP Pillar | Implementation | Class(es) |
|---|---|---|
| Abstraction | Abstract base class defines the provider contract | WeatherProvider (ABC) |
| Inheritance | Concrete providers extend the abstract base | GoogleWeatherProvider, OpenWeatherMapProvider |
| Encapsulation | Private attributes with validated property accessors | Location, WeatherData, Forecast |
| Polymorphism | Interchangeable providers with identical interfaces | Swap Google ↔ OpenWeatherMap without code changes |
Design Patterns Used
- Facade Pattern —
CloudWeatherClientprovides a single entry point - Factory Method —
_create_provider()instantiates the correct provider - Strategy Pattern —
TemperatureConverter,WindSpeedConverterfor interchangeable algorithms - Adapter Pattern —
OpenWeatherMapProvideradapts OWM JSON to library models - Template Method —
WeatherProviderbase class defines the processing template
📦 Installation
pip install cloudweatherlib
For development (with testing tools):
pip install cloudweatherlib[dev]
🚀 Quick Start
Basic Usage — Get Current Weather
from cloudweatherlib import CloudWeatherClient, Location
# Initialize the client with your API provider and key
client = CloudWeatherClient(provider="google", api_key="YOUR_GOOGLE_API_KEY")
# Create a location
dublin = Location("Dublin", latitude=53.3498, longitude=-6.2603, country_code="IE")
# Fetch current weather
weather = client.get_current_weather(dublin)
# Access weather data through clean properties
print(f"City: {weather.location.city_name}")
print(f"Temperature: {weather.temperature_celsius}°C / {weather.temperature_fahrenheit}°F")
print(f"Condition: {weather.condition_text}")
print(f"Wind: {weather.wind_speed_kmh} km/h ({weather.wind_speed_mph} mph)")
print(f"Humidity: {weather.humidity_percent}%")
print(f"UV Index: {weather.uv_index}")
Get Weather Forecast
# Daily forecast (up to 10 days)
forecasts = client.get_forecast(dublin, days=5)
for forecast in forecasts:
print(f"{forecast.date}: {forecast.high_temp_celsius}°C / {forecast.low_temp_celsius}°C "
f"- {forecast.condition_text} (Rain: {forecast.precipitation_probability}%)")
# Hourly forecast (up to 24 hours)
hourly = client.get_hourly_forecast(dublin, hours=12)
Analyze Weather Severity
# Get severity assessment
severity = client.get_severity(weather)
print(f"Severity Level: {severity['level']}") # e.g., "WARNING"
print(f"Severity Score: {severity['score']}/100") # e.g., 35
print(f"Alerts: {severity['alerts']}") # e.g., ["Strong Wind: 52.3 km/h"]
print(f"Is Safe: {severity['is_safe']}") # e.g., False
Multi-City Dashboard Aggregation
# Fetch weather for multiple cities
cities = [
Location("Dublin", 53.3498, -6.2603, "IE"),
Location("London", 51.5074, -0.1278, "GB"),
Location("Paris", 48.8566, 2.3522, "FR"),
Location("Berlin", 52.5200, 13.4050, "DE"),
]
weather_list = [client.get_current_weather(city) for city in cities]
# Get aggregated statistics
summary = client.get_multi_city_summary(weather_list)
print(f"Average Temperature: {summary['temperature']['average_celsius']}°C")
print(f"Hottest City: {summary['temperature']['highest']['city']}")
print(f"Coldest City: {summary['temperature']['lowest']['city']}")
print(f"Windiest City: {summary['wind']['windiest_city']['city']}")
# Group cities by weather condition
grouped = client.group_cities_by_condition(weather_list)
print(f"Sunny cities: {grouped.get('CLEAR', [])}")
print(f"Rainy cities: {grouped.get('RAIN', [])}")
Switch Providers (Polymorphism)
# Using Google Weather API
google_client = CloudWeatherClient(provider="google", api_key="GOOGLE_KEY")
# Using OpenWeatherMap — exact same interface!
owm_client = CloudWeatherClient(provider="openweathermap", api_key="OWM_KEY")
# Both return identical WeatherData objects
weather_google = google_client.get_current_weather(dublin)
weather_owm = owm_client.get_current_weather(dublin)
# Same properties work regardless of provider
print(weather_google.temperature_celsius)
print(weather_owm.temperature_celsius)
Unit Converters — Standalone Usage
from cloudweatherlib.converters.temperature import TemperatureConverter, TemperatureUnit
from cloudweatherlib.converters.wind import WindSpeedConverter, WindSpeedUnit
# Temperature conversions
print(TemperatureConverter.celsius_to_fahrenheit(25.0)) # 77.0
print(TemperatureConverter.fahrenheit_to_celsius(77.0)) # 25.0
print(TemperatureConverter.celsius_to_kelvin(25.0)) # 298.15
# Unified convert method
print(TemperatureConverter.convert(100.0, TemperatureUnit.CELSIUS, TemperatureUnit.FAHRENHEIT)) # 212.0
# Wind speed conversions
print(WindSpeedConverter.kmh_to_mph(100.0)) # 62.1
print(WindSpeedConverter.kmh_to_ms(100.0)) # 27.8
print(WindSpeedConverter.kmh_to_knots(100.0)) # 54.0
# Beaufort Scale classification
print(WindSpeedConverter.to_beaufort_scale(75.0)) # "Near Gale (Force 7)"
Serialize to JSON (FastAPI Integration)
# Convert weather data to a dictionary for API responses
weather_dict = weather.to_dict()
# In FastAPI:
# @router.get("/weather/{city}")
# async def get_weather(city: str, lat: float, lon: float):
# location = Location(city, lat, lon)
# weather = client.get_current_weather(location)
# return {"weather": weather.to_dict(), "severity": client.get_severity(weather)}
📖 API Reference
Core Classes
| Class | Module | Description |
|---|---|---|
CloudWeatherClient |
cloudweatherlib |
High-level Facade — the main entry point |
Location |
cloudweatherlib.models |
Geographic location with validated coordinates |
WeatherData |
cloudweatherlib.models |
Current weather conditions with unit conversions |
Forecast |
cloudweatherlib.models |
Daily forecast data |
CloudWeatherConfig |
cloudweatherlib.config |
Encapsulated configuration management |
Providers
| Class | Module | Description |
|---|---|---|
WeatherProvider |
cloudweatherlib.providers |
Abstract base class (ABC) |
GoogleWeatherProvider |
cloudweatherlib.providers |
Google Maps Weather API v1 |
OpenWeatherMapProvider |
cloudweatherlib.providers |
OpenWeatherMap API v2.5 |
Analyzers
| Class | Module | Description |
|---|---|---|
SeverityAnalyzer |
cloudweatherlib.analyzers |
Weather severity scoring (0-100) |
SeverityLevel |
cloudweatherlib.analyzers |
Severity level constants |
WeatherAggregator |
cloudweatherlib.analyzers |
Multi-city statistics & grouping |
Converters
| Class | Module | Description |
|---|---|---|
TemperatureConverter |
cloudweatherlib.converters |
°C ↔ °F ↔ K conversions |
WindSpeedConverter |
cloudweatherlib.converters |
km/h ↔ mph ↔ m/s ↔ knots |
Exceptions
| Exception | Description |
|---|---|
CloudWeatherLibError |
Base exception for all library errors |
WeatherAPIError |
API request failures |
WeatherDataNotFoundError |
Data parsing failures |
InvalidLocationError |
Invalid coordinates/city |
ProviderNotSupportedError |
Unsupported provider requested |
ConfigurationError |
Invalid configuration |
🧪 Running Tests
# Install dev dependencies
pip install -e ".[dev]"
# Run all tests
pytest
# Run with coverage report
pytest --cov=cloudweatherlib --cov-report=html
# Run specific test file
pytest tests/test_severity.py -v
📋 Requirements
- Python >= 3.9
- requests >= 2.28.0
📄 License
This project is licensed under the MIT License — see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cloudweatherlib-0.1.0.tar.gz.
File metadata
- Download URL: cloudweatherlib-0.1.0.tar.gz
- Upload date:
- Size: 49.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c47749eb3cd0551aa1ac4d5cb838d52bc7754eb1a3d0b8d919d2c8a7fa22b079
|
|
| MD5 |
38d9924b17d813c43ba52f0cb83e46f0
|
|
| BLAKE2b-256 |
9d3ba21c552c31df6de62475200582bbab1e73c90aee30e1676592e0fee36130
|
File details
Details for the file cloudweatherlib-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cloudweatherlib-0.1.0-py3-none-any.whl
- Upload date:
- Size: 46.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17e65df487e7353a887a9a25a0d5561dcb1a19bb0d08b88bbd62f14142ffb4e8
|
|
| MD5 |
517e71d550364a744715821f9ff7a80b
|
|
| BLAKE2b-256 |
0140b9fe87cbc1583c6a920c0465a7853bdcfd5ce8a4901125a179b086a63b23
|