File: _pretty_print.py

package info (click to toggle)
pytest-httpx 0.35.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 424 kB
  • sloc: python: 4,386; makefile: 7; sh: 5
file content (74 lines) | stat: -rw-r--r-- 2,835 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
from typing import Union

import httpx

from pytest_httpx._httpx_internals import _proxy_url
from pytest_httpx._request_matcher import _RequestMatcher


class RequestDescription:
    def __init__(
        self,
        real_transport: Union[httpx.BaseTransport, httpx.AsyncBaseTransport],
        request: httpx.Request,
        matchers: list[_RequestMatcher],
    ):
        self.real_transport = real_transport
        self.request = request

        headers_encoding = request.headers.encoding
        self.expected_headers = {
            # httpx uses lower cased header names as internal key
            header.lower().encode(headers_encoding)
            for matcher in matchers
            if matcher.headers
            for header in matcher.headers
        }
        self.expect_body = any([matcher.expect_body() for matcher in matchers])
        self.expect_proxy = any([matcher.proxy_url is not None for matcher in matchers])
        self.expected_extensions = {
            extension
            for matcher in matchers
            if matcher.extensions
            for extension in matcher.extensions
        }

    def __str__(self) -> str:
        request_description = f"{self.request.method} request on {self.request.url}"
        if extra_description := self.extra_request_description():
            request_description += f" with {extra_description}"
        return request_description

    def extra_request_description(self) -> str:
        extra_description = []

        if self.expected_headers:
            headers_encoding = self.request.headers.encoding
            present_headers = {}
            # Can be cleaned based on the outcome of https://github.com/encode/httpx/discussions/2841
            for name, lower_name, value in self.request.headers._list:
                if lower_name in self.expected_headers:
                    name = name.decode(headers_encoding)
                    if name in present_headers:
                        present_headers[name] += f", {value.decode(headers_encoding)}"
                    else:
                        present_headers[name] = value.decode(headers_encoding)

            extra_description.append(f"{present_headers} headers")

        if self.expect_body:
            extra_description.append(f"{self.request.read()} body")

        if self.expect_proxy:
            proxy_url = _proxy_url(self.real_transport)
            extra_description.append(f"{proxy_url if proxy_url else 'no'} proxy URL")

        if self.expected_extensions:
            present_extensions = {
                name: value
                for name, value in self.request.extensions.items()
                if name in self.expected_extensions
            }
            extra_description.append(f"{present_extensions} extensions")

        return " and ".join(extra_description)