Key Error when passing a variable using session in Flask - python

I want to pass variables from a function to a class in a Flask app using session. This is my code:
#app.route('/login', methods=['POST'])
def login():
if not request.is_json:
return jsonify({"msg": "Missing JSON in request"}), 400
username = request.json.get('username', None)
password = request.json.get('password', None)
session['client_fname'] = request.json.get('Client First Name', None)
session['client_lname'] = request.json.get('Client Last Name', None)
... ...
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token), 200
class PrivateResource(Resource):
#app.route('/protected', methods=['GET'])
#jwt_required
def sendData():
return mysqldb.addUser("{}".format(session['client_fname']),"{}".format(session['client_lname']))
The variables I want to pass are session['client_fname'] and session['client_lname']. However, when I try to trigger sendData() using curl -X GET http://localhost:5000/protected -H "Authorization: Bearer JWTGOESHERE" I get:
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask_restful/__init__.py", line 273, in error_router
return original_handler(e)
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask_restful/__init__.py", line 273, in error_router
return original_handler(e)
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask_jwt_extended/view_decorators.py", line 101, in wrapper
return fn(*args, **kwargs)
File "/Users/open/PycharmProjects/FlaskMiddleware/Flask-API-Middleware-V1/authenticate.py", line 48, in sendData
return mysqldb.addUser("{}".format(session['client_fname'],None),"{}".format(session['client_lname']))
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/werkzeug/local.py", line 377, in <lambda>
__getitem__ = lambda x, i: x._get_current_object()[i]
File "/Users/open/venv/FlaskMiddleware/lib/python2.7/site-packages/flask/sessions.py", line 83, in __getitem__
return super(SecureCookieSession, self).__getitem__(key)
KeyError: 'client_fname'
Whats wrong with the way I'm using session to pass the variables? How can I fix this?
UPDATE
If this is a cookie issue having to do with preserving the session, how could I achieve this? Now I'm creating a cookie file in curl -H "Content-Type: application/json" -X POST -d '{"username":"user1","password":"abc123","Client First Name":"SAUR","Client Last Name":"KRIS"}' http://localhost:5000/login -c cookies.txt and then trying curl -X GET http://localhost:5000/protected -H "Authorization: Bearer JWTGOESHERE" -b cookies.txt. Now I'm getting TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement. and I'm not sure if this is progress or just plain wrong.

It seems that you're using flask_jwt_extended so you could bypass the problem by storing that data directly in the token.
# ...
access_token = create_access_token({
'first_name': request.json.get('Client First Name', None),
'last_name': request.json.get('Client Last Name', None)
})
And then retrieving it in the protected route:
# ...
user_adata = get_jwt_identity()

You are almost definitely not preserving state in between your requests. If you are using postman or curl make sure to save the session id cookie. If you are using requests use requests.session().

Your update looks like it's likely to be progress, but perhaps the mysqldb.addUser function is returning None.
The easiest way to determine if you're making progress would be to debug with a breakpoint at the line return mysqldb.addUser("{}".format(session['client_fname']),"{}".format(session['client_lname'])) (I usually use PyCharm for this, but most IDEs will have something for debug, or you can use pdb). A faster but messier option, add a print statement before the call to mysqldb.addUser, and another print statement afterwards printing the return value.

Related

How do I specify x-apikeyInfoFunc in swager securityDefinitions?

