11import logging
2+ import sys
23from contextlib import asynccontextmanager
3- from datetime import datetime
4+ from datetime import datetime , UTC
45from typing import Annotated , Any
56
67import httpx
@@ -61,9 +62,9 @@ class Settings(BaseSettings):
6162
6263users : list [User ] = []
6364users_by_card : dict [str , User ] = {}
64- users_last_success_run : datetime | None
65- users_last_failed_run : datetime | None
66- users_last_failed_reason : Any
65+ users_last_success_run : datetime | None = None
66+ users_last_failed_run : datetime | None = None
67+ users_last_failed_reason : Any = None
6768
6869
6970@asynccontextmanager
@@ -108,9 +109,15 @@ async def fetch_users():
108109 try :
109110 logging .debug ("Fetching users from Authentik" )
110111 users = await fetch ()
111- except Exception :
112+ except Exception as ex :
112113 logging .exception ("Failed to fetch users" )
114+ global users_last_failed_run
115+ global users_last_failed_reason
116+ users_last_failed_run = datetime .now (tz = UTC )
117+ users_last_failed_reason = ex
113118 else :
119+ global users_last_success_run
120+ users_last_success_run = datetime .now (tz = UTC )
114121 users_by_card = {
115122 ** {
116123 mifare .lower (): user
@@ -135,6 +142,9 @@ async def fetch_users():
135142@app .get ("/users/-/stats" )
136143async def get_user_stats ():
137144 return {
145+ "last_success_run" : users_last_success_run .isoformat ().replace ("+00:00" , "Z" ) if users_last_success_run else None ,
146+ "last_failed_run" : users_last_failed_run .isoformat ().replace ("+00:00" , "Z" ) if users_last_failed_run else None ,
147+ "last_failed_reason" : str (users_last_failed_reason ) if users_last_failed_reason else None ,
138148 "users" : {
139149 "count" : len (users ),
140150 },
0 commit comments