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 (88 lines) | stat: -rw-r--r-- 2,932 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
"""OpenAPI core contrib django requests module"""

import re
from typing import Optional

from django.http.request import HttpRequest
from werkzeug.datastructures import Headers
from werkzeug.datastructures import ImmutableMultiDict

from openapi_core.datatypes import RequestParameters

# https://docs.djangoproject.com/en/stable/topics/http/urls/
#
# Currently unsupported are :
#    - nested arguments, e.g.: ^comments/(?:page-(?P<page_number>\d+)/)?$
#    - unnamed regex groups, e.g.: ^articles/([0-9]{4})/$
#    - multiple named parameters between a single pair of slashes
#     e.g.: <page_slug>-<page_id>/edit/
#
# The regex matches everything, except a "/" until "<". Then only the name
# is exported, after which it matches ">" and everything until a "/".
# A check is made to ensure that "/" is not in an excluded character set such
# as may be found with Django REST Framwork's default value pattern, "[^/.]+".
PATH_PARAMETER_PATTERN = (
    r"(?:[^/]*?)<(?:(?:.*?:))*?(\w+)>(?:(?:[^/]*?\[\^[^/]*/)?[^/]*)"
)


class DjangoOpenAPIRequest:
    path_regex = re.compile(PATH_PARAMETER_PATTERN)

    def __init__(self, request: HttpRequest):
        if not isinstance(request, HttpRequest):
            raise TypeError(f"'request' argument is not type of {HttpRequest}")
        self.request = request

        path = (
            self.request.resolver_match
            and self.request.resolver_match.kwargs
            or {}
        )
        self.parameters = RequestParameters(
            path=path,
            query=ImmutableMultiDict(self.request.GET),
            header=Headers(self.request.headers.items()),
            cookie=ImmutableMultiDict(dict(self.request.COOKIES)),
        )

    @property
    def host_url(self) -> str:
        assert isinstance(self.request._current_scheme_host, str)
        return self.request._current_scheme_host

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

    @property
    def path_pattern(self) -> Optional[str]:
        if self.request.resolver_match is None:
            return None

        route = self.path_regex.sub(r"{\1}", self.request.resolver_match.route)
        # Delete start and end marker to allow concatenation.
        if route[:1] == "^":
            route = route[1:]
        if route[-1:] == "$":
            route = route[:-1]
        return "/" + route

    @property
    def method(self) -> str:
        if self.request.method is None:
            return ""
        assert isinstance(self.request.method, str)
        return self.request.method.lower()

    @property
    def body(self) -> bytes:
        assert isinstance(self.request.body, bytes)
        return self.request.body

    @property
    def content_type(self) -> str:
        content_type = self.request.META.get("CONTENT_TYPE", "")
        assert isinstance(content_type, str)
        return content_type