1
1
import requests
2
2
3
- from cachetools import TTLCache , cached
3
+ from cachetools import TTLCache , LRUCache , cached
4
4
from cachetools .keys import hashkey
5
5
from pathlib import Path
6
6
from tempfile import NamedTemporaryFile
7
7
from typing import Any
8
+ from collections .abc import Generator
8
9
from DIRAC import gConfig
9
10
from DIRAC .ConfigurationSystem .Client .Helpers import Registry
10
-
11
+ from contextlib import contextmanager
11
12
12
13
from diracx .core .preferences import DiracxPreferences
13
14
25
26
DEFAULT_TOKEN_CACHE_TTL = 5 * 60
26
27
DEFAULT_TOKEN_CACHE_SIZE = 1024
27
28
29
+ legacy_exchange_session = requests .Session ()
30
+
28
31
29
32
def get_token (
30
33
username : str , group : str , dirac_properties : set [str ], * , expires_minutes : int | None = None , source : str = ""
@@ -42,7 +45,7 @@ def get_token(
42
45
vo = Registry .getVOForGroup (group )
43
46
scopes = [f"vo:{ vo } " , f"group:{ group } " ] + [f"property:{ prop } " for prop in dirac_properties ]
44
47
45
- r = requests .get (
48
+ r = legacy_exchange_session .get (
46
49
f"{ diracxUrl } /api/auth/legacy-exchange" ,
47
50
params = {
48
51
"preferred_username" : username ,
@@ -71,7 +74,11 @@ def _get_token_file(username: str, group: str, dirac_properties: set[str], *, so
71
74
return token_location
72
75
73
76
74
- def TheImpersonator (credDict : dict [str , Any ], * , source : str = "" ) -> SyncDiracClient :
77
+ diracx_client_cache = LRUCache (maxsize = 64 )
78
+
79
+
80
+ @contextmanager
81
+ def TheImpersonator (credDict : dict [str , Any ], * , source : str = "" ) -> Generator [SyncDiracClient , None , None ]:
75
82
"""
76
83
Client to be used by DIRAC server needing to impersonate
77
84
a user for diracx.
@@ -90,6 +97,10 @@ def TheImpersonator(credDict: dict[str, Any], *, source: str = "") -> SyncDiracC
90
97
set (credDict .get ("groupProperties" , []) + credDict .get ("properties" , [])),
91
98
source = source ,
92
99
)
93
- pref = DiracxPreferences (url = diracxUrl , credentials_path = token_location )
94
-
95
- return SyncDiracClient (diracx_preferences = pref )
100
+ client = diracx_client_cache .get (token_location )
101
+ if client is None :
102
+ pref = DiracxPreferences (url = diracxUrl , credentials_path = token_location )
103
+ client = SyncDiracClient (diracx_preferences = pref )
104
+ client .__enter__ ()
105
+ diracx_client_cache [token_location ] = client
106
+ yield client
0 commit comments