使用 PyCurl 从文件对象上传文件
我正在尝试上传这样的文件:
import pycurl
c = pycurl.Curl()
values = [
("name", "tom"),
("image", (pycurl.FORM_FILE, "tom.png"))
]
c.setopt(c.URL, "http://upload.com/submit")
c.setopt(c.HTTPPOST, values)
c.perform()
c.close()
这工作正常。但是,这仅在文件是本地的情况下才有效。如果我要获取图像:
import urllib2
resp = urllib2.urlopen("http://upload.com/people/tom.png")
如何将 resp.fp 作为文件对象传递,而不是将其写入文件并传递文件名?这可能吗?
I'm attempting to upload a file like this:
import pycurl
c = pycurl.Curl()
values = [
("name", "tom"),
("image", (pycurl.FORM_FILE, "tom.png"))
]
c.setopt(c.URL, "http://upload.com/submit")
c.setopt(c.HTTPPOST, values)
c.perform()
c.close()
This works fine. However, this only works if the file is local. If I was to fetch the image such that:
import urllib2
resp = urllib2.urlopen("http://upload.com/people/tom.png")
How would I pass resp.fp as a file object instead of writing it to a file and passing the filename? Is this possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在完美的情况下,基本上连接两个流是可能的,但这不是一个非常可靠的解决方案。有一堆丑陋的边界条件:
接收数据,和/或停止,
从而导致你挨饿
打破 POST (因为 PycURL 不是
预计必须等待数据
超出当前结束时间
“文件”)。
您最好暂时将文件写入磁盘,然后在知道您拥有整个文件后将其发布。
如果您确实想这样做,最好的方法可能是实现您自己的类文件对象,该对象将管理两个连接之间的桥梁(可以正确缓冲、处理解码等)。
编辑:
根据您留下的评论 - 绝对 - 您只需要 setopt READFUNCTION 。查看 file_upload 示例:
http://pycurl.cvs.sourceforge.net/viewvc/pycurl/pycurl/examples/file_upload.py?revision=1.5&view=markup
它通过在文件上制作一个小包装来实现这一点带有回调的对象以从中读取数据,或者如果您不需要进行任何处理,则可以将
READFUNCTION
回调设置为fp.read
。It might be possible in perfect situations to basically connect the two streams, but it wouldn't be a very robust solution. There are a bunch of ugly boundary conditions:
receiving data, and/or be stalled,
thus causing you to starve out and
break the POST (because PycURL is not
expecting to have to wait for data
beyond the current end of the
"file").
You'll be much better off writing the file to disk temporarily and then POSTing it once you know you have the whole thing.
If you did want to do this, the best way would probably be to implement your own file-like object which would manage the bridge between the two connections (could properly buffer, handle decoding, etc.).
EDIT:
Based on the comment you left - absolutely - you just need to setopt
READFUNCTION
. Check out the file_upload example at:http://pycurl.cvs.sourceforge.net/viewvc/pycurl/pycurl/examples/file_upload.py?revision=1.5&view=markup
It does exactly this by making a tiny wrapper on a file object with a callback to read the data from it, or alternatively if you don't need to do any processing, you can literally set the
READFUNCTION
callback to befp.read
.