How to call microservice-2 from microservice-1 using python? - python

How to call my microservice-2 from microservice-1. So our result looks like this:-
Result :- {“message”: “vivek”} --> {“message”: “keviv”, “random”: 3.89}
command to access microservice-1:-
curl http://127.0.0.1:5000/reverse_random/vivek
microservice-1
from flask import Flask, jsonify
app = Flask(__name__)
#app.route('/reverse_reandom/<string:string>', methods=['GET'])
def reverse(string):
string = string[::-1]
return jsonify({'message': string })
if __name__ == '__main__':
app.run(debug = True)
microservice-2
import random
from flask import Flask, jsonify
app = Flask(__name__)
#app.route('/', methods=['GET'])
def myRandom():
r1 = random.uniform(0, 10)
return jsonify({'message': r1 })
if __name__ == '__main__':
app.run(debug=True)

you'll need to issue a GET request to service 2 in order to get the random number, I suggest to use requests for this, like
r = requests.get('url-for-service-2:port/')
data = r.json()
random_num = data['message']
keep in mind to check the data object for message key, or using .get() or equivalent

Run microservice-2 on a different port. Send request using Python standard or 3rd party library from microservice-1
to microservice-2 upon request to microservice-1.
Below is the example of using Python3 standard library only:
m1.py:
from flask import Flask, jsonify
import urllib
import json
app = Flask(__name__)
#app.route('/reverse_random/<string:string>', methods=['GET'])
def reverse(string):
content = urllib.request.urlopen('http://127.0.0.1:5001').read().decode('utf-8')
print('response from m2: ', content)
string = string[::-1]
return jsonify({'message': string, 'random' : json.loads(content)['message']})
if __name__ == '__main__':
app.run(debug = True)
m2.py:
import random
from flask import Flask, jsonify
app = Flask(__name__)
#app.route('/', methods=['GET'])
def myRandom():
r1 = random.uniform(0, 10)
return jsonify({'message': r1 })
if __name__ == '__main__':
app.run(debug=True, port=5001) # running m2 on a different port than default 5000
Run the m1: python3 m1.py
Run the m2 in a different shell: python3 m2.py
Send request to m1: curl http://127.0.0.1:5000/reverse_random/vivek
The result is:
{
"message": "keviv",
"random": 4.138115905045612
}
Observe the log of m1 and of m2 to make sure m2 was invoked.

To connect between services you can use background tasks such as celery and ramq or use nsq and nats

Related

Dialogflow response from webhook using flask python integration platform digital human uneeq

