Rename api.ApiMethods to api.Methods and move module to bot.

This commit is contained in:
Alex Root Junior 2017-06-04 11:38:05 +03:00
parent 08124e7d38
commit 68eff96798
2 changed files with 48 additions and 47 deletions

130
aiogram/bot/api.py Normal file
View file

@ -0,0 +1,130 @@
import logging
import os
import aiohttp
from ..exceptions import ValidationError, TelegramAPIError
log = logging.getLogger('aiogram')
API_URL = "https://api.telegram.org/bot{token}/{method}"
FILE_URL = "https://api.telegram.org/file/bot{token}/{path}"
def check_token(token):
if any(x.isspace() for x in token):
raise ValidationError('Token is invalid!')
left, sep, right = token.partition(':')
if (not sep) or (not left.isdigit()) or (len(left) < 3):
raise ValidationError('Token is invalid!')
return True
async def _check_result(method_name, response):
"""
Checks whether `result` is a valid API response.
A result is considered invalid if:
- The server returned an HTTP response code other than 200
- The content of the result is invalid JSON.
- The method call was unsuccessful (The JSON 'ok' field equals False)
:raises ApiException: if one of the above listed cases is applicable
:param method_name: The name of the method called
:param response: The returned response of the method request
:return: The result parsed to a JSON dictionary.
"""
if response.status != 200:
body = await response.text()
raise TelegramAPIError(f"The server returned HTTP {response.status}. Response body:\n[{body}]",
method_name, response.status, body)
result_json = await response.json()
if not result_json.get('ok'):
body = await response.text()
code = result_json.get('error_code')
description = result_json.get('description')
raise TelegramAPIError(f"Error code: {code} Description {description}",
method_name, response.status, body)
log.debug(f"Response for '{method_name}': {result_json}")
return result_json.get('result')
def _guess_filename(obj):
name = getattr(obj, 'name', None)
if name and isinstance(name, str) and name[0] != '<' and name[-1] != '>':
return os.path.basename(name)
def _compose_data(params, files=None):
data = aiohttp.formdata.FormData()
if params:
for key, value in params.items():
data.add_field(key, str(value))
if files:
for key, f in files.items():
if isinstance(f, tuple):
if len(f) == 2:
filename, fileobj = f
else:
raise ValueError('Tuple must have exactly 2 elements: filename, fileobj')
else:
filename, fileobj = _guess_filename(f) or key, f
data.add_field(key, fileobj, filename=filename)
return data
async def request(session, token, method, data=None, files=None):
log.debug(f"Make request: '{method}' with data: {data or {}} and files {files or {}}")
data = _compose_data(data, files)
url = API_URL.format(token=token, method=method)
async with session.post(url, data=data) as response:
return await _check_result(method, response)
class Methods:
GET_ME = 'getMe'
GET_UPDATES = 'getUpdates'
SET_WEBHOOK = 'setWebhook'
DELETE_WEBHOOK = 'deleteWebhook'
GET_WEBHOOK_INFO = 'getWebhookInfo'
SEND_MESSAGE = 'sendMessage'
FORWARD_MESSAGE = 'forwardMessage'
SEND_PHOTO = 'sendPhoto'
SEND_AUDIO = 'sendAudio'
SEND_DOCUMENT = 'sendDocument'
SEND_STICKER = 'sendSticker'
SEND_VIDEO = 'sendVideo'
SEND_VOICE = 'sendVoice'
SEND_VIDEO_NOTE = 'sendVideoNote'
SEND_LOCATION = 'sendLocation'
SEND_VENUE = 'sendVenue'
SEND_CONTACT = 'sendContact'
SEND_CHAT_ACTION = 'sendChatAction'
GET_USER_PROFILE_PHOTOS = 'getUserProfilePhotos'
GET_FILE = 'getFile'
KICK_CHAT_MEMBER = 'kickChatMember'
UNBAN_CHAT_MEMBER = 'unbanChatMember'
LEAVE_CHAT = 'leaveChat'
GET_CHAT = 'getChat'
GET_CHAT_ADMINISTRATORS = 'getChatAdministrators'
GET_CHAT_MEMBERS_COUNT = 'getChatMembersCount'
GET_CHAT_MEMBER = 'getChatMember'
ANSWER_CALLBACK_QUERY = 'answerCallbackQuery'
ANSWER_INLINE_QUERY = 'answerInlineQuery'
EDIT_MESSAGE_TEXT = 'editMessageText'
EDIT_MESSAGE_CAPTION = 'editMessageCaption'
EDIT_MESSAGE_REPLY_MARKUP = 'editMessageReplyMarkup'
DELETE_MESSAGE = 'deleteMessage'
SEND_INVOICE = 'sendInvoice'
ANSWER_SHIPPING_QUERY = 'answerShippingQuery'
ANSWER_PRE_CHECKOUT_QUERY = 'answerPreCheckoutQuery'
SEND_GAME = 'sendGame'
SET_GAME_SCORE = 'setGameScore'
GET_GAME_HIGH_SCORES = 'getGameHighScores'

