55
66import httpx
77
8- from fastapi import FastAPI , HTTPException
8+ from fastapi import FastAPI , HTTPException , WebSocket , WebSocketDisconnect
99from fastapi_utilities import repeat_every
1010from pydantic import AliasPath , BaseModel , Field , field_validator
1111from 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():
139141async 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