如何使用 Tweepy 上传内存中的图像?

How to upload in-memory image with Tweepy?

我正在使用 PIL 处理 Python 中的图像,我想通过 Tweepy 将其上传到 Twitter。我可以将 PIL 图像保存到磁盘并使用 Tweepy 上传该文件就好了,但我宁愿直接上传内存中的图像以提高效率。我该如何实现?

这是一个将图像保存到磁盘的简单示例:

from PIL import Image
import tweepy

# Example image manipulation
img = Image.open("input.jpg")

# Do something to the image...

# Save image to disk
img.save("output.jpg")

# Setup Tweepy API
auth = tweepy.OAuthHandler(consumer_key="", consumer_secret="")
auth.set_access_token(key="", secret="")
api = tweepy.API(auth)

# Upload media to Twitter
ret = api.media_upload("output.jpg")

# Attach returned media id to a tweet
api.update_status(media_ids=[ret.media_id_string], status="hello world")

写这个自我回答 post,因为我发现用 tweepy 上传一个内存文件的解释相当糟糕。 API.media_upload() and API.simple_upload() 的 Tweepy 文档供参考。


回答

经过一番挖掘,我发现了一个适用于 this closed issue on github 的代码片段。这是我基于 post:

的回答
from io import BytesIO
from PIL import Image
import tweepy

# Example image manipulation
img = Image.open("input.jpg")

# Do something to the image...

# Save image in-memory
b = BytesIO()
im.save(b, "PNG")
b.seek(0)

# Setup Tweepy API
auth = tweepy.OAuthHandler(consumer_key="", consumer_secret="")
auth.set_access_token(key="", secret="")
api = tweepy.API(auth)

# Upload media to Twitter APIv1.1
ret = api.media_upload(filename="dummy_string", file=b)

# Attach media to tweet
api.update_status(media_ids=[ret.media_id_string], status="hello world")

补充说明

API.media_upload()API.simple_upload()

所需的文件名参数

API.media_upload()API.simple_upload() 都要求您为参数 filename 提供一个字符串,即使您是在内存中上传也是如此。该字符串可以是任何内容,甚至是空字符串,上传似乎仍然有效。 (在 Tweepy v4.4.0 上测试)


Tweepy >= v4.0.0 需要

b.seek(0)

另外需要注意的是b.seek(0)对于Tweepy v4.0.0及以上版本是必须的,根据this other github thread.如果你不执行seek操作,Twitter会回复400 Bad Request.

但是,如果您知道自己在做什么,也可以搜索流的其他部分以从那里开始上传,而不是从头开始上传。


BytesIO

github issue I found the answer from 中,他们使用了这个略有不同的片段:

...

b = io.BytesIO()
img.save(b, "PNG")
b.seek(0)
fp = io.BufferedReader(b)

media = api.media_upload('test.png', file=fp)

这个版本和上面的版本都可以很好地上传图片,所以我不确定 io.BufferedReader() 的作用。