I am using Cloud SQL on Google app engine. Once I add a new user in the console and re-deploy my app the new user can't seem to login? - python-3.x

When I add in a new user and password in the GCP console, refresh and wait, then re deploy and run my web app I can't login with that user. I can still login with my original test user (the first and only user thus far beside the 'postgres' admin. user)
Ive tried deleting and re-adding the same user.Ive tried adding yet another user and deploying - re attempting to login in again. Ive made sure Ive refreshed and waited for the change to take effect before re-deploying the web app . I have logged with my original user , log out and try login with the new user, also initially with the new user.I've scoured online for answers but surprisingly to no avail.
The main , outer, app.py file that has the user management/Auth code using Flask and flask_login functionality :
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import sys
#sys.path.append('/Users/crowledj/Mindfule/dash-flask-login/views/')
#sys.path.append('/Users/crowledj/Mindfule/dash-flask-login/flask_login/')
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__ , external_stylesheets=external_stylesheets)
#server=app.server
app.css.append_css({'external_url': 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css'})
from server import app, server
from flask_login import logout_user, current_user
import success, login, login_fd, logout
#import sqlalchemy
header = html.Div(
className='header',
children=html.Div(
className='container-width',
style={'height': '100%'},
children=[
html.Img(
src='mindfule_company_logo.jpg',
className='logo'
),
html.Div(className='links', children=[
html.Div(id='user-name', className='link'),
html.Div(id='logout', className='link')
])
]
)
)
app.layout = html.Div(
[
header,
html.Div([
html.Div(
html.Div(id='page-content', className='content'),
className='content-container'
),
], className='container-width'),
dcc.Location(id='url', refresh=False),
]
)
#app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
if pathname == '/':
return login.layout
elif pathname == '/login':
return login.layout
elif pathname == '/success':
if current_user.is_authenticated:
print('returning success page from main app ... \n')
return success.layout
else:
return login_fd.layout
elif pathname == '/logout':
if current_user.is_authenticated:
logout_user()
return logout.layout
else:
return logout.layout
else:
return '404'
#app.callback(
Output('user-name', 'children'),
[Input('page-content', 'children')])
def cur_user(input1):
if current_user.is_authenticated:
return html.Div('Current user: ' + current_user.username)
# 'User authenticated' return username in get_id()
else:
return ''
#app.callback(
Output('logout', 'children'),
[Input('page-content', 'children')])
def user_logout(input1):
if current_user.is_authenticated:
return html.A('Logout', href='/logout')
else:
return ''
if __name__ == '__main__':
app.run_server(debug=True,port=8080,host= "foodmoodai.appspot.com") #"0.0.0.0") #
the only Postgres and SQL related code # start of my 'success' page file :
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import plotly.graph_objs as go
from textwrap import dedent as d
from flask import Flask
import pandas as pd
import numpy as np
from NutrientParser import parseNutrientStr_frmUser,parseResearch,parseFoodResearch,find_substring
from userMindfuleClasses import *
import PIL
import urllib3
from PIL import Image
import json,os
import arrow
from server import app
from flask_login import current_user
import psycopg2
from datetime import datetime
timeStamp=datetime.now()
#db_user='test'
#db_pass='test1'
#db_name='foodnmood-db'
#INSTANCE_CONNECTION_NAME='foodmoodai:europe-west2:foodnmood-db'
from sqlalchemy import Table, Column, Integer, String, MetaData,create_engine
meta = MetaData()
#engine = create_engine('postgresql+psycopg2://postgres:Pollgorm1#/cloudsql/foodmoodai:europe-west2:foodnmood-db')
engine = create_engine('postgresql+psycopg2://postgres:Pollgorm1#/?host=/cloudsql/foodmoodai:europe-west2:foodnmood-db')
mealnMoodwithTimesnFoods = Table(
'mealnMoodwithTimesnFoods', meta,
Column('time', String, primary_key = True),
Column('id', String),
Column('food_1', String),
Column('food_2', String),
Column('food_3', String),
Column('mood', String),
)
meta.create_all(engine)
I expect to be able to at least add a new user (which automatically has login permissions) and log in past the log in page when I redeploy the app after making this change in the GCP console.

