Flask Endpoint returning 404 not found - python

I am experimenting with a Flask App to return some json data that is cached with Flask-caching.
This end point works, as well as the flask-caching to cache the get_payload without having to re-run the function:
#app.route('/payload/current', methods=['GET'])
def event_state_current():
return get_payload()
But this endpoint does not work at all, the app will return a URL NOT FOUND:
#app.route('/payload/hourly,', methods=['GET'])
def event_state_hourly():
return get_future()
Is there anything wrong that I am doing with the flask-caching that is causing this? The endpoint that works does what I was expecting flask-caching to do is only run the get payload function every 60 seconds, but I cant figure out why the /payload/hourly doesnt work at all. Its almost like the flask-caching only supports one endpoint, unless I am doing something wrong.
This is the Flask App for anyone to try, it just makes up data but I am not running it on localhost.
from flask import Flask, request, jsonify
from flask_caching import Cache
import datetime, pytz, random
tz = pytz.timezone('America/Chicago')
cache = Cache()
app = Flask(__name__)
cache.init_app(app, config={'CACHE_TYPE': 'SimpleCache'})
#cache.cached(timeout=60, key_prefix='get_payload')
def get_payload():
utc_time = datetime.datetime.utcnow()
utc_time = utc_time.replace(tzinfo=pytz.UTC)
corrected_time = utc_time.astimezone(tz)
randnum = random.randint(1,1000)
response_obj = {'status':'success','server_time_corrected':str(corrected_time),'timezone':str(tz),'payload':randnum}
print(response_obj)
return jsonify(response_obj), 200
#cache.cached(timeout=300, key_prefix='get_future')
def get_future():
utc_time = datetime.datetime.utcnow()
utc_time = utc_time.replace(tzinfo=pytz.UTC)
corrected_time = utc_time.astimezone(tz)
randnum = random.randint(1,1000)
response_obj = {'status':'success','server_time_corrected':str(corrected_time),'timezone':str(tz),'payload':randnum}
print(response_obj)
return jsonify(response_obj), 200
#app.route('/payload/current', methods=['GET'])
def event_state_current():
return get_payload()
#app.route('/payload/hourly,', methods=['GET'])
def event_state_hourly():
return get_future()
if __name__ == '__main__':
app.run(debug=False,port=5000,host='0.0.0.0')
EDIT, screen snips for testing Flask App Endpoints, this GET request works:
This endpoint doesnt work, any ideas to try?

There is a trailing comma in your last URL: '/payload/hourly,'
Just remove it and it should work.

Related

How can i get url parameters in python?

I have tried a lot of things but nothing is working. It always gives me the "Incomplete response received from application" message in the navigator.
My code is:
import sys
from flask import Flask, request
app = Flask(__name__)
#app.route('/')
def application():
uri = request.args.get('url')
message = 'It works!\n'
response = '\n'.join([message, uri])
return response
The problem is or in the #app.route('/') line or in the uri = request.args.get('url').
I just want to call the with the navigator like http://example.com/script/?url=hello.
I tried changing #app.route('/') to #app.route('/script') and #app.route('/script/') but nothing is working... any ideas?
Thanks a lot!
For future readers: note that the original question has been edited in response to this suggestion.
First issue: You seem to be using some very low-level WSGI implementation when Flask does a lot of the sugar for you. Consider testing with a function that lets Flask do the work and then expand as needed.
import sys
from flask import Flask, request
app = Flask(__name__)
#app.route('/')
def test():
uri = request.args.get('url')
message = 'It works!\n'
version = 'Python %s\n' % sys.version.split()[0]
response = '\n'.join([message, version, uri])
return response
Next, keep in mind that Flask wants a string return type. If you want to pass a data structure back, consider jsonify.

How to use Python 3 imports properly in Google Cloud Functions

I am making a simple function to check a URL status and redirect on 404. This app works fine in Flask localhost but when I move this to Google Cloud Functions, I keep getting "Error: could not handle the request". This is when my parameters on both the Cloud Function and the localhost are the exact same.
Am I doing something wrong with importing 'redirect' from Flask?
GCLOUD CODE: NOT WORKING
from flask import Flask, redirect
from flask import request
import requests
def urlincoming():
custID = request.args['custID']
token = request.args['token']
custEmail = request.args['custEmail']
storeDomain = request.args['domain']
adminEmail = request.args['adminEmail']
baseUrl = f"{storeDomain}/account/reset/{custID}/{token}"
baseUrlFailedAuth = f"{storeDomain}/account/invalid_token"
requestBaseUrl = requests.head(baseUrl)
if(requestBaseUrl.status_code == 200):
return redirect(baseUrl)
else:
return redirect(baseUrlFailedAuth)
LOCALHOST CODE: WORKING
from flask import Flask, redirect
from flask import request
import requests
app = Flask(__name__)
#app.route('/urlincoming')
def urlincoming():
custID = request.args['custID']
token = request.args['token']
custEmail = request.args['custEmail']
storeDomain = request.args['domain']
adminEmail = request.args['adminEmail']
baseUrl = f"{storeDomain}/account/reset/{custID}/{token}"
baseUrlFailedAuth = f"{storeDomain}/account/invalid_token"
requestBaseUrl = requests.head(baseUrl)
if(requestBaseUrl.status_code == 200):
return redirect(baseUrl)
else:
return redirect(baseUrlFailedAuth)
All Google Cloud Functions need to have one of the following two signatures:
HTTP Functions:
function_name(request):
...
Background functions:
function_name(data, context):
...
Depending on the type of function you're creating, you either need to add the request or data, context arguments.
from flask import redirect
import requests
def urlincoming(request):
I was able to fix things by adding the request as a argument but I'm not sure why it worked :/

