Skip to content

Commit 1999ece

Browse files
committed
feat: Websocket
Added websocket connection for accessing users cache.
1 parent 980f969 commit 1999ece

1 file changed

Lines changed: 35 additions & 1 deletion

File tree

main.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import httpx
77

8-
from fastapi import FastAPI, HTTPException
8+
from fastapi import FastAPI, HTTPException, WebSocket, WebSocketDisconnect
99
from fastapi_utilities import repeat_every
1010
from pydantic import AliasPath, BaseModel, Field, field_validator
1111
from pydantic_core import PydanticUseDefault
@@ -99,6 +99,7 @@ async def fetch_users():
9999
global users
100100
global users_by_card
101101
try:
102+
logging.debug("Fetching users from Authentik")
102103
users = await fetch()
103104
except Exception:
104105
logging.exception("Failed to fetch users")
@@ -121,6 +122,7 @@ async def fetch_users():
121122
for user in users for unique in user.unique_card_ids
122123
},
123124
}
125+
logging.debug(f"Fetched {len(users)} users ({len(users_by_card)} cards) from Authentik")
124126

125127

126128
@app.get("/users/-/stats")
@@ -139,5 +141,37 @@ async def get_user_stats():
139141
async def get_user_by_card(card_id: str):
140142
user = users_by_card.get(card_id.lower())
141143
if user is None:
144+
logging.warning("[WS] Card %s not found", card_id)
142145
raise HTTPException(status_code=404, detail="Item not found")
146+
logging.info("[HTTP] User %s (%s) found", user.uid, card_id)
143147
return user
148+
149+
150+
@app.websocket("/ws")
151+
async def websocket_endpoint(websocket: WebSocket):
152+
logging.debug("[WS] New connection")
153+
await websocket.accept()
154+
try:
155+
async for message in websocket.iter_json():
156+
logging.debug("[WS] WS Request %r", message)
157+
match message:
158+
case {"action": "get", "object": "user", **kwargs}:
159+
logging.debug("[WS] Get user %r", kwargs)
160+
if "card_id" in kwargs and isinstance(kwargs["card_id"], str):
161+
user = users_by_card.get(kwargs["card_id"].lower())
162+
else:
163+
user = None
164+
165+
if user is None:
166+
logging.warning("[WS] Card %s not found", kwargs.get("card_id"))
167+
await websocket.send_json(
168+
{"status": "error", "error": "user not found"}
169+
)
170+
else:
171+
logging.info("[WS] User %s (%s) found", user.uid, kwargs.get("card_id"))
172+
await websocket.send_json(
173+
{"status": "ok", "object": user.model_dump()}
174+
)
175+
176+
except WebSocketDisconnect:
177+
pass

0 commit comments

Comments
 (0)