v1.1
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import asyncio
|
||||
from time import time
|
||||
from typing import Union
|
||||
|
||||
from aiohttp import ClientSession, FormData
|
||||
|
||||
from kurocore.logger import RequestLogger
|
||||
|
||||
|
||||
class VkToken:
|
||||
__slots__ = (
|
||||
'cur_requests', 'max_rps',
|
||||
'__token', '__last_req'
|
||||
)
|
||||
|
||||
def __init__(self, token):
|
||||
self.cur_requests = 0
|
||||
self.max_rps = 20
|
||||
self.__token = token
|
||||
self.__last_req = 0
|
||||
|
||||
def __call__(self):
|
||||
# if self.cur_requests >= self.max_rps:
|
||||
# raise TypeError('too many requests')
|
||||
# self.cur_requests += 1
|
||||
# self.__last_req = int(time())
|
||||
# if self.__last_req < int(time()):
|
||||
# self.cur_requests = 0
|
||||
return self.__token
|
||||
|
||||
|
||||
class VkTokenProvider:
|
||||
__slots__ = (
|
||||
'tokens',
|
||||
)
|
||||
|
||||
def __init__(self, tokens: (Union[VkToken], VkToken)):
|
||||
if type(tokens) is str:
|
||||
self.tokens = [VkToken(tokens)]
|
||||
else:
|
||||
self.tokens = [VkToken(t) for t in tokens]
|
||||
|
||||
def obtain_token(self):
|
||||
return self.tokens[0]()
|
||||
# for t in self.tokens:
|
||||
# if t.cur_requests < t.max_rps:
|
||||
# return t()
|
||||
# else:
|
||||
# raise ValueError('no free tokens!')
|
||||
|
||||
|
||||
class VK:
|
||||
__slots__ = (
|
||||
'token_provider',
|
||||
'v', 'session'
|
||||
)
|
||||
|
||||
def __init__(self, tokens: (str, list, tuple, set, frozenset), v='5.220'):
|
||||
self.token_provider = VkTokenProvider(tokens)
|
||||
self.v = v
|
||||
self.session = ClientSession()
|
||||
|
||||
def shutdown(self):
|
||||
asyncio.get_event_loop().run_until_complete(self.session.close())
|
||||
|
||||
async def call_method(self, method, **params):
|
||||
params.update({'v': self.v})
|
||||
|
||||
params.update({'access_token': self.token_provider.obtain_token()})
|
||||
|
||||
async with self.session.post(
|
||||
f'https://api.vk.com/method/{method}',
|
||||
data=FormData(params)
|
||||
) as res:
|
||||
j = await res.json()
|
||||
|
||||
if 'error' in j:
|
||||
error = j['error']
|
||||
raise VKApiException(error['error_msg'], error['error_code'])
|
||||
|
||||
params.update({"access_token": "[MASKED]"})
|
||||
RequestLogger.log.debug(f'method: {method} {params}')
|
||||
|
||||
if 'response' in j:
|
||||
return j['response']
|
||||
|
||||
return j
|
||||
|
||||
def get_api(self):
|
||||
return VkApiMethod(self)
|
||||
|
||||
|
||||
class VkApiMethod(object):
|
||||
__slots__ = ('_vk', '_method')
|
||||
|
||||
def __init__(self, vk, method=None):
|
||||
self._vk: VK = vk
|
||||
self._method = method
|
||||
|
||||
def __getattr__(self, method):
|
||||
if '_' in method:
|
||||
m = method.split('_')
|
||||
method = m[0] + ''.join(i.title() for i in m[1:])
|
||||
|
||||
return VkApiMethod(
|
||||
self._vk,
|
||||
(self._method + '.' if self._method else '') + method
|
||||
)
|
||||
|
||||
async def __call__(self, **kwargs):
|
||||
return await self._vk.call_method(self._method, **kwargs)
|
||||
|
||||
|
||||
class VKApiException(Exception):
|
||||
def __init__(self, msg, code):
|
||||
self.msg = msg
|
||||
self.code = code
|
||||
Reference in New Issue
Block a user