Search code examples
pythontwittertwitterapi-python

Twitter API media upload fails with FileNotFoundError


What I want to do

I'm currently coding a Twitter bot which just creates a tweet with a couple of media with the Python wrapper "Twikit". This is the Python code "betsuaka_test.py" I wrote is below:

from twikit import Client

client = Client('ja')

client.login(
        auth_info_1='xxxxxxxxx',
        auth_info_2='[email protected]',
        password='xxxxxxxx'
)

TWEET_TEXT = 'テスト投稿2'
MEDIA_IDS = [
        client.upload_media('https://i.imgur.com/ZFMaW5h.png',0)
]
client.create_tweet(TWEET_TEXT, MEDIA_IDS)

What happenned

When I run this code with python3 betsuaka_test.py, my shell returns the *two types of the error messages alternately:

[error message 1]

ubuntunaoki@LAPTOP-7Q7QL2PR:~$ python3 betsuaka_test.py
Traceback (most recent call last):
  File "/home/ubuntunaoki/betsuaka_test.py", line 13, in <module>
    client.upload_media('https://i.imgur.com/ZFMaW5h.png',0)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 568, in upload_media
    img_size = os.path.getsize(source)
  File "/usr/lib/python3.10/genericpath.py", line 50, in getsize
    return os.stat(filename).st_size
FileNotFoundError: [Errno 2] No such file or directory: 'https://i.imgur.com/ZFMaW5h.png'

[error message2]

ubuntunaoki@LAPTOP-7Q7QL2PR:~$ python3 betsuaka_test.py
Traceback (most recent call last):
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 69, in map_httpcore_exceptions
    yield
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 233, in handle_request
    resp = self._pool.handle_request(req)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection_pool.py", line 216, in handle_request
    raise exc from None
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection_pool.py", line 196, in handle_request
    response = connection.handle_request(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection.py", line 101, in handle_request
    return self._connection.handle_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 143, in handle_request
    raise exc
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 93, in handle_request
    self._send_request_headers(**kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 151, in _send_request_headers
    with map_exceptions({h11.LocalProtocolError: LocalProtocolError}):
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions
    raise to_exc(exc) from exc
httpcore.LocalProtocolError: Illegal header value b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 '

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/ubuntunaoki/betsuaka_test.py", line 5, in <module>
    client.login(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 138, in login
    guest_token = self._get_guest_token()
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 62, in _get_guest_token
    response = self.http.post(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/http.py", line 54, in post
    return self.request('POST', url, **kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/http.py", line 25, in request
    response = self.client.request(method, url, **kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 827, in request
    return self.send(request, auth=auth, follow_redirects=follow_redirects)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 914, in send
    response = self._send_handling_auth(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 942, in _send_handling_auth
    response = self._send_handling_redirects(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 979, in _send_handling_redirects
    response = self._send_single_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 1015, in _send_single_request
    response = transport.handle_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 232, in handle_request
    with map_httpcore_exceptions():
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 86, in map_httpcore_exceptions
    raise mapped_exc(message) from exc
httpx.LocalProtocolError: Illegal header value b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 '

Why this happens?

  • "Twikit" can use not only local image files but also images which is on a web.
  • The image url https://i.imgur.com/ZFMaW5h.png is valid and the image I want pops up when I write down this URL on browser URL bar.

New trial

I tried some modifications.

  • Get image file from image url and put it into a variable image_file
  • And then, put the binary file directly into update_media() function.
from twikit import Client

client = Client('ja')

client.login(
        auth_info_1='xxxxxxx',
        auth_info_2='[email protected]',
        password='xxxxxx'
)
import base64


image_file_path = 'https://i.imgur.com/ZFMaW5h.png'

with open(image_file_path, mode='rb') as f:
    image_file = f.read()

# base64エンコードする
binary_file_b64 = base64.b64encode(image_file)

# base64エンコードしたバイナリデータをターミナルに表示してみる
print(binary_file_b64)

TWEET_TEXT = 'テスト投稿2'
https://avatars.githubusercontent.com/u/7451118?s=200&v=4MEDIA_IDS = [        client.upload_media(binary_file_b64,0)
]
client.create_tweet(TWEET_TEXT, MEDIA_IDS)

but another two error messages came:

Traceback (most recent call last):
  File "/home/ubuntunaoki/betsuaka_test.py", line 15, in <module>
    with open(image_file_path, mode='rb') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'https://i.imgur.com/ZFMaW5h.png'
Traceback (most recent call last):
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 69, in map_httpcore_exceptions
    yield
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 233, in handle_request
    resp = self._pool.handle_request(req)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection_pool.py", line 216, in handle_request
    raise exc from None
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection_pool.py", line 196, in handle_request
    response = connection.handle_request(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/connection.py", line 101, in handle_request
    return self._connection.handle_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 143, in handle_request
    raise exc
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 93, in handle_request
    self._send_request_headers(**kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_sync/http11.py", line 151, in _send_request_headers
    with map_exceptions({h11.LocalProtocolError: LocalProtocolError}):
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpcore/_exceptions.py", line 14, in map_exceptions
    raise to_exc(exc) from exc
httpcore.LocalProtocolError: Illegal header value b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 '

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/ubuntunaoki/betsuaka_test.py", line 5, in <module>
    client.login(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 138, in login
    guest_token = self._get_guest_token()
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/client.py", line 62, in _get_guest_token
    response = self.http.post(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/http.py", line 54, in post
    return self.request('POST', url, **kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/twikit/http.py", line 25, in request
    response = self.client.request(method, url, **kwargs)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 827, in request
    return self.send(request, auth=auth, follow_redirects=follow_redirects)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 914, in send
    response = self._send_handling_auth(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 942, in _send_handling_auth
    response = self._send_handling_redirects(
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 979, in _send_handling_redirects
    response = self._send_single_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_client.py", line 1015, in _send_single_request
    response = transport.handle_request(request)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 232, in handle_request
    with map_httpcore_exceptions():
  File "/usr/lib/python3.10/contextlib.py", line 153, in __exit__
    self.gen.throw(typ, value, traceback)
  File "/home/ubuntunaoki/.local/lib/python3.10/site-packages/httpx/_transports/default.py", line 86, in map_httpcore_exceptions
    raise mapped_exc(message) from exc
httpx.LocalProtocolError: Illegal header value b'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 '

Solution

  • from twikit documentation we can understand the upload_media() signature:

    Uploads media to twitter.
    
    Parameters:
    media_path (str | bytes) – The file path or binary data of the media to be uploaded.
    
    index (int) – The index of the media segment being uploaded. Should start from 0 and increment by 1 for each subsequent upload.
    
    Returns:
    The media ID of the uploaded media.
    
    Return type:
    int
    

    so you should pass to the media_path path to your local file or bytes of this file.

    I would reccomend to you at first to get the image from source, convert result to bytes and then to pass this binary data to the method upload_media()

    I think my answer a little bit help you to achive your goal