I have openapi that defines API with this securityDefinitions:
securityDefinitions:
APIKeyHeader:
type: apiKey
in: header
name: Authorization
security:
- APIKeyHeader: []
When I start the project I get this warning:
WARNING 2022-01-27 13:24:41,001 connexion.operations.secure security_decorator 142 : ... x-apikeyInfoFunc missing
And such error when I try to use API methods:
INFO 2022-01-27 13:56:15,256 connexion.api.security get_authorization_info 131 : ... No auth provided. Aborting with 401.
I found that I need to specify x-apikeyInfoFunc in securityDefinitions. I specified a function that I believe does authentication:
securityDefinitions:
APIKeyHeader:
type: apiKey
in: header
name: Authorization
x-apikeyInfoFunc: util.authentication_decorator.authenticate
security:
- APIKeyHeader: []
The function itself:
def authenticate(arg: Optional[Sequence[str]] = DEFAULT_SCOPE):
""" decorator to handle api key authentication """
def decorator(fun):
""" decorator that gets applied to the function """
def wrapper(*a, **kw):
""" function wrapper """
# pylint: disable=unused-argument
api_key = request.headers.get('Authorization')
if validate_scope(api_key, scopes):
# return fun(*a, **kw)
return fun()
LOGGER.debug('Invalid or missing API key in request')
return {'msg': 'Make sure you supply your API key with sufficient scope in the Authorization header'}, 403
return wrapper
if callable(arg):
scopes = DEFAULT_SCOPE
return decorator(arg)
scopes = arg
return decorator
The function is used as a decorator to authenticate every API method. When I start the project I don't get warning. But I get another error when I actually trying to use one of API method:
ERROR 2022-01-28 13:50:03,330 openapi_helper.app_helper log_exception 1891: Exception on /v1/jira/search_issues_by_tags [GET]
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/lib/python3.6/site-packages/connexion/decorators/decorator.py", line 48, in wrapper
response = function(request)
File "/usr/local/lib/python3.6/site-packages/connexion/decorators/security.py", line 322, in wrapper
token_info = get_authorization_info(auth_funcs, request, required_scopes)
File "/usr/local/lib/python3.6/site-packages/connexion/decorators/security.py", line 127, in get_authorization_info
token_info = func(request, required_scopes)
File "/usr/local/lib/python3.6/site-packages/connexion/decorators/security.py", line 284, in wrapper
token_info = apikey_info_func(apikey, required_scopes=required_scopes)
TypeError: authenticate() got an unexpected keyword argument 'required_scopes'
I'm stuck on this point, don't have idea how to proceed. connexion 2.6.0 is used in this case.
According to Connexion docs, the x-apikeyInfoFunc function must have two parameters: apikey and required_scopes.
Example 1
Example 2

Routing inside routes - A setup function was called after the first request was handled

I am trying to create routes inside of another route (info_form()). For awhile this was working. I am not sure what exactly caused it, but I may have changed some code and that is what caused it to stop working. This is my code:
#app.route('/Register', methods=["GET", "POST"])
def register():
FormErrMessage = 'Email already taken, or invalid email.'
error = False
if request.method == 'POST':
inp_email = request.form['email']
inp_password = request.form['password']
if User.objects(email=inp_email):
error = True
else:
#app.route('/Register/customer-form', methods=['GET', 'POST'])
def info_form():
msg = None
if request.method == 'POST':
form = request.form
inp_name = form['name']
inp_lastName = form['lastName']
inp_zipCode = form['zipCode']
inp_address = form['address']
inp_phoneNumber = form['phoneNumber']
if User.objects(name=inp_name, lastName=inp_lastName):
msg = '...'
elif User.objects(phoneNumber=inp_phoneNumber):
msg = '...'
else:
#app.route('/Register/customer-form/verify/<send>', methods=['GET', 'POST'])
def verify_email(send):
msg = None
error_msg = None
r = 8
if send == 't':
...
if request.method == 'POST':
inp_code = request.form['code']
if int(inp_code) == r:
try:
User(
email=inp_email,
password=inp_password,
user_id=get_user_id(),
admin=False,
loggedIn=1,
# ip_addresses=ipAddress,
registered=False,
name=inp_name,
lastName=inp_lastName,
zipCode=inp_zipCode,
address=inp_address,
phoneNumber=inp_phoneNumber
).save()
email(...)
except ValidationError as e:
print(e)
error_msg = '...'
else:
session['email'] = inp_email
session["password"] = inp_password
print(session)
return redirect('/')
else:
msg = 'Code invalid, try again.'
return render_template('verify.html', email=inp_email, unk_err=error_msg,
msg=msg)
return redirect('/Register/customer-form/verify/t')
return render_template('customerform.html', msg=msg)
return redirect('/Register/customer-form')
return render_template('register.html', FormErrMessage=FormErrMessage, error=error)
It seems to be raising this because the request was already handled.
Traceback (most recent call last):
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 2463, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\William\Nickels\app.py", line 55, in register
#app.route('/Register/customer-form', methods=['GET', 'POST'])
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 1314, in decorator
self.add_url_rule(rule, endpoint, f, **options)
File "C:\Users\William\Nickels\venv\lib\site-packages\flask\app.py", line 90, in wrapper_func
"A setup function was called after the "
AssertionError: A setup function was called after the first request was handled. This usually indicates a bug in the application where a module was not imported and decorators or other functionality was called too late.
To fix this make sure to import all your view modules, database models and everything related at a central place before the application starts serving requests.
Can someone tell me how to fix this or get around it. Thanks.
I don't understand this:
import all your view modules, database models and everything related at a central place before the application starts serving requests.
What that error is trying to say is that you can't do setup-y things (like adding routes) after the Flask app has starting running.
You have a deeper problem, which is assuming that nested route functions will retain visibility an data from enclosing routes. E.g., that the /Register/customer-form route will have access to the inf_email set in the enclosing /Register route. The mechanisms here don't work that way.
Since the intent is to hang on to information from one step of a registration workflow to the next, the common mechanisms is to inject state from one route as hidden form elements so that they'll be carried along to the next route. Here, that would mean passing inf_email et al. to be expanded into the "customerform.html" template (and similar for the "verify.html" template).

