Fix Naming and Keyword Arguments of File.download_* Methods (#3380)

This commit is contained in:
Bibo-Joshi 2022-11-24 12:09:51 +01:00 committed by GitHub
parent 8c03f0e2eb
commit 05c6ca06f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 88 additions and 49 deletions

View file

@ -81,7 +81,7 @@ async def photo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
"""Stores the photo and asks for a location."""
user = update.message.from_user
photo_file = await update.message.photo[-1].get_file()
await photo_file.download_to_memory("user_photo.jpg")
await photo_file.download_to_drive("user_photo.jpg")
logger.info("Photo of %s: %s", user.first_name, "user_photo.jpg")
await update.message.reply_text(
"Gorgeous! Now, send me your location please, or send /skip if you don't want to."

View file

@ -77,25 +77,25 @@ async def msg(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
for file in data.files:
actual_file = await file.get_file()
print(actual_file)
await actual_file.download_to_memory()
await actual_file.download_to_drive()
if (
data.type in ("passport", "driver_license", "identity_card", "internal_passport")
and data.front_side
):
front_file = await data.front_side.get_file()
print(data.type, front_file)
await front_file.download_to_memory()
await front_file.download_to_drive()
if data.type in ("driver_license" and "identity_card") and data.reverse_side:
reverse_file = await data.reverse_side.get_file()
print(data.type, reverse_file)
await reverse_file.download_to_memory()
await reverse_file.download_to_drive()
if (
data.type in ("passport", "driver_license", "identity_card", "internal_passport")
and data.selfie
):
selfie_file = await data.selfie.get_file()
print(data.type, selfie_file)
await selfie_file.download_to_memory()
await selfie_file.download_to_drive()
if data.translation and data.type in (
"passport",
"driver_license",
@ -111,7 +111,7 @@ async def msg(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
for file in data.translation:
actual_file = await file.get_file()
print(actual_file)
await actual_file.download_to_memory()
await actual_file.download_to_drive()
def main() -> None:

View file

@ -2834,7 +2834,7 @@ class Bot(TelegramObject, AbstractAsyncContextManager):
Use this method to get basic info about a file and prepare it for downloading. For the
moment, bots can download files of up to
:tg-const:`telegram.constants.FileSizeLimit.FILESIZE_DOWNLOAD` in size. The file can then
be e.g. downloaded with :meth:`telegram.File.download_to_memory`. It is guaranteed that
be e.g. downloaded with :meth:`telegram.File.download_to_drive`. It is guaranteed that
the link will be valid for at least 1 hour. When the link expires, a new one can be
requested by calling get_file again.

View file

@ -36,21 +36,21 @@ if TYPE_CHECKING:
class File(TelegramObject):
"""
This object represents a file ready to be downloaded. The file can be e.g. downloaded with
:attr:`download_to_memory`. It is guaranteed that the link will be valid for at least 1 hour.
:attr:`download_to_drive`. It is guaranteed that the link will be valid for at least 1 hour.
When the link expires, a new one can be requested by calling :meth:`telegram.Bot.get_file`.
Objects of this class are comparable in terms of equality. Two objects of this class are
considered equal, if their :attr:`file_unique_id` is equal.
.. versionchanged:: 20.0:
``download`` was split into :meth:`download_to_memory` and :meth:`download_to_object`.
``download`` was split into :meth:`download_to_drive` and :meth:`download_to_memory`.
Note:
* Maximum file size to download is
:tg-const:`telegram.constants.FileSizeLimit.FILESIZE_DOWNLOAD`.
* If you obtain an instance of this class from :attr:`telegram.PassportFile.get_file`,
then it will automatically be decrypted as it downloads when you call e.g.
:meth:`download_to_memory`.
:meth:`download_to_drive`.
Args:
file_id (:obj:`str`): Identifier for this file, which can be used to download
@ -59,7 +59,7 @@ class File(TelegramObject):
is supposed to be the same over time and for different bots.
Can't be used to download or reuse the file.
file_size (:obj:`int`, optional): Optional. File size in bytes, if known.
file_path (:obj:`str`, optional): File path. Use e.g. :meth:`download_to_memory` to get the
file_path (:obj:`str`, optional): File path. Use e.g. :meth:`download_to_drive` to get the
file.
Attributes:
@ -68,7 +68,7 @@ class File(TelegramObject):
is supposed to be the same over time and for different bots.
Can't be used to download or reuse the file.
file_size (:obj:`str`): Optional. File size in bytes.
file_path (:obj:`str`): Optional. File path. Use e.g. :meth:`download_to_memory` to get
file_path (:obj:`str`): Optional. File path. Use e.g. :meth:`download_to_drive` to get
the file.
"""
@ -114,9 +114,10 @@ class File(TelegramObject):
def _prepare_decrypt(self, buf: bytes) -> bytes:
return decrypt(b64decode(self._credentials.secret), b64decode(self._credentials.hash), buf)
async def download_to_memory(
async def download_to_drive(
self,
custom_path: FilePathInput = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
@ -130,14 +131,13 @@ class File(TelegramObject):
Note:
If :paramref:`custom_path` isn't provided and :attr:`file_path` is the path of a
local file (which is the case when a Bot API Server is running in local mode), this
method will just return the path.
local file (which is the case when a Bot API Server is running in local mode), this
method will just return the path.
The only exception to this are encrypted files (e.g. a passport file). For these, a
file with the prefix `decrypted_` will be created in the same directory as the
original file in order to decrypt the file without changing the existing one
in-place.
file with the prefix `decrypted_` will be created in the same directory as the
original file in order to decrypt the file without changing the existing one
in-place.
.. versionchanged:: 20.0
@ -145,12 +145,13 @@ class File(TelegramObject):
* Returns :class:`pathlib.Path` object in cases where previously a :obj:`str` was
returned.
* This method was previously called ``download``. It was split into
:meth:`download_to_memory` and :meth:`download_to_object`.
:meth:`download_to_drive` and :meth:`download_to_memory`.
Args:
custom_path (:class:`pathlib.Path` | :obj:`str` , optional): The path where the file
will be saved to. If not specified, will be saved in the current working directory.
Keyword Args:
read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
@ -207,9 +208,10 @@ class File(TelegramObject):
filename.write_bytes(buf)
return filename
async def download_to_object(
async def download_to_memory(
self,
out: BinaryIO,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
@ -222,10 +224,11 @@ class File(TelegramObject):
.. versionadded:: 20.0
Args:
out (:obj:`io.BufferedIOBase`): A file-like object. Must be opened for writing in
binary mode.
Keyword Args:
read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
@ -256,12 +259,42 @@ class File(TelegramObject):
buf = self._prepare_decrypt(buf)
out.write(buf)
async def download_as_bytearray(self, buf: bytearray = None) -> bytearray:
async def download_as_bytearray(
self,
buf: bytearray = None,
*,
read_timeout: ODVInput[float] = DEFAULT_NONE,
write_timeout: ODVInput[float] = DEFAULT_NONE,
connect_timeout: ODVInput[float] = DEFAULT_NONE,
pool_timeout: ODVInput[float] = DEFAULT_NONE,
) -> bytearray:
"""Download this file and return it as a bytearray.
Args:
buf (:obj:`bytearray`, optional): Extend the given bytearray with the downloaded data.
Keyword Args:
read_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.request.BaseRequest.post.read_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. versionadded:: 20.0
write_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.request.BaseRequest.post.write_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. versionadded:: 20.0
connect_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.request.BaseRequest.post.connect_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. versionadded:: 20.0
pool_timeout (:obj:`float` | :obj:`None`, optional): Value to pass to
:paramref:`telegram.request.BaseRequest.post.pool_timeout`. Defaults to
:attr:`~telegram.request.BaseRequest.DEFAULT_NONE`.
.. versionadded:: 20.0
Returns:
:obj:`bytearray`: The same object as :paramref:`buf` if it was specified. Otherwise a
newly allocated :obj:`bytearray`.
@ -273,7 +306,13 @@ class File(TelegramObject):
if is_local_file(self.file_path):
bytes_data = Path(self.file_path).read_bytes()
else:
bytes_data = await self.get_bot().request.retrieve(self._get_encoded_url())
bytes_data = await self.get_bot().request.retrieve(
self._get_encoded_url(),
read_timeout=read_timeout,
write_timeout=write_timeout,
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
)
if self._credentials:
buf.extend(self._prepare_decrypt(bytes_data))
else:

View file

@ -128,7 +128,7 @@ class TestAnimation:
assert new_file.file_id == animation.file_id
assert new_file.file_path.startswith("https://")
new_filepath = await new_file.download_to_memory("game.gif")
new_filepath = await new_file.download_to_drive("game.gif")
assert new_filepath.is_file()

View file

@ -143,7 +143,7 @@ class TestAudio:
assert new_file.file_unique_id == audio.file_unique_id
assert str(new_file.file_path).startswith("https://")
await new_file.download_to_memory("telegram.mp3")
await new_file.download_to_drive("telegram.mp3")
assert path.is_file()

View file

@ -85,7 +85,7 @@ class TestChatPhoto:
assert new_file.file_unique_id == chat_photo.small_file_unique_id
assert new_file.file_path.startswith("https://")
await new_file.download_to_memory(jpg_file)
await new_file.download_to_drive(jpg_file)
assert jpg_file.is_file()
@ -94,7 +94,7 @@ class TestChatPhoto:
assert new_file.file_unique_id == chat_photo.big_file_unique_id
assert new_file.file_path.startswith("https://")
await new_file.download_to_memory(jpg_file)
await new_file.download_to_drive(jpg_file)
assert jpg_file.is_file()

View file

@ -118,7 +118,7 @@ class TestDocument:
assert new_file.file_unique_id == document.file_unique_id
assert new_file.file_path.startswith("https://")
await new_file.download_to_memory("telegram.png")
await new_file.download_to_drive("telegram.png")
assert path.is_file()

View file

@ -132,7 +132,7 @@ class TestFile:
return self.file_content
monkeypatch.setattr(file.get_bot().request, "retrieve", test)
out_file = await file.download_to_memory()
out_file = await file.download_to_drive()
try:
assert out_file.read_bytes() == self.file_content
@ -140,7 +140,7 @@ class TestFile:
out_file.unlink()
async def test_download_local_file(self, local_file):
assert await local_file.download_to_memory() == Path(local_file.file_path)
assert await local_file.download_to_drive() == Path(local_file.file_path)
@pytest.mark.parametrize(
"custom_path_type", [str, Path], ids=["str custom_path", "pathlib.Path custom_path"]
@ -153,7 +153,7 @@ class TestFile:
file_handle, custom_path = mkstemp()
custom_path = Path(custom_path)
try:
out_file = await file.download_to_memory(custom_path_type(custom_path))
out_file = await file.download_to_drive(custom_path_type(custom_path))
assert out_file == custom_path
assert out_file.read_bytes() == self.file_content
finally:
@ -167,7 +167,7 @@ class TestFile:
file_handle, custom_path = mkstemp()
custom_path = Path(custom_path)
try:
out_file = await local_file.download_to_memory(custom_path_type(custom_path))
out_file = await local_file.download_to_drive(custom_path_type(custom_path))
assert out_file == custom_path
assert out_file.read_bytes() == self.file_content
finally:
@ -181,7 +181,7 @@ class TestFile:
file.file_path = None
monkeypatch.setattr(file.get_bot().request, "retrieve", test)
out_file = await file.download_to_memory()
out_file = await file.download_to_drive()
assert str(out_file)[-len(file.file_id) :] == file.file_id
try:
@ -195,13 +195,13 @@ class TestFile:
monkeypatch.setattr(file.get_bot().request, "retrieve", test)
with TemporaryFile() as custom_fobj:
await file.download_to_object(out=custom_fobj)
await file.download_to_memory(out=custom_fobj)
custom_fobj.seek(0)
assert custom_fobj.read() == self.file_content
async def test_download_file_obj_local_file(self, local_file):
with TemporaryFile() as custom_fobj:
await local_file.download_to_object(out=custom_fobj)
await local_file.download_to_memory(out=custom_fobj)
custom_fobj.seek(0)
assert custom_fobj.read() == self.file_content
@ -239,7 +239,7 @@ class TestFile:
return data_file("image_encrypted.jpg").read_bytes()
monkeypatch.setattr(encrypted_file.get_bot().request, "retrieve", test)
out_file = await encrypted_file.download_to_memory()
out_file = await encrypted_file.download_to_drive()
try:
assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes()
@ -252,12 +252,12 @@ class TestFile:
monkeypatch.setattr(encrypted_file.get_bot().request, "retrieve", test)
with TemporaryFile() as custom_fobj:
await encrypted_file.download_to_object(out=custom_fobj)
await encrypted_file.download_to_memory(out=custom_fobj)
custom_fobj.seek(0)
assert custom_fobj.read() == data_file("image_decrypted.jpg").read_bytes()
async def test_download_local_file_encrypted(self, encrypted_local_file):
out_file = await encrypted_local_file.download_to_memory()
out_file = await encrypted_local_file.download_to_drive()
try:
assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes()
finally:
@ -272,7 +272,7 @@ class TestFile:
file_handle, custom_path = mkstemp()
custom_path = Path(custom_path)
try:
out_file = await encrypted_local_file.download_to_memory(custom_path_type(custom_path))
out_file = await encrypted_local_file.download_to_drive(custom_path_type(custom_path))
assert out_file == custom_path
assert out_file.read_bytes() == data_file("image_decrypted.jpg").read_bytes()
finally:
@ -285,7 +285,7 @@ class TestFile:
monkeypatch.setattr(encrypted_local_file.get_bot().request, "retrieve", test)
with TemporaryFile() as custom_fobj:
await encrypted_local_file.download_to_object(out=custom_fobj)
await encrypted_local_file.download_to_memory(out=custom_fobj)
custom_fobj.seek(0)
assert custom_fobj.read() == data_file("image_decrypted.jpg").read_bytes()

View file

@ -145,7 +145,7 @@ class TestInputFile:
message = await bot.send_document(chat_id, data_file("text_file.txt").read_bytes())
out = BytesIO()
await (await message.document.get_file()).download_to_object(out=out)
await (await message.document.get_file()).download_to_memory(out=out)
out.seek(0)
assert out.read().decode("utf-8") == "PTB Rocks! ⅞"
@ -158,7 +158,7 @@ class TestInputFile:
)
out = BytesIO()
await (await message.document.get_file()).download_to_object(out=out)
await (await message.document.get_file()).download_to_memory(out=out)
out.seek(0)
assert out.read().decode("utf-8") == "PTB Rocks! ⅞"

View file

@ -303,7 +303,7 @@ class TestPhoto:
assert new_file.file_unique_id == photo.file_unique_id
assert new_file.file_path.startswith("https://") is True
await new_file.download_to_memory("telegram.jpg")
await new_file.download_to_drive("telegram.jpg")
assert path.is_file()

View file

@ -168,7 +168,7 @@ class TestSticker:
assert new_file.file_unique_id == sticker.file_unique_id
assert new_file.file_path.startswith("https://")
await new_file.download_to_memory("telegram.webp")
await new_file.download_to_drive("telegram.webp")
assert path.is_file()

View file

@ -148,7 +148,7 @@ class TestVideo:
assert new_file.file_unique_id == video.file_unique_id
assert new_file.file_path.startswith("https://")
await new_file.download_to_memory("telegram.mp4")
await new_file.download_to_drive("telegram.mp4")
assert path.is_file()

View file

@ -132,7 +132,7 @@ class TestVideoNote:
assert new_file.file_unique_id == video_note.file_unique_id
assert new_file.file_path.startswith("https://")
await new_file.download_to_memory("telegram2.mp4")
await new_file.download_to_drive("telegram2.mp4")
assert path.is_file()

View file

@ -120,7 +120,7 @@ class TestVoice:
assert new_file.file_unique_id == voice.file_unique_id
assert new_file.file_path.startswith("https://")
await new_file.download_to_memory("telegram.ogg")
await new_file.download_to_drive("telegram.ogg")
assert path.is_file()