Skip to content

Commit 80214a4

Browse files
committed
feat: mocked initial version for server
1 parent 3dee541 commit 80214a4

2 files changed

Lines changed: 91 additions & 0 deletions

File tree

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ shapely
77
klampt==0.9.2
88
pyyaml
99
dacite
10+
fastapi[standard]
1011

1112
# Perception
1213
ultralytics

server/main.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from typing import List
2+
from fastapi import FastAPI, HTTPException
3+
from fastapi.responses import JSONResponse, StreamingResponse
4+
from pydantic import BaseModel, Field
5+
import time
6+
import uuid
7+
# import jwt
8+
9+
SECRET_KEY = "CHANGE_ME_TO_SOMETHING_SECURE"
10+
11+
app = FastAPI(title="GemStack Car‑Summon API (Mock)")
12+
13+
### MODELS ###
14+
15+
class LoginRequest(BaseModel):
16+
username: str
17+
password: str
18+
19+
class CoordinatesRequest(BaseModel):
20+
lat: float = Field(..., ge=-90, le=90)
21+
lon: float = Field(..., ge=-180, le=180)
22+
23+
class CoordinatesResponse(BaseModel):
24+
current_position: CoordinatesRequest
25+
optimized_route: List[CoordinatesRequest]
26+
eta: str
27+
28+
class SummonResponse(BaseModel):
29+
launch_status: str
30+
launch_id: str
31+
32+
class CancelRequest(BaseModel):
33+
launch_id: str
34+
35+
class CancelResponse(BaseModel):
36+
launch_id: str
37+
status: str
38+
39+
class StreamPosition(BaseModel):
40+
current_position: CoordinatesRequest
41+
launch_status: str
42+
eta: str
43+
44+
### HELPERS ###
45+
46+
# def create_jwt(username: str) -> str:
47+
# payload = {"sub": username, "jti": str(uuid.uuid4())}
48+
# return jwt.encode(payload, SECRET_KEY, algorithm="HS256")
49+
50+
### ENDPOINTS ###
51+
52+
# @app.post("/api/login")
53+
# def login(req: LoginRequest):
54+
# if req.username == "admin" and req.password == "password":
55+
# return {"token": create_jwt(req.username)}
56+
# raise HTTPException(status_code=401, detail="Invalid credentials")
57+
58+
@app.post("/api/coordinates", response_model=CoordinatesResponse)
59+
def get_coordinates(req: CoordinatesRequest):
60+
# Mock “optimized route” as a straight line of 3 waypoints
61+
route = [
62+
CoordinatesRequest(lat=req.lat + 0.001 * i, lon=req.lon + 0.001 * i)
63+
for i in range(1, 4)
64+
]
65+
return CoordinatesResponse(
66+
current_position=CoordinatesRequest(lat=req.lat, lon=req.lon),
67+
optimized_route=route,
68+
eta="5 min",
69+
)
70+
71+
@app.post("/api/summon", response_model=SummonResponse)
72+
def summon(req: CoordinatesRequest):
73+
launch_id = str(uuid.uuid4())
74+
return SummonResponse(launch_status="launched", launch_id=launch_id)
75+
76+
@app.get("/api/stream_position/{launch_id}")
77+
def stream_position(launch_id: str):
78+
def event_generator():
79+
lat, lon = 40.0930, -88.2350
80+
for i in range(5):
81+
time.sleep(1)
82+
lat += 0.0005
83+
lon += 0.0005
84+
yield f"data: {StreamPosition(current_position=CoordinatesRequest(lat=lat, lon=lon), launch_status='navigating', eta=f'{5-i} min').json()}\n\n"
85+
yield "data: {\"launch_status\":\"arrived\"}\n\n"
86+
return StreamingResponse(event_generator(), media_type="text/event-stream")
87+
88+
@app.post("/api/cancel", response_model=CancelResponse)
89+
def cancel(req: CancelRequest):
90+
return CancelResponse(launch_id=req.launch_id, status="cancelled")

0 commit comments

Comments
 (0)