基于指定CURL命令编写Python REST文件上传方法遇错求助
解决CURL转Python请求的两个常见问题:JSON反序列化错误与文件流关闭异常
看起来你在把CURL命令转成Python请求时遇到了两个典型问题,我来帮你逐个分析并给出能直接运行的正确实现:
首先是基于requests库的正确代码实现(这是Python处理HTTP请求最常用的工具):
import requests # 目标接口URL url = "https://example.com:8443/api/rest/abc_service/123/upload/passwd" # 请求头仅需保留accept,Content-Type会由requests自动处理 headers = { "accept": "application/json" } # 正确处理文件上传:在上下文管理器内打开文件并发送请求 with open("abhifile.txt", "rb") as file_obj: # 构造multipart/form-data参数,完全对应curl里的-F "body=@abhifile.txt;type=text/plain" files = { "body": ("abhifile.txt", file_obj, "text/plain") } # 发送POST请求 response = requests.post(url, headers=headers, files=files) # 处理响应结果 try: result = response.json() print("请求成功,响应结果:", result) except ValueError: # 若响应不是JSON格式,直接打印原始文本排查问题 print("响应非JSON格式,内容:", response.text) # 查看状态码确认请求是否成功 print("请求状态码:", response.status_code)
接下来逐个分析你遇到的错误:
错误1:后端返回"The provided class ABC doesn't have a JsonObject Constructor..."
这个错误是后端返回的序列化异常,说明你的请求已经到达后端,但后端在处理请求或生成响应时出了问题。大概率是你之前的请求格式不符合后端要求:
- 可能没有正确指定multipart/form-data的参数名(必须是
body,对应curl里的body=@abhifile.txt); - 或者没有设置正确的文件MIME类型(
text/plain); - 也有可能你错误地用了
json参数而非files参数发送请求,导致后端接收到JSON而非表单文件,触发了序列化错误。
错误2:触发"ValueError: I/O operation on closed file"
这是Python文件操作的典型问题,原因是你在文件流关闭后才尝试用它发送请求。比如你可能写了类似这样的错误代码:
# 错误示例:上下文管理器退出后文件已被关闭 file_obj = open("abhifile.txt", "rb") with file_obj: # 这里仅打开了文件但未发送请求 pass # 此时file_obj已经关闭,传入requests.post就会报错 requests.post(url, files={"body": file_obj})
正确的做法是像上面的示例那样,在with块内部完成请求发送,确保文件在请求过程中始终处于打开状态。
额外注意事项
- 不要手动添加
Content-Type: multipart/form-data请求头,requests会根据files参数自动生成正确的头信息(包括边界值),手动添加反而可能导致格式错误; - 确保
abhifile.txt的路径正确,如果文件不在当前脚本的工作目录,要使用绝对路径; - 如果请求仍然失败,优先打印
response.text查看后端返回的详细错误信息,这会帮你更快定位问题。
内容的提问来源于stack exchange,提问作者Abhijit
相关产品推荐
相关产品推荐

