Changeset View
Changeset View
Standalone View
Standalone View
swh/web/api/views/utils.py
# Copyright (C) 2015-2019 The Software Heritage developers | # Copyright (C) 2015-2019 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU Affero General Public License version 3, or any later version | # License: GNU Affero General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
from types import GeneratorType | |||||
from typing import Callable, Any, Optional, Mapping, Dict | |||||
from typing_extensions import Protocol | |||||
from django.http import HttpRequest | |||||
from rest_framework.response import Response | from rest_framework.response import Response | ||||
from rest_framework.decorators import api_view | from rest_framework.decorators import api_view | ||||
from types import GeneratorType | |||||
from swh.web.common.exc import NotFoundExc | from swh.web.common.exc import NotFoundExc | ||||
from swh.web.api.apiurls import APIUrls, api_route | from swh.web.api.apiurls import APIUrls, api_route | ||||
def api_lookup(lookup_fn, *args, | class EnrichFunction(Protocol): | ||||
notfound_msg='Object not found', | def __call__(self, input: Mapping[str, str], | ||||
enrich_fn=None): | request: Optional[HttpRequest]) -> Dict[str, str]: ... | ||||
def api_lookup(lookup_fn: Callable[..., Any], *args: Any, | |||||
notfound_msg: Optional[str] = 'Object not found', | |||||
enrich_fn: Optional[EnrichFunction] = None, | |||||
request: Optional[HttpRequest] = None): | |||||
r""" | r""" | ||||
Capture a redundant behavior of: | Capture a redundant behavior of: | ||||
- looking up the backend with a criteria (be it an identifier or | - looking up the backend with a criteria (be it an identifier or | ||||
checksum) passed to the function lookup_fn | checksum) passed to the function lookup_fn | ||||
- if nothing is found, raise an NotFoundExc exception with error | - if nothing is found, raise an NotFoundExc exception with error | ||||
message notfound_msg. | message notfound_msg. | ||||
- Otherwise if something is returned: | - Otherwise if something is returned: | ||||
- either as list, map or generator, map the enrich_fn function to | - either as list, map or generator, map the enrich_fn function to | ||||
it and return the resulting data structure as list. | it and return the resulting data structure as list. | ||||
- either as dict and pass to enrich_fn and return the dict | - either as dict and pass to enrich_fn and return the dict | ||||
enriched. | enriched. | ||||
Args: | Args: | ||||
- lookup_fn: function expects one criteria and optional supplementary | - lookup_fn: function expects one criteria and optional supplementary | ||||
\*args. | \*args. | ||||
- \*args: supplementary arguments to pass to lookup_fn. | |||||
- notfound_msg: if nothing matching the criteria is found, | - notfound_msg: if nothing matching the criteria is found, | ||||
raise NotFoundExc with this error message. | raise NotFoundExc with this error message. | ||||
- enrich_fn: Function to use to enrich the result returned by | - enrich_fn: Function to use to enrich the result returned by | ||||
lookup_fn. Default to the identity function if not provided. | lookup_fn. Default to the identity function if not provided. | ||||
- \*args: supplementary arguments to pass to lookup_fn. | - request: Input HTTP request that will be provided as parameter | ||||
to enrich_fn. | |||||
Raises: | Raises: | ||||
NotFoundExp or whatever `lookup_fn` raises. | NotFoundExp or whatever `lookup_fn` raises. | ||||
""" | """ | ||||
if enrich_fn is None: | if enrich_fn is None: | ||||
enrich_fn = (lambda x: x) | enrich_fn = (lambda x, request: x) | ||||
res = lookup_fn(*args) | res = lookup_fn(*args) | ||||
if res is None: | if res is None: | ||||
raise NotFoundExc(notfound_msg) | raise NotFoundExc(notfound_msg) | ||||
if isinstance(res, (map, list, GeneratorType)): | if isinstance(res, (list, GeneratorType)) or type(res) == map: | ||||
return [enrich_fn(x) for x in res] | return [enrich_fn(x, request=request) for x in res] | ||||
return enrich_fn(res) | return enrich_fn(res, request=request) | ||||
@api_view(['GET', 'HEAD']) | @api_view(['GET', 'HEAD']) | ||||
def api_home(request): | def api_home(request): | ||||
return Response({}, template_name='api/api.html') | return Response({}, template_name='api/api.html') | ||||
APIUrls.add_url_pattern(r'^$', api_home, view_name='api-1-homepage') | APIUrls.add_url_pattern(r'^$', api_home, view_name='api-1-homepage') | ||||
Show All 15 Lines |