The issue here turned out to actually be completely to do with a local authentication library I had installed from GitHub - which uses 'flask_login' (flask_login==0.4.1 --> pip install flask-login==0.4.1).All I needed to do was update the new user and password in a local .txt file as well as on gcloud's cloud SQL console.

Related

Dash multiple app server set Flask session

Let's say I have 2 apps running, and served by DispatcherMiddleware like the following:
utils.py
import uuid
from flask import session
def set_session():
if 'uid ' not in session:
uid = str(uuid.uuid4())
session['uid'] = uid
index.py
from flask import Flask
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
app1.py
import dash
import dash_html_components as html
from flask import session
from utils import set_session
app = dash.Dash(
__name__,
requests_pathname_prefix='/app1/'
)
def layout():
set_session()
return [html.Div('welcome', id='div'), html.Button(id='submit', n_clicks=0)]
app.layout = layout
#app.callback(Output('div', 'children'),
[Input('submit', 'n_clicks')])
def print_session(n_clicks):
return session['uid']
app2.py
import dash
import dash_html_components as html
from flask import session
from utils import set_session
app = dash.Dash(
__name__,
requests_pathname_prefix='/app2/'
)
def layout():
set_session()
return [html.Div('welcome', id='div'), html.Button(id='submit', n_clicks=0)]
app.layout = layout
#app.callback(Output('div', 'children'),
[Input('submit', 'n_clicks')])
def print_session(n_clicks):
return session['uid']
wsgi.py
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from index import app as index
from flask import Flask
from app1 import app as app1
from app2 import app as app2
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(index, {
'/app1': app1.server,
'/app2': app2.server,
})
I would like to have one session per user and per app.
But the above code raise the error:
Traceback (most recent call last): File "C:\Users\wsgi.py", line 24, in
from app1 import app as app1
File "C:\Users\app1.py", line 254, in
app.layout = layout
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\dash\dash.py", line 510, in layout
layout_value = self._layout_value()
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\dash\dash.py", line 476, in _layout_value
return self._layout() if self._layout_is_function else self._layout
File "C:\Users\app1.py", line 130, in layout
if 'uid' not in session:
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\werkzeug\local.py", line 379, in
__contains__ = lambda x, i: i in x._get_current_object()
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\werkzeug\local.py", line 306, in _get_current_object
return self.__local()
File "C:\Users\AppData\Roaming\Python\Python37\site-packages\flask\globals.py", line 38, in _lookup_req_object
raise RuntimeError(_request_ctx_err_msg)
RuntimeError: Working outside of request context.
One possible solution is to store the session data (or just the session id) as part of your app layout. Here is a small example,
import uuid
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Output, Input, State
def layout():
return html.Div([html.Div('Welcome', id='div'), html.Button("Submit", id='submit', n_clicks=0),
dcc.Store(id="session", data=dict(uid=str(uuid.uuid4())))])
app = dash.Dash(__name__, prevent_initial_callbacks=True)
app.layout = layout
#app.callback(Output('div', 'children'), [Input('submit', 'n_clicks')], State("session", "data"))
def print_session(_, session):
return session['uid']
if __name__ == '__main__':
app.run_server()

hi i am getting "CSRF Failed and CSRF cookie not set." error

