How to submit a query to Google Dialogflow using Flask - python-3.x

I have the following python script that is connecting to Google Dialogflow using Flask and is using a webhook to retrieve the response from Google Dialogflow.
The limitation is that I currently only enter the query in to the Google Dialogflow frontend, with the result returned here in variable result
However how can I use this same script to submit the query to Google Dialogflow, instead of entering in the front end?
Any help appreciated, thanks!
import json
import os
from flask import Flask
from flask import request
from flask import make_response`
`enter code here # Flask app should start in global layout
app = Flask(__name__)
#app.route('/webhook', methods=['POST'])
def webhook():
req = request.get_json(silent=True, force=True)
res = processRequest(req)
res = json.dumps(res, indent=4)
r = make_response(res)
r.headers['Content-Type'] = 'application/json'
return r
def processRequest(req):
result = req.get("queryResult")
result_message = result['fulfillmentText']
print(result_message)
#app.route('/test', methods=['GET'])
def test():
return "Hello there my friend !!"
if __name__ == '__main__':
port = int(os.getenv('PORT', 5000))
app.run(debug=True, port=port, host='0.0.0.0')`

I discovered shortly after posting this that a webhook is whats known as a reverse API, and only shows results as opposed to two way interactions.

Related

How can I host a dynamic flask app that acts as a listener for a twilio phone number?

I made a simple flask app that acts as a listener connected to twilio via a webhook. The logic within the app generates a response and returns the response. I'm stuck trying to deploy and host this app. Anyone have experience with this and suggestions?
Below is similar my python file some things are changed such has account info. This is all I have at the moment:
# IMPORTS =============================================================
from flask import Flask, request, redirect
from twilio.twiml.messaging_response import MessagingResponse
# FIELD VARIBALES ===========================================================
account_sid = 'ACCOUNT_SID'
auth_token = 'AUTH_TOKEN'
twilio_number = 'TWILIO_NUMBER'
# FUNCTIONS =======================================================
# Functions to be used in generating response. These are left out for this thread.
# APP =================================================================
app = Flask(__name__)
#app.route("https://mywebhook.com/sms", methods=['GET', 'POST'])
def sms():
"""Send a dynamic reply to an incoming text message"""
# Get the message the user sent our Twilio number
body = request.values.get('Body', None)
# Start our TwiML response
resp = MessagingResponse()
# Determine the right reply for this message
if body == 'hello':
resp.message("Hi!")
elif body == 'bye':
resp.message("Goodbye")
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
I've tried using Netlify and expected a response when texting my twilio number. However there is no response.

How do I solve page not found error in flask rest api

I have developed a flask application that returns some text from OPEN-AI by giving some inputs.
But unfortunately the rest API in my application returns 404 error.
Here is the code:
from crypt import methods
from warnings import catch_warnings
from flask import Flask,request
from flask_cors import CORS
import flask
import openai
from flask_restful import Api,Resource
import base64
import json
#Init
app = Flask(__name__)
CORS(app)
api = Api(app)
app.run(host='0.0.0.0',port=8080)
#OPENAI CREDENTIALS
openai.api_key = ""
#Functions
class advert(Resource):
def post(self):
try:
request_body=request.json
A=request_body["data"]
adprompt = "Write an advertisement for " + A
response = openai.Completion.create(
engine="text-davinci-002",
prompt=adprompt,
temperature=0.7,
max_tokens=70,
top_p=1.0,
n=1
)
json_advert = json.loads(str(response))
advert_output = json_advert['choices'][0]['text']
to_return= json_advert = json.loads(str(advert_output))
return to_return,200
except:
return ({"ERROR":"Error Occured"}),500
#Mapping
api.add_resource(advert,'/data',methods=['POST'])
if __name__=='__main__':
app.run(debug=True)
This is the response i get:
192.168.1.21 - - [24/Nov/2022 11:52:59] "POST /data HTTP/1.1" 404 -
I've tried changing the port and endpoints, nothing helped .
How to solve this.
Your problem is at this line,
app.run(host='0.0.0.0',port=8080)
take it out, then add the parameters into the last line,
if __name__=='__main__':
app.run(debug=True, host='0.0.0.0',port=8080)
A bit more explanation, when the code hits app.run, it actually starts the server and not running the line api.add_resource. Hence, no path was configured.

Using pytest fixtures in class

I have begun writing unit tests for my Flask API. I have gotten them to work when declared outside of a class. However, for simplicity and OOP constraints, I am trying to have everything run from a class. The issue is I cannot seem to pass any fixture methods to my test class. The code I have here is as follow:
#conftest.py
import os, json, pytest
from ..app import create_app
from flask import Flask
#pytest.fixture
def env_setup():
env_name = os.getenv('FLASK_ENV')
app = create_app(env_name)
return app
I am trying to import env_setup into the following file.
# test_BaseURL.py
import pytest
#pytest.mark.usefixtures("env_setup")
class TestStaticPages:
def setUp(self, env_setup):
"""
Setup Test
"""
self.client = env_setup.test_client()
def test_base_route(self, env_setup):
#client = env_setup.test_client()
url = '/'
html1 = b'Welcome to the API. Please visit '
html2 = b'https://example.com to learn more about this app.'
response = self.client.get(url)
assert response.get_data() == html1 + html2
assert response.status_code == 200
I keep geeting the following error when I run this test:
> response = self.client.get(url)
E AttributeError: 'TestStaticPages' object has no attribute 'client'
src/tests/test_BaseURL.py:18: AttributeError
However if I should uncomment the line with client = env_setup.test_client() it works. For whatever reason it cannot seem to grab the setup from the setUP method and keeps erroring out.
Here is how I fixed my issue:
#conftest.py
import os, json, pytest
from ..app import create_app
from flask import Flask
#pytest.fixture
def client():
env_name = os.getenv('FLASK_ENV')
app = create_app(env_name)
client = app.test_client()
return client
I was then able to import the client into my other test class like so.
#test_StaticView.py
import pytest
#pytest.mark.usefixtures("client")
class TestStaticPages:
def test_base_route(self, client):
url = '/'
html1 = b'Welcome to the API. Please visit '
html2 = b'https://example.com to learn more about this app.'
response = client.get(url)
assert response.get_data() == html1 + html2
assert response.status_code == 200

Pass filepath as parameter to a URL in FLASK(Python)

I want to build an api which accepts a parameter from the user which is a filepath and then process the file given in that path. The file to be processed is already in the server where the api will be running.
As of now, I have written an api where I have hardcoded the filepath in my code which runs the api. Now, I want to configure my api in such a way that accepts a filepath from the user. My api should accept the path as a parameter and process the file that has been given in the path.
The api code is as follows:
The convert function returns the category of the file.
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
#convert(r'D:\files\67cecf40-71cf-4fc4-82e1-696ca41a9fba.pdf')
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
categories=convert(r'D:\files\6628cb99-a400-4821-8b13-aa4744bd1286.pdf')
#app.route('/')
def returnResult():
return categories
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
So, I want to make changes to this code to accept a parameter from the user which will be a filepath and the convert function will process that filepath. I want to know how to make my api accept a filepath parameter from the user.
Trial with requests.args.get:
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
#convert(r'D:\files\67cecf40-71cf-4fc4-82e1-696ca41a9fba.pdf')
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
#app.route('/')
def returnResult():
categories=convert(r'D:\files\'.format(request.args.get('categories')))
return categories
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
results in error :
"RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem."
PRESENT SCENARIO:
I am able to post a filepath to the url. My question is now how do I use this posted url with filepath in my code to trigger my function that takes in the filepath and processes the file. Code to post the filepath:
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
categories=convert('/home/brian/ajay/files/5ca21af9-5b67-45f8-969c-ae571431c665.pdf')
#app.route('/')
def returnResult():
return categories
#app.route('/', defaults={'path': ''})
#app.route('/<path:path>')
def get_dir(path):
return path
##app.route('/get_dir/<path>')
#def get_dir(path):
# return path
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)

Connect to API and send back a message with Flask app

I have a flask app deployed to Heroku and would like to receive text from Chatfuel (bot building platform) and send back texts in return.
Now, what I did is to use my heroku app as a web-hook, so that Chatfuel can make a simple GET or POST query to my API. The problem is that I have no experience with Flask or APIs, so I am not sure about how my app can receive information (in json format) and send it back to chatfuel.
This is what I wrote so far:
import os
import sys
import json
import requests
from flask import Flask, jsonify, render_template, request
app = Flask(__name__)
#app.route('/', methods=['GET'])
def verify():
# when the endpoint is registered as a webhook, it must echo back
# the 'hub.challenge' value it receives in the query arguments
if request.args.get("hub.mode") == "subscribe" and request.args.get("hub.challenge"):
if not request.args.get("hub.verify_token") == os.environ["VERIFY_TOKEN"]:
return "Verification token mismatch", 403
return request.args["hub.challenge"], 200
return "Hello world", 200
#app.route("/json", methods=['GET','POST'])
def json():
url = "chatfuel_api"
data = json.load(urllib2.urlopen(url))
if request.json:
mydata = request.json
return "Thanks",200
else:
return "no json received"
#app.route('/hello', methods = ['GET','POST'])
def api_echo():
if request.method == 'GET':
return "ECHO: GET\n",200
if __name__ == '__main__':
app.run(debug=True)
The verify() function works, as I see an 'Hello world' message if I run the app locally. However, both json() and api_echo() don't work, and when my server receives a get or post request from chatfuel, it returns a 404 error.
As you can see, I really have a lot of confusion, and your help would be really invaluable.
Thanks
You need to make sure you have registered the proper webhook url with Chatfuel. For the code you currently have, to hit the json endpoint the url would be https://www.your_server.com/json
The verify route looks like the hub challenge FB sends, so you would have to register the root of your site (that is, with your current code) with FB to hit the verify function. That url would look like this https://www.your_site.com/

Resources