Skip to content

New rate limiting mechanism #3148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 46 commits into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
fa93a2a
Very first start on a rate limit system
Bibo-Joshi Jul 6, 2022
652f9e3
A bit more work for BaseRateLimiter
Bibo-Joshi Jul 7, 2022
f732459
Get a first proof of concept working
Bibo-Joshi Jul 8, 2022
f90c5e1
Merge branch 'master' into rate-limiter
Bibo-Joshi Jul 9, 2022
103f53d
generics
Bibo-Joshi Jul 9, 2022
79f9295
applicationbuilder
Bibo-Joshi Jul 9, 2022
cd0158f
slots and max-retries
Bibo-Joshi Jul 9, 2022
5d66304
every group gets its own limiter & RetryAfter blocks all requests
Bibo-Joshi Jul 9, 2022
e980308
Fine tuning
Bibo-Joshi Jul 10, 2022
f41271b
add `aiolimiter` as optional dependency
Bibo-Joshi Jul 10, 2022
df72033
Merge branch 'master' into rate-limiter
Bibo-Joshi Jul 10, 2022
e409cf5
Bunch of documentation
Bibo-Joshi Jul 10, 2022
1e48021
smaller fixes
Bibo-Joshi Jul 10, 2022
d509e3b
try fixing docs build
Bibo-Joshi Jul 11, 2022
a407af3
get even more started on tests
Bibo-Joshi Jul 11, 2022
b9eb962
pre-commit & docs
Bibo-Joshi Jul 11, 2022
c77d1be
Update shortcut signature tests
Bibo-Joshi Jul 11, 2022
11caf7d
add two new tests
Bibo-Joshi Jul 12, 2022
8f7140f
Merge branch 'master' into rate-limiter
Bibo-Joshi Jul 12, 2022
8e8506b
More testing
Bibo-Joshi Jul 12, 2022
4ca7ce3
More testing
Bibo-Joshi Jul 13, 2022
1324c51
increase coverage
Bibo-Joshi Jul 13, 2022
63486be
Small updates regarding the reqs
Bibo-Joshi Jul 17, 2022
fadaa31
try stabilizing tests
Bibo-Joshi Jul 17, 2022
4f63760
try fixing worflows
Bibo-Joshi Jul 17, 2022
06cf68a
be a bit more generous for macos
Bibo-Joshi Jul 17, 2022
5e78181
Revert "be a bit more generous for macos"
Bibo-Joshi Jul 17, 2022
4495536
just skip tests on macos
Bibo-Joshi Jul 17, 2022
13ead3d
Apply suggestions from code review
Bibo-Joshi Aug 5, 2022
2a7c98d
pre-commit
Bibo-Joshi Aug 5, 2022
2f079df
get started on review
Bibo-Joshi Aug 5, 2022
734ab3e
Add reqs-all.txt
Bibo-Joshi Aug 18, 2022
ca7fdeb
Rename flags for testing opt deps
Bibo-Joshi Aug 18, 2022
4f3925a
handle integer chat_ids that are passed as string
Bibo-Joshi Aug 18, 2022
3f35a8b
Document global nature of RetryAfter handling
Bibo-Joshi Aug 18, 2022
1636783
add explanatory comments to a test
Bibo-Joshi Aug 18, 2022
2e4b763
test for api_kwargs as well
Bibo-Joshi Aug 18, 2022
6d06441
doc fix
Bibo-Joshi Aug 18, 2022
6ea7a7a
try fixing a test
Bibo-Joshi Aug 18, 2022
aeb7dcf
Merge branch 'master' into rate-limiter
Bibo-Joshi Aug 18, 2022
25b0800
deepsource
Bibo-Joshi Aug 18, 2022
97fe539
try fixing ci
Bibo-Joshi Aug 18, 2022
604380d
Merge branch 'master' into rate-limiter
Bibo-Joshi Aug 25, 2022
242d2e0
Adapt to API 6.2
Bibo-Joshi Aug 25, 2022
9dc6676
small fix
Bibo-Joshi Aug 25, 2022
a0797bb
deepsource
Bibo-Joshi Aug 25, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Setting things up

.. code-block:: bash

$ pip install -r requirements.txt -r requirements-dev.txt
$ pip install -r requirements-all.txt


5. Install pre-commit hooks:
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/docs-linkcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ jobs:
- name: Install dependencies
run: |
python -W ignore -m pip install --upgrade pip
python -W ignore -m pip install -r requirements.txt
python -W ignore -m pip install -r requirements-dev.txt
python -W ignore -m pip install -r docs/requirements-docs.txt
python -W ignore -m pip install -r requirements-all.txt
- name: Check Links
run: sphinx-build docs/source docs/build/html -W --keep-going -j auto -b linkcheck
4 changes: 1 addition & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ jobs:
- name: Install dependencies
run: |
python -W ignore -m pip install --upgrade pip
python -W ignore -m pip install -r requirements.txt
python -W ignore -m pip install -r requirements-dev.txt
python -W ignore -m pip install -r docs/requirements-docs.txt
python -W ignore -m pip install -r requirements-all.txt
- name: Build docs
run: sphinx-build docs/source docs/build/html -W --keep-going -j auto
3 changes: 2 additions & 1 deletion .github/workflows/pre-commit_dependencies_notifier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ on:
pull_request_target:
paths:
- requirements.txt
- requirements-opts.txt
- .pre-commit-config.yaml
permissions:
pull-requests: write
Expand All @@ -14,5 +15,5 @@ jobs:
- name: running the check
uses: Poolitzer/notifier-action@master
with:
notify-message: Hey! Looks like you edited the requirements or the pre-commit hooks. I'm just a friendly reminder to keep the additional dependencies for the hooks in sync with the requirements :)
notify-message: Hey! Looks like you edited the (optional) requirements or the pre-commit hooks. I'm just a friendly reminder to keep the additional dependencies for the hooks in sync with the requirements :)
repo-token: ${{ secrets.GITHUB_TOKEN }}
22 changes: 16 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,32 +42,41 @@ jobs:
python -W ignore -m pip install --upgrade pip
python -W ignore -m pip install -U codecov pytest-cov
python -W ignore -m pip install -r requirements.txt
python -W ignore -m pip install -r requirements-opts.txt
python -W ignore -m pip install -r requirements-dev.txt

- name: Test with pytest
# We run 3 different suites here
# We run 4 different suites here
# 1. Test just utils.datetime.py without pytz being installed
# 2. Test just test_no_passport.py without passport dependencies being installed
# 3. Test everything else
# 3. Test just test_rate_limiter.py without passport dependencies being installed
# 4. Test everything else
# The first & second one are achieved by mocking the corresponding import
# See test_helpers.py & test_no_passport.py for details
run: |
pytest -v --cov -k test_no_passport.py
no_passport_exit=$?
export TEST_NO_PASSPORT='false'
export TEST_PASSPORT='true'
pytest -v --cov --cov-append -k test_helpers.py
no_pytz_exit=$?
export TEST_NO_PYTZ='false'
export TEST_PYTZ='true'
pip uninstall aiolimiter -y
pytest -v --cov --cov-append -k test_ratelimiter.py
no_rate_limiter_exit=$?
export TEST_RATE_LIMITER='true'
pip install -r requirements-opts.txt
pytest -v --cov --cov-append
full_exit=$?
special_exit=$(( no_pytz_exit > no_passport_exit ? no_pytz_exit : no_passport_exit ))
special_exit=$(( special_exit > no_rate_limiter_exit ? special_exit : no_rate_limiter_exit ))
global_exit=$(( special_exit > full_exit ? special_exit : full_exit ))
exit ${global_exit}
env:
JOB_INDEX: ${{ strategy.job-index }}
BOTS: W3sidG9rZW4iOiAiNjk2MTg4NzMyOkFBR1Z3RUtmSEhsTmpzY3hFRE5LQXdraEdzdFpfa28xbUMwIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WldGaU1UUmxNbVF5TnpNeSIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIENQeXRob24gMi43IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMzkwOTgzOTk3IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzI3X2JvdCJ9LCB7InRva2VuIjogIjY3MTQ2ODg4NjpBQUdQR2ZjaVJJQlVORmU4MjR1SVZkcTdKZTNfWW5BVE5HdyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpHWXdPVGxrTXpNeE4yWTIiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNCIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ0NjAyMjUyMiIsICJib3RfdXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8zNF9ib3QifSwgeyJ0b2tlbiI6ICI2MjkzMjY1Mzg6QUFGUnJaSnJCN29CM211ekdzR0pYVXZHRTVDUXpNNUNVNG8iLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpNbU01WVdKaFl6a3hNMlUxIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgQ1B5dGhvbiAzLjUiLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDE0OTY5MTc3NTAiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfdHJhdmlzX2NweXRob25fMzVfYm90In0sIHsidG9rZW4iOiAiNjQwMjA4OTQzOkFBRmhCalFwOXFtM1JUeFN6VXBZekJRakNsZS1Kano1aGNrIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WXpoa1pUZzFOamMxWXpWbCIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIENQeXRob24gMy42IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMzMzODcxNDYxIiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19jcHl0aG9uXzM2X2JvdCJ9LCB7InRva2VuIjogIjY5NTEwNDA4ODpBQUhmenlsSU9qU0lJUy1lT25JMjB5MkUyMEhvZEhzZnotMCIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk9HUTFNRGd3WmpJd1pqRmwiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIFRyYXZpcyB1c2luZyBDUHl0aG9uIDMuNyIsICJzdXBlcl9ncm91cF9pZCI6ICItMTAwMTQ3ODI5MzcxNCIsICJib3RfdXNlcm5hbWUiOiAiQHB0Yl90cmF2aXNfY3B5dGhvbl8zN19ib3QifSwgeyJ0b2tlbiI6ICI2OTE0MjM1NTQ6QUFGOFdrakNaYm5IcVBfaTZHaFRZaXJGRWxackdhWU9oWDAiLCAicGF5bWVudF9wcm92aWRlcl90b2tlbiI6ICIyODQ2ODUwNjM6VEVTVDpZamM1TlRoaU1tUXlNV1ZoIiwgImJvdF9uYW1lIjogIlBUQiB0ZXN0cyBvbiBUcmF2aXMgdXNpbmcgUHlQeSAyLjciLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEzNjM5MzI1NzMiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfdHJhdmlzX3B5cHlfMjdfYm90In0sIHsidG9rZW4iOiAiNjg0MzM5OTg0OkFBRk1nRUVqcDAxcjVyQjAwN3lDZFZOc2c4QWxOc2FVLWNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TVRBek1UWTNNR1V5TmpnMCIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gVHJhdmlzIHVzaW5nIFB5UHkgMy41IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDA3ODM2NjA1IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX3RyYXZpc19weXB5XzM1X2JvdCJ9LCB7InRva2VuIjogIjY5MDA5MTM0NzpBQUZMbVI1cEFCNVljcGVfbU9oN3pNNEpGQk9oMHozVDBUbyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOlpEaGxOekU1TURrd1lXSmkiLCAiYm90X25hbWUiOiAiUFRCIHRlc3RzIG9uIEFwcFZleW9yIHVzaW5nIENQeXRob24gMy40IiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxMjc5NjAwMDI2IiwgImJvdF91c2VybmFtZSI6ICJAcHRiX2FwcHZleW9yX2NweXRob25fMzRfYm90In0sIHsidG9rZW4iOiAiNjk0MzA4MDUyOkFBRUIyX3NvbkNrNTVMWTlCRzlBTy1IOGp4aVBTNTVvb0JBIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6WW1aaVlXWm1NakpoWkdNeSIsICJib3RfbmFtZSI6ICJQVEIgdGVzdHMgb24gQXBwVmV5b3IgdXNpbmcgQ1B5dGhvbiAyLjciLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDEyOTMwNzkxNjUiLCAiYm90X3VzZXJuYW1lIjogIkBwdGJfYXBwdmV5b3JfY3B5dGhvbl8yN19ib3QifSwgeyJ0b2tlbiI6ICIxMDU1Mzk3NDcxOkFBRzE4bkJfUzJXQXd1SjNnN29oS0JWZ1hYY2VNbklPeVNjIiwgInBheW1lbnRfcHJvdmlkZXJfdG9rZW4iOiAiMjg0Njg1MDYzOlRFU1Q6TmpBd056QXpZalZpTkdOayIsICJuYW1lIjogIlBUQiB0ZXN0cyBbMF0iLCAic3VwZXJfZ3JvdXBfaWQiOiAiLTEwMDExODU1MDk2MzYiLCAidXNlcm5hbWUiOiAicHRiXzBfYm90In0sIHsidG9rZW4iOiAiMTA0NzMyNjc3MTpBQUY4bk90ODFGcFg4bGJidno4VWV3UVF2UmZUYkZmQnZ1SSIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOllUVTFOVEk0WkdSallqbGkiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzFdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDg0Nzk3NjEyIiwgInVzZXJuYW1lIjogInB0Yl8xX2JvdCJ9LCB7InRva2VuIjogIjk3MTk5Mjc0NTpBQUdPa09hVzBOSGpnSXY1LTlqUWJPajR2R3FkaFNGLVV1cyIsICJwYXltZW50X3Byb3ZpZGVyX3Rva2VuIjogIjI4NDY4NTA2MzpURVNUOk5XWmtNV1ZoWWpsallqVTUiLCAibmFtZSI6ICJQVEIgdGVzdHMgWzJdIiwgInN1cGVyX2dyb3VwX2lkIjogIi0xMDAxNDAyMjU1MDcwIiwgInVzZXJuYW1lIjogInB0Yl8yX2JvdCJ9XQ==
TEST_NO_PYTZ : "true"
TEST_NO_PASSPORT: "true"
TEST_PYTZ : "false"
TEST_PASSPORT: "false"
TEST_RATE_LIMITER: "false"
TEST_BUILD: "true"
shell: bash --noprofile --norc {0}

