flask session not reloading - python

Right now I am using Flask and a flask 3rd party library Flask-Session
Using the code below, I reload the page 4 times and get the following output:
set userid[0]
127.0.0.1 - - [27/Sep/2014 22:28:35] "GET / HTTP/1.1" 200 -
set userid[1]
127.0.0.1 - - [27/Sep/2014 22:28:37] "GET / HTTP/1.1" 200 -
set userid[2]
127.0.0.1 - - [27/Sep/2014 22:28:37] "GET / HTTP/1.1" 200 -
set userid[3]
127.0.0.1 - - [27/Sep/2014 22:28:38] "GET / HTTP/1.1" 200 -
Code:
from flask import Flask, session
from flask.ext.session import Session
app = Flask(__name__)
sess = Session()
nextId = 0
def verifySessionId():
global nextId
if not 'userId' in session:
session['userId'] = nextId
nextId += 1
sessionId = session['userId']
print ("set userid[" + str(session['userId']) + "]")
else:
print ("using already set userid[" + str(session['userId']) + "]")
sessionId = session.get('userId', None)
return sessionId
#app.route("/")
def hello():
userId = verifySessionId()
return str(userId)
if __name__ == "__main__":
app.config['SECRET_KEY'] = 'super secret key'
app.config['SESSION_TYPE'] = 'filesystem'
sess.init_app(app)
app.debug = True
app.run()
Shouldn't session['userId] be 'saved out' each time I reload the page?

You need to have cookies enabled for sessions to work. Even Flask-Session cannot track a browser without those.
Flask-Session sets a cookie with a unique id, then later on finds your session data again by that cookie.

Related

UnitTest for get flask

I have created a get function in my flask application which looks something similar below.
flask_app.py
_cloudenv='dev.net'
app = Flask(__name__)
csrf = CSRFProtect()
csrf.init_app(app)
#app.route('/')
#app.route('/index')
def index():
project = "Project 1"
framework = "Publish Framework"
version = '0.1'
# May require to change
hostname = 'farid.net'
# return render_template('index.html', title=project , description=f'{project} : {framework} v - {version}' , hostname=hostname , get_env=_cloudenv)
test_flask.py
import flask_app as flk_app
from flask_app import app
class test_tbrp_case(unittest.TestCase):
def test_home_page_getenv(self):
response = app.test_client().get('/')
assert response.status_code == 200
assert response.get_env == 'dev.net'
def test_home_page_gettitle(self):
response = app.test_client().get('/')
assert response.status_code == 200
assert response.title== 'Project 1'
when i run my test cases , it failed, anything that i did wrong here ?

serve() is called twice everytime I reload a blog page in wagtail

I am using wagtail to build a blog website. In order to count the visits of each blog, I override the get_context() and serve() to set cookie. The codes are as follows:
def get_context(self, request):
authorname=self.author.get_fullname_or_username()
data = count_visits(request, self)
context = super().get_context(request)
context['client_ip'] = data['client_ip']
context['location'] = data['location']
context['total_hits'] = data['total_hits']
context['total_visitors'] =data['total_vistors']
context['cookie'] = data['cookie']
context['author']=authorname
return context
def serve(self, request):
context = self.get_context(request)
print(request.COOKIES)
template = self.get_template(request)
response = render(request, template, context)
response.set_cookie(context['cookie'], 'true', max_age=3000)
return response
And the function count_visits is as follows:
def count_visits(request, obj):
data={}
ct = ContentType.objects.get_for_model(obj)
key = "%s_%s_read" % (ct.model, obj.pk)
if not request.COOKIES.get(key):
blog_visit_count, created =BlogVisitNumber.objects.get_or_create(content_type=ct, object_id=obj.pk)
blog_visit_count.count += 1
blog_visit_count.save()
The problem I met is that when I reload the blog page, serve() was loaded twice. The first time request was with cookie info. But the second time the cookie of the request was {}, which caused the count of visit does not work correctly.
I do not understand why serve() is called twice everytime I reload page.
After adding a print command in serve(), the log of reload blog page is as follows:
[19/Sep/2022 23:08:44] "GET /notifications/api/unread_list/?max=5 HTTP/1.1" 200 38
{'csrftoken': 'vAnNLAp8Fb9zPkUOSrHTFGB5Bp4W4aLu8mQWPklIhX1JpDTcKIceeId03jTKJpA3', 'sessionid': '9qdgjulitvosan1twtqe0h5bpfn4z3hg', 'bloglistingpage_7_read': 'true', 'blogdetailpage_6_read': 'true'}
[19/Sep/2022 23:08:44] "GET /blog-1/ HTTP/1.1" 200 27594
{}
[19/Sep/2022 23:08:45] "GET /blog-1/ HTTP/1.1" 200 23783
[19/Sep/2022 23:08:46] "GET /notifications/api/unread_list/?max=5 HTTP/1.1" 200 38
And the log of curl is:
[19/Sep/2022 23:12:24] "GET /notifications/api/unread_list/?max=5 HTTP/1.1" 200 38
{}
[19/Sep/2022 23:12:29] "GET /blog-1/ HTTP/1.1" 200 23783

Superset with Keycloak - Logged out users are not redirected to login

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

Can't get the response from webhook

