Merge pull request #542 from python-telegram-bot/urllib3-vendor-beta

Vendor (embed) urllib3 with our package.
This commit is contained in:
Noam Meltzer 2017-04-29 16:38:44 +03:00 committed by GitHub
commit ca4351079f
10 changed files with 122 additions and 56 deletions

View file

@ -1,5 +1,8 @@
[run] [run]
source = telegram source = telegram
omit = telegram/vendor/*
[report] [report]
omit = tests/ omit =
tests/
telegram/vendor/*

4
.gitmodules vendored Normal file
View file

@ -0,0 +1,4 @@
[submodule "telegram/vendor/urllib3"]
path = telegram/vendor/urllib3
url = https://github.com/python-telegram-bot/urllib3.git
branch = ptb

View file

@ -16,7 +16,7 @@ install:
- pip install -r requirements-dev.txt - pip install -r requirements-dev.txt
- if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then pip install ujson; fi - if [[ $TRAVIS_PYTHON_VERSION != 'pypy'* ]]; then pip install ujson; fi
script: script:
- nosetests -v --with-flaky --no-flaky-report --with-coverage --cover-package=telegram/ - nosetests -v --with-flaky --no-flaky-report --with-coverage --cover-package=telegram/ tests
- if [[ $TRAVIS_PYTHON_VERSION == 3.5 ]]; then pre-commit run --all-files; fi - if [[ $TRAVIS_PYTHON_VERSION == 3.5 ]]; then pre-commit run --all-files; fi
after_success: after_success:
coveralls coveralls

View file

@ -3,7 +3,12 @@ Credits
``python-telegram-bot`` was originally created by ``python-telegram-bot`` was originally created by
`Leandro Toledo <https://github.com/leandrotoledo>`_ and is now maintained by `Leandro Toledo <https://github.com/leandrotoledo>`_ and is now maintained by
`Jannes Höke <https://github.com/jh0ker>`_ (`@jh0ker <https://t.me/jh0ker>`_ on Telegram). `Jannes Höke <https://github.com/jh0ker>`_ (`@jh0ker <https://t.me/jh0ker>`_ on Telegram) and
`Noam Meltzer <https://github.com/tsnoam>`_.
We're vendoring urllib3 as part of ``python-telegram-bot`` which is distributed under the MIT
license. For more info, full credits & license terms, the sources can be found here:
`https://github.com/python-telegram-bot/urllib3`.
Contributors Contributors
------------ ------------

View file

@ -1,3 +1,2 @@
future>=0.15.2 future>=0.15.2
urllib3==1.20
certifi certifi

View file

@ -17,6 +17,13 @@ def requirements():
return requirements_list return requirements_list
packages = find_packages(exclude=['tests*'])
packages.extend(['telegram.vendor.urllib3.urllib3',
'telegram.vendor.urllib3.urllib3.packages', 'telegram.vendor.urllib3.urllib3.packages.ssl_match_hostname',
'telegram.vendor.urllib3.urllib3.packages.backports', 'telegram.vendor.urllib3.urllib3.contrib',
'telegram.vendor.urllib3.urllib3.util',
])
with codecs.open('README.rst', 'r', 'utf-8') as fd: with codecs.open('README.rst', 'r', 'utf-8') as fd:
fn = os.path.join('telegram', 'version.py') fn = os.path.join('telegram', 'version.py')
with open(fn) as fh: with open(fn) as fh:
@ -32,7 +39,7 @@ with codecs.open('README.rst', 'r', 'utf-8') as fd:
keywords='python telegram bot api wrapper', keywords='python telegram bot api wrapper',
description="We have made you a wrapper you can't refuse", description="We have made you a wrapper you can't refuse",
long_description=fd.read(), long_description=fd.read(),
packages=find_packages(exclude=['tests*']), packages=packages,
install_requires=requirements(), install_requires=requirements(),
extras_require={ extras_require={
'json': 'ujson', 'json': 'ujson',

View file

@ -19,6 +19,10 @@
"""A library that provides a Python interface to the Telegram Bot API""" """A library that provides a Python interface to the Telegram Bot API"""
from sys import version_info from sys import version_info
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'vendor', 'urllib3'))
from .base import TelegramObject from .base import TelegramObject
from .user import User from .user import User

View file

@ -129,31 +129,33 @@ class Bot(TelegramObject):
return decorator return decorator
def _message_wrapper(self, url, data, *args, **kwargs):
if kwargs.get('reply_to_message_id'):
data['reply_to_message_id'] = kwargs.get('reply_to_message_id')
if kwargs.get('disable_notification'):
data['disable_notification'] = kwargs.get('disable_notification')
if kwargs.get('reply_markup'):
reply_markup = kwargs.get('reply_markup')
if isinstance(reply_markup, ReplyMarkup):
data['reply_markup'] = reply_markup.to_json()
else:
data['reply_markup'] = reply_markup
result = self._request.post(url, data, timeout=kwargs.get('timeout'))
if result is True:
return result
return Message.de_json(result, self)
def message(func): def message(func):
@functools.wraps(func) @functools.wraps(func)
def decorator(self, *args, **kwargs): def decorator(self, *args, **kwargs):
url, data = func(self, *args, **kwargs) url, data = func(self, *args, **kwargs)
return Bot._message_wrapper(self, url, data, *args, **kwargs)
if kwargs.get('reply_to_message_id'):
data['reply_to_message_id'] = kwargs.get('reply_to_message_id')
if kwargs.get('disable_notification'):
data['disable_notification'] = kwargs.get('disable_notification')
if kwargs.get('reply_markup'):
reply_markup = kwargs.get('reply_markup')
if isinstance(reply_markup, ReplyMarkup):
data['reply_markup'] = reply_markup.to_json()
else:
data['reply_markup'] = reply_markup
result = self._request.post(url, data, timeout=kwargs.get('timeout'))
if result is True:
return result
return Message.de_json(result, self)
return decorator return decorator
@ -283,7 +285,6 @@ class Bot(TelegramObject):
return url, data return url, data
@log @log
@message
def sendPhoto(self, def sendPhoto(self,
chat_id, chat_id,
photo, photo,
@ -291,7 +292,7 @@ class Bot(TelegramObject):
disable_notification=False, disable_notification=False,
reply_to_message_id=None, reply_to_message_id=None,
reply_markup=None, reply_markup=None,
timeout=None, timeout=20.,
**kwargs): **kwargs):
"""Use this method to send photos. """Use this method to send photos.
@ -308,9 +309,7 @@ class Bot(TelegramObject):
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
to remove reply keyboard or to force a reply from the user. to remove reply keyboard or to force a reply from the user.
timeout (Optional[int|float]): If this value is specified, use it as the read timeout timeout (Optional[int|float]): Send file timeout (default: 20 seconds).
from the server (instead of the one specified during creation of the connection
pool).
**kwargs (dict): Arbitrary keyword arguments. **kwargs (dict): Arbitrary keyword arguments.
Returns: Returns:
@ -327,10 +326,19 @@ class Bot(TelegramObject):
if caption: if caption:
data['caption'] = caption data['caption'] = caption
return url, data return self._message_wrapper(
url,
data,
chat_id=chat_id,
photo=photo,
caption=caption,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
reply_markup=reply_markup,
timeout=timeout,
**kwargs)
@log @log
@message
def sendAudio(self, def sendAudio(self,
chat_id, chat_id,
audio, audio,
@ -341,7 +349,7 @@ class Bot(TelegramObject):
disable_notification=False, disable_notification=False,
reply_to_message_id=None, reply_to_message_id=None,
reply_markup=None, reply_markup=None,
timeout=None, timeout=20.,
**kwargs): **kwargs):
"""Use this method to send audio files, if you want Telegram clients to """Use this method to send audio files, if you want Telegram clients to
display them in the music player. Your audio must be in an .mp3 format. display them in the music player. Your audio must be in an .mp3 format.
@ -370,9 +378,7 @@ class Bot(TelegramObject):
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
to remove reply keyboard or to force a reply from the user. to remove reply keyboard or to force a reply from the user.
timeout (Optional[int|float]): If this value is specified, use it as the read timeout timeout (Optional[int|float]): Send file timeout (default: 20 seconds).
from the server (instead of the one specified during creation of the connection
pool).
**kwargs (dict): Arbitrary keyword arguments. **kwargs (dict): Arbitrary keyword arguments.
Returns: Returns:
@ -395,10 +401,22 @@ class Bot(TelegramObject):
if caption: if caption:
data['caption'] = caption data['caption'] = caption
return url, data return self._message_wrapper(
url,
data,
chat_id=chat_id,
audio=audio,
duration=duration,
performer=performer,
title=title,
caption=caption,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
reply_markup=reply_markup,
timeout=20.,
**kwargs)
@log @log
@message
def sendDocument(self, def sendDocument(self,
chat_id, chat_id,
document, document,
@ -407,7 +425,7 @@ class Bot(TelegramObject):
disable_notification=False, disable_notification=False,
reply_to_message_id=None, reply_to_message_id=None,
reply_markup=None, reply_markup=None,
timeout=None, timeout=20.,
**kwargs): **kwargs):
"""Use this method to send general files. """Use this method to send general files.
@ -426,9 +444,7 @@ class Bot(TelegramObject):
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
to remove reply keyboard or to force a reply from the user. to remove reply keyboard or to force a reply from the user.
timeout (Optional[int|float]): If this value is specified, use it as the read timeout timeout (Optional[int|float]): Send file timeout (default: 20 seconds).
from the server (instead of the one specified during creation of the connection
pool).
**kwargs (dict): Arbitrary keyword arguments. **kwargs (dict): Arbitrary keyword arguments.
Returns: Returns:
@ -447,7 +463,18 @@ class Bot(TelegramObject):
if caption: if caption:
data['caption'] = caption data['caption'] = caption
return url, data return self._message_wrapper(
url,
data,
chat_id=chat_id,
document=document,
filename=filename,
caption=caption,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
reply_markup=reply_markup,
timeout=timeout,
**kwargs)
@log @log
@message @message
@ -492,7 +519,6 @@ class Bot(TelegramObject):
return url, data return url, data
@log @log
@message
def sendVideo(self, def sendVideo(self,
chat_id, chat_id,
video, video,
@ -501,7 +527,7 @@ class Bot(TelegramObject):
disable_notification=False, disable_notification=False,
reply_to_message_id=None, reply_to_message_id=None,
reply_markup=None, reply_markup=None,
timeout=None, timeout=20.,
**kwargs): **kwargs):
"""Use this method to send video files, Telegram clients support mp4 """Use this method to send video files, Telegram clients support mp4
videos (other formats may be sent as telegram.Document). videos (other formats may be sent as telegram.Document).
@ -521,9 +547,7 @@ class Bot(TelegramObject):
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
to remove reply keyboard or to force a reply from the user. to remove reply keyboard or to force a reply from the user.
timeout (Optional[int|float]): If this value is specified, use it as the read timeout timeout (Optional[int|float]): Send file timeout (default: 20 seconds).
from the server (instead of the one specified during creation of the connection
pool).
Returns: Returns:
:class:`telegram.Message`: On success, instance representing the message posted. :class:`telegram.Message`: On success, instance representing the message posted.
@ -541,10 +565,20 @@ class Bot(TelegramObject):
if caption: if caption:
data['caption'] = caption data['caption'] = caption
return url, data return self._message_wrapper(
url,
data,
chat_id=chat_id,
video=video,
duration=duration,
caption=caption,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
reply_markup=reply_markup,
timeout=timeout,
**kwargs)
@log @log
@message
def sendVoice(self, def sendVoice(self,
chat_id, chat_id,
voice, voice,
@ -553,7 +587,7 @@ class Bot(TelegramObject):
disable_notification=False, disable_notification=False,
reply_to_message_id=None, reply_to_message_id=None,
reply_markup=None, reply_markup=None,
timeout=None, timeout=20.,
**kwargs): **kwargs):
"""Use this method to send audio files, if you want Telegram clients to display the file as """Use this method to send audio files, if you want Telegram clients to display the file as
a playable voice message. For this to work, your audio must be in an .ogg file encoded with a playable voice message. For this to work, your audio must be in an .ogg file encoded with
@ -575,9 +609,7 @@ class Bot(TelegramObject):
reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A reply_markup (Optional[:class:`telegram.ReplyMarkup`]): Additional interface options. A
JSON-serialized object for an inline keyboard, custom reply keyboard, instructions JSON-serialized object for an inline keyboard, custom reply keyboard, instructions
to remove reply keyboard or to force a reply from the user. to remove reply keyboard or to force a reply from the user.
timeout (Optional[int|float]): If this value is specified, use it as the read timeout timeout (Optional[int|float]): Send file timeout (default: 20 seconds).
from the server (instead of the one specified during creation of the connection
pool).
**kwargs (dict): Arbitrary keyword arguments. **kwargs (dict): Arbitrary keyword arguments.
Returns: Returns:
@ -596,7 +628,18 @@ class Bot(TelegramObject):
if caption: if caption:
data['caption'] = caption data['caption'] = caption
return url, data return self._message_wrapper(
url,
data,
chat_id=chat_id,
voice=voice,
duration=duration,
caption=caption,
disable_notification=disable_notification,
reply_to_message_id=reply_to_message_id,
reply_markup=reply_markup,
timeout=timeout,
**kwargs)
@log @log
@message @message

View file

@ -78,7 +78,7 @@ class Request(object):
(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
], ],
timeout=urllib3.Timeout( timeout=urllib3.Timeout(
connect=self._connect_timeout, read=read_timeout),) connect=self._connect_timeout, read=read_timeout, total=None))
# Set a proxy according to the following order: # Set a proxy according to the following order:
# * proxy defined in proxy_url (+ urllib3_proxy_kwargs) # * proxy defined in proxy_url (+ urllib3_proxy_kwargs)

1
telegram/vendor/urllib3 vendored Submodule

@ -0,0 +1 @@
Subproject commit 4b076eedffc1afabf0215ced3820603de73d1ce7