-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/h0m4m/alibaba-rta-hackathon
- Loading branch information
Showing
9 changed files
with
154 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,19 @@ | ||
from fastapi import FastAPI, HTTPException | ||
from pydantic import BaseModel | ||
from fastapi import FastAPI, HTTPException, Depends | ||
from sqlalchemy import create_engine, Column, Integer, String, Float, DateTime | ||
from sqlalchemy.ext.declarative import declarative_base | ||
from sqlalchemy.orm import sessionmaker, Session | ||
from typing import List | ||
from pydantic import BaseModel | ||
from fastapi.middleware.cors import CORSMiddleware | ||
from datetime import datetime | ||
|
||
# Database setu | ||
DATABASE_URL = "postgresql://alibabapost:[email protected]:5432/alibabapost123" | ||
|
||
engine = create_engine(DATABASE_URL) | ||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) | ||
Base = declarative_base() | ||
|
||
app = FastAPI() | ||
|
||
# Adding CORS middleware to allow requests from React frontend | ||
|
@@ -19,112 +29,147 @@ | |
allow_headers=["*"], | ||
) | ||
|
||
# Accident Hotspot model | ||
class AccidentHotspot(BaseModel): | ||
# SQLAlchemy Models | ||
class User(Base): | ||
__tablename__ = 'users' | ||
id = Column(Integer, primary_key=True, index=True) | ||
username = Column(String, unique=True, index=True, nullable=False) | ||
password = Column(String, nullable=False) | ||
first_name = Column(String) | ||
last_name = Column(String) | ||
role = Column(String, nullable=False) # 'driver' or 'customer' | ||
|
||
class AccidentHotspot(Base): | ||
__tablename__ = 'accident_hotspots' | ||
id = Column(Integer, primary_key=True, index=True) | ||
lat = Column(Float, nullable=False) | ||
lng = Column(Float, nullable=False) | ||
intensity = Column(Integer, nullable=False) | ||
description = Column(String) | ||
|
||
class BusyPoint(Base): | ||
__tablename__ = 'busy_points' | ||
id = Column(Integer, primary_key=True, index=True) | ||
lat = Column(Float, nullable=False) | ||
lng = Column(Float, nullable=False) | ||
weekday = Column(String, nullable=False) | ||
time_interval = Column(String, nullable=False) | ||
max_drivers = Column(Integer, nullable=False) | ||
current_drivers = Column(Integer, nullable=False) | ||
assigned_drivers = Column(String) # Comma-separated driver IDs | ||
|
||
|
||
class UserLogin(BaseModel): | ||
username: str | ||
password: str | ||
|
||
|
||
# Create tables in the database | ||
Base.metadata.create_all(bind=engine) | ||
|
||
# Pydantic Models | ||
class UserCreate(BaseModel): | ||
username: str | ||
password: str | ||
first_name: str = None | ||
last_name: str = None | ||
role: str # 'driver' or 'customer' | ||
|
||
class AccidentHotspotCreate(BaseModel): | ||
lat: float | ||
lng: float | ||
intensity: int | ||
description: str | ||
|
||
# Updated mock data with accident hotspots in Sharjah, UAE | ||
mock_hotspots = [ | ||
{"lat": 25.319000, "lng": 55.375000, "intensity": 6, "description": "High accident risk, close to your location."}, | ||
{"lat": 25.3573, "lng": 55.4033, "intensity": 5, "description": "Moderate accident risk, located further away."}, | ||
{"lat": 25.3625, "lng": 55.4307, "intensity": 4, "description": "Occasional accidents in residential zone, located far away."}, | ||
] | ||
|
||
# Busy Point model | ||
class BusyPoint(BaseModel): | ||
class BusyPointCreate(BaseModel): | ||
lat: float | ||
lng: float | ||
weekday: str | ||
time_interval: str | ||
max_drivers: int | ||
current_drivers: int | ||
assigned_drivers: List[str] # Track assigned drivers by their unique IDs | ||
|
||
# Request model for updating busy points | ||
class BusyPointUpdateRequest(BaseModel): | ||
lat: float | ||
lng: float | ||
driver_id: str # Unique identifier for the driver (e.g., username) | ||
current_drivers: int = 0 | ||
assigned_drivers: List[str] = [] | ||
|
||
# Dependency to get DB session | ||
def get_db(): | ||
db = SessionLocal() | ||
try: | ||
yield db | ||
finally: | ||
db.close() | ||
|
||
# API Endpoints | ||
@app.post("/signup") | ||
async def signup(user: UserCreate, db: Session = Depends(get_db)): | ||
db_user = db.query(User).filter(User.username == user.username).first() | ||
if db_user: | ||
raise HTTPException(status_code=400, detail="Username already exists") | ||
new_user = User( | ||
username=user.username, | ||
password=user.password, | ||
first_name=user.first_name, | ||
last_name=user.last_name, | ||
role=user.role | ||
) | ||
db.add(new_user) | ||
db.commit() | ||
db.refresh(new_user) | ||
return {"message": "Signup successful"} | ||
|
||
# Mock data for busy points for taxi dispatch (added `assigned_drivers` field) | ||
mock_busy_points = [ | ||
# Busy point near your location on Monday between 8 PM and 10 PM | ||
{"lat": 25.318250, "lng": 55.374100, "weekday": "Monday", "time_interval": "20:00-22:00", "max_drivers": 3, "current_drivers": 0, "assigned_drivers": []}, | ||
@app.post("/login") | ||
async def login(user: UserLogin, db: Session = Depends(get_db)): | ||
# Query the database for the user with given username and password | ||
db_user = db.query(User).filter(User.username == user.username, User.password == user.password).first() | ||
|
||
# Another point on Monday but at a different time | ||
{"lat": 25.3500, "lng": 55.4000, "weekday": "Monday", "time_interval": "12:00-14:00", "max_drivers": 2, "current_drivers": 0, "assigned_drivers": []}, | ||
|
||
# A point for Tuesday for variety | ||
{"lat": 25.3300, "lng": 55.4100, "weekday": "Tuesday", "time_interval": "17:00-19:00", "max_drivers": 4, "current_drivers": 0, "assigned_drivers": []}, | ||
] | ||
# If user does not exist, raise an HTTP exception | ||
if not db_user: | ||
raise HTTPException(status_code=400, detail="Incorrect username or password") | ||
|
||
# If the user is found, return success with user details | ||
return { | ||
"message": "Login successful", | ||
"first_name": db_user.first_name, | ||
"last_name": db_user.last_name, | ||
"role": db_user.role | ||
} | ||
|
||
@app.get("/api/accident-hotspots", response_model=List[AccidentHotspot]) | ||
async def get_accident_hotspots(): | ||
return mock_hotspots | ||
@app.get("/api/accident-hotspots", response_model=List[AccidentHotspotCreate]) | ||
async def get_accident_hotspots(db: Session = Depends(get_db)): | ||
return db.query(AccidentHotspot).all() | ||
|
||
@app.get("/api/busy-points", response_model=List[BusyPoint]) | ||
async def get_busy_points(): | ||
@app.get("/api/busy-points", response_model=List[BusyPointCreate]) | ||
async def get_busy_points(db: Session = Depends(get_db)): | ||
# Get current weekday and time | ||
now = datetime.now() | ||
current_weekday = now.strftime("%A") | ||
current_time = now.strftime("%H:%M") | ||
|
||
# Filter busy points based on current weekday and time interval | ||
relevant_points = [] | ||
for point in mock_busy_points: | ||
if point["weekday"] == current_weekday: | ||
start_time, end_time = point["time_interval"].split("-") | ||
if start_time <= current_time <= end_time and point["current_drivers"] < point["max_drivers"]: | ||
for point in db.query(BusyPoint).all(): | ||
if point.weekday == current_weekday: | ||
start_time, end_time = point.time_interval.split("-") | ||
if start_time <= current_time <= end_time and point.current_drivers < point.max_drivers: | ||
relevant_points.append(point) | ||
|
||
return relevant_points | ||
|
||
@app.post("/api/update-busy-point") | ||
async def update_busy_point(request: BusyPointUpdateRequest): | ||
# Update current drivers count for a busy point when a driver approaches | ||
for point in mock_busy_points: | ||
if point["lat"] == request.lat and point["lng"] == request.lng: | ||
if request.driver_id not in point["assigned_drivers"]: | ||
if point["current_drivers"] < point["max_drivers"]: | ||
point["current_drivers"] += 1 | ||
point["assigned_drivers"].append(request.driver_id) | ||
return {"message": "Driver assigned successfully"} | ||
else: | ||
return {"message": "Max drivers reached for this point"} | ||
else: | ||
return {"message": "Driver has already been assigned to this point"} | ||
|
||
return {"message": "Busy point not found"} | ||
|
||
# User authentication endpoints | ||
class User(BaseModel): | ||
username: str | ||
password: str | ||
first_name: str = None | ||
last_name: str = None | ||
|
||
fake_user_db = {} | ||
|
||
@app.post("/signup") | ||
async def signup(user: User): | ||
if user.username in fake_user_db: | ||
raise HTTPException(status_code=400, detail="Username already exists") | ||
fake_user_db[user.username] = { | ||
"password": user.password, | ||
"first_name": user.first_name, | ||
"last_name": user.last_name, | ||
} | ||
return {"message": "Signup successful"} | ||
|
||
@app.post("/login") | ||
async def login(user: User): | ||
if user.username not in fake_user_db or fake_user_db[user.username]["password"] != user.password: | ||
raise HTTPException(status_code=400, detail="Incorrect username or password") | ||
return { | ||
"message": "Login successful", | ||
"first_name": fake_user_db[user.username]["first_name"], | ||
"last_name": fake_user_db[user.username]["last_name"] | ||
} | ||
async def update_busy_point(request: BusyPointCreate, db: Session = Depends(get_db)): | ||
busy_point = db.query(BusyPoint).filter(BusyPoint.lat == request.lat, BusyPoint.lng == request.lng).first() | ||
if not busy_point: | ||
return {"message": "Busy point not found"} | ||
|
||
if request.driver_id not in busy_point.assigned_drivers.split(","): | ||
if busy_point.current_drivers < busy_point.max_drivers: | ||
busy_point.current_drivers += 1 | ||
assigned_drivers = busy_point.assigned_drivers.split(",") if busy_point.assigned_drivers else [] | ||
assigned_drivers.append(request.driver_id) | ||
busy_point.assigned_drivers = ",".join(assigned_drivers) | ||
db.commit() | ||
db.refresh(busy_point) | ||
return {"message": "Driver assigned successfully"} | ||
else: | ||
return {"message": "Max drivers reached for this point"} | ||
else: | ||
return {"message": "Driver has already been assigned to this point"} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters