如何使用requests.put()使用Python上载文件?

如何使用requests.put()使用Python上载文件?,python,encoding,python-requests,fedora-commons,Python,Encoding,Python Requests,Fedora Commons,我试图使用Python中的请求库将文件上载到localhost上的FedoraCommons存储库中。我很确定我的主要问题是不理解open()/read(),以及如何使用http请求发送数据 def postBinary(fileName,dirPath,url): path = dirPath+'/'+fileName print('to ' + url + '\n' + path) openBin = {'file':(fileName,open(path,'rb')

我试图使用Python中的请求库将文件上载到localhost上的FedoraCommons存储库中。我很确定我的主要问题是不理解
open()
/
read()
,以及如何使用http请求发送数据

def postBinary(fileName,dirPath,url):
    path = dirPath+'/'+fileName
    print('to ' + url + '\n' + path)
    openBin = {'file':(fileName,open(path,'rb').read())}
    headers = {'Slug': fileName} #not important
    r = requests.put(url, files=openBin,headers=headers, auth=HTTPBasicAuth('username', 'pass'))
    print(r.text)
    print("and the url used:")
    print(r.url)
这将成功地将文件上载到存储库中,但之后文件将稍大并损坏。例如,一个6.6kb的图像变成了6.75kb,无法再打开

那么我应该如何使用put-in-python正确打开和上传文件呢?

###额外详情:###

  • 当我将
    files=openBin
    替换为
    data=openBin
    时,我最终得到的是我的字典,我假设数据是一个字符串。我不知道这些信息是否有用。
    “文件=文件名。扩展名和文件=类型89A%24%02Q%03%E7%FF%00E%5B%19%FC%。。。。 文件的大小会增加到兆字节

  • 我之所以特别使用put,是因为Fedora RESTful HTTP API端点要求使用
    put

以下命令不起作用:


curl-u用户名:密码-H“内容类型:text/plain”-X PUT-T/path/to/someFile.jpeghttp://localhost:8080/fcrepo/rest/someFile.jpeg

更新

使用
requests.put()
files
参数发送一个多部分/表单数据编码请求,即使声明了正确的内容类型,服务器似乎也无法在不损坏数据的情况下处理该请求

curl
命令仅对请求正文中包含的原始数据执行PUT。您可以通过在
data
参数中传递文件数据来创建类似的请求。在标头中指定内容类型:

headers = {'Content-type': 'image/jpeg', 'Slug': fileName}
r = requests.put(url, data=open(path, 'rb'), headers=headers, auth=('username', 'pass'))
您可以根据需要改变
内容类型
标题以适应负载


尝试设置文件的
内容类型

如果您确定它是一个文本文件,请尝试在
curl
命令中使用的
text/plain
——即使您似乎正在上载jpeg文件?但是,对于jpeg图像,您应该使用
image/jpeg

否则,对于任意二进制数据,您可以使用
application/octet-stream

openBin = {'file': (fileName, open(path,'rb'), 'image/jpeg' )}

另外,不必显式读取代码中的文件内容,
请求将为您执行此操作,因此只需传递如上所示的打开文件句柄。

查看(使用
POST
方法)或(使用
PUT
方法)。帖子信息对我没有帮助,例外情况是套接字的协议错误。你发送的PUT方法链接我已经尝试过了,也没有运气:(创建了一个已损坏的文件嘿,我尝试过将内容类型文本纯文本作为标题,以及其他各种类型的文件。这可以为任何类型的文件调用,因此我没有指定。文本纯文本在下载时仍在curl中工作,但在python中不适用于请求,也不适用于“image/jpeg”或“application/octet stream”。尽管我注意到它有一个p存储库中的roperty hasMimeType为:multipart/form data;boundary=9f74e4d3067e4ce482bdc9e311b58d2d这有什么帮助吗?还感谢您提供有关读取的提示,我以前在调试时添加了它。我接受它out@awscott:服务器似乎无法正确处理多部分/表单格式的请求。我已将答案更新为显示一个更简单的方法,该方法生成与正在工作的
curl
命令类似的请求。您是正确的,它工作了!谢谢!我也按照您的建议为应用程序/octet流创建了内容类型头,现在它工作正常。r=requests.put(url,data=open(path,'rb'),headers=headers,auth=('username','pass'))-关于这一点,如果文件太大,则在不将其读入内存的情况下对其进行流式处理会更有意义?如果是,如何做到这一点?