Merge modifications for more separate backend functions #69
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								backend/src/trips/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								backend/src/trips/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										104
									
								
								backend/src/trips/trips_router.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								backend/src/trips/trips_router.py
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user