I created a webhook using python ( using this example) for my project in api.ai
My code is here :
#!/usr/bin/env python
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)
print("Request:")
print(json.dumps(req, indent=4))
res = makeWebhookResult(req)
res = json.dumps(res, indent=4)
print(res)
r = make_response(res)
r.headers['Content-Type'] = 'application/json'
return r
def makeWebhookResult(req):
if req.get("result").get("action") != "delivery.info":
return {}
result = req.get("result")
parameters = result.get("parameters")
parcelnr = parameters.get("parcelnumber")
parcelinfo = {'5000':'your parcel has been shipped', '5001':'your parcel has
not been shipped', '5002':'should be delivered on three days', '5003':'your
parcel has not been shipped', '5004':'your parcel has been shipped'}
speech = "Parcel with numner" + parcelnr + " is " +
str(parcelinfo[parcelnr]) "
print("Response:")
print(speech)
return {
"speech": speech,
"displayText": speech,
#"data": {},
# "contextOut": [],
"source": "apiai-debot"
}
if __name__ == '__main__':
port = int(os.getenv('PORT', 5000))
print "Starting app on port %d" % port
app.run(debug=True, port=port, host='0.0.0.0')
Api agent is :
image1
image2
I don't understand where i'm wrong.
My agent work ok, but when i ask the bot to get info from the webhook i get the text response from api.ai not from webhook.
Can you help me please ?
The following is working for me. request.data will be receiving message alerts from the TradingView webhook message.
#app.route('/webhook', methods=['POST'])
def webhook():
print("\nrequest.data={}".format(request.data))
return request.data
In TradingView Alert Message, I am using following...
exchange = {{exchange}}, ticker = {{ticker}}, price = {{close}}, volume = {{volume}}
...and I am getting following message in logs:
$ heroku logs --tail
2022-01-12T20:38:00.510006+00:00 app[web.1]: request.data=b'exchange = BINANCE, ticker = BTCUSDT, price = 43671.85, volume = 10.70612'
2022-01-12T20:38:00.510512+00:00 app[web.1]: 10.1.58.75 - - [12/Jan/2022:20:38:00 +0000] "POST /webhook HTTP/1.1" 200 73 "-" "Go-http-client/1.1"
You are using the wrong url for the webhook in the fulfillment.
Your code is mapping the request to /webhook, while your url is https://your-domain.com/debotwebhook.
Either change #app.route('/webhook', methods=['POST']) to #app.route('/debotwebhook', methods=['POST']) or change the url in api.ai to https://your-domain.com/webhook
Also, I see an extra " in your speech variable after str(parcelinfo[parcelnr]).
Here is the agent I tested with your code and on the right you can see the answer:

Flask session member not persisting across requests

I'm writing a quick app to view a giant XML file with some AJAX style calls to viewgroup. My problem is session['groups'] not persisting. I have some old array with only 4 members that is stuck somewhere (cookie?..). That value is present when view is called. I then overwrite that session member with info from the recently opened xml file that contains 20+ members.
However, when viewgroup is called the session variable has reverted to the old value with only 4 members in the array!
Code followed by output. Note the 3 sessionStatus() calls
def sessionStatus():
print "# of groups in session = " + str(len(session['groups']))
#app.route('/')
def index():
cams = [file for file in os.listdir('xml/') if file.lower().endswith('xml')]
return render_template('index.html', cam_files=cams)
#app.route('/view/<xmlfile>')
def view(xmlfile):
path = 'xml/' + secure_filename(xmlfile)
print 'opening ' + path
xmlf = open(path, 'r')
tree = etree.parse(xmlf)
root = tree.getroot()
p = re.compile(r'Group')
groups = []
for g in root:
if (p.search(g.tag) is not None) and (g.attrib['Comment'] != 'Root'):
groups.append(Group(g.attrib['Comment']))
sessionStatus()
session['groups'] = groups
sessionStatus()
return render_template('view.html', xml=xmlfile, groups=groups)
#app.route('/viewgroup/<name>')
def viewGroup(name):
groups = session['groups']
sessionStatus()
if groups is None or len(groups) == 0:
raise Exception('invalid group name')
groups_filtered = [g for g in groups if g.name == name]
if len(groups_filtered) != 1:
raise Exception('invalid group name', groups_filtered)
group = groups_filtered[0]
prop_names = [p.name for p in group.properties]
return prop_names
Output
opening xml/d.xml
# of groups in session = 5
# of groups in session = 57
127.0.0.1 - - [17/Aug/2011 17:27:29] "GET /view/d.xml HTTP/1.1" 200 -
127.0.0.1 - - [17/Aug/2011 17:27:29] "GET /static/ivtl.css HTTP/1.1" 304 -
127.0.0.1 - - [17/Aug/2011 17:27:29] "GET /static/jquery.js HTTP/1.1" 304 -
127.0.0.1 - - [17/Aug/2011 17:27:29] "GET /static/raphael-min.js HTTP/1.1" 304 -
127.0.0.1 - - [17/Aug/2011 17:27:29] "GET /static/ivtl.css HTTP/1.1" 304 -
127.0.0.1 - - [17/Aug/2011 17:27:29] "GET /favicon.ico HTTP/1.1" 404 -
# of groups in session = 5
127.0.0.1 - - [17/Aug/2011 17:27:31] "GET /viewgroup/DeviceInformation HTTP/1.1" 200 -
I need all 57 groups to stay around. Any hints?
The data was simply too big to serialize into the session. Now I generate a key into a global dict and store that key in the session.
gXmlData[path] = groups
There's the problem that the global dict will stay around forever with more and more keys but the process isn't meant to live long.
Maybe your data is too big.
If your data is larger than 4KB, a server-side session is needed. Have a look at Flask-Session.

Categories