When I try to post an array of files in Python using requests, I get “TypeError: a bytes-like object is required, not ‘dict'”.
In order to send an album in Telegram from local, we need to provide an array of files, which contains file type. So I try:
import requests
bot_token = '<BOT_TOKEN>'
send_to = 1234567890
data = {'chat_id': send_to}
album = [
{'type': 'photo', 'media': 'test/foo.png'},
{'type': 'photo', 'media': 'test/bar.png'},
]
for i in range(len(album)):
album[i]['media'] = open(album[i]['media'], 'rb')
files = {'media': album}
test = requests.post(
f'https://api.telegram.org/{bot_token}/sendMediaGroup',
data=data, files=files)
When I run this I get:
Traceback (most recent call last):
File "D:/Games/GitHub/tgapi/test_album.py", line 87, in <module>
data=data, files=files)
File "C:ProgramDataAnacondalibsite-packagesrequestsapi.py", line 116, in post
return request('post', url, data=data, json=json, **kwargs)
File "C:ProgramDataAnacondalibsite-packagesrequestsapi.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "C:ProgramDataAnacondalibsite-packagesrequestssessions.py", line 519, in request
prep = self.prepare_request(req)
File "C:ProgramDataAnacondalibsite-packagesrequestssessions.py", line 462, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "C:ProgramDataAnacondalibsite-packagesrequestsmodels.py", line 316, in prepare
self.prepare_body(data, files, json)
File "C:ProgramDataAnacondalibsite-packagesrequestsmodels.py", line 504, in prepare_body
(body, content_type) = self._encode_files(files, data)
File "C:ProgramDataAnacondalibsite-packagesrequestsmodels.py", line 169, in _encode_files
body, content_type = encode_multipart_formdata(new_fields)
File "C:ProgramDataAnacondalibsite-packagesurllib3filepost.py", line 90, in encode_multipart_formdata
body.write(data)
TypeError: a bytes-like object is required, not 'dict'
P.S.:
- Adding
headers={'Content-Type': 'multipart/form-data'}
intorequests.post
does not help. - The code to send a single file is:
files = {'photo': open('test/foo.png', 'rb')}
test = requests.post(
f'https://api.telegram.org/{bot_token}/sendPhoto',
data=data, files=files)
2
Answers
By referring to a popular package pyTelegramBotAPI, I've figured out:
At this moment,
And finally this code will work:
Note that, just like what is done in pyTelegramBotAPI, it's much better to generate a random filename by:
You’re not sending in an array, your files variable is a dictionary, which is exactly what the error is telling you.
Instead of adding the album from your loop to a dict key of media, just add it to an array and pass that in to your request