
- Created FastAPI application with SQLite database integration - Implemented OpenWeatherMap client with caching - Added endpoints for current weather, forecasts, and history - Included comprehensive error handling and validation - Set up Alembic migrations - Created detailed README with usage examples generated with BackendIM... (backend.im)
54 lines
2.3 KiB
Python
54 lines
2.3 KiB
Python
from typing import List, Optional, Dict, Any
|
|
from sqlalchemy.orm import Session
|
|
from sqlalchemy import func
|
|
from datetime import datetime, timedelta
|
|
|
|
from app.crud.base import CRUDBase
|
|
from app.models.weather import City, WeatherRecord
|
|
from app.schemas.weather import CityCreate, CityUpdate, WeatherRecordCreate
|
|
|
|
class CRUDCity(CRUDBase[City, CityCreate, CityUpdate]):
|
|
def get_by_name_and_country(self, db: Session, *, name: str, country: str) -> Optional[City]:
|
|
return db.query(City).filter(
|
|
func.lower(City.name) == func.lower(name),
|
|
func.lower(City.country) == func.lower(country)
|
|
).first()
|
|
|
|
def get_by_coordinates(self, db: Session, *, latitude: float, longitude: float) -> Optional[City]:
|
|
# Use a small delta to find cities by approximate coordinates
|
|
delta = 0.01 # About 1km at the equator
|
|
return db.query(City).filter(
|
|
City.latitude.between(latitude - delta, latitude + delta),
|
|
City.longitude.between(longitude - delta, longitude + delta)
|
|
).first()
|
|
|
|
class CRUDWeatherRecord(CRUDBase[WeatherRecord, WeatherRecordCreate, WeatherRecordCreate]):
|
|
def get_latest_by_city_id(self, db: Session, *, city_id: int) -> Optional[WeatherRecord]:
|
|
return db.query(WeatherRecord).filter(
|
|
WeatherRecord.city_id == city_id
|
|
).order_by(WeatherRecord.timestamp.desc()).first()
|
|
|
|
def get_history_by_city_id(
|
|
self, db: Session, *, city_id: int, start_date: datetime, end_date: datetime
|
|
) -> List[WeatherRecord]:
|
|
return db.query(WeatherRecord).filter(
|
|
WeatherRecord.city_id == city_id,
|
|
WeatherRecord.timestamp.between(start_date, end_date)
|
|
).order_by(WeatherRecord.timestamp).all()
|
|
|
|
def get_forecast_by_city_id(
|
|
self, db: Session, *, city_id: int
|
|
) -> List[WeatherRecord]:
|
|
"""
|
|
Get weather forecast data for a city.
|
|
In a real application, this might fetch forecasts from an external API,
|
|
but for this example, we'll just return the most recent data.
|
|
"""
|
|
current_time = datetime.utcnow()
|
|
return db.query(WeatherRecord).filter(
|
|
WeatherRecord.city_id == city_id,
|
|
WeatherRecord.timestamp >= current_time
|
|
).order_by(WeatherRecord.timestamp).all()
|
|
|
|
city = CRUDCity(City)
|
|
weather_record = CRUDWeatherRecord(WeatherRecord) |