Exemple #1
0
    def setUp(self):
        """Define test variables and initialize app."""
        self.app = create_app()
        self.client = self.app.test_client
        self.database_path = environ.get(
            'DATABASE_URL_TEST',
            'postgresql://app_user@localhost:5432/casting_agency')

        setup_db(self.app, self.database_path)

        self.new_actor = {
            "name": "Elijah Wood",
            "gender": "male"
        }

        self.new_movie = {
            "title": "Lord of the Rings",
            "release_date": "2001-12-13",
            "actors": [1]
        }

        self.token_assistant = environ.get('ASSISTANT_TOKEN', '')
        self.token_director = environ.get('DIRECTOR_TOKEN', '')
        self.token_producer = environ.get('PRODUCER_TOKEN', '')

        # binds the app to the current context
        with self.app.app_context():
            self.db = SQLAlchemy()
            self.db.init_app(self.app)
    def setUp(self):
        """Define test variables and initialize app."""
        self.app = create_app()
        setup_db(self.app, env='test')
        self.client = self.app.test_client

        # binds the app to the current context
        with self.app.app_context():
            self.db = SQLAlchemy()
            self.db.init_app(self.app)
            # create all tables
            self.db.create_all()
Exemple #3
0
 def reset_db():
     reset_database()
     setup_db()
Exemple #4
0
import pymongo
from flask.helpers import make_response
from flask.templating import render_template
from flask import Flask, redirect, url_for, jsonify, request
from bson.objectid import ObjectId
from flask.wrappers import Response
from pytz import timezone

from config import setup_logging, setup_db
from lib import TimeFormat, convert_time_fields, TimePattern, convert_to_csv, TimePatternSimple, TimeFormatSimple, \
    parse_user_accept_languages
from run_import import import_checkins, run_import_dec, run_import_suc

logger = setup_logging()
db = setup_db()
suc_collection = db.suc
checkin_collection = db.checkin

tz_utc = timezone('UTC')
tz_zurich = timezone("Europe/Zurich")

max_distance = 20000
pattern_latlng = re.compile("(\d+\.\d+),(\d+\.\d+)")
legacy_nof_stalls = 10


class JSONEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, ObjectId):
            return str(o)
def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__)
    setup_db(app)

    cors = CORS(app, resources={r"/v1/*": {"origins": "*"}})

    @app.after_request
    def after_request(response):
        response.headers.add('Allow-Control-Allow-Headers',
                             'Content-Type,Authorization,true')
        response.headers.add('Allow-Control-Allow-Methods',
                             'GET, POST, DELETE, OPTIONS')

        return response

    @app.route('/v1/categories', methods=['GET'])
    def get_all_categories():

        categories = Category.query.all()

        if len(categories) == 0:
            abort(Not_found)

        # Create dictionary for categories {id -> type}
        data = {cate.id: cate.type for cate in categories}
        return jsonify({"success": True, "categories": data}), Ok

    @app.route('/v1/questions', methods=['GET'])
    def get_all_question():

        questions = Question.query.order_by(Question.id).all()
        # get page of questions
        page = request.args.get('page', 1, type=int)
        start = (page - 1) * QUESTIONS_PER_PAGE

        questions_page = Question.query.order_by(
            Question.id).limit(QUESTIONS_PER_PAGE).offset(start).all()

        categories = Category.query.all()
        categories_data = {cate.id: cate.type for cate in categories}

        # not found if no question or cateqories
        if len(questions) == 0 or len(categories) == 0\
                or len(questions_page) == 0:
            abort(Not_found)

        return jsonify({
            "success": True,
            "questions": [q.format() for q in questions_page],
            "total_questions": len(questions),
            "categories": categories_data
        }), Ok

    @app.route('/v1/questions/<int:question_id>', methods=['DELETE'])
    def delete_question(question_id):
        question = Question.query.get(question_id)
        if question is None:
            abort(Not_found)

        try:
            question.delete()
        except Exception as e:
            # not processable if can't delete the question
            print(e)
            abort(Not_processable)

        return jsonify({'success': True, 'deleted_id': question_id}), Ok

    @app.route('/v1/questions', methods=['POST'])
    def create_question():
        body = request.get_json()

        search_term = body.get('searchTerm', None)
        if search_term:

            # search for questions that has the search term (case insensitive)
            page = request.args.get('page', 1, type=int)
            start = (page - 1) * QUESTIONS_PER_PAGE
            questions = Question.query.filter(
                Question.question.ilike(f'%{search_term}%')).order_by(
                    Question.id).limit(QUESTIONS_PER_PAGE).offset(start).all()
            # not found if no questions
            if len(questions) == 0:
                abort(Not_found)

            return jsonify({
                'success': True,
                'questions': [q.format() for q in questions],
                'total_questions': len(questions)
            }), Ok

        else:
            question = body.get('question', None)
            answer = body.get('answer', None)
            difficulty = body.get('difficulty', None)
            category = body.get('category', None)

            # bad request if one of the required fields is missing
            if (question is None) or (answer is None) or\
                    (difficulty is None) or (category is None):
                abort(Bad_request)

            new_question = Question(question=question,
                                    answer=answer,
                                    difficulty=difficulty,
                                    category=category)

            try:
                new_question.insert()
            except Exception as e:
                # not processable if can't insert the question
                print(e)
                abort(Not_processable)

            questions = Question.query.all()

            return jsonify({
                'success': True,
                'created_id': new_question.id,
                'total_questions': len(questions)
            }), Created

    @app.route('/v1/categories/<int:category_id>/questions', methods=['GET'])
    def get_category_questions(category_id):

        category = Category.query.get(category_id)

        if category is None:
            abort(Not_found)

        page = request.args.get('page', 1, type=int)
        start = (page - 1) * QUESTIONS_PER_PAGE

        # get all question of that category
        questions = Question.query.filter(
            Question.category == category_id).order_by(
                Question.id).limit(QUESTIONS_PER_PAGE).offset(start).all()

        if len(questions) == 0:
            abort(Not_found)

        return jsonify({
            'success': True,
            'questions': [q.format() for q in questions],
            'total_questions': len(questions),
            'current_category': category.type
        }), Ok

    @app.route('/v1/quizzes', methods=['POST'])
    def play_quiz():
        body = request.get_json()

        # get the required parameters
        previous_questions = body.get('previous_questions', None)
        category = body.get('quiz_category', None)

        # Bad request if one of the required parameter is none
        if (previous_questions is None) or (category is None):
            abort(Bad_request)

        # get all question if id is 0
        if category['id'] == 0:
            questions = Question.query.all()
        # get all question of quiz category
        else:
            questions = Question.query.filter(
                Question.category == category['id']).all()

        if len(questions) == 0:
            abort(Not_found)

        if len(previous_questions) >= len(questions):
            return jsonify({
                'success': True,
                'message': "No more questions"
            }), Ok

        import numpy as np
        # make number of trials to avoid infinite loop
        trials = 0
        while trials <= 100:
            chosen_question = np.random.choice(questions, replace=True)
            if not (chosen_question.id in previous_questions):
                break
            trials += 1

        if trials > 100:
            abort(Not_found)

        return jsonify({'success': True, 'question': chosen_question.format()})

    @app.errorhandler(400)
    def bad_request(error):
        return jsonify({
            'success': False,
            'error_code': Bad_request,
            'message': "Bad Request"
        }), Bad_request

    @app.errorhandler(404)
    def not_found(error):
        return jsonify({
            "success": False,
            "message": "Not Found",
            "error_code": Not_found
        }), Not_found

    @app.errorhandler(405)
    def method_not_allowed(error):
        return jsonify({
            "success": False,
            "message": "Method not Allowed",
            "error_code": Method_not_allowed
        }), Method_not_allowed

    @app.errorhandler(422)
    def not_processable(error):
        return jsonify({
            'success': False,
            'error_code': Not_processable,
            'message': "Cannot be processed"
        }), Not_processable

    return app
