appengine python中包含多部分/表单数据的Post请求不起作用
我正试图从appengine应用程序向dotcloud上托管的外部(django)api发送一个多部分post请求。请求包括一些文本和一个文件(pdf),并使用以下代码发送appengine python中包含多部分/表单数据的Post请求不起作用,python,django,google-app-engine,post,Python,Django,Google App Engine,Post,我正试图从appengine应用程序向dotcloud上托管的外部(django)api发送一个多部分post请求。请求包括一些文本和一个文件(pdf),并使用以下代码发送 from google.appengine.api import urlfetch from poster.encode import multipart_encode from libs.poster.streaminghttp import register_openers register_openers() fil
from google.appengine.api import urlfetch
from poster.encode import multipart_encode
from libs.poster.streaminghttp import register_openers
register_openers()
file_data = self.request.POST['file_to_upload']
the_file = file_data
send_url = "http://127.0.0.1:8000/"
values = {
'user_id' : '12341234',
'the_file' : the_file
}
data, headers = multipart_encode(values)
headers['User-Agent'] = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
data = str().join(data)
result = urlfetch.fetch(url=send_url, payload=data, method=urlfetch.POST, headers=headers)
logging.info(result.content)
当此方法运行时,Appengine会发出以下警告(我不确定是否与我的问题有关)
Django通过以下错误发送
<class 'django.utils.datastructures.MultiValueDictKeyError'>"Key 'the_file' not found in <MultiValueDict: {}>"
如果我加上
print request.POST.keys()
我得到了一个包含用户\u id和\u文件的字典,表明该文件没有作为文件发送。如果我对文件也这样做,即
print request.FILES.keys()
我得到一个空列表[]
编辑1:
我已经改变了我的问题,以实施某人的建议,但这仍然失败。我还包括了Glenn发送的链接建议添加的标题,但没有joy
编辑2:
我还尝试将_文件作为
the_file = file_data.file
the_file = file_data.file.read()
但我也犯了同样的错误
编辑3:
我还试着编辑我的django应用程序来
the_file = request.POST["the_file"]
但是,当我试图用
path = default_storage.save(file_location, ContentFile(the_file.read()))
它失败了
<type 'exceptions.AttributeError'>'unicode' object has no attribute 'read'<traceback object at 0x101f10098>
“unicode”对象没有属性“read”
同样,如果我尝试访问_file.file(我可以在appengine应用程序中访问),它会告诉我
<type 'exceptions.AttributeError'>'unicode' object has no attribute 'file'<traceback object at 0x101f06d40>
“unicode”对象没有属性“file”
您正在对数据进行URL编码,而您应该对其进行多部分编码。看看这个:这里是我在本地测试的一些代码,应该可以做到这一点(我使用了不同于webapp2的处理程序,但试图将其修改为webapp2。您还需要在此处找到海报库):
在GAE上的POST处理程序中:
from google.appengine.api import urlfetch
from poster.encode import multipart_encode
payload = {}
payload['test_file'] = self.request.POST['test_file']
payload['user_id'] = self.request.POST['user_id']
to_post = multipart_encode(payload)
send_url = "http://127.0.0.1:8000/"
result = urlfetch.fetch(url=send_url, payload="".join(to_post[0]), method=urlfetch.POST, headers=to_post[1])
logging.info(result.content)
确保HTML表单包含method=“POST”enctype=“multipart/form data”
。希望这有帮助
编辑:
我尝试使用webapp2处理程序,并意识到文件的服务方式不同于我使用works(KAY)测试的框架。下面是应该实现这一技巧的更新代码(在生产中测试):
导入webapp2
从google.appengine.api导入urlfetch
从poster.encode导入multipart_encode,MultipartParam
类UploadTest(webapp2.RequestHandler):
def post(自我):
有效载荷={}
file\u data=self.request.POST['test\u file']
有效负载['test_file']=MultipartParam('test_file',filename=file_data.filename,
filetype=file\u data.type,
fileobj=file_data.file)
有效负载['name']=self.request.POST['name']
数据,标题=多部分编码(有效负载)
发送url=”http://127.0.0.1:8000/"
t=urlfetch.fetch(url=send_url,payload=”“.join(数据),method=urlfetch.POST,headers=headers)
self.response.headers['Content-Type']='text/plain'
自我、回应、输出、写入(t.content)
def get(自我):
self.response.out.write(“”)
文件上传测试
""")
您好,谢谢您的代码。appengine field here()中有一个bug,它限制了multipart_encode方法的实用性。我现在只是在测试一个变通方法。我不完全确定这个错误是否会影响到您试图完成的任务。事实上,我不知道这个bug是否仍然有效,因为您可以对数据进行编码,并将其打包为POST urlfetch中的有效负载,就像我使用poster lib.Perfect给出的示例代码一样!编辑后的版本完全按照要求工作-非常感谢您的帮助,这让我分心!
<type 'exceptions.AttributeError'>'unicode' object has no attribute 'file'<traceback object at 0x101f06d40>
from google.appengine.api import urlfetch
from poster.encode import multipart_encode
payload = {}
payload['test_file'] = self.request.POST['test_file']
payload['user_id'] = self.request.POST['user_id']
to_post = multipart_encode(payload)
send_url = "http://127.0.0.1:8000/"
result = urlfetch.fetch(url=send_url, payload="".join(to_post[0]), method=urlfetch.POST, headers=to_post[1])
logging.info(result.content)
import webapp2
from google.appengine.api import urlfetch
from poster.encode import multipart_encode, MultipartParam
class UploadTest(webapp2.RequestHandler):
def post(self):
payload = {}
file_data = self.request.POST['test_file']
payload['test_file'] = MultipartParam('test_file', filename=file_data.filename,
filetype=file_data.type,
fileobj=file_data.file)
payload['name'] = self.request.POST['name']
data,headers= multipart_encode(payload)
send_url = "http://127.0.0.1:8000/"
t = urlfetch.fetch(url=send_url, payload="".join(data), method=urlfetch.POST, headers=headers)
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write(t.content)
def get(self):
self.response.out.write("""
<html>
<head>
<title>File Upload Test</title>
</head>
<body>
<form action="" method="POST" enctype="multipart/form-data">
<input type="text" name="name" />
<input type="file" name="test_file" />
<input type="submit" value="Submit" />
</form>
</body>
</html>""")