Commit 525df442 authored by Jakob Moser's avatar Jakob Moser
Browse files

Add API stub

parent 71d147ed
Loading
Loading
Loading
Loading

clams/api.py

0 → 100644
+23 −0
Original line number Diff line number Diff line
from typing import Optional, Any
from flask import Blueprint
from clams.problem_details import not_found

bp = Blueprint("api", __name__, url_prefix="/api/v1")


@bp.get("/<path:_>")
def fallback_not_found(_):
    """
    If you can't find a matching API endpoint, fallback to returning a 404.

    We completely ignore the provided path (hence the argument name "_" and not something useful),
    because if this method is ever reached, we already know the only viable response is a 404.
    """
    return _404_or(None)


def _404_or(thing: Optional[Any]) -> Any:
    """
    Return either the thing if it is not None, or a 404 message and status code
    """
    return thing if thing is not None else not_found()
+37 −0
Original line number Diff line number Diff line
"""
Provide RFC 7807-compliant problem details responses for the API.
"""
from typing import Optional


def unauthorized():
    """
    Return a 401 message and status code
    """
    return _problem_response(title="Unauthorized", status=401)


def not_found():
    """
    Return a 404 message and status code
    """
    return _problem_response(title="Not Found", status=404)


def _problem_response(
    title: str,
    status: int,
    type_uri: Optional[str] = None,
    extensions: Optional[dict] = None,
) -> tuple[dict, int, dict]:
    type_dict = {"type": type_uri} if type_uri is not None else {}
    title_dict = {"title": title}

    # Combine the type_dict, title_dict and extensions (if provided) into one response dictionary
    response_dict = type_dict | title_dict | (extensions or {})

    return (
        response_dict,
        status,
        {"Content-Type": "application/problem+json"},
    )