我在Java中为blobstore API实现了这个GWT示例: https://cloud.google.com/appengine/docs/java/blobstore/
通过客户端表单(在浏览器中)进行POST时,它可以正常工作。
但是,现在我将文件(图像)发送到同一个/上传服务处理程序,但是从我的离线程序(而不是浏览器)中的python请求发送:
r = requests.post(url+'upload', files= {'myFile': open('fig.jpeg', 'rb')})
我得到以下异常
必须从blob上传回调请求中调用
在(服务器端)的第一行:
Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
List<BlobKey> blobKeys = blobs.get("myFile");
我做错了什么?
答案 0 :(得分:1)
/upload
处理程序不适合您直接调用,既不是浏览器也不是python应用程序。相反,您的应用程序需要进行两次调用:第一次到您的服务器获取一个临时URL,然后第二次上传到该URL,它将直接与blobstore连接。您的服务器应使用blobstoreService.createUploadUrl
生成该临时URL,如您链接的文档this section的第1步所述。
在第二次调用(上传)过程中,blobstore将直接调用您的上传处理程序,以通知您的应用程序有关新blob的信息。这就是blobstoreService.getUploads(req)
知道如何解释的原因。
所以你的python应用程序将进行2次调用,你的服务器也将处理2个请求。第一个请求直接来自python应用程序,只是请求URL。第二个请求将在上传期间发生,但实际上会直接来自blobstore。
答案 1 :(得分:0)
import datetime
import time
import requests # to make get and post requests
import json
from flask import Flask, Response, request, render_template # request : is not same as requests its flask request on url
app = Flask(__name__)
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True
# 3. no need to give any url mapping for callback function,
# this will get call once demo() return back to hello() at post request call.
def callbacks(response, *args, **kwargs):
print(" -- callbacks starts -- : ", datetime.datetime.now().time())
if response.status_code == 200:
#print(response.text)
print(" -- callback end -- : ", datetime.datetime.now().time());
#return response
# return Response(response, status=200) do not return response here this will cause problem when
# 2. on post request call made from hello(): resp = requests.post(......)
@app.route('/demo' , methods=['POST']) # validate request of type methods=['POST']
def demo():
print("Post request received : ", datetime.datetime.now().time())
if request.method == 'POST': # check request of type post
time.sleep(5) # some sleep time to check if callback is working
print("Post response sent to callback : ", datetime.datetime.now().time())
# return response with data received from request.data and status = 200
return Response(request.data, headers={'Content-Type': 'application/json'}, status=200)
# 1. run this file and hit url localhost:5000/ to execute ( GET request)
@app.route('/', methods=['GET'])
def hello():
print("Hello start : ", datetime.datetime.now().time())
url = 'http://jsonplaceholder.typicode.com/users'; # url will return json list
data = requests.get(
url=url,
headers={'Content-Type': 'application/json'}
) # get request to get json data from url using requests lib
# check if flask request is get
if request.method == 'GET':
# post request to another url /demo with data as a json as argument ,
# imp : hooks to link callback function once /demo url returns response callback will start execute
resp = requests.post( url = 'http://localhost:5000/demo',
headers = {'Content-Type': 'application/json'},
json = data.json(),
hooks={'response': callbacks }
)
print("Hello End : ",datetime.datetime.now().time())
# render with html template with argument as data and result
return render_template('index.html', result=resp.json(), data=data.json())
# OR
# return Response(response='OK', status=resp.status_code) # return response with 200 or 'OK'
if __name__ == '__main__':
app.run(debug=False)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSON OUTPUT</title>
</head>
<body>
<table border="1">
<tr><td>ID</td><td>Name</td><td>Email</td></tr>
{% for d in data %}
<tr><td>{{ d['id'] }}</td><td>{{ d['name'] }}</td><td>{{ d['email'] }}</td></tr>
{% endfor %}
</table>
<div>{{ result }}</div>
</body>
</html>