diff --git a/backend/src/main.py b/backend/src/main.py index 3688b2d..3550e66 100644 --- a/backend/src/main.py +++ b/backend/src/main.py @@ -1,28 +1,18 @@ """Main app for backend api""" import logging from contextlib import asynccontextmanager -from fastapi import FastAPI, HTTPException +from fastapi import FastAPI from .logging_config import configure_logging -from .structs.landmark import Landmark -from .structs.linked_landmarks import LinkedLandmarks -from .structs.trip import Trip -from .landmarks.landmarks_manager import LandmarkManager from .toilets.toilets_router import router as toilets_router from .optimization.optimization_router import router as optimization_router from .landmarks.landmarks_router import router as landmarks_router from .payments.payment_router import router as payment_router -from .optimization.optimizer import Optimizer -from .optimization.refiner import Refiner -from .cache import client as cache_client +from .trips.trips_router import router as trips_router logger = logging.getLogger(__name__) -manager = LandmarkManager() -optimizer = Optimizer() -refiner = Refiner(optimizer=optimizer) - @asynccontextmanager async def lifespan(app: FastAPI): @@ -33,6 +23,7 @@ async def lifespan(app: FastAPI): logger.info("Shutting down logging") +# Create the fastapi app app = FastAPI(lifespan=lifespan) @@ -52,85 +43,14 @@ app.include_router(optimization_router) # Call with "/get/toilets" for fetching toilets around coordinates. app.include_router(toilets_router) + # Include the payment router for interacting with paypal sdk. # See src/payment/payment_router.py for more information on how to call. app.include_router(payment_router) -#### For already existing trips/landmarks -@app.get("/trip/{trip_uuid}") -def get_trip(trip_uuid: str) -> Trip: - """ - Look-up the cache for a trip that has been previously generated using its identifier. - - Args: - trip_uuid (str) : unique identifier for a trip. - - Returns: - (Trip) : the corresponding trip. - """ - try: - trip = cache_client.get(f"trip_{trip_uuid}") - return trip - except KeyError as exc: - logger.error(f"Failed to fetch trip with UUID {trip_uuid}: {str(exc)}") - raise HTTPException(status_code=404, detail="Trip not found") from exc - - -@app.get("/landmark/{landmark_uuid}") -def get_landmark(landmark_uuid: str) -> Landmark: - """ - Returns a Landmark from its unique identifier. - - Args: - landmark_uuid (str) : unique identifier for a Landmark. - - Returns: - (Landmark) : the corresponding Landmark. - """ - try: - landmark = cache_client.get(f"landmark_{landmark_uuid}") - return landmark - except KeyError as exc: - logger.error(f"Failed to fetch landmark with UUID {landmark_uuid}: {str(exc)}") - raise HTTPException(status_code=404, detail="Landmark not found") from exc - - -@app.post("/trip/recompute-time/{trip_uuid}/{removed_landmark_uuid}") -def update_trip_time(trip_uuid: str, removed_landmark_uuid: str) -> Trip: - """ - Updates the reaching times of a given trip when removing a landmark. - - Args: - landmark_uuid (str) : unique identifier for a Landmark. - - Returns: - (Landmark) : the corresponding Landmark. - """ - # First, fetch the trip in the cache. - try: - trip = cache_client.get(f'trip_{trip_uuid}') - except KeyError as exc: - logger.error(f"Failed to update trip with UUID {trip_uuid} (trip not found): {str(exc)}") - raise HTTPException(status_code=404, detail='Trip not found') from exc - - landmarks = [] - next_uuid = trip.first_landmark_uuid - - # Extract landmarks - try : - while next_uuid is not None: - landmark = cache_client.get(f'landmark_{next_uuid}') - # Filter out the removed landmark. - if next_uuid != removed_landmark_uuid : - landmarks.append(landmark) - next_uuid = landmark.next_uuid # Prepare for the next iteration - except KeyError as exc: - logger.error(f"Failed to update trip with UUID {trip_uuid} : {str(exc)}") - raise HTTPException(status_code=404, detail=f'landmark {next_uuid} not found') from exc - - # Re-link every thing and compute times again - linked_tour = LinkedLandmarks(landmarks) - trip = Trip.from_linked_landmarks(linked_tour, cache_client) - - return trip +# Endpoint for putting together a trip, fetching landmarks by UUID and updating trip times. Three routes +# Call with "/trip/{trip_uuid}" for getting trip by UUID. +# Call with "/landmark/{landmark_uuid}" for getting landmark by UUID. +# Call with "/trip//trip/recompute-time/{trip_uuid}/{removed_landmark_uuid}" for updating trip times. +app.include_router(trips_router) diff --git a/backend/src/trips/__init__.py b/backend/src/trips/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/src/trips/trips_router.py b/backend/src/trips/trips_router.py new file mode 100644 index 0000000..d13babf --- /dev/null +++ b/backend/src/trips/trips_router.py @@ -0,0 +1,104 @@ +import logging +from fastapi import HTTPException, APIRouter + +from ..structs.landmark import Landmark +from ..structs.linked_landmarks import LinkedLandmarks +from ..structs.trip import Trip +from ..landmarks.landmarks_manager import LandmarkManager +from ..optimization.optimizer import Optimizer +from ..optimization.refiner import Refiner +from ..cache import client as cache_client + + +logger = logging.getLogger(__name__) + + +manager = LandmarkManager() +optimizer = Optimizer() +refiner = Refiner(optimizer=optimizer) + + +# Initialize the API router +router = APIRouter() + + +#### For already existing trips/landmarks +@router.get("/trip/{trip_uuid}") +def get_trip(trip_uuid: str) -> Trip: + """ + Look-up the cache for a trip that has been previously generated using its identifier. + + Args: + trip_uuid (str) : unique identifier for a trip. + + Returns: + (Trip) : the corresponding trip. + """ + try: + trip = cache_client.get(f"trip_{trip_uuid}") + return trip + except KeyError as exc: + logger.error(f"Failed to fetch trip with UUID {trip_uuid}: {str(exc)}") + raise HTTPException(status_code=404, detail="Trip not found") from exc + + +# Fetch a landmark from memcached by its uuid +@router.get("/landmark/{landmark_uuid}") +def get_landmark(landmark_uuid: str) -> Landmark: + """ + Returns a Landmark from its unique identifier. + + Args: + landmark_uuid (str) : unique identifier for a Landmark. + + Returns: + (Landmark) : the corresponding Landmark. + """ + try: + landmark = cache_client.get(f"landmark_{landmark_uuid}") + return landmark + except KeyError as exc: + logger.error(f"Failed to fetch landmark with UUID {landmark_uuid}: {str(exc)}") + raise HTTPException(status_code=404, detail="Landmark not found") from exc + + +# Update the times between landmarks when removing an item from the list +@router.post("/trip/recompute-time/{trip_uuid}/{removed_landmark_uuid}") +def update_trip_time(trip_uuid: str, removed_landmark_uuid: str) -> Trip: + """ + Updates the reaching times of a given trip when removing a landmark. + + Args: + landmark_uuid (str) : unique identifier for a Landmark. + + Returns: + (Landmark) : the corresponding Landmark. + """ + # First, fetch the trip in the cache. + try: + trip = cache_client.get(f'trip_{trip_uuid}') + except KeyError as exc: + logger.error(f"Failed to update trip with UUID {trip_uuid} (trip not found): {str(exc)}") + raise HTTPException(status_code=404, detail='Trip not found') from exc + + landmarks = [] + next_uuid = trip.first_landmark_uuid + + # Extract landmarks + try : + while next_uuid is not None: + landmark = cache_client.get(f'landmark_{next_uuid}') + # Filter out the removed landmark. + if next_uuid != removed_landmark_uuid : + landmarks.append(landmark) + next_uuid = landmark.next_uuid # Prepare for the next iteration + except KeyError as exc: + logger.error(f"Failed to update trip with UUID {trip_uuid} : {str(exc)}") + raise HTTPException(status_code=404, detail=f'landmark {next_uuid} not found') from exc + + # Re-link every thing and compute times again + linked_tour = LinkedLandmarks(landmarks) + trip = Trip.from_linked_landmarks(linked_tour, cache_client) + + return trip +