Beispiel #1
0
def create_app(atm, debug=False):
    db = atm.db
    app = Flask(__name__)
    app.config['DEBUG'] = debug
    app.config['SQLALCHEMY_DATABASE_URI'] = make_absolute(db.engine.url)

    # Create the Flask-Restless API manager.
    manager = APIManager(app, flask_sqlalchemy_db=SQLAlchemy(app))

    # Allow the CORS header
    @app.after_request
    def add_cors_headers(response):
        response.headers[
            'Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
        response.headers['Access-Control-Allow-Origin'] = '*'
        response.headers['Access-Control-Allow-Credentials'] = 'true'
        return response

    @app.route('/api/run', methods=['POST'])
    @auto_abort((KeyError, ValueError))
    def atm_run():
        data = request.json
        run_conf = RunConfig(data)

        dataruns = atm.add_datarun(**run_conf.to_dict())
        if not isinstance(dataruns, list):
            dataruns = [dataruns]

        response = {
            'status': 200,
            'datarun_ids': [datarun.id for datarun in dataruns]
        }

        return jsonify(response)

    @app.route('/')
    def swagger():
        return redirect('/static/swagger/swagger-ui/index.html')

    # Create API endpoints, which will be available at /api/<tablename> by
    # default. Allowed HTTP methods can be specified as well.
    manager.create_api(db.Dataset, methods=['GET', 'POST'])
    manager.create_api(db.Datarun, methods=['GET'])
    manager.create_api(db.Hyperpartition, methods=['GET'])
    manager.create_api(db.Classifier, methods=['GET'])

    return app
Beispiel #2
0
def create_app(atm, debug=False):
    db = atm.db
    app = Flask(__name__)
    app.config['DEBUG'] = debug
    app.config['SQLALCHEMY_DATABASE_URI'] = make_absolute(db.engine.url)

    # Create the Flask-Restless API manager.
    manager = APIManager(app, flask_sqlalchemy_db=SQLAlchemy(app))

    @app.route('/api/run', methods=['POST'])
    @auto_abort((KeyError, ValueError))
    def atm_run():
        data = request.json
        run_conf = RunConfig(data)

        dataruns = atm.create_dataruns(run_conf)

        response = {
            'status': 200,
            'datarun_ids': [datarun.id for datarun in dataruns]
        }

        return jsonify(response)

    @app.route('/')
    def swagger():
        return redirect('/static/swagger/swagger-ui/index.html')

    # Create API endpoints, which will be available at /api/<tablename> by
    # default. Allowed HTTP methods can be specified as well.
    manager.create_api(db.Dataset, methods=['GET', 'POST'])
    manager.create_api(db.Datarun, methods=['GET'])
    manager.create_api(db.Hyperpartition, methods=['GET'])
    manager.create_api(db.Classifier, methods=['GET'])

    return app
Beispiel #3
0
from flask import request, make_response, render_template
from flask.ext.sqlalchemy import SQLAlchemy
from .models import Base
from api import config
from .forms import UserForm
from .models import User, Data, Device
from flask_restful import Resource, Api, reqparse, abort
#from flask.ext.restless import APIManager
from flask_restless_swagger import SwagAPIManager as APIManager

app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app)
db.Model = Base
api = Api(app)
manager = APIManager(app, flask_sqlalchemy_db=db)

manager.create_api(User,
                   methods=['GET', 'POST', 'DELETE', 'PUT'],
                   collection_name='user',
                   results_per_page=5,
                   allow_functions=True)
manager.create_api(Device,
                   methods=['GET', 'POST', 'DELETE', 'PUT'],
                   collection_name='device',
                   results_per_page=5,
                   allow_functions=True)
