File: requests.py

package info (click to toggle)
python-openapi-core 0.19.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,008 kB
  • sloc: python: 18,868; makefile: 47
file content (97 lines) | stat: -rw-r--r-- 3,211 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""OpenAPI core contrib requests requests module"""

from typing import Optional
from typing import Union
from urllib.parse import parse_qs
from urllib.parse import urlparse

from requests import PreparedRequest
from requests import Request
from requests.cookies import RequestsCookieJar
from werkzeug.datastructures import Headers
from werkzeug.datastructures import ImmutableMultiDict

from openapi_core.contrib.requests.protocols import SupportsCookieJar
from openapi_core.datatypes import RequestParameters


class RequestsOpenAPIRequest:
    """
    Converts a requests request to an OpenAPI request

    Internally converts to a `PreparedRequest` first to parse the exact
    payload being sent
    """

    def __init__(self, request: Union[Request, PreparedRequest]):
        if not isinstance(request, (Request, PreparedRequest)):
            raise TypeError(
                "'request' argument is not type of "
                f"{Request} or {PreparedRequest}"
            )
        if isinstance(request, Request):
            request = request.prepare()

        self.request = request
        if request.url is None:
            raise RuntimeError("Request URL is missing")
        self._url_parsed = urlparse(request.url, allow_fragments=False)

        cookie = {}
        if isinstance(self.request, SupportsCookieJar) and isinstance(
            self.request._cookies, RequestsCookieJar
        ):
            # cookies are stored in a cookiejar object
            cookie = self.request._cookies.get_dict()

        self.parameters = RequestParameters(
            query=ImmutableMultiDict(parse_qs(self._url_parsed.query)),
            header=Headers(dict(self.request.headers)),
            cookie=ImmutableMultiDict(cookie),
        )

    @property
    def host_url(self) -> str:
        return f"{self._url_parsed.scheme}://{self._url_parsed.netloc}"

    @property
    def path(self) -> str:
        assert isinstance(self._url_parsed.path, str)
        return self._url_parsed.path

    @property
    def method(self) -> str:
        method = self.request.method
        return method and method.lower() or ""

    @property
    def body(self) -> Optional[bytes]:
        if self.request.body is None:
            return None
        if isinstance(self.request.body, bytes):
            return self.request.body
        assert isinstance(self.request.body, str)
        # TODO: figure out if request._body_position is relevant
        return self.request.body.encode("utf-8")

    @property
    def content_type(self) -> str:
        # Order matters because all python requests issued from a session
        # include Accept */* which does not necessarily match the content type
        return str(
            self.request.headers.get("Content-Type")
            or self.request.headers.get("Accept")
        )


class RequestsOpenAPIWebhookRequest(RequestsOpenAPIRequest):
    """
    Converts a requests request to an OpenAPI Webhook request

    Internally converts to a `PreparedRequest` first to parse the exact
    payload being sent
    """

    def __init__(self, request: Union[Request, PreparedRequest], name: str):
        super().__init__(request)
        self.name = name