在后台执行 python 脚本,同时发回 dialogflow 响应(Python Flask)
Execute python script in background, while dialogflow response is sent back (Python Flask)
app = Flask(__name__)
av=""
time=""
action=""
def again():
...
@app.route('/')
def index():
return 'Hello World!'
def results():
global action
req = request.get_json(force=True)
action = req.get('queryResult').get('action')
if(action=="get_address"):
global av
global time
av=req.get('queryResult').get('parameters').get('location').get('city')
threade=threading.Thread(target=again())
threade.start()
textv="Thanks! Please enter your name now."
return {'fulfillmentText': textv}
else:
textv="Time: " + time
return {'fulfillmentText': textv}
# create a route for webhook
@app.route('/webhook', methods=['GET', 'POST'])
def webhook():
# return response
return make_response(jsonify(results()))
# run the app
if __name__ == '__main__':
app.run()
所以这是 python 脚本,用于我的 Dialogflow 代理后端。代理具有以下会话结构:
您好->请输入地址->请输入姓名(浪费时间)->[然后给出行程时间]
所以这个代理基本上给出了输入地址和固定地址之间的旅行时间(使用again()
中的脚本)
另外请注意,我是在浪费时间,因为如果我直接尝试在地址后输出旅行时间,Dialogflow 代理会说,已超过截止日期。所以为了克服这个问题,我尝试了线程,以便在后台计算旅行时间,同时,响应返回到 dialogflow,它询问用户名,然后输出旅行时间。
但问题是,DialogFlow 仍然显示已超过最后期限(在 "Please enter you address")。我怀疑原因是,即使 python 脚本 returns webhook,但 dialogflow 不显示输出,直到 python 脚本停止执行。那么我该如何克服呢?
总结一下,我希望返回请求(get_address
操作),同时计算行程时间(使用 again()
)并在下一个请求中返回。
所以按照建议, 我从 results()
函数的 if()
部分中删除了 return {'fulfillmentText': textv}
并将其替换为 return {'followupEventInput': 'IN_PROGRESS'}
,但它仍然显示 DEADLINE_EXCEEDED
。正如我之前所说,问题似乎在于 results()
函数根本没有返回。
您面临的问题是您的计算任务可能需要超过最长 4 秒的 DialogFlow 在问题和答案之间等待。
事实上,一个基本的解决方案是在某个时候购买,问其他问题。
在接下来的交互过程中,您需要检查后台线程是否完成,然后获取时间。否则你需要延长这个过程。
一种稍微好一点的方法是触发事件(而不是提问):
- 输入地址
- webhook 被调用
- 启动后台线程,休眠3秒,触发事件IN_PROGRESS
- DialogFlow 意图 I1 由事件触发 IN_PROGRESS,向用户显示一条消息(即处理它)
- webhook 在 Intent I1 之后调用,休眠 3 秒,然后检查后台线程状态
我自己想出来的。问题在于语法:
threade=threading.Thread(target=again())
again
后不应该有()
。
app = Flask(__name__)
av=""
time=""
action=""
def again():
...
@app.route('/')
def index():
return 'Hello World!'
def results():
global action
req = request.get_json(force=True)
action = req.get('queryResult').get('action')
if(action=="get_address"):
global av
global time
av=req.get('queryResult').get('parameters').get('location').get('city')
threade=threading.Thread(target=again())
threade.start()
textv="Thanks! Please enter your name now."
return {'fulfillmentText': textv}
else:
textv="Time: " + time
return {'fulfillmentText': textv}
# create a route for webhook
@app.route('/webhook', methods=['GET', 'POST'])
def webhook():
# return response
return make_response(jsonify(results()))
# run the app
if __name__ == '__main__':
app.run()
所以这是 python 脚本,用于我的 Dialogflow 代理后端。代理具有以下会话结构:
您好->请输入地址->请输入姓名(浪费时间)->[然后给出行程时间]
所以这个代理基本上给出了输入地址和固定地址之间的旅行时间(使用again()
中的脚本)
另外请注意,我是在浪费时间,因为如果我直接尝试在地址后输出旅行时间,Dialogflow 代理会说,已超过截止日期。所以为了克服这个问题,我尝试了线程,以便在后台计算旅行时间,同时,响应返回到 dialogflow,它询问用户名,然后输出旅行时间。
但问题是,DialogFlow 仍然显示已超过最后期限(在 "Please enter you address")。我怀疑原因是,即使 python 脚本 returns webhook,但 dialogflow 不显示输出,直到 python 脚本停止执行。那么我该如何克服呢?
总结一下,我希望返回请求(get_address
操作),同时计算行程时间(使用 again()
)并在下一个请求中返回。
所以按照建议, 我从 results()
函数的 if()
部分中删除了 return {'fulfillmentText': textv}
并将其替换为 return {'followupEventInput': 'IN_PROGRESS'}
,但它仍然显示 DEADLINE_EXCEEDED
。正如我之前所说,问题似乎在于 results()
函数根本没有返回。
您面临的问题是您的计算任务可能需要超过最长 4 秒的 DialogFlow 在问题和答案之间等待。
事实上,一个基本的解决方案是在某个时候购买,问其他问题。
在接下来的交互过程中,您需要检查后台线程是否完成,然后获取时间。否则你需要延长这个过程。
一种稍微好一点的方法是触发事件(而不是提问):
- 输入地址
- webhook 被调用
- 启动后台线程,休眠3秒,触发事件IN_PROGRESS
- DialogFlow 意图 I1 由事件触发 IN_PROGRESS,向用户显示一条消息(即处理它)
- webhook 在 Intent I1 之后调用,休眠 3 秒,然后检查后台线程状态
我自己想出来的。问题在于语法:
threade=threading.Thread(target=again())
again
后不应该有()
。