import functools import os import time from typing import Union import requests from classes.secret import Secret from exceptions import InvokeError from scheduler.block import BaseBlock class HashableDict(dict): def __hash__(self): return hash(tuple(sorted(self.items()))) class HashableList(list): def __hash__(self): return hash(tuple(sorted(self))) @functools.lru_cache def invoke( endpoint: str, app_id: str, access_key: str, access_secret: str, user: str, input: Union[str, HashableDict, HashableList], timeout: int = 300, ) -> dict: url = os.path.join(endpoint, "applications", app_id, "async") headers = { "x-langlink-access-key": access_key, "x-langlink-access-secret": access_secret, "x-langlink-user": user, } r = requests.post( url, headers=headers, params={ "return_trace": True, }, json={ "input": input, }, ) x = r.json() if r.status_code != 200: raise InvokeError( application_id=app_id, code=x["code"], message=x["message"], node_id=x.get("node_id"), ) interaction_id = x["id"] debug_url = os.path.join(endpoint, "applications", app_id, "debug", interaction_id) while timeout > 0: r = requests.get( debug_url, headers=headers, ) x = r.json() if r.status_code != 200: raise InvokeError( application_id=app_id, code=x["code"], message=x["message"], node_id=x.get("node_id"), ) logs = x["debug"] if len(logs) > 0: return dict((l["block"], l["output"]) for l in logs) time.sleep(10) timeout -= 10 raise TimeoutError(f"timeout on invoke app {app_id}") class Invoke(BaseBlock): def __init__( self, endpoint: str, app_id: str, access_key: str, access_secret: Secret, user: str, output_key: str, timeout: int = 300, ): super(Invoke, self).__init__() self.endpoint = endpoint self.app_id = app_id self.access_key = access_key self.access_secret = access_secret self.user = user self.output_key = output_key self.timeout = timeout def __call__(self, input: str) -> str: return invoke( self.endpoint, self.app_id, self.access_key, self.access_secret, self.user, input, self.timeout, ).get(self.output_key) class InvokeWithList(BaseBlock): def __init__( self, endpoint: str, app_id: str, access_key: str, access_secret: Secret, user: str, output_key: str, timeout: int = 300, ): super(InvokeWithList, self).__init__() self.endpoint = endpoint self.app_id = app_id self.access_key = access_key self.access_secret = access_secret self.user = user self.output_key = output_key self.timeout = timeout def __call__(self, input: list) -> str: return invoke( self.endpoint, self.app_id, self.access_key, self.access_secret, self.user, HashableList(input), self.timeout, ).get(self.output_key) class InvokeWithDict(BaseBlock): def __init__( self, endpoint: str, app_id: str, access_key: str, access_secret: Secret, user: str, output_key, timeout: int = 300, ): super(InvokeWithDict, self).__init__() self.endpoint = endpoint self.app_id = app_id self.access_key = access_key self.access_secret = access_secret self.user = user self.output_key = output_key self.timeout = timeout def __call__(self, input: dict) -> str: return invoke( self.endpoint, self.app_id, self.access_key, self.access_secret, self.user, HashableDict(input), self.timeout, ).get(self.output_key)