I am trying to send a response to Dialogflow Es using webhook written in python-flask.
Integration platform :
digital human --> Uneeq
I tried with the fulfillment library (dialogflow_fulfillment) but it was not working so I tried it without a library like :
if req.get('queryResult').get('action') == 'appointment':
print("ïntent triggered")
return {"fulfillmentText": 'BUDDY!'}
It worked!
Now the issue is before integrating this chatbot to digital human I wrote the whole code using the fulfillment library. Now I need to change the whole code for this purpose.
As I am unable to extract entities using context-based intents (session-vars) like :
case = agent.context.get('session-vars').get('parameters').get('case')
name = agent.context.get('session-vars').get('parameters').get('name')['name']
email = agent.context.get('session-vars').get('parameters').get('email')
phone = agent.context.get('session-vars').get('parameters').get('phone')
So my question is how to accomplish this task successfully?
If I try to use the fulfillment library then how to send a response to Dialogflow so that digital human will understand it since "agent.add" doesn't work.
Or, If I try to do it without a library then how to extract entities(from the session-vars) like (case, name, email, phone).
I need to save all these parameters(entities) in firebase, These output context (only session-vars parameters not other contexts):
This is the response I am getting correctly without library:
Unable to proceed at any cost!
looking forward to your response.
Thanks in advance!
Complete code (with the library):
from dialogflow_fulfillment import WebhookClient
from flask import Flask, request, Response
import json
app = Flask(__name__)
def handler(agent: WebhookClient) :
"""Handle the webhook request.."""
req = request.get_json(force=True)
a= req.get('queryResult').get('action')
if req.get('queryResult').get('action') == 'appointment':
name = agent.context.get('session-vars').get('parameters').get('name')['name']
email = agent.context.get('session-vars').get('parameters').get('email')
phone = agent.context.get('session-vars').get('parameters').get('phone')
print("ïntent triggered")
agent.add('BUDDY!')
#app.route('/webhook', methods=['GET', 'POST'])
def webhook():
req = request.get_json(force=True)
agent = WebhookClient(req)
agent.handle_request(handler)
return agent.response
if __name__ == '__main__':
app.run(debug=True)
Complete code (without library):
import urllib
import json
import os
from flask import Flask
from flask import request
from flask import make_response
# 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 = makeWebhookResult(req)
res = json.dumps(res, indent=4)
r = make_response(res)
#print(res)
r.headers['Content-Type'] = 'application/json'
return r
def makeWebhookResult(req):
intent_name = req.get('queryResult').get('intent').get('displayName')
print(intent_name)
action_name = req['queryResult']['action']
if req.get('queryResult').get('action') == 'input.welcome':
print("intent trigered")
return {"fulfillmentText": 'Hi there'}
if action_name == 'test':
cont = req.get('queryResult').get('outputContexts')[0]['name']
print(type(cont))
x = cont.split("/")
print(x[6])
if x[6] == 'session-vars' :
para = req['queryResult']['outputContexts']
print(para)
print("test intent trigered")
return {"fulfillmentText": 'Bye there'}
if __name__ == '__main__':
app.run(debug=True)

Python flask: return values multiple times

I ran my code on Jupyter Notebook and I wanted to return different values on the web while running the function. However, it only returned one value. I also tried yield, but it had an error on the web.
from werkzeug.wrappers import Request, Response
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
list = [0,0,0]
for i in range(10):
list.append(i)
return str(list)
if __name__ == "__main__":
from werkzeug.serving import run_simple
run_simple('localhost', 9000, app)
Output:
[0,0,0,0]
Expected Output:
[0,0,0,0]
then change to:
[0,0,0,0,1]
then go on until it stops at:
[0,0,0,0,1,2,3,4,5,6,7,8,9]
Your indent is a little off on the return of the list. This is returning it on the first loop. Corrected Code is below:
from werkzeug.wrappers import Request, Response
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
list = [0,0,0]
for i in range(10):
list.append(i)
return str(list)
if __name__ == "__main__":
from werkzeug.serving import run_simple
run_simple('localhost', 9000, app)

random number generator using python

I am creating a microservice using Flask, that needs to give me a random number.
Unfortunately I am getting this error:
AttributeError: 'function' object has no attribute 'uniform'
import random
from flask import Flask
app: Flask = Flask(__name__)
#app.route('/', methods=['GET'])
def random():
r1 = random.uniform(0, 10)
return r1
if __name__ == '__main__':
app.run(debug=True)
new to microservice and python.
It is because you redefined random. You can either change the function name or give alias to imported random library.
Method 1:
Change the function name you defined.
import random
from flask import Flask
app: Flask = Flask(__name__)
#app.route('/', methods=['GET'])
def myRandom(): //Changed here
r1 = random.uniform(0, 10)
return r1
if __name__ == '__main__':
app.run(debug=True)
Method 2
Import random using alias.
import random as r //Changed here
from flask import Flask
app: Flask = Flask(__name__)
#app.route('/', methods=['GET'])
def random():
r1 = r.uniform(0, 10)
return r1
if __name__ == '__main__':
app.run(debug=True)

Running background Celery task in Flask

