From 4a274ba4403433bd6db098eee6ee801b9da2ed56 Mon Sep 17 00:00:00 2001 From: Badiboy Date: Wed, 3 Nov 2021 18:48:46 +0300 Subject: [PATCH] Custom request sender Added apihelper.CUSTOM_REQUEST_SENDER option. It allows to substitute requests.request to your own function. --- README.md | 34 ++++++++++++++++++++++++++++++---- telebot/apihelper.py | 13 ++++++++++--- telebot/util.py | 15 +++++++++++++++ 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 39406d4..62e77c1 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ ## Contents - * [Getting started.](#getting-started) + * [Getting started](#getting-started) * [Writing your first bot](#writing-your-first-bot) * [Prerequisites](#prerequisites) * [A simple echo bot](#a-simple-echo-bot) @@ -49,6 +49,7 @@ * [Using web hooks](#using-web-hooks) * [Logging](#logging) * [Proxy](#proxy) + * [Testing](#testing) * [API conformance](#api-conformance) * [F.A.Q.](#faq) * [How can I distinguish a User and a GroupChat in message.chat?](#how-can-i-distinguish-a-user-and-a-groupchat-in-messagechat) @@ -57,7 +58,7 @@ * [More examples](#more-examples) * [Bots using this API](#bots-using-this-api) -## Getting started. +## Getting started This API is tested with Python 3.6-3.9 and Pypy 3. There are two ways to install the library: @@ -622,7 +623,6 @@ When using webhooks telegram sends one Update per call, for processing it you sh There are some examples using webhooks in the [examples/webhook_examples](examples/webhook_examples) directory. ### Logging - You can use the Telebot module logger to log debug info about Telebot. Use `telebot.logger` to get the logger of the TeleBot module. It is possible to add custom logging Handlers to the logger. Refer to the [Python logging module page](https://docs.python.org/2/library/logging.html) for more info. @@ -634,7 +634,6 @@ telebot.logger.setLevel(logging.DEBUG) # Outputs debug messages to console. ``` ### Proxy - You can use proxy for request. `apihelper.proxy` object will use by call `requests` proxies argument. ```python @@ -649,6 +648,33 @@ If you want to use socket5 proxy you need install dependency `pip install reques apihelper.proxy = {'https':'socks5://userproxy:password@proxy_address:port'} ``` +### Testing +You can disable or change the interaction with real Telegram server by using +```python +apihelper.CUSTOM_REQUEST_SENDER = your_handler +``` +parameter. You can pass there your own function that will be called instead of _requests.request_. + +For example: +```python +def custom_sender(method, url, **kwargs): + print("custom_sender. method: {}, url: {}, params: {}".format(method, url, kwargs.get("params"))) + result = util.CustomRequestResponse('{"ok":true,"result":{"message_id": 1, "date": 1, "chat": {"id": 1, "type": "private"}}}') + return result +``` + +Then you can use API and proceed requests in your handler code. +```python +apihelper.CUSTOM_REQUEST_SENDER = custom_sender +tb = TeleBot("test") +res = tb.send_message(123, "Test") +``` + +Result will be: + +`custom_sender. method: post, url: https://api.telegram.org/botololo/sendMessage, params: {'chat_id': '123', 'text': 'Test'}` + + ## API conformance diff --git a/telebot/apihelper.py b/telebot/apihelper.py index 9588c4e..e9162ce 100644 --- a/telebot/apihelper.py +++ b/telebot/apihelper.py @@ -40,10 +40,12 @@ RETRY_TIMEOUT = 2 MAX_RETRIES = 15 CUSTOM_SERIALIZER = None +CUSTOM_REQUEST_SENDER = None ENABLE_MIDDLEWARE = False + def _get_req_session(reset=False): if SESSION_TIME_TO_LIVE: # If session TTL is set - check time passed @@ -136,9 +138,14 @@ def _make_request(token, method_name, method='get', params=None, files=None): method, request_url, params=params, files=files, timeout=(connect_timeout, read_timeout), proxies=proxy) else: - result = _get_req_session().request( - method, request_url, params=params, files=files, - timeout=(connect_timeout, read_timeout), proxies=proxy) + if CUSTOM_REQUEST_SENDER: + result = CUSTOM_REQUEST_SENDER( + method, request_url, params=params, files=files, + timeout=(connect_timeout, read_timeout), proxies=proxy) + else: + result = _get_req_session().request( + method, request_url, params=params, files=files, + timeout=(connect_timeout, read_timeout), proxies=proxy) logger.debug("The server returned: '{0}'".format(result.text.encode('utf8'))) diff --git a/telebot/util.py b/telebot/util.py index f871f09..05105ef 100644 --- a/telebot/util.py +++ b/telebot/util.py @@ -12,6 +12,11 @@ import logging from telebot import types +try: + import ujson as json +except ImportError: + import json + try: # noinspection PyPackageRequirements from PIL import Image @@ -165,6 +170,16 @@ class AsyncTask: return self.result +class CustomRequestResponse(): + def __init__(self, json_text, status_code = 200, reason = ""): + self.status_code = status_code + self.text = json_text + self.reason = reason + + def json(self): + return json.loads(self.text) + + def async_dec(): def decorator(fn): def wrapper(*args, **kwargs):