git reimport
This commit is contained in:
86
src/zvk/plugins/vk/api.py
Normal file
86
src/zvk/plugins/vk/api.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
from zvk.util.network import Network
|
||||
from zvk.util.zlogging import logger
|
||||
|
||||
# BOT_MESSAGE_RANDOM_ID_MIN = 1337000000
|
||||
# BOT_MESSAGE_RANDOM_ID_MAX = 1338000000
|
||||
|
||||
API_VERSION = '5.85'
|
||||
|
||||
|
||||
class MagicAccumulatingAttributeCatcher:
|
||||
api: VKApi
|
||||
full_method_name: str
|
||||
|
||||
def __init__(self, api, full_method_name=None):
|
||||
self.api = api
|
||||
|
||||
if full_method_name is None:
|
||||
full_method_name = ''
|
||||
|
||||
self.full_method_name = full_method_name
|
||||
|
||||
def __getattr__(self, item):
|
||||
return MagicAccumulatingAttributeCatcher(self.api, f'{self.full_method_name}.{item}')
|
||||
|
||||
async def __call__(self, **kwargs):
|
||||
return await self.api.call_method(self.full_method_name, **kwargs)
|
||||
|
||||
|
||||
API_CALL_RETRY_COUNT = 3
|
||||
|
||||
|
||||
class VKApi:
|
||||
"""
|
||||
VK api asynchronous interaction interface. Supports dope syntax like
|
||||
`await api.messages.get()`.
|
||||
"""
|
||||
|
||||
_access_token: str
|
||||
_net: Network
|
||||
|
||||
def __init__(self, config, net):
|
||||
self._access_token = config['api']['access_token']
|
||||
self._net = net
|
||||
|
||||
def __getattr__(self, name):
|
||||
return MagicAccumulatingAttributeCatcher(self, name)
|
||||
|
||||
async def call_method(self, full_method_name, **params):
|
||||
url = f'https://api.vk.com/method/{full_method_name}'
|
||||
|
||||
params['access_token'] = self._access_token
|
||||
params['v'] = API_VERSION
|
||||
|
||||
# TODO: random_id management
|
||||
# if self.name == 'messages.send' and 'random_id' not in params:
|
||||
# params['random_id'] = random.randint(BOT_MESSAGE_RANDOM_ID_MIN, BOT_MESSAGE_RANDOM_ID_MAX)
|
||||
# if self.name == 'messages.send' and 'message' in params:
|
||||
# params['message'] = params['message'].replace('--', '--')
|
||||
|
||||
# filter empty values
|
||||
params = {k: v for k, v in params.items() if v is not None}
|
||||
|
||||
for retry in range(API_CALL_RETRY_COUNT):
|
||||
response, result = await self._net.post_json(url, sequential=True, data=params)
|
||||
|
||||
if 'error' in result:
|
||||
error = result['error']
|
||||
if error['error_code'] == 6:
|
||||
logger.warning('Too many requests, waiting and retrying...')
|
||||
await asyncio.sleep(1)
|
||||
continue
|
||||
|
||||
raise RuntimeError(f'A significant VKApi error occurred {full_method_name}({params}) -> {error}')
|
||||
|
||||
if 'response' not in result:
|
||||
raise RuntimeError(f'Malformed api response {full_method_name}({params}) -> {result}')
|
||||
|
||||
logger.debug(f'VKApi call {full_method_name}({params}) -> {result}')
|
||||
|
||||
return result['response']
|
||||
|
||||
raise RuntimeError(f'VKApi call unsuccessful after retries: {full_method_name}({params})')
|
Reference in New Issue
Block a user