11from __future__ import annotations
22
3+ from functools import cached_property
34import os
45from datetime import date , datetime
56from typing import Annotated , Any , MutableMapping , TypeVar
1011 EmailStr ,
1112 Field ,
1213 PrivateAttr ,
14+ computed_field ,
1315 field_validator ,
1416 model_validator ,
1517)
@@ -158,6 +160,15 @@ class RegistryConfig(BaseModel):
158160 Groups : MutableMapping [str , GroupConfig ]
159161 """DIRAC groups section, subsections represent the name of the group."""
160162
163+ @computed_field # type: ignore[misc]
164+ @cached_property
165+ def _preferred_username_to_sub (self ) -> dict [str , str ]:
166+ """Compute reverse lookup map from preferred username to user sub.
167+
168+ This computed field is automatically cached by Pydantic v2.
169+ """
170+ return {user .PreferedUsername : sub for sub , user in self .Users .items ()}
171+
161172 def sub_from_preferred_username (self , preferred_username : str ) -> str :
162173 """Get the user sub from the preferred username.
163174
@@ -171,10 +182,10 @@ def sub_from_preferred_username(self, preferred_username: str) -> str:
171182 KeyError: If no user with the given preferred username is found.
172183
173184 """
174- for sub , user in self . Users . items () :
175- if user . PreferedUsername == preferred_username :
176- return sub
177- raise KeyError (f"User { preferred_username } not found in registry" )
185+ try :
186+ return self . _preferred_username_to_sub [ preferred_username ]
187+ except KeyError :
188+ raise KeyError (f"User { preferred_username } not found in registry" ) from None
178189
179190
180191class DIRACConfig (BaseModel ):
0 commit comments