Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
await api_ws.send(json.dumps({
'action': action,
'params': params,
'echo': {
'seq': seq
}
}))
return _handle_api_result(await ResultStore.fetch(seq))
def _is_available(self) -> bool:
# available only when current event ws has a corresponding api ws
return event_ws and event_ws.headers.get(
'X-Self-ID', '*') in self._connected_clients
class UnifiedApi(Api):
"""
Call APIs through different communication methods
depending on availability.
"""
def __init__(self, *args,
http_api: Api = None,
ws_reverse_api: Api = None,
**kwargs):
super().__init__(*args, **kwargs)
self._http_api = http_api
self._ws_reverse_api = ws_reverse_api
async def call_action(self, action: str, **params) -> Any:
result = None
succeeded = False
def _handle_api_result(result: Optional[Dict[str, Any]]) -> Any:
"""
Retrieve 'data' field from the API result object.
:param result: API result that received from HTTP API
:return: the 'data' field in result object
:raise ActionFailed: the 'status' field is 'failed'
"""
if isinstance(result, dict):
if result.get('status') == 'failed':
raise ActionFailed(retcode=result.get('retcode'))
return result.get('data')
class HttpApi(Api):
"""Call APIs through HTTP."""
def __init__(self, api_root: Optional[str], access_token: Optional[str],
*args, **kwargs):
super().__init__(*args, **kwargs)
self._api_root = api_root.rstrip('/') if api_root else None
self._access_token = access_token
async def call_action(self, action: str, **params) -> Any:
if not self._is_available():
raise ApiNotAvailable
headers = {}
if self._access_token:
headers['Authorization'] = 'Token ' + self._access_token
@classmethod
async def fetch(cls, seq: int) -> Dict[str, Any]:
future = asyncio.get_event_loop().create_future()
cls._futures[seq] = future
try:
return await asyncio.wait_for(future, 60) # wait for only 60 secs
except asyncio.TimeoutError:
# haven't received any result until timeout,
# we consider this API call failed with a network error.
raise NetworkError('WebSocket API call timeout')
finally:
# don't forget to remove the future object
del cls._futures[seq]
class WebSocketReverseApi(Api):
"""Call APIs through reverse WebSocket."""
def __init__(self, connected_clients: Dict[str, Websocket],
*args, **kwargs):
super().__init__(*args, **kwargs)
self._connected_clients = connected_clients
async def call_action(self, action: str, **params) -> Any:
api_ws = None
if self._is_available():
api_ws = self._connected_clients.get(
event_ws.headers.get('X-Self-ID', '*'))
elif params.get('self_id'):
api_ws = self._connected_clients.get(str(params['self_id']))
elif len(self._connected_clients) == 1:
api_ws = list(self._connected_clients.values())[0]