Python Flask extracting results from endpoint - python

In the Flask script below, I want to use the results of the endpoint '/three' in my endpoint '/five'.
The endpoint for '/three' works fine, however when I try the endpoint '/five', I get the error: TypeError: 'Response' object is not subscriptable.
How do I correctly use the output of '/three' to compute '/five'?
from flask import Flask, url_for, redirect
app = Flask(__name__)
#app.route('/three')
def three():
return {'message':3}
#app.route('/five')
def five():
old_message = redirect(url_for('three'))['message'] # expect to return 3
new_message = {'message':old_message + 2 } # 3+2 = 5
return new_message # expecting {'message':5}
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=8080)

if you want to trigger the three method via http request, you could use requests package, then JSON-parse it, manipulate and return to the client:
from flask import jsonify
import requests
import json
...
...
...
#app.route('/three')
def three():
return {'message':3}
#app.route('/five')
def five():
http_req = requests.get('http://localhost:8000/three')
my_three_json = json.loads(http_req.text)
my_three_json["message"] += 2
return jsonify(my_three_json)

Related

Python/Flask-RESTful make JSON parameters global like http parameters

I am looking for a way to make the parameters I would send through a json file global, so they can be easily used from differente functions inside the code. At the moment I can reproduce this by sending these parameters inside the http request and not from a json.
example code:
from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class ApiPage(Resource):
def calculation(self, a, b):
total = a + b
return total
def get(self, a, b):
total1 = self.calculation(a, b) + 10
return {'total': total1}
api.add_resource(ApiPage, '/<int:a>/<int:b>')
if __name__ == '__main__':
app.run(debug=True, port=8070)
http that works:
http://127.0.0.1:8070/120/80
Json file I am looking to use:
{"a":120, "b":80}

How to fix return request.get_json and get null in web?

I am trying to use flask-socket to request json from a client and want to return this object to the web. I try to print the object it is work in terminal but show null when I open local host. How can I fix this?
Or should I user socket in client to send message and get it in server?
Code for Server:
from flask import Flask, request, jsonify, Response
import json
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def add_message():
jsonData = request.get_json()
print(jsonData)
return jsonify(jsonData)
if __name__ == '__main__':
app.run(debug=True, host='127.0.0.1')
Code for Client:
import requests
while 1:
requests.post('http://127.0.0.1:5000/', json={"mytext": "lalala"})
I want the on the web can display the json data from my client side such as{"mytext":"lalala"} instead of null. My Output..
In addition, I want to pass a dynamic value from my client side and return it on the web. Thanks a lot!
In order to retrieve key-value pairs
For a GET request: you have to use request.args docs
For a POST request: you have to use request.get_json() docs
For a request to get a path parameter, you have to register your param as such docs
#app.route('/<name>', methods=['GET'])
def add_message_get_param(name):
print(name)
return jsonify({'name': name})
Now as you've stated, you want to pass a json. But your browser screenshot indicates that you call your endpoint with /hello. In order to pass a key-value pair, you'll have to do something like /?mykey=myvalue. I've added the path parameter for completeness
Thus, your server has to become
from flask import Flask, request, jsonify
app = Flask(__name__)
#app.route('/', methods=['GET'])
def add_message_get():
jsonData = request.args
print(jsonData)
return jsonify(jsonData)
#app.route('/<name>', methods=['GET'])
def add_message_get_param(name):
print(name)
return jsonify({'name': name})
#app.route('/', methods=['POST'])
def add_message_post():
jsonData = request.get_json()
print(jsonData)
return jsonify(jsonData)
if __name__ == '__main__':
app.run(debug=True, host='127.0.0.1')
and your client for debugging purposes:
import requests
result = requests.post('http://127.0.0.1:5000/', json={"mytext":"lalala"})
print(f'POST result: {result.text}')
result = requests.get('http://127.0.0.1:5000/?mytext=lalala')
print(f'GET result: {result.text}')
result = requests.get('http://127.0.0.1:5000/Antonis')
print(f'GET result: {result.text}')
Remove the .data from
return jsonify(jsonData).data

flask_dance + Google Search Console API searchAnalytics

