Ejemplo n.º 1
0
def read_by_id(model: str, _id: int) -> Tuple[Response, int]:
    """
    Get an item in the model DB by ID from URL path and cache the result

    Args:
        model (str): Name of model of the item to request by ID
        _id (int): ID of the item being requested

    Raises:
        NotFound: Item does not exist
        BadRequest: Model does not exist

    Returns:
        Tuple[Response, int]: Flask Response & HTTP status code
    """
    try:
        item = models[model].query.filter_by(id=_id).first()

        if not item:
            raise NotFound(f"{model} {_id} does not exist")

        responder = Responder()
        responder.results.append(item.as_dict)
        return responder.succeed()

    except KeyError:
        raise BadRequest(f"{model} does not exist")
Ejemplo n.º 2
0
def create(model: str) -> Tuple[Response, int]:
    """
    Create model item, adding it to the database.

    Args:
        model (str): Name of model of the item to create

    Raises:
        BadRequest: Improper/missing POST data
        BadRequest: Model does not exist
        Conflict: Item already exists

    Returns:
        Tuple[Response, int]: Flask Response & HTTP status code
    """
    try:
        item = models[model](**load_json(request.data))
        item.save()

        responder = Responder()
        responder.results.append(item.as_dict)
        return responder.succeed(msg=f"Created {item}")

    except TypeError:
        raise BadRequest(f"Improper/missing POST data")

    except KeyError:
        raise BadRequest(f"{model} does not exist")

    except IntegrityError:
        raise Conflict(f"{item} already exists")
Ejemplo n.º 3
0
def index() -> Tuple[Response, int]:
    """
    Responds with basic 'Hello World'

    Returns:
        Tuple[Response, int]: Flask Response & HTTP status code
    """
    from app.utilities.responder import Responder
    responder = Responder()
    return responder.succeed(msg="Hello World!")
Ejemplo n.º 4
0
def delete(model: str, _id: int) -> Tuple[Response, int]:
    """
    Delete model item's record from the database by ID

    Args:
        model (str): Name of model of the item to delete by ID
        _id (int): ID of the item being deleted

    Raises:
        NotFound: Item does not exist
        BadRequest: Model does not exist

    Returns:
        Tuple[Response, int]: Flask Response & HTTP status code
    """
    try:
        item = models[model].query.filter_by(id=_id).first()

        if not item:
            raise NotFound(f"{model} {_id} does not exist")

        item.delete()

        return Responder().succeed(msg=f"Deleted {model} {_id}!")

    except KeyError:
        raise BadRequest(f"{model} does not exist")
Ejemplo n.º 5
0
def update(model: str, _id: int) -> Tuple[Response, int]:
    """
    Update model item's record in the database by ID

    Args:
        model (str): Name of model of the item to update by ID
        _id (int): ID of the item being updated

    Raises:
        NotFound: Item does not exist
        BadRequest: Improper/missing POST data
        BadRequest: Model does not exist
        Conflict: Item in updated state already exists (idempotency)

    Returns:
        Tuple[Response, int]: Flask Response & HTTP status code
    """
    try:
        item = models[model].query.filter_by(id=_id).first()
        item.update(id=_id, **load_json(request.data))

        return Responder().succeed(msg=f"Updated {model} {_id}")

    except AttributeError:
        raise NotFound(f"{model} {_id} does not exist")

    except TypeError:
        raise BadRequest(f"Improper/missing POST data")

    except KeyError:
        raise BadRequest(f"{model} does not exist")

    except IntegrityError:
        raise Conflict(f"Item already exists")
def generic_http_handler(http_exc: Exception) -> Tuple[Response, int]:
    """
    A handler for HTTP exceptions via werkzeug.exceptions

    Args:
        http_exc (Exception): werkzeug.exceptions exception

    Returns:
        Tuple[Response, int]: Flask Response & HTTP status code
    """
    return Responder().fail(msg=http_exc.description, http_code=http_exc.code)
def sqlalchemy_conn_handler(exc: OperationalError) -> Tuple[Response, int]:
    """
    A handler for sqlalchemy.exc.OperationalError

    Args:
        exc (OperationalError): SQL Alchemy operational error

    Returns:
        Tuple[Response, int]: Flask Response & HTTP status code
    """
    return Responder().fail(msg="Database error", http_code=500)
def redis_conn_handler(exc: ConnectionError) -> Tuple[Response, int]:
    """
    A handler for redis.exceptions.ConnectionError

    Args:
        exc (ConnectionError): Redis connection error

    Returns:
        Tuple[Response, int]: Flask Response & HTTP status code
    """
    return Responder().fail(msg="Cache error", http_code=500)
def generic_exception_handler(exc: Exception) -> Tuple[Response, int]:
    """
    A handler for any raised uncaught exceptions

    Args:
        exc (Exception): A raised uncaught exception

    Returns:
        Tuple[Response, int]: Flask Response & HTTP status code
    """
    return Responder().fail(msg="Something went wrong", http_code=500)
Ejemplo n.º 10
0
    def get_all_paginated_results(**kwargs) -> Tuple[Response, int]:
        """
        You may notice the kwargs object isn't used in this nested
        function, it is only used by the cache.memoize decorator, so
        that the results for pagination query params like 
        "?per_page=2&page=4" aren't cached the same as others like:
        "?per_page=3&page=2".

        Note: It may be faster/better to un-nest this later

        Returns:
            Tuple[Response, int]: Flask Response & HTTP status code
        """

        results = models[model].query.paginate(error_out=False)

        if not results:
            return Responder().succeed(msg=f"No {model} results found")

        responder = Responder()
        responder.results += [item.as_dict for item in results.items]
        responder.pagination = pagination_dict(results)

        return responder.succeed()