manager.create_api(Data,
                   methods=['GET', 'POST', 'DELETE', 'PUT'],
                   collection_name='data',
                   results_per_page=5,
Beispiel #4
0
def create_app(ini_file=DEFAULT_INI_FILE):
    app = Flask(__name__)
    INIConfig(app)
    app.config.from_inifile(ini_file)
    app.secret_key = app.config['common']['secret_key']
    if app.config.get('sentry', {}).get('dsn') is not None:
        sentry.init_app(app,
                        dsn=app.config['sentry']['dsn'],
                        logging=True,
                        level=logging.ERROR)
    strict = int(app.config['common'].get('strict_update', 0))
    sqluri = os.environ.get('SQLURI')
    if sqluri is None:
        sqluri = app.config['common']['sqluri']
    app.db = init(sqluri)

    preprocessors = {}
    for method in ('POST_RESOURCE', 'PATCH_RESOURCE', 'DELETE_RESOURCE',
                   'POST_RELATIONSHIP', 'PATCH_RELATIONSHIP',
                   'DELETE_RELATIONSHIP'):
        preprocessors[method] = [partial(add_timestamp, strict, method)]

    app.db.session = Session()
    if 'whoosh' in app.config and 'path' in app.config['whoosh']:
        _SEARCH['WHOOSH_BASE'] = app.config['whoosh']['path']

    get_indexer(_SEARCH, app.db.session)
    app.register_blueprint(search)
    app.register_blueprint(heartbeat)

    manager = APIManager(app,
                         flask_sqlalchemy_db=app.db,
                         preprocessors=preprocessors)

    methods = ['GET', 'POST', 'DELETE', 'PATCH', 'PUT']

    for model in published:
        manager.create_api(model,
                           methods=methods,
                           serializer_class=JsonSerializer,
                           page_size=50,
                           allow_to_many_replacement=True,
                           allow_delete_from_to_many_relationships=True)

    @app.route('/api/')
    def get_models():
        models = []
        for model in published:
            name = model.__table__.name
            inspected = sa_inspect(model)
            # XXX collection name may vary
            primary_key = [key.name for key in inspected.primary_key]
            model = {
                'name': name,
                'primary_key': primary_key,
                'collection_name': name
            }
            model['relationships'] = {}

            for name, relationship in inspected.relationships.items():
                rel = {'target': relationship.target.name}
                model['relationships'][name] = rel

            models.append(model)

        return jsonify({'models': models})

    @app.after_request
    def set_etag(response):
        if request.blueprint in ('swagger', 'heartbeat'):
            return response

        if request.path.rstrip('/') == '/api':
            return response

        if response.status_code > 399:
            return response

        # suboptimal: redeserialization
        # XXX use six
        try:
            result = json.loads(str(response.data, 'utf8'))
        except TypeError:
            result = json.loads(str(response.data))

        data = result.get('data')
        last_modified = None

        # hackish - it depends on url routes XXX
        relation_name = request.view_args.get('relation_name')
        resource_id = request.view_args.get('resource_id')
        api = 'api' in g and g.api or None

        # the relationship was changed
        if (request.method in ('POST', 'PATCH') and relation_name
                and response.status_code == 204):
            # let's update the parent timestamp
            instance = get_by(api.session, api.model, resource_id)
            instance.last_modified = g.last_modified

        # we're sending back some data
        if data is not None:
            if 'last_modidied' in data:
                last_modified = data['last_modified']
            elif api:
                instance = get_by(api.session, api.model, resource_id)
                if instance and hasattr(instance, 'last_modified'):
                    last_modified = instance.last_modified

        # empty response
        else:
            if response.status_code == 204:
                # we did change it, we need to resend the ETag
                last_modified = g.last_modified
            else:
                last_modified = None

            if 'Content-Type' in response.headers:
                response.headers.remove('Content-Type')

        etag = last_modified and str(last_modified) or None

        # checking If-None-Match on GET calls
        if (request.method == 'GET' and request.if_none_match):
            if etag and etag in request.if_none_match:
                return NotModified()

        # adding an ETag header
        if etag:
            response.set_etag(etag)

        return response

    @app.before_request
    def before_req():
        authenticate(app, request)
        g.debug = _DEBUG

    logging.config.fileConfig(ini_file)
    return app