@@ -71,6 +71,7 @@ def __init__(
7171 sk = os .environ .get ("VOLC_SECRETKEY" )
7272 if api_key is None :
7373 api_key = os .environ .get ("ARK_API_KEY" )
74+ self ._base_url = base_url
7475 self .ak = ak
7576 self .sk = sk
7677 self .api_key = api_key
@@ -107,10 +108,10 @@ def _get_endpoint_sts_token(self, endpoint_id: str):
107108 def _get_endpoint_certificate (self , endpoint_id : str ) -> key_agreement_client :
108109 if self ._certificate_manager is None :
109110 cert_path = os .environ .get ("E2E_CERTIFICATE_PATH" )
110- if (self .ak is None or self .sk is None ) and cert_path is None :
111- raise ArkAPIError ("must set (ak and sk ) or (E2E_CERTIFICATE_PATH ) \
112- before get endpoint token." )
113- self ._certificate_manager = E2ECertificateManager (self .ak , self .sk , self .region )
111+ if (self .ak is None or self .sk is None ) and cert_path is None and self . api_key is None :
112+ raise ArkAPIError ("must set (api_key ) or (ak and sk ) \
113+ or (E2E_CERTIFICATE_PATH) before get endpoint token." )
114+ self ._certificate_manager = E2ECertificateManager (self .ak , self .sk , self .region , self . _base_url , self . api_key )
114115 return self ._certificate_manager .get (endpoint_id )
115116
116117 def _get_bot_sts_token (self , bot_id : str ):
@@ -164,6 +165,7 @@ def __init__(
164165 sk = os .environ .get ("VOLC_SECRETKEY" )
165166 if api_key is None :
166167 api_key = os .environ .get ("ARK_API_KEY" )
168+ self ._base_url = base_url
167169 self .ak = ak
168170 self .sk = sk
169171 self .api_key = api_key
@@ -200,10 +202,10 @@ def _get_endpoint_sts_token(self, endpoint_id: str):
200202 def _get_endpoint_certificate (self , endpoint_id : str ) -> key_agreement_client :
201203 if self ._certificate_manager is None :
202204 cert_path = os .environ .get ("E2E_CERTIFICATE_PATH" )
203- if (self .ak is None or self .sk is None ) and cert_path is None :
204- raise ArkAPIError ("must set (ak and sk ) or (E2E_CERTIFICATE_PATH ) \
205- before get endpoint token." )
206- self ._certificate_manager = E2ECertificateManager (self .ak , self .sk , self .region )
205+ if (self .ak is None or self .sk is None ) and cert_path is None and self . api_key is None :
206+ raise ArkAPIError ("must set (api_key ) or (ak and sk ) \
207+ or (E2E_CERTIFICATE_PATH) before get endpoint token." )
208+ self ._certificate_manager = E2ECertificateManager (self .ak , self .sk , self .region , self . _base_url , self . api_key )
207209 return self ._certificate_manager .get (endpoint_id )
208210
209211 @property
@@ -301,22 +303,46 @@ def _load_api_key(self, ep: str, duration_seconds: int,
301303
302304class E2ECertificateManager (object ):
303305
304- def __init__ (self , ak : str , sk : str , region : str ):
306+ class CertificateResponse ():
307+ Certificate : str
308+ """The certificate content."""
309+
310+ def __init__ (self , ak : str , sk : str , region : str , base_url : str | URL = BASE_URL , api_key : str | None = None ):
305311 self ._certificate_manager : Dict [str , key_agreement_client ] = {}
306312
307- import volcenginesdkcore
313+ # local cache prepare
314+ self ._init_local_cert_cache ()
308315
316+ # api instance prepare
317+ import volcenginesdkcore
318+ self ._api_instance_enabled = True
319+ if ak is None or sk is None :
320+ self ._api_instance_enabled = False
309321 configuration = volcenginesdkcore .Configuration ()
310322 configuration .ak = ak
311323 configuration .sk = sk
312324 configuration .region = region
313325 configuration .schema = "https"
314-
315326 volcenginesdkcore .Configuration .set_default (configuration )
316327 self .api_instance = volcenginesdkark .ARKApi ()
317328
329+ # global cert path prepare
318330 self .cert_path = os .environ .get ("E2E_CERTIFICATE_PATH" )
319331
332+ # ark client prepare
333+ self .client = Ark (
334+ base_url = base_url ,
335+ api_key = api_key ,
336+ ak = ak , sk = sk ,
337+ )
338+ self ._e2e_uri = "/e2e/get/certificate"
339+ self ._x_session_token = {'X-Session-Token' : self ._e2e_uri }
340+
341+ def _load_cert_by_cert_path (self ) -> str :
342+ with open (self .cert_path , 'r' ) as f :
343+ cert_pem = f .read ()
344+ return cert_pem
345+
320346 def _load_cert_by_ak_sk (self , ep : str ) -> str :
321347 get_endpoint_certificate_request = volcenginesdkark .GetEndpointCertificateRequest (
322348 id = ep
@@ -329,13 +355,52 @@ def _load_cert_by_ak_sk(self, ep: str) -> str:
329355
330356 return resp .pca_instance_certificate
331357
358+ def _sync_load_cert_by_auth (self , ep : str ) -> str :
359+ try : # try to make request with session header (used for header statistic)
360+ resp = self .client .post (self ._e2e_uri , options = {"headers" : self ._x_session_token },
361+ body = {"model" : ep }, cast_to = self .CertificateResponse )
362+ except Exception as e :
363+ raise ArkAPIError ("Getting Certificate failed: %s\n " % e )
364+ if 'error' in resp :
365+ raise ArkAPIError ("Getting Certificate failed: %s\n " % resp ['error' ])
366+ return resp ['Certificate' ]
367+
368+ def _save_cert_to_file (self , ep : str , cert_pem : str ):
369+ cert_file_path = os .path .join (self ._cert_storage_path , f"{ ep } .pem" )
370+ with open (cert_file_path , 'w' ) as f :
371+ f .write (cert_pem )
372+
373+ def _load_cert_locally (self , ep : str ) -> str | None :
374+ cert_file_path = os .path .join (self ._cert_storage_path , f"{ ep } .pem" )
375+ if os .path .exists (cert_file_path ):
376+ last_modified_time = os .path .getmtime (cert_file_path )
377+ current_time = time .time ()
378+ time_difference = current_time - last_modified_time
379+ if time_difference <= self ._cert_expiration_seconds :
380+ with open (cert_file_path , 'r' ) as f :
381+ return f .read ()
382+ else :
383+ os .remove (cert_file_path )
384+ return None
385+
386+ def _init_local_cert_cache (self ):
387+ self ._cert_storage_path = "/tmp/ark/certificates"
388+ self ._cert_expiration_seconds = 14 * 24 * 60 * 60 # 14 days
389+
390+ if not os .path .exists (self ._cert_storage_path ):
391+ os .makedirs (self ._cert_storage_path )
392+
332393 def get (self , ep : str ) -> key_agreement_client :
333394 if ep not in self ._certificate_manager :
334- if self .cert_path is not None :
335- with open (self .cert_path , 'r' ) as f :
336- cert_pem = f .read ()
337- else :
338- cert_pem = self ._load_cert_by_ak_sk (ep )
395+ cert_pem = self ._load_cert_locally (ep )
396+ if cert_pem is None :
397+ if self .cert_path is not None :
398+ cert_pem = self ._load_cert_by_cert_path ()
399+ elif self ._api_instance_enabled :
400+ cert_pem = self ._load_cert_by_ak_sk (ep )
401+ else :
402+ cert_pem = self ._sync_load_cert_by_auth (ep )
403+ self ._save_cert_to_file (ep , cert_pem )
339404 self ._certificate_manager [ep ] = key_agreement_client (
340405 certificate_pem_string = cert_pem
341406 )
0 commit comments