{"detail": "CSRF Failed: CSRF cookie not set."} error in postman , i am using django rest_framework for developing ios android backend .
when i first time clear all cookies and use my login api is working fine
this will give me all info about user as per my code but after that when i try to hit any api using post method its always give crsf failed.
i also use csrf_exempt decorator in view and urls.py and also tried CsrfExemptMixin from brace package.
my login code is
from django.contrib.auth import login,logout
from django.shortcuts import render,redirect
# local py files
from .models import *
from .serializers import *
from app_apis.models import *
# third party
from rest_framework import (generics,
permissions)
from knox.views import LoginView as KnoxLoginView
from rest_framework.response import Response
from rest_framework.authtoken.serializers import AuthTokenSerializer
from knox.models import AuthToken
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from braces.views import CsrfExemptMixin
from django.middleware.csrf import get_token
# Register API
class RegisterView(CsrfExemptMixin,generics.GenericAPIView):
serializer_class=RegisterUserSerializer
#method_decorator(csrf_exempt)
def post(self,request,*args, **kwargs):
serializer=self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
print
logout(request)
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
"token": AuthToken.objects.create(user)[1]
})
class LoginAPI(CsrfExemptMixin,KnoxLoginView):
permission_classes = (permissions.AllowAny,)
def get(self,request):
example={
"username":"user_name",
"password":"Your Password"
}
return Response(example)
#method_decorator(csrf_exempt)
def post(self, request, format=None):
serializer = AuthTokenSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
user_id_main=user.id
user_name=user.username
user_data=[user_id_main,user_name]
print(user_data)
projects=ProjectTable.objects.filter(created_by_id=user_id_main).values_list('name')
project_names=projects
login(request, user)
temp_list=super(LoginAPI, self).post(request, format=None)
temp_list.data["project_list"]=project_names
temp_list.data["user_data"]=user_data
temp_list.data['csrf_token']=get_token(request)
return Response({"data":temp_list.data})
# logout
def logout_view(request):
logout(request)
return redirect("user_profile:login")
please guide me . thanks in advance
Do not use rest_framework.authentication.SessionAuthentication in DEFAULT_AUTHENTICATION_CLASSES
Reference link: https://stackoverflow.com/a/56101653/217586
use corsheaders in installed app https://pypi.org/project/django-cors-headers/ use and follow the documentation

Pass filepath as parameter to a URL in FLASK(Python)

I want to build an api which accepts a parameter from the user which is a filepath and then process the file given in that path. The file to be processed is already in the server where the api will be running.
As of now, I have written an api where I have hardcoded the filepath in my code which runs the api. Now, I want to configure my api in such a way that accepts a filepath from the user. My api should accept the path as a parameter and process the file that has been given in the path.
The api code is as follows:
The convert function returns the category of the file.
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
#convert(r'D:\files\67cecf40-71cf-4fc4-82e1-696ca41a9fba.pdf')
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
categories=convert(r'D:\files\6628cb99-a400-4821-8b13-aa4744bd1286.pdf')
#app.route('/')
def returnResult():
return categories
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
So, I want to make changes to this code to accept a parameter from the user which will be a filepath and the convert function will process that filepath. I want to know how to make my api accept a filepath parameter from the user.
Trial with requests.args.get:
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
#convert(r'D:\files\67cecf40-71cf-4fc4-82e1-696ca41a9fba.pdf')
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
#app.route('/')
def returnResult():
categories=convert(r'D:\files\'.format(request.args.get('categories')))
return categories
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
results in error :
"RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed
an active HTTP request. Consult the documentation on testing for
information about how to avoid this problem."
PRESENT SCENARIO:
I am able to post a filepath to the url. My question is now how do I use this posted url with filepath in my code to trigger my function that takes in the filepath and processes the file. Code to post the filepath:
import ectd
from ectd import convert
from flask import Flask, request
from flask_restful import Resource, Api
#from flask.views import MethodView
app = Flask(__name__)
api = Api(app)
class ectdtext(Resource):
def get(self, result):
return {'data': ectd.convert(result)}
#api.add_resource(ectdtext, '/ectd/<result>')
categories=convert('/home/brian/ajay/files/5ca21af9-5b67-45f8-969c-ae571431c665.pdf')
#app.route('/')
def returnResult():
return categories
#app.route('/', defaults={'path': ''})
#app.route('/<path:path>')
def get_dir(path):
return path
##app.route('/get_dir/<path>')
#def get_dir(path):
# return path
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)

I am running a python dash web app on GAE.It works well locally but local images I have in an assets folder to not appear after deploy?

