Combining Flask-restless, Flask-security and regular Python requests Combining Flask-restless, Flask-security and regular Python requests flask flask

Combining Flask-restless, Flask-security and regular Python requests


I finally went to Flask-JWT (https://pypi.python.org/pypi/Flask-JWT/0.1.0)

Here is my modified minimal example:

from flask import Flask, render_template, request, url_for, redirectfrom flask.ext.sqlalchemy import SQLAlchemyfrom flask.ext.security import Security, SQLAlchemyUserDatastore, \    UserMixin, RoleMixin, login_required, current_user, logout_userfrom flask.ext.restless import APIManagerfrom flask.ext.restless import ProcessingExceptionfrom flask.ext.login import user_logged_in# JWT importsfrom datetime import timedeltafrom flask_jwt import JWT, jwt_required# Create appapp = Flask(__name__)app.config['DEBUG'] = Trueapp.config['SECRET_KEY'] = 'super-secret'app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'# expiration delay for tokens (here is one minute)app.config['JWT_EXPIRATION_DELTA'] = timedelta(seconds=60)# Create database connection objectdb = SQLAlchemy(app)# creates the JWT Token authentication  ======================================jwt = JWT(app)@jwt.authentication_handlerdef authenticate(username, password):    user = user_datastore.find_user(email=username)    print '%s vs. %s' % (username, user.email)    if username == user.email and password == user.password:        return user    return None@jwt.user_handlerdef load_user(payload):    user = user_datastore.find_user(id=payload['user_id'])    return user# Define Flask-security models ===============================================roles_users = db.Table('roles_users',        db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),        db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))class Role(db.Model, RoleMixin):    id = db.Column(db.Integer(), primary_key=True)    name = db.Column(db.String(80), unique=True)    description = db.Column(db.String(255))class User(db.Model, UserMixin):    id = db.Column(db.Integer, primary_key=True)    email = db.Column(db.String(255), unique=True)    password = db.Column(db.String(255))    active = db.Column(db.Boolean())    confirmed_at = db.Column(db.DateTime())    roles = db.relationship('Role', secondary=roles_users,                            backref=db.backref('users', lazy='dynamic'))#Some additional stuff to query over...class SomeStuff(db.Model):    __tablename__ = 'somestuff'    id = db.Column(db.Integer, primary_key=True)    data1 = db.Column(db.Integer)    data2 = db.Column(db.String(10))    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=True)    user = db.relationship(User, lazy='joined', join_depth=1, viewonly=True)# Setup Flask-Securityuser_datastore = SQLAlchemyUserDatastore(db, User, Role)security = Security(app, user_datastore)# Flask-Restless API ==========================================================@jwt_required()def auth_func(**kw):    return Trueapimanager = APIManager(app, flask_sqlalchemy_db=db)apimanager.create_api(SomeStuff,    methods=['GET', 'POST', 'DELETE', 'PUT'],    url_prefix='/api/v1',    collection_name='free_stuff',    include_columns=['data1', 'data2', 'user_id'])apimanager.create_api(SomeStuff,    methods=['GET', 'POST', 'DELETE', 'PUT'],    url_prefix='/api/v1',    preprocessors=dict(GET_SINGLE=[auth_func], GET_MANY=[auth_func]),    collection_name='protected_stuff',    include_columns=['data1', 'data2', 'user_id'])# Create some users to test with@app.before_first_requestdef create_user():    db.create_all()    user_datastore.create_user(email='test', password='test')    user_datastore.create_user(email='test2', password='test2')    ###    stuff = SomeStuff(data1=2, data2='toto', user_id=1)    db.session.add(stuff)    stuff = SomeStuff(data1=5, data2='titi', user_id=1)    db.session.add(stuff)    db.session.commit()# Views@app.route('/')@login_requireddef home():    print(request.headers)    return render_template('index.html')@app.route('/logout/')def log_out():    logout_user()    return redirect(request.args.get('next') or '/')if __name__ == '__main__':    app.run()

Then, to interact with it via requests:

>>>  import requests, json   >>>  r=requests.get('http://127.0.0.1:5000/api/v1/free_stuff')  # this is OK   >>>  print 'status:', r.status_codestatus: 200   >>>  r=requests.get('http://127.0.0.1:5000/api/v1/protected_stuff')  # this should fail   >>>  print 'status:', r.status_codestatus: 401   >>>  print r.json(){u'status_code': 401, u'description': u'Authorization header was missing', u'error':    u'Authorization Required'}   >>>  # Authenticate and retrieve Token   >>>  r = requests.post('http://127.0.0.1:5000/auth', ...:                   data=json.dumps({'username': 'test', 'password': 'test'}),...:                   headers={'content-type': 'application/json'}...:                   )   >>>  print 'status:', r.status_codestatus: 200   >>>  token = r.json()['token']   >>>  # now we have the token, we can navigate to restricted area:   >>>  r = requests.get('http://127.0.0.1:5000/api/v1/protected_stuff', ...:                   headers={'Authorization': 'Bearer %s' % token})   >>>  print 'status:', r.status_codestatus: 200 


Your original query (of using python requests module) helped me get unstuck :)I did not do anything different.

I am not using Flask-Restless (yet)

FWIW - I was able to get the auth token using "just" Flask-Security (i.e. without having to use Flask-jwt)

See here for details