Skip to content

Commit 980f969

Browse files
committed
fix: Parsing None in card lists
Authentik sometimes returns None instead of empty list when one doesn't have cards defined. Now "None" shouldn't be an issue.
1 parent 479f9c7 commit 980f969

1 file changed

Lines changed: 40 additions & 23 deletions

File tree

main.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import os
1+
import logging
22
from contextlib import asynccontextmanager
33
from datetime import datetime
44
from typing import Annotated, Any
@@ -7,7 +7,8 @@
77

88
from fastapi import FastAPI, HTTPException
99
from fastapi_utilities import repeat_every
10-
from pydantic import AliasPath, BaseModel, Field
10+
from pydantic import AliasPath, BaseModel, Field, field_validator
11+
from pydantic_core import PydanticUseDefault
1112
from pydantic_settings import BaseSettings
1213

1314

@@ -39,7 +40,16 @@ class User(BaseModel):
3940
uid: Annotated[str, Field(validation_alias="username")]
4041
mifare_card_ids: Annotated[list[str], Field(validation_alias=AliasPath("attributes", "mifareCardId"))] = []
4142
unique_card_ids: Annotated[list[str], Field(validation_alias=AliasPath("attributes", "uniquecardId"))] = []
42-
membership_expiration: Annotated[int, Field(validation_alias=AliasPath("attributes", "membershipExpirationTimestamp"))]
43+
membership_expiration: Annotated[
44+
int,
45+
Field(validation_alias=AliasPath("attributes", "membershipExpirationTimestamp"))
46+
]
47+
48+
@field_validator("mifare_card_ids", "unique_card_ids", mode='plain')
49+
def use_default_for_missing_cards(cls, v) -> str:
50+
if v is None:
51+
raise PydanticUseDefault()
52+
return v
4353

4454

4555
class Settings(BaseSettings):
@@ -74,7 +84,10 @@ async def fetch() -> list[User]:
7484
headers={"Authorization": f"Bearer {config.authentik_token}"},
7585
timeout=15.0,
7686
) as client:
77-
response = await client.get("https://auth.apps.hskrk.pl/api/v3/core/users/?attributes={\"membershipExpirationTimestamp__gt\": 1734998400}&page_size=200")
87+
response = await client.get(
88+
"https://auth.apps.hskrk.pl/api/v3/core/users/"
89+
"?attributes={\"membershipExpirationTimestamp__gt\": 1734998400}&page_size=200",
90+
)
7891
return [
7992
User(**u)
8093
for u in response.json()['results']
@@ -85,25 +98,29 @@ async def fetch() -> list[User]:
8598
async def fetch_users():
8699
global users
87100
global users_by_card
88-
users = await fetch()
89-
users_by_card = {
90-
**{
91-
mifare.lower(): user
92-
for user in users for mifare in user.mifare_card_ids
93-
},
94-
**{
95-
transform_card_number_to_unique(mifare).lower(): user
96-
for user in users for mifare in user.mifare_card_ids
97-
},
98-
**{
99-
unique.lower(): user
100-
for user in users for unique in user.unique_card_ids
101-
},
102-
**{
103-
transform_card_number_to_mifare(unique).lower(): user
104-
for user in users for unique in user.unique_card_ids
105-
},
106-
}
101+
try:
102+
users = await fetch()
103+
except Exception:
104+
logging.exception("Failed to fetch users")
105+
else:
106+
users_by_card = {
107+
**{
108+
mifare.lower(): user
109+
for user in users for mifare in user.mifare_card_ids
110+
},
111+
**{
112+
transform_card_number_to_unique(mifare).lower(): user
113+
for user in users for mifare in user.mifare_card_ids
114+
},
115+
**{
116+
unique.lower(): user
117+
for user in users for unique in user.unique_card_ids
118+
},
119+
**{
120+
transform_card_number_to_mifare(unique).lower(): user
121+
for user in users for unique in user.unique_card_ids
122+
},
123+
}
107124

108125

109126
@app.get("/users/-/stats")

0 commit comments

Comments
 (0)