You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python通过multipart/form-data POST发送内存字节文件?

问题:直接转发图片字节到VK上传API(无需落地存储)

当前实现是通过requests.get('https://service.com/test.jpeg')获取图片字节后,先写入本地硬盘,再调用以下代码发送:

def send_file(path_to_image: str):
    url = get_upload_link()
    data = {'photo': open(path_to_image, 'rb')}
    r = requests.post(url, files=data)

send_file("test.jpeg")

希望直接使用bytes对象完成转发,无需落地存储,但多次尝试均失败:

  • 尝试1:直接传递bytes给open(),触发报错ValueError: embedded null byte
def send_file(image: bytes):
    url = get_upload_link()
    data = {'photo': open(image, 'rb')}
    r = requests.post(url, files=data)
  • 尝试2:用BytesIO包装bytes,但后端返回与传入files=None相同的响应
def upload_photo(image: bytes):
    url = get_upload_link()
    file = BytesIO(image)
    data = {'photo': file}

    r = requests.post(url, files=data)

此外还尝试过file.getbuffer()、file.read()返回值、StringIO对象等方式,均未解决问题。


解决方案

VK上传API需要明确的文件元信息(文件名、MIME类型)才能正确处理上传请求,只需给files中的文件对象补充这些信息即可,无需构造_io.BufferedReader。修改后的代码如下:

from io import BytesIO
import requests

def upload_photo(image: bytes):
    url = get_upload_link()
    # 用BytesIO包装图片字节,同时指定文件名和图片MIME类型
    file_buffer = BytesIO(image)
    files = {
        'photo': ('test.jpeg', file_buffer, 'image/jpeg')
    }
    response = requests.post(url, files=files)
    return response

关键说明

  • 尝试1错误原因:open()函数仅接受文件路径字符串,不能直接传入bytes对象,因此触发参数类型错误。
  • 尝试2错误原因:仅传递BytesIO对象时,requests不会自动生成文件名和Content-Type请求头,VK API无法识别这是有效图片文件,因此返回无文件上传的响应。
  • 补充元信息后,请求格式会和本地文件上传完全一致,API就能正常处理。

内容的提问来源于stack exchange,提问作者Neykuratick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 12:54:18