View file

@ -4,7 +4,8 @@ import json
import aiohttp
from .. import api, types
from . import api
from .. import types
from ..utils.payload import generate_payload
@ -112,13 +113,13 @@ class BaseBot:
async def _send_file(self, file_type, file, payload):
methods = {
'photo': api.ApiMethods.SEND_PHOTO,
'audio': api.ApiMethods.SEND_AUDIO,
'document': api.ApiMethods.SEND_DOCUMENT,
'sticker': api.ApiMethods.SEND_STICKER,
'video': api.ApiMethods.SEND_VIDEO,
'voice': api.ApiMethods.SEND_VOICE,
'video_note': api.ApiMethods.SEND_VIDEO_NOTE
'photo': api.Methods.SEND_PHOTO,
'audio': api.Methods.SEND_AUDIO,
'document': api.Methods.SEND_DOCUMENT,
'sticker': api.Methods.SEND_STICKER,
'video': api.Methods.SEND_VIDEO,
'voice': api.Methods.SEND_VOICE,
'video_note': api.Methods.SEND_VIDEO_NOTE
}
method = methods[file_type]
@ -127,40 +128,40 @@ class BaseBot:
req = self.request(method, payload)
elif isinstance(file, io.IOBase):
data = {file_type: file.read()}
req = self.request(api.ApiMethods.SEND_PHOTO, payload, data)
req = self.request(api.Methods.SEND_PHOTO, payload, data)
elif isinstance(file, bytes):
data = {file_type: file}
req = self.request(api.ApiMethods.SEND_PHOTO, payload, data)
req = self.request(api.Methods.SEND_PHOTO, payload, data)
else:
data = {file_type: file}
req = self.request(api.ApiMethods.SEND_PHOTO, payload, data)
req = self.request(api.Methods.SEND_PHOTO, payload, data)
return await req
async def get_me(self) -> types.User:
return await self.request(api.ApiMethods.GET_ME)
return await self.request(api.Methods.GET_ME)
async def get_updates(self, offset=None, limit=None, timeout=None, allowed_updates=None) -> [dict, ...]:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.GET_UPDATES, payload)
return await self.request(api.Methods.GET_UPDATES, payload)
async def set_webhook(self, url, certificate=None, max_connections=None, allowed_updates=None) -> dict:
payload = generate_payload(**locals(), exclude='certificate')
if certificate:
cert = {'certificate': certificate}
req = self.request(api.ApiMethods.SET_WEBHOOK, payload, cert)
req = self.request(api.Methods.SET_WEBHOOK, payload, cert)
else:
req = self.request(api.ApiMethods.SET_WEBHOOK, payload)
req = self.request(api.Methods.SET_WEBHOOK, payload)
return await req
async def delete_webhook(self) -> bool:
payload = {}
return await self.request(api.ApiMethods.DELETE_WEBHOOK, payload)
return await self.request(api.Methods.DELETE_WEBHOOK, payload)
async def get_webhook_info(self) -> types.WebhookInfo:
payload = {}
return await self.request(api.ApiMethods.GET_WEBHOOK_INFO, payload)
return await self.request(api.Methods.GET_WEBHOOK_INFO, payload)
async def send_message(self, chat_id, text, parse_mode=None, disable_web_page_preview=None,
disable_notification=None, reply_to_message_id=None, reply_markup=None) -> dict:
@ -168,11 +169,11 @@ class BaseBot:
reply_markup = json.dumps(reply_markup)
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.SEND_MESSAGE, payload)
return await self.request(api.Methods.SEND_MESSAGE, payload)
async def forward_message(self, chat_id, from_chat_id, message_id, disable_notification=None) -> dict:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.FORWARD_MESSAGE, payload)
return await self.request(api.Methods.FORWARD_MESSAGE, payload)
async def send_photo(self, chat_id, photo, caption=None, disable_notification=None, reply_to_message_id=None,
reply_markup=None) -> dict:
@ -243,7 +244,7 @@ class BaseBot:
reply_markup = json.dumps(reply_markup)
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.SEND_LOCATION, payload)
return await self.request(api.Methods.SEND_LOCATION, payload)
async def send_venue(self, chat_id, latitude, longitude, title, address, foursquare_id, disable_notification=None,
reply_to_message_id=None, reply_markup=None) -> dict:
@ -251,7 +252,7 @@ class BaseBot:
reply_markup = json.dumps(reply_markup)
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.SEND_VENUE, payload)
return await self.request(api.Methods.SEND_VENUE, payload)
async def send_contact(self, chat_id, phone_number, first_name, last_name=None, disable_notification=None,
reply_to_message_id=None, reply_markup=None) -> types.Message:
@ -259,52 +260,52 @@ class BaseBot:
reply_markup = json.dumps(reply_markup)
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.SEND_CONTACT, payload)
return await self.request(api.Methods.SEND_CONTACT, payload)
async def send_chat_action(self, chat_id, action) -> bool:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.SEND_CHAT_ACTION, payload)
return await self.request(api.Methods.SEND_CHAT_ACTION, payload)
async def get_user_profile_photos(self, user_id, offset=None, limit=None) -> dict:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.GET_USER_PROFILE_PHOTOS, payload)
return await self.request(api.Methods.GET_USER_PROFILE_PHOTOS, payload)
async def get_file(self, file_id) -> dict:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.GET_FILE, payload)
return await self.request(api.Methods.GET_FILE, payload)
async def kick_chat_user(self, chat_id, user_id) -> bool:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.KICK_CHAT_MEMBER, payload)
return await self.request(api.Methods.KICK_CHAT_MEMBER, payload)
async def unban_chat_member(self, chat_id, user_id) -> bool:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.UNBAN_CHAT_MEMBER, payload)
return await self.request(api.Methods.UNBAN_CHAT_MEMBER, payload)
async def leave_chat(self, chat_id) -> bool:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.LEAVE_CHAT, payload)
return await self.request(api.Methods.LEAVE_CHAT, payload)
async def get_chat(self, chat_id) -> types.Chat:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.GET_CHAT, payload)
return await self.request(api.Methods.GET_CHAT, payload)
async def get_chat_administrators(self, chat_id) -> [types.ChatMember]:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.GET_CHAT_ADMINISTRATORS, payload)
return await self.request(api.Methods.GET_CHAT_ADMINISTRATORS, payload)
async def get_chat_members_count(self, chat_id) -> int:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.GET_CHAT_MEMBERS_COUNT, payload)
return await self.request(api.Methods.GET_CHAT_MEMBERS_COUNT, payload)
async def get_chat_member(self, chat_id, user_id) -> types.ChatMember:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.GET_CHAT_MEMBER, payload)
return await self.request(api.Methods.GET_CHAT_MEMBER, payload)
async def answer_callback_query(self, callback_query_id, text=None, show_alert=None, url=None,
cache_time=None) -> bool:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.ANSWER_CALLBACK_QUERY, payload)
return await self.request(api.Methods.ANSWER_CALLBACK_QUERY, payload)
async def answer_inline_query(self, inline_query_id, results, cache_time=None, is_personal=None, next_offset=None,
switch_pm_text=None, switch_pm_parameter=None) -> bool:
@ -312,7 +313,7 @@ class BaseBot:
results = json.dumps([item for item in results])
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.ANSWER_INLINE_QUERY, payload)
return await self.request(api.Methods.ANSWER_INLINE_QUERY, payload)
async def edit_message_text(self, text, chat_id=None, message_id=None, inline_message_id=None, parse_mode=None,
disable_web_page_preview=None, reply_markup=None) -> dict or bool:
@ -320,7 +321,7 @@ class BaseBot:
reply_markup = json.dumps(reply_markup)
payload = generate_payload(**locals())
raw = await self.request(api.ApiMethods.EDIT_MESSAGE_TEXT, payload)
raw = await self.request(api.Methods.EDIT_MESSAGE_TEXT, payload)
if raw is True:
return raw
return raw
@ -331,7 +332,7 @@ class BaseBot:
reply_markup = json.dumps(reply_markup)
payload = generate_payload(**locals())
raw = await self.request(api.ApiMethods.EDIT_MESSAGE_CAPTION, payload)
raw = await self.request(api.Methods.EDIT_MESSAGE_CAPTION, payload)
if raw is True:
return raw
return raw
@ -342,14 +343,14 @@ class BaseBot:
reply_markup = json.dumps(reply_markup)
payload = generate_payload(**locals())
raw = await self.request(api.ApiMethods.EDIT_MESSAGE_REPLY_MARKUP, payload)
raw = await self.request(api.Methods.EDIT_MESSAGE_REPLY_MARKUP, payload)
if raw is True:
return raw
return raw
async def delete_message(self, chat_id, message_id) -> bool:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.DELETE_MESSAGE, payload)
return await self.request(api.Methods.DELETE_MESSAGE, payload)
async def send_invoice(self, chat_id: int, title: str, description: str, payload: str, provider_token: str,
start_parameter: str, currency: str, prices: list, photo_url: str = None,
@ -366,7 +367,7 @@ class BaseBot:
payload_ = generate_payload(**locals())
return await self.request(api.ApiMethods.SEND_INVOICE, payload_)
return await self.request(api.Methods.SEND_INVOICE, payload_)
async def answer_shipping_query(self, shipping_query_id: str, ok: bool,
shipping_options: [types.ShippingOption] = None, error_message: str = None) -> bool:
@ -375,12 +376,12 @@ class BaseBot:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.ANSWER_SHIPPING_QUERY, payload)
return await self.request(api.Methods.ANSWER_SHIPPING_QUERY, payload)
async def answer_pre_checkout_query(self, pre_checkout_query_id: str, ok: bool, error_message: str = None) -> bool:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.ANSWER_PRE_CHECKOUT_QUERY, payload)
return await self.request(api.Methods.ANSWER_PRE_CHECKOUT_QUERY, payload)
async def send_game(self, chat_id: int, game_short_name: str, disable_notification: bool = None,
reply_to_message_id: int = None,
@ -390,14 +391,14 @@ class BaseBot:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.SEND_GAME, payload)
return await self.request(api.Methods.SEND_GAME, payload)
async def set_game_score(self, user_id: int, score: int, force: bool = None, disable_edit_message: bool = None,
chat_id: int = None, message_id: int = None,
inline_message_id: str = None) -> dict or bool:
payload = generate_payload(**locals())
raw = self.request(api.ApiMethods.SET_GAME_SCORE, payload)
raw = self.request(api.Methods.SET_GAME_SCORE, payload)
if raw is True:
return raw
return raw
@ -406,4 +407,4 @@ class BaseBot:
inline_message_id: str = None) -> dict:
payload = generate_payload(**locals())
return await self.request(api.ApiMethods.GET_GAME_HIGH_SCORES, payload)
return await self.request(api.Methods.GET_GAME_HIGH_SCORES, payload)