tornado 中 Flask API 的替代品(Dialogflow webhook)

我需要在 Tornado 服务器中为 Dialogflow 创建一个 webhook。我以前用烧瓶做过这个。我是他们两个的初学者。Flask Flask webhook代码的代码:


from flask import render_template

import os

from flask import Flask

from flask import request

from flask import make_response

import json

import time


app = Flask(__name__)


@app.route("/")

def index():

    return render_template("index.html")


@app.route('/webhook', methods=['POST', 'GET'])

def webhook():

    req = request.get_json(silent=True, force=True)

    print(json.dumps(req, indent=4))

    res = makeWebhookResult(req)

    res = json.dumps(res, indent=4)

    print("+++++++++++++++RESPONSE+++++++++++++++++", res)

    r = make_response(res)

    r.headers['Content-Type'] = 'application/json'

    return r


# Right now I'm just printing a response to see if it works properly


def makeWebhookResult(req):

      queryResult = req.get('queryResult').get("queryText")

      speech =  queryResult       

      return {

            "fulfillmentText": 'YOLO',

            "source": 'App'

        }


#./ngrok http 8090

if __name__ == '__main__':

    port = int(os.getenv('PORT', 8090))

    print("Starting app on port %d" % (port))

    app.run(debug=True, port=port, host='localhost')


现在我像这样在龙卷风中试过这个:


import tornado.ioloop

import tornado.web as web

import tornado

import json

import os


static_root = os.path.join(os.path.dirname(__file__), 'static')



class MainHandler(tornado.web.RequestHandler):

    def get(self):

        template = "./templates/index.html"

        self.render(template)



它适用于 Flask。当我尝试通过龙卷风运行它(使用 ngrok 进行隧道传输)时,我收到警告:tornado.access:405 POST /webhook (127.0.0.1) 0.83ms


我阅读了龙卷风的文档,但我似乎仍然无法弄清楚我该怎么做。我假设问题出在 Webhook 类中。我在这里做错了什么?


鸿蒙传说
浏览 166回答 1
1回答

jeck猫

警告显示POST请求有问题 - 并处理POST您需要def post()的类方法Webhook。它应该post()代替prepare()(这是为了不同的东西)。你可以用self.write(dictionary)它来发送'application/json'class Webhook(tornado.web.RequestHandler):&nbsp; &nbsp; def post(self):&nbsp; &nbsp; &nbsp; &nbsp; if self.request.headers.get("Content-Type", "").startswith("application/json"):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data_input = json.loads(self.request.body)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('data_input:', data_input)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('data_input json.dumps:', json.dumps(data_input, indent=4))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data_output = self.webhook_result(data_input) # get as normal dict, not string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('data_output:', data_output)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('data_output json.dumps:', json.dumps(data_output, indent=4))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.write(data_output) # it will send as JSON&nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.write({'error': 'Wrong Content-Type'}) # it will send as JSON顺便说一句:如果你发送值到webhook_result()那么你可以获得这个值 - 即 as data- 并使用它而不是self.req&nbsp; &nbsp; def webhook_result(self, data):&nbsp; &nbsp; &nbsp; &nbsp; speech = data.get('queryResult').get("queryText")&nbsp; &nbsp; &nbsp; &nbsp; print('speech:', speech)&nbsp; &nbsp; &nbsp; &nbsp; return {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "fulfillmentText": 'YOLO',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "source": 'App'&nbsp; &nbsp; &nbsp; &nbsp; }我测试的代码import tornadoimport tornado.webimport jsonimport osstatic_root = os.path.join(os.path.dirname('.'), 'static')class MainHandler(tornado.web.RequestHandler):&nbsp; &nbsp; def get(self):&nbsp; &nbsp; &nbsp; &nbsp; #self.render("./templates/index.html")&nbsp; &nbsp; &nbsp; &nbsp; # to test POST request but with wrong Content-Type&nbsp; &nbsp; &nbsp; &nbsp; self.write('''<form action="/webhook" method="POST"><button>SUBMIT</button></form>''')class Webhook(tornado.web.RequestHandler):&nbsp; &nbsp; def post(self):&nbsp; &nbsp; &nbsp; &nbsp; if self.request.headers.get("Content-Type", "").startswith("application/json"):&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data_input = json.loads(self.request.body)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('data_input:', data_input)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('data_input json.dumps:', json.dumps(data_input, indent=4))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data_output = self.webhook_result(data_input) # get as normal dict, not string&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('data_output:', data_output)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print('data_output json.dumps:', json.dumps(data_output, indent=4))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.write(data_output) # it will send as JSON&nbsp; &nbsp; &nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.write({'error': 'Wrong Content-Type'}) # it will send as JSON&nbsp; &nbsp; def webhook_result(self, data):&nbsp; &nbsp; &nbsp; &nbsp; speech = data.get('queryResult').get("queryText")&nbsp; &nbsp; &nbsp; &nbsp; print('speech:', speech)&nbsp; &nbsp; &nbsp; &nbsp; return {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "fulfillmentText": 'YOLO',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "source": 'App'&nbsp; &nbsp; &nbsp; &nbsp; }handlers = [&nbsp; &nbsp; (r'/', MainHandler),&nbsp; &nbsp; (r'/webhook', Webhook),&nbsp; &nbsp; # probably it should be as last&nbsp; &nbsp; #(r'(.*)', web.StaticFileHandler, {'path': static_root}),]settings = dict(&nbsp; &nbsp; debug=True,&nbsp; &nbsp; static_path=static_root)application = tornado.web.Application(handlers, **settings)if __name__ == "__main__":&nbsp; &nbsp; port = 8090&nbsp; &nbsp; application.listen(port)&nbsp; &nbsp; print(f"Running: http://127.0.0.1:{port}")&nbsp; &nbsp; tornado.ioloop.IOLoop.instance().start()我用来发送POST带有 JSON 数据的请求的代码:import requestsurl = 'http://127.0.0.1:8090/webhook'data = {'queryResult': {'queryText': 'Hello World'}}r = requests.post(url, json=data)print(r.status_code)print(r.headers.get('Content-Type'))print(r.json())顺便说一句:在 Flask 中你可以做@app.route('/webhook', methods=['POST', 'GET'])def webhook():&nbsp; &nbsp; data_input = request.get_json(silent=True, force=True)&nbsp; &nbsp; data_output = makeWebhookResult(data_input)&nbsp; &nbsp; return jsonify(data_output)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python