Oauth2 in Python with Flask gets 302 from API

I am trying to access MeisterTask's API with Python and Flask, and no matter what I do, I seem to always get a 302 code in return from the API, although I can get an access token (or so I think). Here is the code I have so far (I tried reducing it, this is the smallest snippet I could get that replicates the error):
from flask import Flask, redirect, url_for, session, request, jsonify
from flask_oauthlib.client import OAuth
app = Flask(__name__)
app.debug = True
app.secret_key = "development"
oauth = OAuth(app)
meistertask = oauth.remote_app(
'meistertask',
consumer_key= "XXXXXX",
consumer_secret= "XXXXXX",
request_token_params={"scope" : "meistertask"},
base_url='https://www.meistertask.com/api',
request_token_url=None,
access_token_method='GET',
access_token_url='https://www.mindmeister.com/login/oauth2/token',
authorize_url='https://www.mindmeister.com/oauth2/authorize'
)
#app.route('/')
def index():
if 'meistertask_token' in session:
me = meistertask.get('user')
return jsonify(me.data)
return redirect(url_for('login'))
#app.route('/login')
def login():
return meistertask.authorize(callback=url_for('authorized', _external=True))
#app.route('/logout')
def logout():
session.pop('meistertask_token', None)
return redirect(url_for('index'))
#app.route('/login/authorized')
def authorized():
resp = meistertask.authorized_response()
print(resp.get('code'))
if resp is None or resp.get('code') is None:
return 'Access denied: reason=%s error=%s resp=%s' % (
request.args['error'],
request.args['error_description'],
resp
)
session['meistertask_token'] = (resp['code'], '')
return "Hello"
#meistertask.tokengetter
def get_meistertask_oauth_token():
return session.get('meistertask_token')
if __name__ == "__main__":
app.run()
And here is the traceback:
flask_oauthlib.client.OAuthException: Invalid response from meistertask
Traceback (most recent call last):
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2309, in __call__ return self.wsgi_app(environ, start_response)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2295, in wsgi_app response = self.handle_exception(e)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\_compat.py", line 35, in reraise raise value
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2292, in wsgi_app response = self.full_dispatch_request()
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\_compat.py", line 35, in reraise raise value
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1813, in full_dispatch_request rv = self.dispatch_request()
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1799, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args)
File "~\Documents\MeisterTaskServer\hello.py", line 49, in authorized resp = meistertask.authorized_response()
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_oauthlib\client.py", line 707, in authorized_response data = self.handle_oauth2_response(args)
File "~\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask_oauthlib\client.py", line 692, in handle_oauth2_response
Things I have tried
Tried to modify the method to get the access token from GET to POST. The API clearly states that I should use GET, yet every other example I have seen on flask_oauthlib's GitHub uses POST (the examples are 3 years old, but some still work, namely the GitHub one). Either give the same result.
Tried doing it barebones, without any library. The resulting code was thrice as long and also had more problems.
Used Django instead of Flask. Never even managed to get the hello world example going, it was too much work, and also I have discovered the library flask_oauthlib.
Things worth mentioning
I derived this code from this here GitHub example
There is also code there I omitted in order to keep the snippet short, that establishes that the server should use SSL (as per the request from the API that the redirect_uri should use HTTPS)
The app manages to redirect me over at MeisterTask and asks for my permission. Once I grant it, it redirects to "https://127.0.0.1:5000/login/authorized?code=some_token" where I get the traceback. If I look with Chrome's debugging tools to the requests made and what I receive, I see that I get an 302 from the API, but I also get an access token.
I run Windows 10 with Python 3.7.0
So what's the deal? What's the next step here? I've run out of things to try. Thank you for taking the time to solve this!

