Add Weathers data query/api endpoint and pydantic scheme

This commit is contained in:
sosokker 2024-04-26 21:09:55 +07:00
parent e27ea919b8
commit 92484d9e43
5 changed files with 197 additions and 3 deletions

View File

@ -1,10 +1,10 @@
import uvicorn
from fastapi import FastAPI
from routers import video
from routers import video, weather
app = FastAPI(
title="Dispatch",
title="Healthcare-System",
description="Hello Stranger.",
root_path="/api/v1",
docs_url="/docs/swagger",
@ -13,6 +13,7 @@ app = FastAPI(
)
app.include_router(video.router, prefix="/camera")
app.include_router(weather.router, prefix="/weather")
@app.get("/")
def read_root():

View File

@ -5,7 +5,8 @@ This file contains the SQLAlchemy model for the weather data.
from sqlalchemy import Column, Integer, Float, DateTime, Text
from sqlalchemy.orm import relationship
from .database import Base
from database import Base
class WeatherData(Base):
__tablename__ = "data"

View File

@ -0,0 +1,68 @@
from datetime import datetime, timedelta
from sqlalchemy import func
from sqlalchemy.orm import Session
from models import WeatherData
def _get_weather_data_query(session: Session):
return session.query(
WeatherData.timestamp, WeatherData.outdoor_temp, WeatherData.outdoor_feels_like,
WeatherData.outdoor_pressure, WeatherData.outdoor_humidity, WeatherData.outdoor_weather,
WeatherData.outdoor_description, WeatherData.outdoor_pm25, WeatherData.outdoor_pm10,
WeatherData.indoor_temp, WeatherData.indoor_light
).order_by(WeatherData.timestamp.desc())
def get_weather_data(session: Session):
"""
Get all weather data from the database.
"""
return _get_weather_data_query(session).all()
def get_last_n_day_data(session: Session, n: int):
"""
Get the weather data for the last n days from the database.
"""
start_date = datetime.now() - timedelta(days=n)
return _get_weather_data_query(session).filter(WeatherData.timestamp >= start_date).all()
def get_indoor_data(session: Session, limit: int = 10):
"""
Get the latest indoor data from the database.
"""
return session.query(
WeatherData.timestamp, WeatherData.indoor_temp, WeatherData.indoor_light
).order_by(WeatherData.timestamp.desc()).limit(limit).all()
def get_outdoor_data(session: Session, limit: int = 10):
"""
Get the latest outdoor data from the database.
"""
return session.query(
WeatherData.timestamp, WeatherData.outdoor_temp, WeatherData.outdoor_feels_like,
WeatherData.outdoor_pressure, WeatherData.outdoor_humidity, WeatherData.outdoor_weather,
WeatherData.outdoor_description, WeatherData.outdoor_pm25, WeatherData.outdoor_pm10
).order_by(WeatherData.timestamp.desc()).limit(limit).all()
def _get_average_data_query(session: Session, columns, n: int):
start_date = datetime.now() - timedelta(days=n)
return session.query(*columns).filter(WeatherData.timestamp >= start_date)
def get_average_outdoor_data_last_n_day(session: Session, n: int):
"""
Get the average outdoor data for the last n days from the database.
"""
columns = [
func.avg(WeatherData.outdoor_temp), func.avg(WeatherData.outdoor_feels_like),
func.avg(WeatherData.outdoor_pressure), func.avg(WeatherData.outdoor_humidity),
func.avg(WeatherData.outdoor_pm25), func.avg(WeatherData.outdoor_pm10)
]
return _get_average_data_query(session, columns, n).first()
def get_average_indoor_data_last_n_day(session: Session, n: int):
"""
Get the average indoor data for the last n days from the database.
"""
columns = [func.avg(WeatherData.indoor_temp), func.avg(WeatherData.indoor_light)]
return _get_average_data_query(session, columns, n).first()

View File

@ -0,0 +1,85 @@
from sqlalchemy import func
from sqlalchemy.orm import Session
from database import engine, SessionLocal, Base
from scheme import WeatherDataBase, IndoorDataBase, OutdoorDataBase, AverageIndoorData, AverageOutdoorData
from query.weather import (get_weather_data, get_last_n_day_data, get_indoor_data, get_outdoor_data,
get_average_outdoor_data_last_n_day, get_average_indoor_data_last_n_day)
from fastapi import APIRouter, Depends, HTTPException
Base.metadata.create_all(bind=engine)
router = APIRouter()
#Dependency
def get_db():
db = SessionLocal()
try :
yield db
finally:
db.close()
@router.get("/", response_model=list[WeatherDataBase])
async def get_latest_weather_data(db: Session = Depends(get_db)):
weather_data = get_weather_data(db)
if not weather_data:
raise HTTPException(status_code=404, detail="Weather data not found")
return weather_data
@router.get("/{days}", response_model=list[WeatherDataBase])
async def get_weather_data_last_n_days(days: int, db: Session = Depends(get_db)):
weather_data = get_last_n_day_data(db, days)
if not weather_data:
raise HTTPException(status_code=404, detail=f"Weather data for the last {days} days not found")
return weather_data
@router.get("/indoor/{days}", response_model=list[IndoorDataBase])
async def get_indoor_data_last_n_days(days: int, db: Session = Depends(get_db)):
indoor_data = get_indoor_data(db, days)
if not indoor_data:
raise HTTPException(status_code=404, detail=f"Indoor data for the last {days} days not found")
return indoor_data
@router.get("/outdoor/{days}", response_model=list[OutdoorDataBase])
async def get_outdoor_data_last_n_days(days: int, db: Session = Depends(get_db)):
outdoor_data = get_outdoor_data(db, days)
if not outdoor_data:
raise HTTPException(status_code=404, detail="Outdoor data not found")
return outdoor_data
@router.get("/average/outdoor/{days}", response_model=AverageOutdoorData)
async def get_average_outdoor_data(days: int, db: Session = Depends(get_db)):
average_outdoor_data = get_average_outdoor_data_last_n_day(db, days)
print("HERERERERERE ", average_outdoor_data)
if not average_outdoor_data:
raise HTTPException(status_code=404, detail=f"Average outdoor data for the last {days} days not found")
average_outdoor_model = AverageOutdoorData(
avg_outdoor_temp=average_outdoor_data[0],
avg_outdoor_feels_like=average_outdoor_data[1],
avg_outdoor_pressure=average_outdoor_data[2],
avg_outdoor_humidity=average_outdoor_data[3],
avg_outdoor_pm25=average_outdoor_data[4],
avg_outdoor_pm10=average_outdoor_data[5]
)
return average_outdoor_model
@router.get("/average/indoor/{days}", response_model=AverageIndoorData)
async def get_average_indoor_data(days: int, db: Session = Depends(get_db)):
average_indoor_data = get_average_indoor_data_last_n_day(db, days)
if not average_indoor_data:
raise HTTPException(status_code=404, detail=f"Average indoor data for the last {days} days not found")
average_indoor_model = AverageIndoorData(
avg_indoor_temp=average_indoor_data[0],
avg_indoor_light=average_indoor_data[1]
)
return average_indoor_model

View File

@ -6,6 +6,31 @@ from pydantic import BaseModel
from typing import Optional
from datetime import datetime
class IndoorDataBase(BaseModel):
timestamp: Optional[datetime]
indoor_temp: Optional[float]
indoor_light: Optional[int]
class Config:
from_attributes = True
class OutdoorDataBase(BaseModel):
timestamp: Optional[datetime]
outdoor_temp: Optional[float]
outdoor_feels_like: Optional[float]
outdoor_pressure: Optional[int]
outdoor_humidity: Optional[int]
outdoor_weather: Optional[str]
outdoor_description: Optional[str]
outdoor_pm25: Optional[int]
outdoor_pm10: Optional[int]
class Config:
from_attributes = True
class WeatherDataBase(BaseModel):
timestamp: Optional[datetime]
outdoor_temp: Optional[float]
@ -22,6 +47,20 @@ class WeatherDataBase(BaseModel):
class Config:
from_attributes = True
class AverageOutdoorData(BaseModel):
avg_outdoor_temp: Optional[float]
avg_outdoor_feels_like: Optional[float]
avg_outdoor_pressure: Optional[float]
avg_outdoor_humidity: Optional[float]
avg_outdoor_pm25: Optional[float]
avg_outdoor_pm10: Optional[float]
class AverageIndoorData(BaseModel):
avg_indoor_temp: Optional[float]
avg_indoor_light: Optional[float]
class Camera(BaseModel):
camera_id: int
link: str