Expand Down Expand Up @@ -95,6 +104,7 @@ jobs:
run: |
python -W ignore -m pip install --upgrade pip
python -W ignore -m pip install -r requirements.txt
python -W ignore -m pip install -r requirements-opts.txt
python -W ignore -m pip install -r requirements-dev.txt
- name: Compare to official api
run: |
Expand Down
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ repos:
- tornado~=6.2
- APScheduler~=3.9.1
- cachetools~=5.2.0
- aiolimiter~=1.0.0
- . # this basically does `pip install -e .`
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.971
Expand All @@ -43,14 +44,14 @@ repos:
name: mypy-ptb
files: ^telegram/.*\.py$
additional_dependencies:
- types-ujson
- types-pytz
- types-cryptography
- types-cachetools
- httpx~=0.23.0
- tornado~=6.2
- APScheduler~=3.9.1
- cachetools~=5.2.0
- aiolimiter~=1.0.0
- . # this basically does `pip install -e .`
- id: mypy
name: mypy-examples
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1 @@
include LICENSE LICENSE.lesser Makefile requirements.txt README_RAW.rst telegram/py.typed
include LICENSE LICENSE.lesser Makefile requirements.txt requirements-opts.txt README_RAW.rst telegram/py.typed
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ PTB can be installed with optional dependencies:

* ``pip install python-telegram-bot[passport]`` installs the `cryptography>=3.0 <https://cryptography.io/en/stable>`_ library. Use this, if you want to use Telegram Passport related functionality.
* ``pip install python-telegram-bot[socks]`` installs ``httpx[socks]``. Use this, if you want to work behind a Socks5 server.
* ``pip install python-telegram-bot[rate-limiter]`` installs ``aiolimiter~=1.0.0``. Use this, if you want to use ``telegram.ext.AIORateLimiter``.

Quick Start
===========
Expand Down
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ def autodoc_process_bases(app, name, obj, option, bases: list):
# Now convert `telegram._message.Message` to `telegram.Message` etc
match = re.search(pattern=r"(telegram(\.ext|))\.[_\w\.]+", string=base)
if not match or "_utils" in base:
return
continue

parts = match.group(0).split(".")

Expand Down
6 changes: 6 additions & 0 deletions docs/source/telegram.ext.aioratelimiter.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
telegram.ext.AIORateLimiter
============================

.. autoclass:: telegram.ext.AIORateLimiter
:members:
:show-inheritance:
6 changes: 6 additions & 0 deletions docs/source/telegram.ext.baseratelimiter.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
telegram.ext.BaseRateLimiter
============================

.. autoclass:: telegram.ext.BaseRateLimiter
:members:
:show-inheritance:
3 changes: 1 addition & 2 deletions docs/source/telegram.ext.extbot.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ telegram.ext.ExtBot

.. autoclass:: telegram.ext.ExtBot
:show-inheritance:

.. autofunction:: telegram.ext.ExtBot.insert_callback_data
:members: insert_callback_data, defaults, rate_limiter, initialize, shutdown
8 changes: 8 additions & 0 deletions docs/source/telegram.ext.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,11 @@ Arbitrary Callback Data

telegram.ext.callbackdatacache
telegram.ext.invalidcallbackdata

Rate Limiting
-------------

.. toctree::

