Source code for aiohttp_json_api.middleware

"""Middleware."""
from aiohttp import hdrs

from .common import (
    JSONAPI, JSONAPI_CONTENT_TYPE, JSONAPI_CONTENT_TYPE_PARSED,
    logger
)
from .errors import (
    Error, ErrorList, HTTPUnsupportedMediaType, HTTPNotAcceptable
)
from .helpers import best_match, get_mime_type_params
from .utils import error_to_response


[docs]async def jsonapi_middleware(app, handler): """Middleware for handling JSON API errors.""" async def middleware_handler(request): try: route_name = request.match_info.route.name namespace = request.app[JSONAPI]['routes_namespace'] if route_name and route_name.startswith('%s.' % namespace): request_ct = request.headers.get(hdrs.CONTENT_TYPE) content_type_error = \ f"Content-Type '{JSONAPI_CONTENT_TYPE}' is required." if request_ct is None and request.has_body: raise HTTPUnsupportedMediaType(detail=content_type_error) if (request_ct is not None and request_ct != JSONAPI_CONTENT_TYPE): raise HTTPUnsupportedMediaType(detail=content_type_error) accept_header = request.headers.get(hdrs.ACCEPT, '*/*') matched_mt, parsed_mt = best_match( (JSONAPI_CONTENT_TYPE,), accept_header ) if matched_mt != JSONAPI_CONTENT_TYPE: raise HTTPNotAcceptable() if JSONAPI_CONTENT_TYPE_PARSED[:2] == parsed_mt[:2]: additional_params = get_mime_type_params(parsed_mt) if additional_params: formatted = ','.join( f'{k}={v}' for k, v in additional_params.items() ) detail = (f'JSON API media type is modified ' f'with media type parameters. ({formatted})') raise HTTPNotAcceptable(detail=detail) return await handler(request) except Exception as exc: if isinstance(exc, (Error, ErrorList)): if app[JSONAPI]['log_errors']: logger.exception(exc) return error_to_response(request, exc) else: raise return middleware_handler