Reputation: 503
I am trying to use Flask-appbuilder in an IoT project. So, FAB is used for rapid application buildup and we need dedicated RESTful API for Mobile App and 3rd party service suppliers.
In FAB, there is an implementation for RESTful API, as subclass of BaseCURDView. Most URL is defined as
http://host//api/list
If the mobile app acts as an user agent like browser, it collect username/password, login and access FAB's RESTful API, then permissions, url is not a big deal, everything can follow B/S programming. AKA, all security model is based upon cookie and session. Most of the request information are inside the flask.g.user/flask.request.*.
If the webapp has to support more standard style RESTful API, as described in flask books by miguel. The external webapp has to embed the api key/secret to specified url to exchange token, then use token in header or http parameters to access resources for CRUD operations.
http://host/api/v1/get_token
header:api_key:balabalabala
header:api_secret:abcdefxyz
return {'token':'1234567890'}
http://host/api/v1/resource
header:token:1234567890
return {'resource':'abcdefghijk'}
I have successfully merged them together in FAB's views.py.
from flask import render_template
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder import ModelView, BaseView, expose
from app import appbuilder, db
from flask import Flask, jsonify
from flask import abort
from flask import make_response
from flask import request
from flask import url_for
tasks = [
{
'id': 1,
'title': u'Buy groceries',
'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
'done': False
},
{
'id': 2,
'title': u'Learn Python',
'description': u'Need to find a good python tutorial',
'done': False
}
]
def make_public_task(task):
new_task = {}
for field in task:
if field == 'id':
new_task['uri'] = url_for('get_task', task_id=task['id'], _external=True)
else:
new_task[field] = task[field]
return new_task
class ApiView(BaseView):
route_base = "/api/v1"
default_view = "index"
@expose("/index")
def index(self):
#return jsonify({'tasks': map(make_public_task, tasks)})
print repr(request.args)
print repr(request.method)
print repr(request.headers)
return jsonify(tasks)
@expose("/get_token")
def get_token(self):
print repr(request.headers)
return jsonify({'res': True})
@expose("/get_resource")
def get_resource(self):
return jsonify({'res': False})
@expose("/del_resource")
def del_resource(self):
return jsonify({'res': False})
"""
Application wide 404 error handler
"""
@appbuilder.app.errorhandler(404)
def page_not_found(e):
return render_template('404.html', base_template=appbuilder.base_template, appbuilder=appbuilder), 404
db.create_all()
appbuilder.add_view_no_menu(ApiView())
Yes, I can implement standard RESTful API just I did in another flask project with http headers and custom queries with sqlalchemy. But I am not sure if it is the proper way to do that. Since most of the data are requested directly from sqlalchemy raw queries, they are quite different programming experiences.
Open for any suggestions, before moving forward.
Upvotes: 0
Views: 1563
Reputation: 503
Actually FAB's REST API is designed for AJAX, so for mobile app and 3rd party applications, we need a seperate RESTful API, which can follow flask megatutorial and best practice and resue REST-auth library from Miguel.
FAB can work with both anyway.
Upvotes: 0