Python requests调用API遇类型错误:期望bytes/bytearray却得str或序列化失败
问题分析与解决方案
错误根源
两种尝试的核心矛盾在于API的请求格式要求:
- 方法1:把base64编码后的字符串放入JSON payload,但API明确要求
archive_data是bytes/bytearray类型,JSON传输的字符串无法被识别为字节,触发验证失败。 - 方法2:直接将字节放入JSON payload,而JSON格式本身不支持序列化字节类型,直接抛出
TypeError。
API要求字节类型的字段,说明它不接受JSON格式的请求体,而是需要通过**表单格式(multipart/form-data)**传递二进制数据。
修正方案
方案1:直接传递原始文件字节(推荐)
如果API需要的是文件的原始二进制内容,无需base64编码,直接用files参数传递文件对象即可:
import requests def api_call(): filepath = 'File_Path' filename = filepath.split("/")[-1] # 用with语句自动管理文件句柄,避免资源泄漏 with open(filepath, mode='rb') as file_data: # 普通文本字段放在data参数中 form_data = { "archive_name": filename } # 二进制文件放在files参数中 file_payload = { "archive_data": file_data } headers = { "Access_key": "ABC" } url = get_from_env(URL) # 发送multipart/form-data格式的请求 response = requests.post(url, headers=headers, data=form_data, files=file_payload) json_response = response.json() print(json_response) api_call()
方案2:传递base64编码后的字节(若API明确要求)
如果API确实需要base64编码后的字节,需将base64字符串转回字节,并用data参数发送表单数据(而非JSON):
import requests import base64 def api_call(): filepath = 'File_Path' with open(filepath, mode='rb') as file_data: # 先编码为base64字节,转成字符串后再转回字节 base64_str = base64.b64encode(file_data.read()).decode('utf-8') filename = filepath.split("/")[-1] form_payload = { "archive_data": base64_str.encode('utf-8'), "archive_name": filename } headers = { "Access_key": "ABC" } url = get_from_env(URL) # 用data参数发送表单,字节会被正确传递 response = requests.post(url, headers=headers, data=form_payload) json_response = response.json() print(json_response) api_call()
关键提示
- 不要用
json=payload传递二进制数据:JSON仅支持字符串、数字、列表、字典等基础类型,无法直接序列化字节。 - 使用
files参数是Python传递二进制文件的标准方式,requests会自动处理multipart/form-data格式的请求头。
内容的提问来源于stack exchange,提问作者Jay Bhajiyawala
相关产品推荐
相关产品推荐

