weather_api/main.py
Argiris Deligiannidis 8e18e72452
All checks were successful
continuous-integration/drone/push Build is passing
modified: main.py
2024-04-18 19:57:12 +03:00

190 lines
4.8 KiB
Python

import utils
from typing import Optional
from pydantic import BaseModel
from fastapi import FastAPI, status, HTTPException
from db_connector import database,engine,DB_REBUILD
if DB_REBUILD == 'True':
database.metadata.drop_all(engine)
utils.initialize_database()
class Location(BaseModel):
id: int = None
name: str = None
country: str = None
longitude: float = None
latitude: float = None
user: int = None
class Users(BaseModel):
id: int = None
name: str = None
email: str = None
class Config(BaseModel):
id: int = None
user_id: int = None
location_id: int = None
app = FastAPI()
def error_4xx_handler(return_data: dict) -> None:
"""
Handles errors with status code 400.
Checks if the key 'error' exists in the `return_data` dictionary.
If it does, it raises an HTTPException with status code 400 and the value
of the 'error' key as the detail.
Args:
return_data (dict): Data returned from an API endpoint.
Raises:
HTTPException: If the 'error' key is present in `return_data`.
"""
# Check if 'error' key exists in the return_data dictionary
if 'error' in return_data.keys():
# Raise HTTPException with status code 400 and the 'error' value as detail
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail={'error': return_data['error']}
)
@app.get("/")
async def index_response():
"""
A function that returns a status of "OK" when the root URL is accessed.
No parameters are passed, and it returns a dictionary with the status.
"""
return {"Status": "OK"}
@app.get("/locations")
async def get_location_weather(
places: Optional[str] = 'all',
user: Optional[int] = None
):
"""
A function to retrieve weather data for specified locations.
Parameters:
places (str): A string containing location identifiers separated by commas.
Returns:
dict: A dictionary containing weather data for the specified locations.
"""
#NOTE: Add option for fetching weather data for all locations, (debugging purposes)
if places == 'database_locations':
result = utils.get_database_locations(user=None)
elif places == 'configured':
result = utils.get_database_locations(user)
else:
if places != 'all':
places = [int(x) for x in list(places.split(","))]
result = utils.retrieve_weather_data(places)
error_4xx_handler(result)
return result
@app.get("/locations/{id}")
async def get_weather_by_id(id: int):
"""
Retrieves weather data for a specified location ID.
Parameters:
id (int): The ID of the location to retrieve weather data for.
Returns:
dict: A dictionary containing the retrieved weather data for the specified location.
"""
result = utils.retrieve_weather_data([id])
error_4xx_handler(result)
return result
@app.post("/locations", status_code=status.HTTP_201_CREATED)
async def add_location(loc: Location):
"""
Add a new location to the database.
Parameters:
- loc (Location): The location object to be added.
Raises:
- HTTPException: If the name exceeds 200 characters.
Returns:
None
"""
if len(loc.name.encode('utf-8')) > 200:
raise HTTPException(
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
detail={'name': 'Name cannot be longer than 200 characters'}
)
else:
id = int(loc.id)
#if loc.name!= 'existing':
# id = utils.get_available_ids(1)[0]
utils.add_location({"id":id ,"name":loc.name,"country":loc.country,"longitude":loc.longitude,"latitude":loc.latitude, "user": loc.user}, no_commit=False)
@app.delete("/locations/{id}")
async def delete_location(id: int):
"""
Delete a location by its ID.
Parameters:
id (int): The ID of the location to be deleted.
Returns:
None
"""
print(f"deleted location {id}")
utils.delete_location(id)
@app.get("/location/search")
async def search_location(query: str):
"""
A function to retrieve search results based on the provided query string.
Parameters:
query (str): The search query string.
Returns:
The search results based on the provided query.
"""
result = utils.search_location(query)
return result
@app.post("/location/disable")
async def search_location(id: int,
user: int
):
"""
A function to disable a location configuration based on the provided ID and user.
Parameters:
id (int): The ID of the location to be disabled.
user (int): The user ID related to the location.
Returns:
None
"""
result = utils.config_disable_location(id, user)
return result