Problem has been updated to include progress made
I have the following code and my celery tasks kick off fine, I just don't know where I should store the async result so that I can look at it again later
#!/usr/bin/env python
"""Page views."""
from flask import render_template, request
from flask import Flask
from celerytest import add
from time import sleep
app = Flask(__name__)
async_res = []
#app.route('/', methods=['GET', 'POST'])
def run():
if request.method == 'GET':
return render_template("template.html")
else:
form = request.form
n1 = str(form.get("n1"))
n2 = str(form.get("n2"))
aysnc_res = add.delay(n1,n2)
return render_template("loading.html")
#app.route('/loading')
def check_if_complete():
if async_res.ready() == True:
return render_template("template2.html", val=async_res.get())
else:
sleep(5)
return render_template("loading.html")
if __name__ == '__main__':
app.run()
It appears that storing async_res as a global variable in my flask app causes server errors. So what's the best method of storing the result so that I can check on it in my "loading page"
I ended up being able to save the ID of my task in the session dictionary in Flask
See code below:
#!/usr/bin/env python
"""Page views."""
from flask import render_template, request
from flask import Flask
from celerytest import add
from time import sleep
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def run():
if request.method == 'GET':
return render_template("template.html")
else:
form = request.form
n1 = str(form.get("n1"))
n2 = str(form.get("n2"))
aysnc_res = add.delay(n1,n2)
session['TASK_ID'] = async_res.id
return render_template("loading.html")
#app.route('/loading')
def check_if_complete():
aysnc_res = session['TASK_ID']
if async_res.ready() == True:
return render_template("template2.html", val=async_res.get())
else:
sleep(5)
return render_template("loading.html")
if __name__ == '__main__':
app.run()

Displaying stackOverflow API JSON data using Flask

I've been trying to display my username and reputation from the JSON data retrieved from the StackOverflow API.
Im using the python module Requests to retrieve the data.
Here is the code
from flask import Flask,jsonify
import requests
import simplejson
import json
app = Flask(__name__)
#app.route("/")
def home():
uri = "https://api.stackexchange.com/2.0/users? order=desc&sort=reputation&inname=fuchida&site=stackoverflow"
try:
uResponse = requests.get(uri)
except requests.ConnectionError:
return "Connection Error"
Jresponse = uResponse.text
return Jresponse
if __name__ == "__main__":
app.run(debug = True)
The unused imports is what I need to get this done but cant seem to know how to get it done.
Below is what is returned to the browser, I want to just display the username [display_name] and the reputation. what options do I have to get this done ?
{"items":[{"user_id":540028,"user_type":"registered","creation_date":1292207782,"display_name":"Fuchida","profile_image":"http://www.gravatar.com/avatar/6842025a595825e2de75dfc3058f0bee?d=identicon&r=PG","reputation":13,"reputation_change_day":0,"reputation_change_week":0,"reputation_change_month":0,"reputation_change_quarter":0,"reputation_change_year":0,"age":24,"last_access_date":1332905685,"last_modified_date":1332302766,"is_employee":false,"link":"http://stackoverflow.com/users/540028/fuchida","website_url":"http://blog.Fuchida.me","location":"Minneapolis
MN","account_id":258084,"badge_counts":{"gold":0,"silver":0,"bronze":3}}],"quota_remaining":282,"quota_max":300,"has_more":false}
Use json.loads() to read and decode the data.
from flask import Flask,jsonify
import requests
import simplejson
import json
app = Flask(__name__)
#app.route("/")
def home():
uri = "https://api.stackexchange.com/2.0/users? order=desc&sort=reputation&inname=fuchida&site=stackoverflow"
try:
uResponse = requests.get(uri)
except requests.ConnectionError:
return "Connection Error"
Jresponse = uResponse.text
data = json.loads(Jresponse)
displayName = data['items'][0]['display_name']# <-- The display name
reputation = data['items'][0]['reputation']# <-- The reputation
return Jresponse
if __name__ == "__main__":
app.run(debug = True)

Categories

Resources