I'm currently testing Google Search Console API and Flask Dance to do the oauth stuff.
It works great for getting the /sites, but i get an
ValueError: View function did not return a response
if i try to query searchAnalytics with /search
According to https://developers.google.com/webmaster-tools/search-console-api-original/v3/searchanalytics/query#try-it it must be POST + additonal data. e.g.:
json={'startDate':'2017-11-01','endDate':'2017-12-01'}
In https://developers.google.com/oauthplayground/ it works like this but with flask dance sadly not. any ideas?
import os
from werkzeug.contrib.fixers import ProxyFix
from flask import Flask, redirect, url_for
from flask_dance.contrib.google import make_google_blueprint, google
from raven.contrib.flask import Sentry
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
sentry = Sentry(app)
app.secret_key = os.environ.get("FLASK_SECRET_KEY", "supersekrit")
app.config["GOOGLE_OAUTH_CLIENT_ID"] = os.environ.get("GOOGLE_OAUTH_CLIENT_ID")
app.config["GOOGLE_OAUTH_CLIENT_SECRET"] = os.environ.get("GOOGLE_OAUTH_CLIENT_SECRET")
google_bp = make_google_blueprint(scope=["profile", "email", "https://www.googleapis.com/auth/webmasters"])
app.register_blueprint(google_bp, url_prefix="/login")
#app.route("/")
def index():
return "BlA BLA"
#app.route("/sites")
def sites():
if not google.authorized:
return redirect(url_for("google.login"))
resp = google.get("/webmasters/v3/sites")
siteEntry = resp.json()["siteEntry"]
result = ""
for site in siteEntry:
result = result + site["siteUrl"] + "</br>"
return result
#app.route("/search")
def search():
if not google.authorized:
return redirect(url_for("google.login"))
resp = google.post("/webmasters/v3/sites/https%3A%2F%2Fzrce.eu/searchAnalytics/query", json={'startDate':'2017-11-01','endDate':'2017-12-01'})
print(resp)
if __name__ == "__main__":
app.run()
All API routes should always return something even if its an empty response.
Simply return a response, it can be "" or resp.

Python requsts.post returning 405 error: The method is not allowed for the requested URL

Howdie do,
I'm just running a simple flask API call.
The flask API will take a XML request in and then parse the XML and print it to the terminal screen.
However, everytime I do this, I'm receiving
The method is not allowed for the requested URL
The Flask script is:
__author__ = 'Jeremy'
from flask import Flask
from flask import request
import xmltodict
app = Flask(__name__)
#app.route('/', methods=['POST'])
def parsexml():
xmlrequest = xmltodict.parse(request.data)
print xmlrequest
if __name__ == '__main__':
app.run()
The script that sends the XML is:
__author__ = 'Jeremy'
import requests
xml = """
<dtc:GetShipmentUpdates>
<dtc:GetShipmentUpdatesRequest>
<dtc:SearchStartTime>2015-07-12T12:00:00</dtc:SearchStartTime>
<dtc:SearchEndTime>2015-07-12T12:30:00</dtc:SearchEndTime>
</dtc:GetShipmentUpdatesRequest>
</dtc:GetShipmentUpdates> """
headers = {'Content-Type': 'application/xml'}
r = requests.post('http://127.0.0.1:5000/', data=xml, headers=headers)
print r.content
Does anyone know why this is happening and if so, how can I send a POST request to my flask application running on 127.0.0.1:5000
You aren't returning anything from parsexml. Try returning some content:
#app.route('/', methods=['POST'])
def parsexml():
xmlrequest = xmltodict.parse(request.data)
print xmlrequest
return "Thanks for the data!"
Howdie do,
You can't send POST requests to /
So I changed it to go to the following:
__author__ = 'Jeremy'
from flask import Flask
from flask import request
import xmltodict
app = Flask(__name__)
#app.route('/')
def say_hello():
return "Say goodbye Jeremy"
#app.route('/api', methods=['POST'])
def parsexml():
xmlrequest = xmltodict.parse(request.data)
return xmlrequest
if __name__ == '__main__':
app.run(host='0.0.0.0', port=int("80"))
Work now

Flask equivalent of Sinatra's "passing"

In my Flask application, I want to expose a URI like this:
http://<base_uri>/some_string
and I wish to handle requests to it differently depending on whether some_string is an integer or not.
With Sinatra I can achieve that via "passing" as shown below:
get '/:some_string' do
if is_integer(:some_string)
'Your URI contains an integer'
else
pass # This will pass the request on the the method below which can handle it
end
get '/*' do
'Your URI contains some string'
end
Here the call pass in the first route lets the second route process the request if :some_string is not an integer.
I couldn't find any equivalent functionality in Flask. Can someone please suggest a solution in Flask?
Type conversion in url routes can do this for you:
from flask import Flask
import unittest
app = Flask(__name__)
app.debug = True
#app.route('/<int:thing>')
def num(thing):
return 'INT'
#app.route('/<thing>')
def string(thing):
return 'STR'
class TestDispatch(unittest.TestCase):
def setUp(self):
self.client = app.test_client()
def test_int(self):
resp = self.client.get('/10')
self.assertEqual("INT", resp.data)
def test_str(self):
resp = self.client.get('/hello')
self.assertEqual("STR", resp.data)
if __name__ == '__main__':
unittest.main()

Categories