Python Flask, BlueMix, js - Anonymous Function - python

Using Flask and BlueMix to deploy a web app. Having some js issues that I cannot seem to figure out. I keep getting the same error in the browser console. I don't know any js so any help would be very appreciated!
jquery-1.11.1.min.js:4 POST http://newfla.mybluemix.net/ 405 (Method Not Allowed)
send # jquery-1.11.1.min.js:4
m.extend.ajax # jquery-1.11.1.min.js:4
(anonymous function) # demo.js:66
m.event.dispatch # jquery-1.11.1.min.js:3
r.handle # jquery-1.11.1.min.js:3
Here is the supposed (anonymous function)
$.ajax({
type: 'POST',
data: {
text: $content.val()
},
url: '/',
dataType: 'json',
success: function(response) {
$loading.hide();
if (response.error) {
showError(response.error);
} else {
$results.show();
showTraits(response);
showTextSummary(response);
showVizualization(response);
}
}
UPDATE:
I've tried a few different things matching your suggestions. Here is where I am now, any ideas?
consumer_token = 'aaaaaaaaaaaaaaaaaaaaaaaaa' #substitute values from twitter website
consumer_secret = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
access_token = '3473558363-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
access_secret = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
auth = tweepy.OAuthHandler(consumer_token,consumer_secret)
auth.set_access_token(access_token,access_secret)
api = tweepy.API(auth)
class PersonalityInsightsService:
"""Wrapper on the Personality Insights service"""
def __init__(self, vcapServices):
"""
Construct an instance. Fetches service parameters from VCAP_SERVICES
runtime variable for Bluemix, or it defaults to local URLs.
"""
self.url = "https://gateway.watsonplatform.net/personality-insights/api"
self.username = "aaaaaa-vvvv-1111-2222-mmmmmmmm"
self.password = "password"
if vcapServices is not None:
print("Parsing VCAP_SERVICES")
services = json.loads(vcapServices)
svcName = "personality_insights"
if svcName in services:
print("Personality Insights service found!")
svc = services[svcName][0]["credentials"]
self.url = svc["url"]
self.username = svc["username"]
self.password = svc["password"]
else:
print("ERROR: The Personality Insights service was not found")
def getProfile(self, text):
"""Returns the profile by doing a POST to /v2/profile with text"""
if self.url is None:
raise Exception("No Personality Insights service is bound to this app")
response = requests.post(self.url + "/v2/profile",
auth=(self.username, self.password),
headers = {"content-type": "text/plain"},
data=text
)
try:
return json.loads(response.text)
except:
raise Exception("Error processing the request, HTTP: %d" % response.status_code)
class DemoService(object):
"""
REST service/app. Since we just have 1 GET and 1 POST URLs,
there is not even need to look at paths in the request.
This class implements the handler API for cherrypy library.
"""
screen_name = "realDonaldTrump"
maxnumtweets= 500
saveFile = open("static/public/text/en.txt",'a')
saveFile.seek(0)
saveFile.truncate()
for status in tweepy.Cursor(api.user_timeline,id=screen_name).items(maxnumtweets):
print status.text[0:2] + '\n'
saveFile = open("static/public/text/en.txt",'a')
textyt = status.text
texty = ''.join(i for i in textyt if ord(i)<128)
saveFile.write(texty.encode('utf-8')+'\n'+'\n')
saveFile.close()
def __init__(self, service):
self.service = service
self.defaultContent = None
try:
contentFile = open("static/public/text/en.txt", "r")
self.defaultContent = contentFile.read()
except Exception as e:
print "ERROR: couldn't read text file: %s" % e
finally:
contentFile.close()
def GET(self):
return render_template('newin.html', content= self.defaultContent)
def POST(self, text=None):
"""
Send 'text' to the Personality Insights API
and return the response.
"""
try:
profileJson = self.service.getProfile(text)
return json.dumps(profileJson)
except Exception as e:
print "ERROR: %s" % e
return str(e)
#app.route('/')
def main():
return render_template('index.html')
#app.route('/getpost', methods=['GET', 'POST'])
def new():
personalityInsights = PersonalityInsightsService(os.getenv("VCAP_SERVICES"))
c = DemoService(personalityInsights)
if request.method == 'GET':
return c.GET()
elif request.method == 'POST':
return c.POST()

This isn't a Javascript issue. The view function that is serving the root URL is not configured to accept POST requests. Response code 405 is METHOD NOT ALLOWED (the method here being POST as opposed to GET, PUT, DELETE, OPTIONS, HEAD, etc...
I'm able to recreate it with a very simple hello world Flask app
app.py:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def hello_world():
return 'Hello World'
if __name__ == '__main__':
app.run(debug=True)
Running the app from the command line (will be made available at http://localhost:5000/):
python app.py
and then trying to post against it from another terminal (using the requests library):
import requests
response = requests.post('http://localhost:5000/', data='')
print response will yield:
<Response [405]>
Note the 405 - the same response code you received, method not allowed. You need to explicitly define any methods other than GET that you want your Flask views to use by updating the app.route decorator:
#app.route('/', methods=['GET', 'POST'])
def hello_world():
return 'Hello World'
Generally however, you'll want to implement different functionality if a client does a POST instead of a GET. You can do this by looking at the request.method (you'll also need to import request):
from flask import Flask, request
app = Flask(__name__)
#app.route('/', methods=['GET', 'POST'])
def hello_world():
if request.method == 'GET':
return 'You GOT hello world'
elif request.method == 'POST':
return 'You POSTed hello world'
if __name__ == '__main__':
app.run(debug=True)
If you'd like to read more about the different HTTP methods, they are defined here.

Related

How can I return API objects in application using flask

from flask import Flask, request, jsonify
import requests
app = Flask(__name__)
#app.route('/address_search', methods=['GET'])
def sample():
zipcode = request.args.get('zipcode', None)
url = f'https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}'
response = requests.get(url)
# results = response.json()
# results = jsonify(response) ?????
return response
if __name__ == '__main__':
app.run(debug=True)
I'm trying to create an Application which return the Address.
I succeeded to return url but about response, I can't and Internal Server Error appears
So I thought in flask, requests.get(url) cannot be used but I didn't came up an another way.
I heard that jsonify() is used but I don't known how.
I searched it in Google for two days but I still cannot find it's answer.
Someone please give me advice.
So, you want to return the response of that API in your web application, i guess this is what you're looking for?
#app.route('/address_search', methods=['GET'])
def sample():
zipcode = request.args.get('zipcode', None)
url = f'https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}'
response = requests.get(url)
response_json = response.json()
return jsonify(response_json)
EDIT, response to your comment:
You can't do jsonify(response_json)['results'][0] because jsonify turns the JSON data to Flask Response object, instead try this:
#app.route('/address_search', methods=['GET'])
def sample():
zipcode = request.args.get('zipcode', None)
url = f'https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}'
response = requests.get(url)
response_json = response.json()
results = response_json['results'][0]
return jsonify(results)

How to get access token from redirect url

I want to get a access token from Spotify. I get from Spotify some this:
https://example.com/callback#access_token=NwAExz...BV3O2Tk&token_type=Bearer&expires_in=3600&state=123
I see it into address bar. Where https://example.com/callback is my site and access_token needed value. How to get it?
I tried like this, but get None
print(flask.request.args.get('access_token'))
Full code
import flask
app = flask.Flask(__name__)
#app.route("/")
def render_index():
return flask.render_template('index.html')
#app.route("/redirect_spotify_token", methods = ['POST'])
def redirect_spotify_token():
return flask.redirect('https://accounts.spotify.com/authorize?...')
#app.route("/callback/spotify_token", methods = ['POST', 'GET'])
def callback_token():
#
# how to get access token?
#
return 'ok'
if __name__ == "__main__":
app.run(host='0.0.0.0', port=8080)
I do my project via a service repl.it. Maybe that's why I can't read request's args like this
flask.request.args.get('access_token')
Solution
Redirect from Spotify to /callback_token. In this case, function an arg token is None. The my page callback_token.html is parse url and redirect to callback_token() with token.
main.py
#app.route("/callback_token")
#app.route("/callback_token/<token>")
def callback_token(token=None):
if token is None:
return render_template('callback_token.html')
else:
#logic with token
return redirect(url_for('index'))
callback_token.html with javascript
var parsedHash = new URLSearchParams(
window.location.hash.substr(1)
);
location.href = `your_url.com/callback_token/${parsedHash.get('access_token')}`

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.

Is it possible to make POST request in Flask?

There is a need to make POST request from server side in Flask.
Let's imagine that we have:
#app.route("/test", methods=["POST"])
def test():
test = request.form["test"]
return "TEST: %s" % test
#app.route("/index")
def index():
# Is there something_like_this method in Flask to perform the POST request?
return something_like_this("/test", { "test" : "My Test Data" })
I haven't found anything specific in Flask documentation. Some say urllib2.urlopen is the issue but I failed to combine Flask and urlopen. Is it really possible?
For the record, here's general code to make a POST request from Python:
#make a POST request
import requests
dictToSend = {'question':'what is the answer?'}
res = requests.post('http://localhost:5000/tests/endpoint', json=dictToSend)
print 'response from server:',res.text
dictFromServer = res.json()
Notice that we are passing in a Python dict using the json= option. This conveniently tells the requests library to do two things:
serialize the dict to JSON
write the correct MIME type ('application/json') in the HTTP header
And here's a Flask application that will receive and respond to that POST request:
#handle a POST request
from flask import Flask, render_template, request, url_for, jsonify
app = Flask(__name__)
#app.route('/tests/endpoint', methods=['POST'])
def my_test_endpoint():
input_json = request.get_json(force=True)
# force=True, above, is necessary if another developer
# forgot to set the MIME type to 'application/json'
print 'data from client:', input_json
dictToReturn = {'answer':42}
return jsonify(dictToReturn)
if __name__ == '__main__':
app.run(debug=True)
Yes, to make a POST request you can use urllib, see the documentation.
I would however recommend to use the requests module instead.
EDIT:
I suggest you refactor your code to extract the common functionality:
#app.route("/test", methods=["POST"])
def test():
return _test(request.form["test"])
#app.route("/index")
def index():
return _test("My Test Data")
def _test(argument):
return "TEST: %s" % argument

Categories