Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/aiohttp/abc.py: 92%
90 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:40 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:40 +0000
1import asyncio
2import logging
3from abc import ABC, abstractmethod
4from collections.abc import Sized
5from http.cookies import BaseCookie, Morsel
6from typing import (
7 TYPE_CHECKING,
8 Any,
9 Awaitable,
10 Callable,
11 Dict,
12 Generator,
13 Iterable,
14 List,
15 Optional,
16 Tuple,
17)
19from multidict import CIMultiDict
20from yarl import URL
22from .helpers import get_running_loop
23from .typedefs import LooseCookies
25if TYPE_CHECKING: # pragma: no cover
26 from .web_app import Application
27 from .web_exceptions import HTTPException
28 from .web_request import BaseRequest, Request
29 from .web_response import StreamResponse
30else:
31 BaseRequest = Request = Application = StreamResponse = None
32 HTTPException = None
35class AbstractRouter(ABC):
36 def __init__(self) -> None:
37 self._frozen = False
39 def post_init(self, app: Application) -> None:
40 """Post init stage.
42 Not an abstract method for sake of backward compatibility,
43 but if the router wants to be aware of the application
44 it can override this.
45 """
47 @property
48 def frozen(self) -> bool:
49 return self._frozen
51 def freeze(self) -> None:
52 """Freeze router."""
53 self._frozen = True
55 @abstractmethod
56 async def resolve(self, request: Request) -> "AbstractMatchInfo":
57 """Return MATCH_INFO for given request"""
60class AbstractMatchInfo(ABC):
61 @property # pragma: no branch
62 @abstractmethod
63 def handler(self) -> Callable[[Request], Awaitable[StreamResponse]]:
64 """Execute matched request handler"""
66 @property
67 @abstractmethod
68 def expect_handler(
69 self,
70 ) -> Callable[[Request], Awaitable[Optional[StreamResponse]]]:
71 """Expect handler for 100-continue processing"""
73 @property # pragma: no branch
74 @abstractmethod
75 def http_exception(self) -> Optional[HTTPException]:
76 """HTTPException instance raised on router's resolving, or None"""
78 @abstractmethod # pragma: no branch
79 def get_info(self) -> Dict[str, Any]:
80 """Return a dict with additional info useful for introspection"""
82 @property # pragma: no branch
83 @abstractmethod
84 def apps(self) -> Tuple[Application, ...]:
85 """Stack of nested applications.
87 Top level application is left-most element.
89 """
91 @abstractmethod
92 def add_app(self, app: Application) -> None:
93 """Add application to the nested apps stack."""
95 @abstractmethod
96 def freeze(self) -> None:
97 """Freeze the match info.
99 The method is called after route resolution.
101 After the call .add_app() is forbidden.
103 """
106class AbstractView(ABC):
107 """Abstract class based view."""
109 def __init__(self, request: Request) -> None:
110 self._request = request
112 @property
113 def request(self) -> Request:
114 """Request instance."""
115 return self._request
117 @abstractmethod
118 def __await__(self) -> Generator[Any, None, StreamResponse]:
119 """Execute the view handler."""
122class AbstractResolver(ABC):
123 """Abstract DNS resolver."""
125 @abstractmethod
126 async def resolve(self, host: str, port: int, family: int) -> List[Dict[str, Any]]:
127 """Return IP address for given hostname"""
129 @abstractmethod
130 async def close(self) -> None:
131 """Release resolver"""
134if TYPE_CHECKING: # pragma: no cover
135 IterableBase = Iterable[Morsel[str]]
136else:
137 IterableBase = Iterable
140ClearCookiePredicate = Callable[["Morsel[str]"], bool]
143class AbstractCookieJar(Sized, IterableBase):
144 """Abstract Cookie Jar."""
146 def __init__(self, *, loop: Optional[asyncio.AbstractEventLoop] = None) -> None:
147 self._loop = get_running_loop(loop)
149 @abstractmethod
150 def clear(self, predicate: Optional[ClearCookiePredicate] = None) -> None:
151 """Clear all cookies if no predicate is passed."""
153 @abstractmethod
154 def clear_domain(self, domain: str) -> None:
155 """Clear all cookies for domain and all subdomains."""
157 @abstractmethod
158 def update_cookies(self, cookies: LooseCookies, response_url: URL = URL()) -> None:
159 """Update cookies."""
161 @abstractmethod
162 def filter_cookies(self, request_url: URL) -> "BaseCookie[str]":
163 """Return the jar's cookies filtered by their attributes."""
166class AbstractStreamWriter(ABC):
167 """Abstract stream writer."""
169 buffer_size = 0
170 output_size = 0
171 length: Optional[int] = 0
173 @abstractmethod
174 async def write(self, chunk: bytes) -> None:
175 """Write chunk into stream."""
177 @abstractmethod
178 async def write_eof(self, chunk: bytes = b"") -> None:
179 """Write last chunk."""
181 @abstractmethod
182 async def drain(self) -> None:
183 """Flush the write buffer."""
185 @abstractmethod
186 def enable_compression(self, encoding: str = "deflate") -> None:
187 """Enable HTTP body compression"""
189 @abstractmethod
190 def enable_chunking(self) -> None:
191 """Enable HTTP chunked mode"""
193 @abstractmethod
194 async def write_headers(
195 self, status_line: str, headers: "CIMultiDict[str]"
196 ) -> None:
197 """Write HTTP headers"""
200class AbstractAccessLogger(ABC):
201 """Abstract writer to access log."""
203 def __init__(self, logger: logging.Logger, log_format: str) -> None:
204 self.logger = logger
205 self.log_format = log_format
207 @abstractmethod
208 def log(self, request: BaseRequest, response: StreamResponse, time: float) -> None:
209 """Emit log to logger."""