33"""Cache handling for kernel specs."""
44
55import os
6- from typing import Dict , Optional , Union
6+ from typing import Dict , Optional , Set , Union
77
88from jupyter_client .kernelspec import KernelSpec
99from jupyter_server .utils import ensure_async
@@ -33,7 +33,7 @@ class KernelSpecCache(SingletonConfigurable):
3333
3434 cache_enabled_env = "EG_KERNELSPEC_CACHE_ENABLED"
3535 cache_enabled = CBool (
36- False ,
36+ True ,
3737 config = True ,
3838 help = """Enable Kernel Specification caching. (EG_KERNELSPEC_CACHE_ENABLED env var)""" ,
3939 )
@@ -110,7 +110,7 @@ def get_item(self, kernel_name: str) -> Optional[KernelSpec]:
110110 )
111111 return kernelspec
112112
113- def get_all_items (self ) -> Optional [ Dict [str , CacheItemType ] ]:
113+ def get_all_items (self ) -> Dict [str , CacheItemType ]:
114114 """Retrieves all kernel specification from the cache.
115115
116116 If cache is disabled or no items are in the cache, an empty dictionary is returned;
@@ -140,6 +140,34 @@ def put_item(self, kernel_name: str, cache_item: Union[KernelSpec, CacheItemType
140140 kernel_name = kernel_name
141141 )
142142 )
143+ # Irrespective of cache enablement, add/update the 'metadata.client_envs' entry
144+ # with the set of configured values. If the stanza already exists in the kernelspec
145+ # update with the union of it and those values configured via `EnterpriseGatewayApp'.
146+ # We apply this logic here so that its only performed once for cached values or on
147+ # every retrieval when caching is not enabled.
148+ # Note: We only need to do this if we have a KernelSpec instance, since CacheItemType
149+ # instances will have already been modified.
150+
151+ # Create a set from the configured value, update it with the (potential) value
152+ # in the kernelspec, and apply the changes back to the kernelspec.
153+
154+ client_envs : Set [str ] = set (self .parent .client_envs )
155+ kspec_client_envs : Set [str ]
156+ if type (cache_item ) is KernelSpec :
157+ kspec : KernelSpec = cache_item
158+ kspec_client_envs = set (kspec .metadata .get ("client_envs" , []))
159+ else :
160+ kspec_client_envs = set (cache_item ["spec" ].get ("metadata" , {}).get ("client_envs" , []))
161+
162+ client_envs .update (kspec_client_envs )
163+ if type (cache_item ) is KernelSpec :
164+ kspec : KernelSpec = cache_item
165+ kspec .metadata ["client_envs" ] = list (client_envs )
166+ else :
167+ if "metadata" not in cache_item ["spec" ]:
168+ cache_item ["spec" ]["metadata" ] = {}
169+ cache_item ["spec" ]["metadata" ]["client_envs" ] = list (client_envs )
170+
143171 if self .cache_enabled :
144172 if type (cache_item ) is KernelSpec :
145173 cache_item = KernelSpecCache .kernel_spec_to_cache_item (cache_item )
@@ -159,9 +187,8 @@ def put_item(self, kernel_name: str, cache_item: Union[KernelSpec, CacheItemType
159187
160188 def put_all_items (self , kernelspecs : Dict [str , CacheItemType ]) -> None :
161189 """Adds or updates a dictionary of kernel specification in the cache."""
162- if self .cache_enabled and kernelspecs :
163- for kernel_name , cache_item in kernelspecs .items ():
164- self .put_item (kernel_name , cache_item )
190+ for kernel_name , cache_item in kernelspecs .items ():
191+ self .put_item (kernel_name , cache_item )
165192
166193 def remove_item (self , kernel_name : str ) -> Optional [CacheItemType ]:
167194 """Removes the cache item corresponding to kernel_name from the cache."""
@@ -212,7 +239,7 @@ def _initialize(self):
212239
213240 @staticmethod
214241 def kernel_spec_to_cache_item (kernelspec : KernelSpec ) -> CacheItemType :
215- """Convets a KernelSpec instance to a CacheItemType for storage into the cache."""
242+ """Converts a KernelSpec instance to a CacheItemType for storage into the cache."""
216243 cache_item = dict ()
217244 cache_item ["spec" ] = kernelspec .to_dict ()
218245 cache_item ["resource_dir" ] = kernelspec .resource_dir
@@ -221,7 +248,8 @@ def kernel_spec_to_cache_item(kernelspec: KernelSpec) -> CacheItemType:
221248 @staticmethod
222249 def cache_item_to_kernel_spec (cache_item : CacheItemType ) -> KernelSpec :
223250 """Converts a CacheItemType to a KernelSpec instance for user consumption."""
224- return KernelSpec .from_resource_dir (cache_item ["resource_dir" ])
251+ kernel_spec = KernelSpec (resource_dir = cache_item ["resource_dir" ], ** cache_item ["spec" ])
252+ return kernel_spec
225253
226254
227255class KernelSpecChangeHandler (FileSystemEventHandler ):
0 commit comments