telegram.ext.baseratelimiter
telegram.ext.aioratelimiter
4 changes: 4 additions & 0 deletions requirements-all.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-r requirements.txt
-r requirements-dev.txt
-r requirements-opts.txt
-r docs/requirements-docs.txt
3 changes: 0 additions & 3 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# cryptography is an optional dependency, but running the tests properly requires it
cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3

pre-commit

pytest==7.1.2
Expand Down
7 changes: 7 additions & 0 deletions requirements-opts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Format:
# package_name==version # req-1, req-2, req-3!ext
# `pip install ptb-raw[req-1/2]` will install `package_name`
# `pip install ptb[req-1/2/3]` will also install `package_name`
httpx[socks] # socks
cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3,>=3.0 # passport
aiolimiter~=1.0.0 # rate-limiter!ext
26 changes: 21 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""The setup and build script for the python-telegram-bot library."""
import subprocess
import sys
from collections import defaultdict
from pathlib import Path

from setuptools import find_packages, setup
Expand Down Expand Up @@ -35,6 +36,25 @@ def get_packages_requirements(raw=False):
return packs, reqs


def get_optional_requirements(raw=False):
"""Build the optional dependencies"""
requirements = defaultdict(list)

with Path("requirements-opts.txt").open() as reqs:
for line in reqs:
if line.startswith("#"):
continue
dependency, names = line.split("#")
dependency = dependency.strip()
for name in names.split(","):
name = name.strip()
if name.endswith("!ext") and raw:
continue
requirements[name].append(dependency)

return requirements


def get_setup_kwargs(raw=False):
"""Builds a dictionary of kwargs for the setup function"""
packages, requirements = get_packages_requirements(raw=raw)
Expand Down Expand Up @@ -69,11 +89,7 @@ def get_setup_kwargs(raw=False):
long_description_content_type="text/x-rst",
packages=packages,
install_requires=requirements,
extras_require={
"socks": "httpx[socks]",
# 3.4-3.4.3 contained some cyclical import bugs
"passport": "cryptography!=3.4,!=3.4.1,!=3.4.2,!=3.4.3,>=3.0",
},
extras_require=get_optional_requirements(raw=raw),
include_package_data=True,
classifiers=[
"Development Status :: 5 - Production/Stable",
Expand Down
21 changes: 20 additions & 1 deletion telegram/_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,25 @@ async def _post(
# Drop any None values because Telegram doesn't handle them well
data = {key: value for key, value in data.items() if value is not None}

return await self._do_post(
endpoint=endpoint,
data=data,
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
)

async def _do_post(
self,
endpoint: str,
data: JSONDict,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
) -> Union[bool, JSONDict, None]:
# This also converts datetimes into timestamps.
# We don't do this earlier so that _insert_defaults (see above) has a chance to convert
# to the default timezone in case this is called by ExtBot
Expand Down Expand Up @@ -2902,7 +2921,7 @@ async def get_user_profile_photos(
api_kwargs=api_kwargs,
)

return UserProfilePhotos.de_json(result, self) # type: ignore[return-value, arg-type]
return UserProfilePhotos.de_json(result, self) # type: ignore[arg-type,return-value]

@_log
async def get_file(
Expand Down
6 changes: 5 additions & 1 deletion telegram/ext/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@
"""Extensions over the Telegram Bot API to facilitate bot making"""

__all__ = (
"AIORateLimiter",
"Application",
"ApplicationBuilder",
"ApplicationHandlerStop",
"BaseHandler",
"BasePersistence",
"BaseRateLimiter",
"CallbackContext",
"CallbackDataCache",
"CallbackQueryHandler",
Expand All @@ -36,7 +39,6 @@
"DictPersistence",
"ExtBot",
"filters",
"BaseHandler",
"InlineQueryHandler",
"InvalidCallbackData",
"Job",
Expand All @@ -56,9 +58,11 @@
)

from . import filters
from ._aioratelimiter import AIORateLimiter
from ._application import Application, ApplicationHandlerStop
from ._applicationbuilder import ApplicationBuilder
from ._basepersistence import BasePersistence, PersistenceInput
from ._baseratelimiter import BaseRateLimiter
from ._callbackcontext import CallbackContext
from ._callbackdatacache import CallbackDataCache, InvalidCallbackData
from ._callbackqueryhandler import CallbackQueryHandler
Expand Down
Loading