demo version prepped
This commit is contained in:
62
backend/api/v1/__init__.py
Normal file
62
backend/api/v1/__init__.py
Normal file
@@ -0,0 +1,62 @@
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from config import settings
|
||||
|
||||
from simulator import alarm_simulator, ticket_simulator, cleanup_alarms, cleanup_incidents, robot_simulator
|
||||
|
||||
import asyncio
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
import time
|
||||
|
||||
from .incidents import router as incidents_router
|
||||
from .alarms import router as alarms_router
|
||||
from .cellsites import router as cellsites_router
|
||||
from .simulator import router as simulator_router
|
||||
from .robots import router as robots_router
|
||||
|
||||
origins: list[str] = settings.cors_origins.split(",")
|
||||
|
||||
ALARM_CLEANUP_INTERVAL = 180
|
||||
INCIDENT_CLEANUP_INTERVAL = 240
|
||||
|
||||
# NOTE: All 5 simulators run on a single thread using Python's event loop. Using this instead of multithreading to keep things simple. Good enough for demoing the idea.
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
task1 = asyncio.create_task(alarm_simulator(5))
|
||||
task2 = asyncio.create_task(ticket_simulator(20))
|
||||
task3 = asyncio.create_task(cleanup_alarms(interval=ALARM_CLEANUP_INTERVAL, max_age_seconds=5))
|
||||
task4 = asyncio.create_task(cleanup_incidents(interval=INCIDENT_CLEANUP_INTERVAL, max_age_seconds=10))
|
||||
task5 = asyncio.create_task(robot_simulator(8))
|
||||
|
||||
# NOTE: This is for the stats endpoint, to send to frontend
|
||||
simulator.next_alarm_cleanup_at = time.time() + ALARM_CLEANUP_INTERVAL
|
||||
simulator.next_incident_cleanup_at = time.time() + INCIDENT_CLEANUP_INTERVAL
|
||||
|
||||
yield
|
||||
task1.cancel()
|
||||
task2.cancel()
|
||||
task3.cancel()
|
||||
task4.cancel()
|
||||
task5.cancel()
|
||||
|
||||
def create_app() -> FastAPI:
|
||||
# TODO: Add a toggle / Flag or endpoint to turn off the simulator
|
||||
# app = FastAPI()
|
||||
app = FastAPI(lifespan=lifespan)
|
||||
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=origins,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
app.include_router(incidents_router, prefix="/api/v1")
|
||||
app.include_router(cellsites_router, prefix="/api/v1")
|
||||
app.include_router(alarms_router, prefix="/api/v1")
|
||||
app.include_router(simulator_router, prefix="/api/v1")
|
||||
app.include_router(robots_router, prefix="/api/v1")
|
||||
|
||||
return app
|
||||
21
backend/api/v1/alarms/__init__.py
Normal file
21
backend/api/v1/alarms/__init__.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from fastapi import APIRouter, Query
|
||||
import database as db
|
||||
from typing import Any
|
||||
from logger import get_logger
|
||||
logger = get_logger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/alarms", tags=["alarms"])
|
||||
|
||||
@router.get("/")
|
||||
def get_alarms(
|
||||
id: int | None = Query(None),
|
||||
before: int | None = Query(None)
|
||||
) -> list[dict[Any, Any]]:
|
||||
conn = db.connect_to_db()
|
||||
try:
|
||||
return db.get_alarms(conn, id=id, before=before)
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching alarms (id={id}, before={before}): {e}", exc_info=True)
|
||||
return []
|
||||
finally:
|
||||
conn.close()
|
||||
32
backend/api/v1/cellsites/__init__.py
Normal file
32
backend/api/v1/cellsites/__init__.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from fastapi import APIRouter
|
||||
import database as db
|
||||
from typing import Any
|
||||
from logger import get_logger
|
||||
logger = get_logger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/cellsites", tags=["cellsites"])
|
||||
|
||||
@router.get("/")
|
||||
def get_cellsites() -> list[dict[Any, Any]]: # type: ignore
|
||||
conn = db.connect_to_db()
|
||||
try:
|
||||
with db.connect_to_db() as conn:
|
||||
return db.get_cellsites(conn)
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching cellsites: {e}", exc_info=True)
|
||||
return []
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
@router.get("/{id}")
|
||||
def get_cellsite(id: int) -> list[dict[str, Any]]: # type: ignore
|
||||
conn = db.connect_to_db()
|
||||
try:
|
||||
with db.connect_to_db() as conn:
|
||||
return db.get_cellsite(conn, id)
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching cellsite {id}: {e}", exc_info=True)
|
||||
return []
|
||||
finally:
|
||||
conn.close()
|
||||
34
backend/api/v1/incidents/__init__.py
Normal file
34
backend/api/v1/incidents/__init__.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from fastapi import APIRouter, Query
|
||||
import database as db
|
||||
from typing import Any
|
||||
from logger import get_logger
|
||||
logger = get_logger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/incidents", tags=["incidents"])
|
||||
|
||||
|
||||
@router.get("/{incident_id}")
|
||||
def get_incident(incident_id: int) -> dict[str, Any] | None:
|
||||
conn = db.connect_to_db()
|
||||
try:
|
||||
return db.get_incident_by_id(conn, incident_id)
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching incident {incident_id}: {e}", exc_info=True)
|
||||
return None
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
@router.get("/")
|
||||
def get_incidents(
|
||||
id: int | None = Query(None),
|
||||
before: int | None = Query(None)
|
||||
) -> list[dict[str, Any]]:
|
||||
conn = db.connect_to_db()
|
||||
try:
|
||||
return db.get_incidents(conn, id=id, before=before)
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching incidents (id={id}, before={before}): {e}", exc_info=True)
|
||||
return []
|
||||
finally:
|
||||
conn.close()
|
||||
30
backend/api/v1/robots/__init__.py
Normal file
30
backend/api/v1/robots/__init__.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from fastapi import APIRouter
|
||||
import database as db
|
||||
from logger import get_logger
|
||||
logger = get_logger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/robots", tags=["robots"])
|
||||
|
||||
@router.get("/")
|
||||
def get_robots():
|
||||
conn = db.connect_to_db()
|
||||
try:
|
||||
return db.get_robots(conn)
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching robots: {e}", exc_info=True)
|
||||
return []
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
@router.get("/{robot_id}")
|
||||
def get_robot(robot_id: int):
|
||||
conn = db.connect_to_db()
|
||||
try:
|
||||
return db.get_robot_by_id(conn, robot_id)
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching robot {robot_id}: {e}", exc_info=True)
|
||||
return None
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
# TODO: Add worklog + history to view when in historical mode in FE
|
||||
23
backend/api/v1/simulator/__init__.py
Normal file
23
backend/api/v1/simulator/__init__.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from fastapi import APIRouter
|
||||
import database as db
|
||||
import simulator
|
||||
from logger import get_logger
|
||||
logger = get_logger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/simulator", tags=["simulator"])
|
||||
|
||||
@router.get("/status")
|
||||
def get_status():
|
||||
conn = db.connect_to_db()
|
||||
try:
|
||||
stats = db.get_simulator_stats(conn)
|
||||
return {
|
||||
**stats,
|
||||
"next_alarm_cleanup_at": simulator.next_alarm_cleanup_at,
|
||||
"next_incident_cleanup_at": simulator.next_incident_cleanup_at,
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Ticket simulator /api/v1/status error: {e}", exc_info=True)
|
||||
return {}
|
||||
finally:
|
||||
conn.close()
|
||||
Reference in New Issue
Block a user