How can I send server-side events from Flask while accessing the request context?

I am trying to use Flask to send a stream of events to a front-end client as documented in this question. This works fine if I don't access anything in the request context, but fails as soon as I do.
Here's an example to demonstrate.
from time import sleep
from flask import Flask, request, Response
app = Flask(__name__)
#app.route('/events')
def events():
return Response(_events(), mimetype="text/event-stream")
def _events():
while True:
# yield "Test" # Works fine
yield request.args[0] # Throws RuntimeError: Working outside of request context
sleep(1)
Is there a way to access the request context for server-sent events?
You can use the #copy_current_request_context decorator to make a copy of the request context that your event stream function can use:
from time import sleep
from flask import Flask, request, Response, copy_current_request_context
app = Flask(__name__)
#app.route('/events')
def events():
#copy_current_request_context
def _events():
while True:
# yield "Test" # Works fine
yield request.args[0]
sleep(1)
return Response(_events(), mimetype="text/event-stream")
Note that to be able to use this decorator the target function must be moved inside the view function that has the source request.

Flask-pymongo RuntimeError: Working outside of application context

I'm writing a program to read mongodb document based on id field using flask-pymongo. But I'm getting error, can anybody tell me where am I going wrong?
code:
from flask import Flask, make_response, jsonify
from flask_pymongo import PyMongo
from collections import OrderedDict
from bson import json_util
import json
app = Flask('__name__')
app.config['MONGO_DBNAME'] = 'db_name'
app.config['MONGO_URI'] = 'mongodb://192.168.55.24:27017/db_name'
mongo_connection = PyMongo(app)
#app.route('/')
def index(inp_id):
collection = mongo_connection.db.table_name
one_record = collection.find_one({'id': inp_id})
obj_str = json_util.dumps(one_record)
obj_dict = json.loads(obj_str, object_hook=OrderedDict)
return make_response(jsonify(obj_dict), 200)
if __name__ == '__main__':
index('5cd00a468b36db516b6d2f16') # I think this is where I'm going wrong
giving me the below error:
RuntimeError: Working outside of application context.
If I pass id value directly in the place of inp_id I get the result but I'm trying to write a generic one.
Flask has an application context, You might need to use app.app_context() to make it work.
The application context keeps track of the application-level data
during a request, CLI command, or other activity. Rather than passing
the application around to each function, the current_app and g proxies
are accessed instead.
Try this :
def index(inp_id):
with app.app_context():
collection = mongo_connection.db.table_name
one_record = collection.find_one({'id': inp_id})
obj_str = json_util.dumps(one_record)
obj_dict = json.loads(obj_str, object_hook=OrderedDict)
return make_response(jsonify(obj_dict), 200)
For more information, read Flask Application context

Flask_dance with Google API; Missing required parameter: refresh_token

I trid to make authorization system with flask_dance and Google.
I was successful in authorize first but after a while, the program caused this error even though I didn't change it at all.
My whole code is here (It's almost the same as the tutorial one though
from flask import Flask, redirect, url_for
from flask_dance.contrib.google import make_google_blueprint, google
app = Flask(__name__)
app.secret_key = "supersekrit"
blueprint = make_google_blueprint(
client_id="",
client_secret="",
scope=["profile", "email"]
)
app.register_blueprint(blueprint, url_prefix="/login")
#app.route("/")
def index():
if not google.authorized:
return redirect(url_for("google.login"))
resp = google.get("/oauth2/v2/userinfo")
assert resp.ok, resp.text
return "You are {email} on Google".format(email=resp.json()["email"])
if __name__ == "__main__":
app.run()
How can I fix this error?
This problem seems to be the one referenced in this Github issue. The suggested solution is to request offline access:
google_blueprint = make_google_blueprint(
client_id='',
client_secret='',
scope=['profile', 'email'],
offline=True
)

Categories