Exemple #6
0
def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__)
    setup_db(app)
    CORS(app, resources={r"/*": {"origins": "*"}})

    @app.after_request
    def after_request(response):
        response.headers.add('Access-Control-Allow-Headers',
                             'Content-Type,Authorization,true')
        response.headers.add('Access-Control-Allow-Methods',
                             'GET,POST,PUT,DELETE,OPTIONS')
        return response

    # index for check health
    @app.route('/')
    def index():
        return jsonify({"success": True, "message": 'healthy'})

    # ----------------------------------------------------------------------- #
    # Actors
    # ----------------------------------------------------------------------- #
    '''
  Endpoint to handle GET requests for actors, including pagination (every 5)
  This endpoint return a list of actors, their names, and movies participating
  '''

    @app.route('/actors')
    @requires_auth('get:actors')
    def get_actors(payload):
        page = request.args.get('page', 1, type=int)
        actors = Actor.query.order_by(Actor.id)

        actors = actors.paginate(page=page, per_page=ACTORS_PER_PAGE)
        if actors is None:
            abort(404)

        return jsonify({
            "success": True,
            "actors": [actor.long() for actor in actors.items],
            "total": actors.total,
        })

    '''
  Endpoint to handle create an actor
  This endpoint return if success the actor ID, otherwise 400 or 422 errors
  '''

    @app.route('/actors', methods=['POST'])
    @requires_auth('create:actors')
    def create_actor(payload):
        body = request.get_json()

        if body is None:
            abort(400)

        name = body.get('name', None)
        gender = body.get('gender', None)

        if name is None or gender is None:
            abort(400)

        actor = Actor(name=name, gender=gender)
        try:
            actor.insert()
        except Exception:
            print(sys.exc_info())
            db.session.rollback()
            abort(422)

        return jsonify({"success": True, "actor": actor.id})

    '''
  Endpoint to handle update an actor
  This endpoint return if success the actor name and gender,
  otherwise 400 or 422 errors
  '''

    @app.route('/actors/<int:actor_id>', methods=['PATCH'])
    @requires_auth('update:actors')
    def update_actor(payload, actor_id):
        body = request.get_json()

        if body is None:
            abort(400)

        actor = Actor.query.filter_by(id=actor_id).one_or_none()
        if actor is None:
            abort(404)

        name = body.get('name', None)
        gender = body.get('gender', None)

        if name is None and gender is None:
            abort(400)

        if name is not None:
            actor.name = name

        if gender is not None:
            actor.gender = gender

        try:
            actor.update()
        except Exception:
            print(sys.exc_info())
            db.session.rollback()
            abort(422)

        return jsonify({"success": True, "actor": actor.short()})

    '''
  Endpoint to DELETE actor using a actor ID
  '''

    @app.route('/actors/<int:actor_id>', methods=['DELETE'])
    @requires_auth('delete:actors')
    def delete_actor(payload, actor_id):
        actor = Actor.query.filter_by(id=actor_id).one_or_none()
        if actor is None:
            abort(404)

        try:
            actor.delete()
        except Exception:
            print(sys.exc_info())
            db.session.rollback()
            abort(422)

        return jsonify({'success': True, 'deleted': actor_id})

    # ----------------------------------------------------------------------- #
    # Movies
    # ----------------------------------------------------------------------- #
    '''
  Endpoint to handle GET requests for movies, including pagination (every 5)
  This endpoint return a list of movies, their title, release_date
  and actors cast
  '''

    @app.route('/movies')
    @requires_auth('get:movies')
    def get_movies(payload):
        page = request.args.get('page', 1, type=int)
        movies = Movie.query.order_by(Movie.id)

        movies = movies.paginate(page=page, per_page=MOVIES_PER_PAGE)
        if movies is None:
            abort(404)

        return jsonify({
            "success": True,
            "total": movies.total,
            "movies": [movie.long() for movie in movies.items],
        })

    '''
  Endpoint to handle create a new movie
  This endpoint return if success the movie ID, otherwise 400 or 422 errors
  '''

    @app.route('/movies', methods=['POST'])
    @requires_auth('create:movies')
    def create_movie(payload):
        body = request.get_json()

        if body is None:
            abort(400)

        title = body.get('title', None)
        release_date = body.get('release_date', None)
        actors = body.get('actors', None)

        if title is None or release_date is None or actors is None:
            abort(400)

        movie = Movie(title=title, release_date=release_date)
        try:
            movie.insert()
        except Exception:
            print(sys.exc_info())
            db.session.rollback()
            abort(422)

        for actor in actors:
            cast = Cast(movie_id=movie.id, actor_id=actor)
            cast.insert()

        return jsonify({"success": True, "movie": movie.id})

    '''
  Endpoint to handle update a movie
  This endpoint return if success the movie title, release_date and cast,
  otherwise 400 or 422 errors
  '''

    @app.route('/movies/<int:movie_id>', methods=['PATCH'])
    @requires_auth('update:movies')
    def update_movie(payload, movie_id):
        body = request.get_json()

        if body is None:
            abort(400)

        movie = Movie.query.filter_by(id=movie_id).one_or_none()
        if movie is None:
            abort(404)

        title = body.get('title', None)
        release_date = body.get('release_date', None)
        actors = body.get('actors', None)

        if title is None and release_date is None and actors is None:
            abort(400)

        if title is not None:
            movie.title = title

        if release_date is not None:
            movie.release_date = release_date

        if actors is not None:
            movie.actors = actors

        try:
            movie.update()
        except Exception:
            print(sys.exc_info())
            db.session.rollback()
            abort(422)

        return jsonify({"success": True, "movie": movie.long()})

    '''
  Endpoint to DELETE movie using a movie ID
  '''

    @app.route('/movies/<int:movie_id>', methods=['DELETE'])
    @requires_auth('delete:movies')
    def delete_movie(payload, movie_id):
        movie = Movie.query.filter_by(id=movie_id).one_or_none()
        if movie is None:
            abort(404)

        try:
            movie.delete()
        except Exception:
            print(sys.exc_info())
            db.session.rollback()
            abort(422)

        return jsonify({'success': True, 'deleted': movie_id})

    # ----------------------------------------------------------------------- #
    # Error handlers for expected errors
    # imported from previous udacity projects
    # ----------------------------------------------------------------------- #

    @app.errorhandler(400)
    def bad_request(error):
        return jsonify({
            "error": 400,
            "message": "Bad request",
            "success": False
        }), 400

    @app.errorhandler(404)
    def not_found(error):
        return jsonify({
            "error": 404,
            "message": "Resource could not be found",
            "success": False
        }), 404

    @app.errorhandler(405)
    def unprocessable(error):
        return jsonify({
            "error": 405,
            "message": "Method not allowed",
            "success": False
        }), 405

    @app.errorhandler(422)
    def unprocessable(error):
        return jsonify({
            "error": 422,
            "message": "Request could not be processable",
            "success": False
        }), 422

    @app.errorhandler(500)
    def unprocessable(error):
        return jsonify({
            "error": 500,
            "message": "Internal server error",
            "success": False
        }), 500

    @app.errorhandler(AuthError)
    def auth_error(error):
        return jsonify({
            "success": False,
            "error": error.status_code,
            "message": error.error['description']
        }), error.status_code

    return app