Source code for backend.app.api.sites

from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session, func, select

from backend.app.models.site import Site
from backend.database import get_db

site_router = APIRouter(prefix="/sites", tags=["Research Sites"])


[docs] @site_router.post("/") async def create_site(site: Site, db: Annotated[Session, Depends(get_db)]): """ Create a new site. This endpoint allows the creation of a new research site in the database. :param site: The site information to be added. :type site: Site :param db: The database session. :type db: Session :return: The created site. :rtype: Site """ db.add(site) db.commit() db.refresh(site) return site
[docs] @site_router.get("/") async def get_sites(db: Annotated[Session, Depends(get_db)]): """ Retrieve all sites. This endpoint retrieves all research sites stored in the database. :param db: The database session. :type db: Session :return: A list of all sites. :rtype: list[Site] """ sites = db.query(Site).all() return sites
[docs] @site_router.get("/{site-id}") async def get_site_by_id(site_id: int, db: Annotated[Session, Depends(get_db)]): """ Retrieve a site by its ID. This endpoint retrieves a research site by its ID. :param site_id: The ID of the site. :type site_id: int :param db: The database session. :type db: Session :return: The site with the specified ID. :rtype: Site """ statement = select(Site).where(Site.id == site_id) return db.exec(statement).one()
[docs] @site_router.get("/by-area/{min_lon}/{min_lat}/{max_lon}/{max_lat}/") async def get_sites_by_area( min_lon: float, min_lat: float, max_lon: float, max_lat: float, db: Annotated[Session, Depends(get_db)], ): """ Retrieve sites within a specified area. This endpoint retrieves research sites that are \ located within a specified bounding box. :param min_lon: Minimum longitude of the bounding box. :type min_lon: float :param min_lat: Minimum latitude of the bounding box. :type min_lat: float :param max_lon: Maximum longitude of the bounding box. :type max_lon: float :param max_lat: Maximum latitude of the bounding box. :type max_lat: float :param db: The database session. :type db: Session :return: A list of sites within the specified bounding box. :rtype: list[Site] :raise HTTPException: no Site found in that area """ bbox = ( f"POLYGON(({min_lon} {min_lat}, {min_lon} {max_lat}, {max_lon}" f" {max_lat}, {max_lon} {min_lat}, {min_lon} {min_lat}))" ) statement = select(Site).where( Site.func.ST_Within(Site.geo_location, func.ST_GeomFromText(bbox, 4326)) ) results = db.exec(statement).all() if not results: raise HTTPException( status_code=404, detail="No site found in the specified area" ) return results