I am displaying static .jpg/.png images on my dash app locally and they show up fine. Even a logo in the header of the app in the browser.They simply are not being found at all after deployment. the rest of the app runs fine. you can see this by going to http://foodmoodai.appspot.com and login with user 'test' and password 'test1'.I have tried all the suggestions here on SO and online - which almost almost involve change to the app.yaml file - enabling static images by including various commands for the '-handlers' section. None of these have changed the error for me.you can see my app.yaml below.
As stated I have tried many combinations of advice for the app.yaml file such as,
#handlers:
- url: /imgages
static_dir: imgages
- url: /.*
script: app.app
my latest app.yaml file,
runtime: python
env: flex
entrypoint: gunicorn app:app.server -b :$PORT
threadsafe: true
manual_scaling:
instances: 1
runtime_config:
python_version: 3.7
resources:
cpu: 1
memory_gb: 0.5
disk_size_gb: 10
handlers:
# This configures Google App Engine to serve the files in the app's static
# directory.
- url: /static
static_dir: static/
# This handler routes all requests not caught above to your main app. It is
# required when static routes are defined, but can be omitted (along with
# the entire handlers section) when there are no static files defined.
- url: /.*
script: auto
#handlers:
- url: /imgages
static_dir: imgages
- url: /.*
script: app.app
the start of my main 'app.py' file,
# index page
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import sys
#sys.path.append('/Users/crowledj/Mindfule/dash-flask-login/views/')
#sys.path.append('/Users/crowledj/Mindfule/dash-flask-login/flask_login/')
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__ , external_stylesheets=external_stylesheets)
server=app.server
app.css.append_css({'external_url': 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css'})
from server import app, server
from flask_login import logout_user, current_user
import success, login, login_fd, logout
#import sqlalchemy
header = html.Div(
className='header',
children=html.Div(
className='container-width',
style={'height': '100%'},
children=[
html.Img(
src='mindfule_company_logo.jpg',
className='logo'
),
html.Div(className='links', children=[
html.Div(id='user-name', className='link'),
html.Div(id='logout', className='link')
])
]
)
)
important section from the 'success.py' file (called on successful login),
import dash
#import dash_auth
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import plotly.graph_objs as go
from textwrap import dedent as d
from flask import Flask
import pandas as pd
import numpy as np
from NutrientParser import parseNutrientStr_frmUser,parseResearch,parseFoodResearch,find_substring
from userMindfuleClasses import *
import PIL
import urllib3
from PIL import Image
import json,os
import arrow
from server import app
from flask_login import current_user
import psycopg2
from datetime import datetime
from sqlalchemy import Table, Column, Integer, String, MetaData,create_engine
meta = MetaData()
#engine = create_engine('postgresql+psycopg2://postgres:Pollgorm1#/cloudsql/foodmoodai:europe-west2:foodnmood-db')
engine = create_engine('postgresql+psycopg2://postgres:Pollgorm1#/?host=/cloudsql/foodmoodai:europe-west2:foodnmood-db')
mealnMoodwithTimesnFoods = Table(
'mealnMoodwithTimesnFoods', meta,
Column('time', String, primary_key = True),
Column('id', String),
Column('food_1', String),
Column('food_2', String),
Column('food_3', String),
Column('mood', String),
)
meta.create_all(engine)
researchDict=pd.read_csv('./researchFindings2.csv')
food_perNutrient=pd.read_csv('./foods_perNutrientSheet - Sheet1.csv')
#prepare a .csv to use as the table
f_ptr= open("./nutrientRdas.csv","w")
f_ptr.write("Vitamin A,Vitamin B-6,Vitamin C,Vitamin D,Iron,Zinc,Magnesium,Vitamin B-12,Folic acid,Glucose,EPA\n")
f_ptr.close()
#user_1=User()
colors = {
'logo_font' : '#797d7f',
'logo_background' : ' #f2f3f4',
'submit_button_font' : '#fbfcfc',
'blue' : '#4530CA'
}
layout = html.Div([
html.Div(children = [
dcc.Input(
id = 'meal_input',
placeholder = 'Start typing...',
value='',
style={
'textAlign': 'left',
'font-weight' : 'bold',
and the section with a static image attempted too be loaded ,
html.Div(className = 'row1', children =[
html.Div([ #opening brackets for Food Images DIV
html.P('Lunch', style = {'font-weight' : 'normal', 'color': '#212122', 'font-size' : '15px', 'padding-left': 10, 'padding-top' : 5}),
html.Div([
html.Div([
html.Img(
id='meal_image1',
src = 'apple.jpg',
#food_NutritionixOutputDict1 = parseNutrientStr_frmUser("apple",'2147b24b','aa03660c9838d2a7669b7981d8854604',True,False,False,'000000001',2017),
#src=food_NutritionixOutputDict1['orig_food_struct']['foods'][0]['photo']['thumb'] ,
style={
'height' : '50px',
'width' : '50px',
'position' : 'absolute',
'top' : 60,
'left' : 30,
})
]),
html.Div([
html.P('Apple',
id='meal_p1',
style = {
I expect the images to be found on the browser # run of deployed cloud app. And for them to show on there browser session # login.
Instead these show up as image not found icons.
There are several javascript errors that can be seen in the inspect element in the browser after login.

Setting up a python dash dashboard inside a flask app

I'm trying to build a website that allows people to access different kinds of graphs in a dash app. I want the users to log in with a username and a password before they can access the dashboard. This is what I have thus far
from flask import Flask, flash, render_template, request, session
import os, dash
import dash_html_components as html
import dash_core_components as dcc
import flask
app = Flask(__name__)
dash_app = dash.Dash(__name__, server=app, url_base_pathname='/dash_app')
dash_app.config['suppress_callback_exceptions']=True
def index_page():
index = html.Div([
dcc.Link('Page 1', href='/page1'),
html.Br(),
dcc.Link('Page 2', href='/page2'),
html.Br(),
dcc.Link('Page 3', href='/page3'),
html.Br()
])
return index
dash_app.layout = html.Div(children=[
dcc.Location(id='url', refresh=False),
html.Div(id = 'page-content')
])
page_1 = html.Div([
html.H1('Welcome to page 1'),
index_page()
])
page_2 = html.Div([
html.H1('Welcome to page 2'),
index_page()
])
page_3 = html.Div([
html.H1('Welcome to page 3'),
index_page()
])
#dash_app.callback(
dash.dependencies.Output('page-content','children'),
[dash.dependencies.Input('url','pathname')]
)
def display_page(pathname):
if pathname == '/page1':
return page_1
if pathname == '/page2':
return page_2
if pathname == '/page3':
return page_3
else:
return index_page()
#app.route('/')
def home():
if not session.get('logged_in'):
return render_template('login.html')
else:
return flask.redirect('/dash_app')
#app.route('/login', methods=['POST'])
def do_admin_login():
if request.form['password'] == 'password' and request.form['username'] == 'admin':
session['logged_in'] = True
else:
flash('wrong password!')
return home()
if __name__ == "__main__":
app.secret_key = os.urandom(12)
app.run(debug=True, port=5000)
There are two problems that I want to solve:
With this setup, you don't have to login to access the dashboard. If, instead of entering the username and password, you go directly to http://localhost:5000/dash_app you get to see the dashboard immediately. I only want to give access to people that are logged in.
If I refresh my browser page, after clicking on one of the three page links, I get a message saying "Not Found":I don't understand why this is happening and it feels to me like this has something to with the structure of the app.
Question: How do I solve these two issues? And, more generally; does this structure fit the goal I am trying to achieve? Is this the correct way to setup a dashboard inside a flask app? (I know that this login setup is not safe)
Edit: Regarding the refresh problem, I am sure that it has something to do with the dash app being run inside the flask app, because when I run the dash app by itself I can refresh http://localhost:5000/page1 and it renders successfully.
You should use flask-security instead of building your own login mechanism it solve lot of issue like Registration, Login, Logout, Forgot Password etc.

Resources