This question already has an answer here:
Why not generate the secret key every time Flask starts?
(1 answer)
Closed 4 years ago.
I'm currently super stumped. I have a large flask application that I recently deployed to my production ec2 server that's not functioning properly. It works fine in dev/test. It looks like, maybe, apache is hanging. When I first deployed it, it worked a few times. Then, after that I started getting 500 server errors. When I restart apache, it works fine again for a session but the 500 server errors come back. Each time, on a different page of the application. This is reoccurring. How would I go about fixing this? Here's my routes/app.py:
from flask import Flask, render_template,redirect,request,url_for, flash, session
from Index_generator import index_generator
from Yelp_api import request_yelp
from plaid import auth
from search_results import search,search1
from Options import return_data
from datetime import timedelta
import os
import urllib2
import time
from path import path_data
#from writer import create_config_file
import logging
from logging_path import log_dir
logger = logging.getLogger("Routing")
logger.setLevel(logging.INFO)
foodie_log = log_dir()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - % (message)s')
foodie_log.setFormatter(formatter)
logger.addHandler(foodie_log)
app = Flask(__name__)
app.secret_key = os.urandom(24)
go = path_data()
#app.before_request
def make_session_permanent():
session.permanent = False
app.permanent_session_lifetime = timedelta(seconds=300)
##app.route('/setup',methods=['GET','POST'])
#def setup():
# if request.method == 'POST':
# Username=request.form['username']
# Password=request.form['password']
# Port=request.form['port']
# Host=request.form['host']
# C_Key=request.form['CONSUMER_KEY']
# C_Sec=request.form['CONSUMER_SECRET']
# Tok=request.form['TOKEN']
# Tok_Sec=request.form['TOKEN_SECRET']
# clientid=request.form['client_id']
# Sec=request.form['secret']
# create_config_file(Username,Password,Port,Host,C_Key,C_Sec,Tok,Tok_Sec,clientid,Sec)
# return 'complete'
# elif request.method == 'GET':
#
# return render_template('setup.html')
#app.route('/')
def home():
store = index_generator()
session['store'] = store
return render_template('home.html')
#app.route('/about')
def about():
return render_template('about.html')
#app.route('/home_city',methods = ['POST'])
def home_city():
try:
CITY=request.form['city']
store = session.get('store')
request_yelp(DEFAULT_LOCATION=CITY,data_store=store)
return render_template('bank.html')
except Exception as e:
logger.error(e)
error = 'Sorry, no results. Is' + ' ' +CITY + ' '+ 'your hometown? If not, try again and if so, we have been made aware of the issue and is working to resolve it'
return render_template('home.html',error=error)
#app.route('/traveling',methods = ['POST'])
def travel():
store = session.get('store')
answer=request.form['Travel']
if answer == 'yes':
#time.sleep(2)
return render_template('destination.html')
else:
results_home = search(index=store)
time.sleep(2)
return return_data(results_home)
#app.route('/dest_city',methods = ['POST'])
def dest_city():
store = session.get('store')
try:
DESTINATION=request.form['dest_city']
request_yelp(DEFAULT_LOCATION=DESTINATION, data_store=store,sourcetype='dest_city')
results_dest = search1(index=store)
time.sleep(2)
return return_data(results_dest)
except urllib2.HTTPError:
error = 'Sorry, no results. Is your destination city? If not, try again and if so, we have been made aware of the issue and is working to resolve it'
return render_template('destination.html',error=error)
#app.route('/bank',methods = ['POST'])
def bank():
try:
store = session.get('store')
print store
Bank=request.form['Fin_Bank']
Username=request.form['username']
Password=request.form['password']
Test = auth(account=Bank,username=Username,password=Password,data_store=store)
if Test == 402 or Test ==401:
error = 'Invalid credentials'
return render_template('bank.html',error=error)
else :
return render_template('travel.html')
except:
logger.error(e)
if __name__ == '__main__':
app.run(debug=True)
app.secret_key=os.urandom(24)
Not completely sure if this causes your errors but you should definitely change this:
You have to set app.secret_key to a static value rather than os.urandom(24), e.g.:
app.secret_key = "/\xfa-\x84\xfeW\xc3\xda\x11%/\x0c\xa0\xbaY\xa3\x89\x93$\xf5\x92\x9eW}"
With your current code, each worker thread of your application will have a different secret key, which can result in errors or session inconsistency depending on how you use the session object in your application.
Related
Here I am attaching my server.py and util.py
I have trained a model, and now wish to print the data on user's demand.
server.py
from flask import Flask, request, jsonify
#from waitress import serve
import util
import json
#%run util.ipynb
app = Flask(__name__)
#app.route('/hi')
def hi():
return util.areas()
#app.route('/locations')
def locations():
response = jsonify({
'locations': util.locations()
})
response.headers.add('Access-Control-Allow-Origin', '*')
return response
#app.route('/predict_home_price', methods=['GET', 'POST'])
def predict_home_price():
total_sqft = float(request.form['total_sqft'])
location = request.form['location']
size = int(request.form['size'])
bath = int(request.form['bath'])
area_type = request.form['area_type']
balcony = int(request.form['balcony'])
response = jsonify({
'estimated_price': util.get_estimated_price(area_type, location, size, total_sqft, bath, balcony)
})
response.headers.add('Access-Control-Allow-Origin', '*')
return response
if __name__ == '__main__':
print('python flask started')
app.run()
#serve(app, host='0.0.0.0', port=50100, threads=1)
util.py
import json
import joblib
import numpy as np
__locations = None
__area = None
__model = None
def get_estimated_price(area_type, location, size, total_sqft, bath, balcony):
x = np.zeros(6)
x[0] = __area.index(area_type)
x[1] = __locations.index(location)
x[2] = size
x[3] = total_sqft
x[4] = bath
x[5] = balcony
return round(__model.predict([x])[0][0],2)
def locations():
return __locations
def areas():
return __area
def load_saved_artifacts():
print("loading saved artifacts...start")
global __data_columns
global __locations
global __area
with open('./artifacts/locations.json','r') as f:
__locations = json.load(f)['data_locations']
with open('./artifacts/area.json','r') as f:
__area = json.load(f)['data_area']
global __model
__model = joblib.load('./artifacts/Banglore_Real_State_Price')
print(" loading artifacts is done")
if __name__ == '__main__':
load_saved_artifacts()
#print(locations())
#print(areas())
print(get_estimated_price('Super built-up Area','Electronic City Phase II',2,1056,2,1))
print(get_estimated_price('Built-up Area','Uttarahalli',3,1440,2,3))
print(get_estimated_price('Super built-up Area','Lingadheeranahalli',3,1521,3,1))
print(get_estimated_price('Super built-up Area','Kothanur',2,1200,2,1))
Immediate help is really appreciated
I have trained a model, and now wish to print the data on user's demand.
I am seeing this error in server.py file, " The browser (or proxy) sent a request that this server could not understand." I checked everything works fine if I am sending data to browser but not when asking for the data, I tried Postman for sending the data.
http://127.0.0.1:5000/predict_home_price -> shows bad request.
http://127.0.0.1:5000/locations -> shows correct data
http://127.0.0.1:5000/hi -> shows correct data
As you mentioned, when you're sending data to the server it works, and that's because you're using a POST request and the request has form data in it.
But when you're "asking for data", you're probably using a GET request, which has no form data in it, and that's why the server responses with an error.
You can modify your code so you can decide what you should do for each type of request:
#app.route('/predict_home_price', methods=['GET', 'POST'])
def predict_home_price():
if request.method == "POST":
# get form data and do something with it
elif request.method == "GET":
# return some value, without looking for form data
import vars
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
def stuff(insta_username, insta_password, hashtag, caption):
vars.insta_username = insta_username
vars.insta_password = insta_password
vars.hashtag = hashtag
vars.caption = caption
print(f"name {vars.insta_username}")
print(f"pass {vars.insta_password}")
print(f"ahsh {vars.hashtag}")
print(f"cap {vars.caption}")
#app.route('/', methods=['GET','POST'])
def getvalue():
stuff(request.form['username'], request.form['password'], request.form['hashtag'], request.form['caption'])
# idk(request.form['username'], request.form['password'], request.form['hashtag'], request.form['caption'])
return render_template('pass.html', n=vars.insta_username, p=vars.insta_password, h=vars.hashtag, c=vars.caption)
if __name__ == '__main__':
vars.init()
app.run(debug=True)
I am trying to assess data that I put in a HTML form to python variables. I used flask for this. The issue is that the variables here get filled by the HTML Form but they go back empty when they are used in the main.py file below.
from vars import *
import vars
import random
from time import sleep
from instagrapi import Client
client = Client()
class StartupRoutine:
def __init__(self, welcome, insta_username, insta_password, hashtag, caption, pause):
self.welcome = welcome
self.insta_username = insta_username
self.insta_password = insta_password
self.hashtag = hashtag
self.caption = caption
self.pause = pause
print(f"username {vars.insta_username}")
print(f"password {vars.insta_password}")
print(f"hashtag {vars.hashtag}")
print(f"caption {vars.caption}")
startUp = StartupRoutine(print("Instagrapi), vars.insta_username, vars.insta_password, vars.hashtag, vars.caption, random.randrange(3, 5))
startUp.welcome
print("Starting bot")
print("Attempting login")
boolLoggedin = client.login(startUp.insta_username, startUp.insta_password, True)
print("Successfully logged in")
This is the main.py file where I try to assign variables from vars.py in the startup routine.
def init():
global insta_username
global insta_password
global hashtag
global caption
insta_username = ""
insta_password = ""
hashtag = ""
caption = ""
This is the vars file which gets imported in main.py for use but just has empty values
I am trying to fill the empty variables in vars.py with the data i insert in the HTML forms. I can see they get filled in the server.py file but as soon as the vars.py file gets imported in the main/py file the variables go back to empty.
I think the issue is in server.py where the variables are in a function.
P.S. I'm sorry for a very messy post. This is my first time using stack overflow and I'm only a junior at college.
Thanks for the help.
I am trying to implement Superset using Keycloak for authentication. Following the post here: Using KeyCloak(OpenID Connect) with Apache SuperSet, the login part works fine.
I also have a timeout set on the session (security requirement) using the Superset Docs: https://superset.apache.org/docs/installation/configuring-superset#flask-app-configuration-hook
The part that doesn't work, when a user is logged out, they are not redirected to the login page. It's just a bunch of errors thrown on the screen, and the user can't see anything. Anyone have a hint as to how I get the user redirected to the login page?
Worth noting, the whole thing is behind an nginx reverse proxy.
Here's the full superset_config.py, in case it's helpful...
from flask_appbuilder.security.manager import AUTH_OID
from superset.security import SupersetSecurityManager
from flask_oidc import OpenIDConnect
from flask_appbuilder.security.views import AuthOIDView
from flask_login import login_user
from urllib.parse import quote
from flask_appbuilder.views import ModelView, SimpleFormView, expose
import logging
class AuthOIDCView(AuthOIDView):
#expose('/login/', methods=['GET', 'POST'])
def login(self, flag=True):
sm = self.appbuilder.sm
oidc = sm.oid
#self.appbuilder.sm.oid.require_login
def handle_login():
user = sm.auth_user_oid(oidc.user_getfield('email'))
if user is None:
info = oidc.user_getinfo(['preferred_username', 'given_name', 'family_name', 'email'])
user = sm.add_user(info.get('preferred_username'), info.get('given_name'), info.get('family_name'), info.get('email'), sm.find_role('Gamma'))
login_user(user, remember=False)
return redirect(self.appbuilder.get_url_for_index)
return handle_login()
#expose('/logout/', methods=['GET', 'POST'])
def logout(self):
oidc = self.appbuilder.sm.oid
oidc.logout()
super(AuthOIDCView, self).logout()
redirect_url = request.url_root.strip('/') + self.appbuilder.get_url_for_login
return redirect(oidc.client_secrets.get('issuer') + '/protocol/openid-connect/logout?redirect_uri=' + quote(redirect_url))
class OIDCSecurityManager(SupersetSecurityManager):
authoidview = AuthOIDCView
def __init__(self,appbuilder):
super(OIDCSecurityManager, self).__init__(appbuilder)
if self.auth_type == AUTH_OID:
self.oid = OpenIDConnect(self.appbuilder.get_app)
SQLALCHEMY_DATABASE_URI = 'a sting'
MENU_HIDE_USER_INFO = True
FEATURE_FLAGS = {
"ROW_LEVEL_SECURITY": True,
"DASHBOARD_RBAC": True,
}
ENABLE_PROXY_FIX = True
PROXY_FIX_CONFIG = {"x_for": 1, "x_proto": 0, "x_host": 1, "x_port": 0, "x_prefix": 0}
class ReverseProxied(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
# print(environ)
if script_name:
environ['SCRIPT_NAME'] = script_name
path_info = environ['PATH_INFO']
if path_info.startswith(script_name):
environ['PATH_INFO'] = path_info[len(script_name):]
scheme = environ.get('HTTP_X_SCHEME', '')
print(scheme)
if scheme:
environ['wsgi.url_scheme'] = scheme
return self.app(environ, start_response)
ADDITIONAL_MIDDLEWARE = [ReverseProxied, ]
def role_mapper(role_list):
# not exposing our roles
# Auth Settings
AUTH_TYPE = AUTH_OID
OIDC_CLIENT_SECRETS = '/a/path' #real config contains correct path
OIDC_ID_TOKEN_COOKIE_SECURE = False
OIDC_REQUIRE_VERIFIED_EMAIL = False
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = 'Gamma'
CUSTOM_SECURITY_MANAGER = OIDCSecurityManager
# Webserver Setting
SUPERSET_WEBSERVER_PROTOCOL = "http"
SUPERSET_WEBSERVER_ADDRESS = "127.0.0.1"
SUPERSET_WEBSERVER_PORT = 8088
# Flask Application Builder Settings
SILENCE_FAB = False
FAB_ADD_SECURITY_VIEWS = True
FAB_ADD_SECURITY_PERMISSION_VIEW = True
FAB_ADD_SECURITY_VIEW_MENU_VIEW = True
FAB_ADD_SECURITY_PERMISSION_VIEWS_VIEW = True
# Session Timeout
from flask import session
from flask import Flask
from datetime import timedelta
def make_session_permanent():
session.permanent = True
# Set up max age of session to 1 minute for testing
PERMANENT_SESSION_LIFETIME = timedelta(minutes=1)
def FLASK_APP_MUTATOR(app: Flask) -> None:
app.before_request_funcs.setdefault(None, []).append(make_session_permanent)```
I am also facing same issue, when user is trying to login agin after logout once its throwing 502 error, Because when user made logout only from superset he is getting logout but in keykloak status kept as login , How to logout from keykloak also when user logout from superset dashboard
I am doing an app and I am using the Blueprints structure. My code is running okay, but I got this error while trying to implment flask-caching into one function.
The error returned is:
AttributeError: 'Blueprint' object has no attribute 'cache'
Does anybody has a light of solution in here to make the cache happens to this function?
Here is a piece of my code:
from flask import render_template, redirect, request, Blueprint
from cache import store_weather, number_of_views, cached_weather, cache
import json, requests
bp = Blueprint('bp', __name__, url_prefix="/weather")
main = Blueprint('main', __name__)
api_key = "42fbb2fcc79717f7601238775a679328"
#main.route('/')
def hello():
views = 5
max_views = number_of_views()
return render_template('index.html', cached_weather=cached_weather, max_views=max_views, views=views)
#bp.route('/', methods=['GET'])
def weather():
clean_list_cache()
if request.args.get('max').isdigit():
views = int(request.args.get('max'))
else:
views = 5
try:
city_name = request.args.get('city')
if city_name not in cached_weather:
uri = 'http://api.openweathermap.org/data/2.5/weather?q={city}&appid={key}'.format(city=city_name,key=api_key)
# On that point, we bring the data from the Open Weather API
rUrl = requests.get(uri)
# The temperature of the Open Weather API is in Kelvin, so, we have to subtract 273.15 to transform
# it into Celsius degrees
temperature = str(round((json.loads(rUrl.content)['main'])['temp']-273.15))+" °C"
name = json.loads(rUrl.content)['name']
description = json.loads(rUrl.content)['weather'][0]['description']
city_data = { "temp":temperature, "name":name, "desc":description }
store_weather(city_data)
max_views = number_of_views(views)
return render_template('weather.html', cached_weather = cached_weather, error_rec_city = False, max_views=max_views, views=views)
except KeyError:
max_views = number_of_views(views)
return render_template('weather.html', cached_weather=cached_weather, error_rec_city = True, max_views=max_views, views=views)
#bp.cache.cached(timeout=30, key_prefix='list_cache')
def clean_list_cache():
cached_weather.clear()
The error occurs, as you are trying to call cache on your blueprint: #bp.cache.cached. An example from the docs how to use cache is:
#app.route("/")
#cache.cached(timeout=50)
def index():
return render_template('index.html')
So you have to squeeze the cache decorator between your app decorator and the function
I'm working in an API with python, flask and implementing JWT with a timeout for expiration, but I'd like to set also a limit request, So the token is gonna be invalid if the time is out or the token has been used in five requests.
I'd been working with the timeout for expiration, but I can't find how to implement the expiration by five requests. Thanks by the help.
The Code til now:
from flask import *
import jwt
import datetime
from flask_pymongo import PyMongo
from functools import wraps
import hashlib
app = Flask(__name__)
app.config['MONGO_DBNAME'] = 'MONGOCONEX'
app.config['MONGO_URI'] = 'mongodb://localhost:27017/MONGOCONEX'
app.config['log_log_1'] = 'LOGKEYCONNECT'
app.config['key1'] = 'SECRECTKEY'
app.config['key2'] = 'PASSKEY'
mongo = PyMongo(app)
def token_required(f):
#wraps(f)
def decorated(*args, **kwargs):
token = request.args.get('token')
if not token:
return jsonify({'error': 402,'message':'Token is missing'})
try:
data = jwt.decode(token, app.config['key1'])
except:
return jsonify({'error': 403,'message': 'Token Invalid'})
return f(*args, **kwargs)
return decorated
#app.route('/results', methods=['GET'])
#token_required
def get_all_stars():
results = mongo.db.resultados
output = []
date_start = datetime.datetime.now() - datetime.timedelta(days=1*365)
date_end = datetime.datetime.now() + datetime.timedelta(days=1*365)
for s in results.find():
#print(s)
if date_start <= s['day'] <= date_end:
output.append({'day':s['day'], 'monthly_prediction':s['monthly_prediction'], 'percent_prediction':s['percent_prediction']})
return jsonify({'result' : output})
#app.route('/login', methods=['GET'])
def login():
log_key = request.args.get('l_k')
password_k = request.args.get('p_k')
md5_hash = hashlib.md5()
md5_hash.update(b""+app.config['key2']+"")
encoded_pass_key = md5_hash.hexdigest()
if (log_key == app.config['log_log_1']) and (password_k == encoded_pass_key):
token = jwt.encode({'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=2)}, app.config['key1'])
return jsonify({'token': token.decode('UTF-8')})
return jsonify({'error': 401, 'description': 'Not verified', 'Wrong Auth': 'Auth Required'})
if __name__ == '__main__':
try:
app.run(debug=True)
except Exception as e:
print('Error: '+str(e))
I see you're using mongo, the workflow is you can put counter along with the token in mongo database and count it how many it has been used, then adding logic to compare which one comes first, the time limit or how many times the token has been used, if it has been used five times you can revoke the token & generate a new token or another workflow you want to do. Here's the further reference to revoke/blacklist the token after it has been accesed five times https://flask-jwt-extended.readthedocs.io/en/stable/blacklist_and_token_revoking/