Source

audrid / audrid / views / api.py

Full commit
# coding: utf-8
"""
API methods.
"""

from audrid import (app, db)
from audrid.utils import (random_id)
from audrid import validators as V
from audrid.models import Document, Log, User, Exam, Audit
from flask import (jsonify, request)
from functools import wraps
import json
import datetime

def authorization_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        try:
            username = request.authorization.username
            user_obj = User.query.filter_by(username=username).first()
            if not user_obj.password == request.authorization.password:
                return jsonify({"message" : "Not authorized"}), 401
        except Exception as exc:
            return jsonify({"message" : "Not authorized"}), 401
        # app.logger.debug('successfully authenticated %s' % user_obj)
        kwargs.update({"user" : user_obj})
        return f(*args, **kwargs)
    return decorated_function

@app.route('/api/v1/info', methods=['GET'])
@authorization_required
def info(user=None):
    return jsonify(info='Audrid API', version="1")

@app.route('/api/v1/pools', methods=['GET'])
@authorization_required
def pools_get(user=None):
    docs = Document.query.filter_by(deleted=False).filter_by(type='pool').all()
    bodies = [ d.to_python() for d in docs ]
    return jsonify(pools=bodies)

@app.route('/api/v1/pools', methods=['POST'])
@authorization_required
def pools_post(user=None):
    # validation
    try:
        pool = V.pool(json.loads(request.data))
    except Exception as exc:
        # app.logger.error(exc)
        return jsonify(message='error during validation: %s' % exc), 400
    
    # create the document and log entry
    try:
        doc = Document(id=pool['id'], body=json.dumps(pool), type='pool')
        db.session.add(doc)
        db.session.flush()
        log = Log(
            document_id=pool['id'], 
            body=json.dumps(pool), 
            tag='pool_created', 
            user_id=user.id, 
            date=datetime.datetime.now())
        db.session.add(log)
        db.session.commit()        
    except Exception as exc:
        # app.logger.error(exc)
        db.session.rollback()
        return jsonify(message='storage error: %s' % exc), 400

    return jsonify(message='ok')

@app.route('/api/v1/pools', methods=['DELETE'])
@authorization_required
def pools_delete(user=None):
    try:
        docs = Document.query.filter_by(deleted=False).all()
        for doc in docs:
            doc.deleted = True
            db.session.add(doc)
            db.session.flush()
            log = Log(
                document_id=doc.id, 
                body=json.dumps({}),
                tag='pool_deleted', 
                user_id=user.id, 
                date=datetime.datetime.now())
        db.session.commit()
    except Exception as exc:
        # app.logger.error(exc)
        db.session.rollback()
        return jsonify(message='storage error: %s' % exc), 400

    return jsonify(message='ok')

@app.route('/api/v1/exams', methods=['GET'])
@authorization_required
def exams_get_all(user=None):
    return jsonify(exams=[ e.as_dict() for e in Exam.query.filter_by(deleted=False).all() ])

@app.route('/api/v1/exams', methods=['POST'])
@authorization_required
def exams_post(user=None):
    try:
        exam_dict = V.exam(json.loads(request.data))
    except Exception as exc:
        return jsonify(message='error during validation: %s' % exc), 400
    try:
        exam = Exam(**exam_dict)
        db.session.add(exam)
        db.session.commit()
    except Exception as exc:
        return jsonify(message='storage error: %s' % exc), 400
    return jsonify(message='ok')

@app.route('/api/v1/exams', methods=['DELETE'])
@authorization_required
def exams_delete(user=None):
    exams = Exam.query.filter_by(deleted=False).all()
    for e in exams:
        e.deleted = True
        db.session.add(e)
        db.session.flush()
    db.session.commit()
    return jsonify(message='ok')

@app.route('/api/v1/audits', methods=['GET'])
@authorization_required
def audits_get_all(user=None):
    return jsonify(audits=[ a.as_dict() for a in Audit.query.filter_by().all() ])

@app.route('/api/v1/audits', methods=['POST'])
@authorization_required
def audits_post(user=None):
    try:
        audit_dict = V.audit(json.loads(request.data))
    except Exception as exc:
        return jsonify(message='error during validation: %s' % exc), 400
    try:
        exam = Exam.query.filter_by(id=audit_dict['exam_id']).first_or_404()
        pool = Document.query.filter_by(id=exam.pool_id).first_or_404()

        trial_id = random_id()
        
        doc = Document(id=trial_id, body=json.dumps({'pool' : pool.to_python(),  'id' : trial_id}), type='trial')
        db.session.add(doc)
        db.session.flush()

        log = Log(
            document_id=doc.id, 
            body=json.dumps({}),
            tag='trial_created', 
            user_id=user.id, 
            date=datetime.datetime.now())
        db.session.add(log)
        db.session.flush()

        audit_dict.update({'trial_id' : trial_id})
        audit = Audit(**audit_dict)
        db.session.add(audit)
        db.session.commit()

    except Exception as exc:
        app.logger.error(exc)
        return jsonify(message='storage error: %s' % exc), 400
    return jsonify(message='ok')

@app.route('/api/v1/audits', methods=['DELETE'])
@authorization_required
def audits_delete(user=None):
    try:
        audits = Audit.query.filter_by(status='registered').all()
        for audit in audits:
            doc = Document.query.filter_by(id=audit.trial_id).first()
            doc.deleted = True
            log = Log(
                document_id=audit.trial_id, 
                body=json.dumps({}),
                tag='trial_deleted', 
                user_id=user.id, 
                date=datetime.datetime.now())
            db.session.add(log) 
            db.session.add(doc)
            db.session.delete(audit)
        db.session.commit()
    except Exception as exc:
        app.logger.error(exc)
        return jsonify(message='storage error: %s' % exc), 400
    return jsonify(message='ok')