'NoneType' object is not subscriptable [duplicate]

This question already has answers here:
How to get POSTed JSON in Flask?
(13 answers)
Closed 6 years ago.
I am creating an ios app that uses a server written in flask + python, and when I make a connection to the server to register a user I keep getting a 'NoneType' object is not subscriptable error in my server.py file. Basically my question is what is causing this error and how am I able to fix this. Also if anyone can point me in the right direction of different or easier ways to do this I would appreciate it thanks!
Here is the server.py file:
import bcrypt
from flask import Flask, request, make_response,jsonify
from flask_restful import Resource, Api
from pymongo import MongoClient
from json import JSONEncoder
from bson.objectid import ObjectId
from functools import wraps
app = Flask(__name__)
mongo = MongoClient('localhost', 27017)
app.db = mongo.eventure_db
app.bcrypt_rounds = 12
api = Api(app)
# Authentication code.
def check_auth(username, password):
# check_auth should access the database and check if the username + password are correct.
# create a collection to hold the users.
user_collection = app.db.users
user = user_collection.find_one({'username': username})
if user is None:
return False
else:
# check if hash generated matches stored hash
encodedPassword = password.encode('utf-8')
if bcrypt.hashpw(encodedPassword, user['password']) == user['password']:
return True
else:
return False
# User resource
class User(Resource):
def post(self):
if (request.json['username'] == None
or request.json['password'] == None):
return ({'error': 'Request requires username and password'},
400,
None)
user_collection = app.db.users
user = user_collection.find_one({'username': request.json['username']})
if user is not None:
return ({'error': 'Username already in use'}, 400, None)
else:
encodedPassword = request.json['password'].encode('utf-8')
hashed = bcrypt.hashpw(
encodedPassword, bcrypt.gensalt(app.bcrypt_rounds))
request.json['password'] = hashed
user_collection.insert_one(request.json)
#requires_auth
def get(self):
return (None, 200, None)
api.add_resource(User, '/eventure/api/v1.1/user/')
# Must define a custom JSON Serializer for flask_restful
# this is because ObjectId is not a string, and therefore,
# Flask's default serializer cannot serialize it.
#api.representation('application/json')
def output_json(data, code, headers=None):
resp = make_response(JSONEncoder().encode(data), code)
resp.headers.extend(headers or {})
return resp
if __name__ == '__main__':
app.config['TRAP_BAD_REQUEST_ERRORS'] = True
app.run(host='localhost', port=8789, debug=True)
And this is my register function in swift:
#IBAction func register(_ sender: AnyObject) {
let url = URL(string: "http://localhost:8789/eventure/api/v1.1/user/")
var request = URLRequest(url: url!)
request.httpMethod = "POST"
request.setValue(generateBasicAuthHeader(username: username.text!, password: password.text!), forHTTPHeaderField: "Authorization")
let session = URLSession.shared
let task = session.dataTask(with: request) { data, response, error in
if let response = response, let data = data {
print(String(data: data, encoding: String.Encoding.utf8))
}
}
task.resume()
self.username.text = ""
self.password.text = ""
}
traceback:
[28/Oct/2016 19:22:33] "POST /eventure/api/v1.1/user/ HTTP/1.1" 500 -
Traceback (most recent call last):
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/_compat.py", line 32, in reraise
raise value.with_traceback(tb)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/_compat.py", line 32, in reraise
raise value.with_traceback(tb)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask_restful/__init__.py", line 471, in wrapper
resp = resource(*args, **kwargs)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/Users/Dynee/eventure-backend-api/development/lib/python3.5/site-packages/flask_restful/__init__.py", line 581, in dispatch_request
resp = meth(*args, **kwargs)
File "/Users/Dynee/eventure-backend-api/server.py", line 128, in post
if (request.json['username'] == None
TypeError: 'NoneType' object is not subscriptable
Also here is the generateBasicAuthHeader function:
func generateBasicAuthHeader(username: String, password: String) -> String {
let loginString = String(format: "%#:%#", username, password)
let loginData = loginString.data(using: String.Encoding.utf8)!
let base64LoginString = loginData.base64EncodedString()
let basicAuthHeader = "Basic \(base64LoginString)"
return basicAuthHeader
}
You need to explicitly set the content-type to application/json for request.json to work properly in flask. If the header isn't set, request.json would return None.
But the recommended to get json data in flask from a post request is to use request.get_json()
I'll also urge you to test your api with the nifty requests module before using your ios application.
>>> import requests
>>> requests.post(url, json={'name': 'hello world'})
It already sets the appropriate headers required to make a json request
If it works with the requests module, then you can be sure that it's going to work with your ios application. you just need to make sure you're setting the correct content-type.
You can forcefully tell flask to ignore the content-type header with
request.get_json(force=True)

Flask-Admin modelview function

I have a flask app with Flask-Admin to manage the users with the /admin/userview modelview.
I wanted it to show the page when a user that is in the DB with the correct group navigates to /admin/userview, and return plain text "not admin" if they are not. Fortunately I got the last part to work, but unfortunately I cannot seem to get the first part (continuing to show the page if they are in the correct group). Here's the relevant code:
class MyView(ModelView):
#expose('/', methods = ['GET', 'POST'])
def index(self):
## grab kerberos username (PROD)
secuser = request.environ.get('REMOTE_USER')
adminresult = User.query.filter_by(usrlevel='admin').all()
adminresult = str(adminresult)
adminresult = adminresult.strip('[]')
managerresult = User.query.filter_by(usrlevel='manager').all()
managerresult = str(managerresult)
managerresult = managerresult.strip('[]')
if secuser in adminresult:
pass <---------------\
elif secuser in managerresult: |- if a user is apart of either, this gives a ValueError
pass <---------------/
else:
return "NOT ADMIN" <--------- This works!
##ADMIN
admin = Admin(flaskapp, index_view=MyHomeView(), name="test APP")
admin.add_view(MyView(User, db.session, "Edit Users"))
Here's the traceback that I get when a user is in adminresult or in managerresult:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1478, in full_dispatch_request
response = self.make_response(rv)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1566, in make_response
raise ValueError('View function did not return a response')
ValueError: View function did not return a response
How do I get the ModelView "User" to display it's contents if the user is in either group, and to just return "not admin" text if they are not? I think I got half of that done, just continuing seems to be an issue...
Thanks!
You should actually put the check in is_accessible:
class MyView(ModelView):
def is_accessible(self):
# grab kerberos username (PROD)
secuser = request.environ.get('REMOTE_USER')
admins_and_managers = User.query
.filter(User.usrlevel.in_('admin', 'manager'))
# Better yet, filter again on `secuser`
# to avoid loading *every* admin and manager
# on *every* request for this resource
# and then use `.first` or `.one`
.all()
return secuser in admins_and_managers

Categories