Source code for magpie.ui.utils

from magpie.definitions.pyramid_definitions import exception_response, Request, HTTPBadRequest
from magpie.utils import get_header, CONTENT_TYPE_JSON
from typing import TYPE_CHECKING
import json
if TYPE_CHECKING:
    from magpie.definitions.typedefs import Str, JSON, CookiesType, HeadersType, Optional  # noqa: F401
    from magpie.definitions.pyramid_definitions import Response  # noqa: F401


[docs]def check_response(response): if response.status_code >= 400: raise exception_response(response.status_code, body=response.text) return response
[docs]def request_api(request, # type: Request path, # type: Str method="GET", # type: Str data=None, # type: Optional[JSON] headers=None, # type: Optional[HeadersType] cookies=None, # type: Optional[CookiesType] ): # type: (...) -> Response """ Use a pyramid sub-request to request Magpie API routes via the UI. This avoids max retries and closed connections when using 1 worker (eg: during tests). Some information is retrieved from ``request`` to pass down to the sub-request (eg: cookies). If they are passed as argument, corresponding values will override the ones found in ``request``. All sub-requests to the API are assumed to be of ``magpie.common.CONTENT_TYPE_JSON`` unless explicitly overridden with ``headers``. """ method = method.upper() extra_kwargs = {"method": method} if headers: headers = dict(headers) else: headers = {"Accept": CONTENT_TYPE_JSON, "Content-Type": CONTENT_TYPE_JSON} # although no body is required per-say for HEAD/GET requests, add it if missing # this avoid downstream errors when 'request.POST' is accessed # we use a plain empty byte str because empty dict `{}` or `None` cause errors on each case # of local/remote testing with corresponding `webtest.TestApp`/`requests.Request` if not data: data = u"" if isinstance(data, dict) and get_header("Content-Type", headers, split=[",", ";"]) == CONTENT_TYPE_JSON: data = json.dumps(data) if isinstance(cookies, dict): cookies = list(cookies.items()) if cookies and isinstance(headers, dict): headers = list(cookies.items()) for c, v in cookies: headers.append(("Set-Cookie", "{}={}".format(c, v))) if not cookies: cookies = request.cookies # cookies must be added to kw only if populated, iterable error otherwise if cookies: extra_kwargs["cookies"] = cookies subreq = Request.blank(path, base_url=request.application_url, headers=headers, POST=data, **extra_kwargs) return request.invoke_subrequest(subreq, use_tweens=True)
[docs]def error_badrequest(func): """ Decorator that encapsulates the operation in a try/except block, and returns HTTP Bad Request on exception. """ def wrap(*args, **kwargs): try: return func(*args, **kwargs) except Exception as e: raise HTTPBadRequest(detail=str(e)) return wrap