Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/aiohttp/client.py
7730 views
"""HTTP Client for asyncio."""12import asyncio3import base644import hashlib5import json6import os7import sys8import traceback9import warnings10from contextlib import suppress11from types import SimpleNamespace, TracebackType12from typing import (13Any,14Awaitable,15Callable,16Coroutine,17FrozenSet,18Generator,19Generic,20Iterable,21List,22Mapping,23Optional,24Set,25Tuple,26Type,27TypeVar,28Union,29)3031import attr32from multidict import CIMultiDict, MultiDict, MultiDictProxy, istr33from yarl import URL3435from . import hdrs, http, payload36from .abc import AbstractCookieJar37from .client_exceptions import (38ClientConnectionError as ClientConnectionError,39ClientConnectorCertificateError as ClientConnectorCertificateError,40ClientConnectorError as ClientConnectorError,41ClientConnectorSSLError as ClientConnectorSSLError,42ClientError as ClientError,43ClientHttpProxyError as ClientHttpProxyError,44ClientOSError as ClientOSError,45ClientPayloadError as ClientPayloadError,46ClientProxyConnectionError as ClientProxyConnectionError,47ClientResponseError as ClientResponseError,48ClientSSLError as ClientSSLError,49ContentTypeError as ContentTypeError,50InvalidURL as InvalidURL,51ServerConnectionError as ServerConnectionError,52ServerDisconnectedError as ServerDisconnectedError,53ServerFingerprintMismatch as ServerFingerprintMismatch,54ServerTimeoutError as ServerTimeoutError,55TooManyRedirects as TooManyRedirects,56WSServerHandshakeError as WSServerHandshakeError,57)58from .client_reqrep import (59ClientRequest as ClientRequest,60ClientResponse as ClientResponse,61Fingerprint as Fingerprint,62RequestInfo as RequestInfo,63_merge_ssl_params,64)65from .client_ws import ClientWebSocketResponse as ClientWebSocketResponse66from .connector import (67BaseConnector as BaseConnector,68NamedPipeConnector as NamedPipeConnector,69TCPConnector as TCPConnector,70UnixConnector as UnixConnector,71)72from .cookiejar import CookieJar73from .helpers import (74DEBUG,75PY_36,76BasicAuth,77TimeoutHandle,78ceil_timeout,79get_env_proxy_for_url,80get_running_loop,81sentinel,82strip_auth_from_url,83)84from .http import WS_KEY, HttpVersion, WebSocketReader, WebSocketWriter85from .http_websocket import WSHandshakeError, WSMessage, ws_ext_gen, ws_ext_parse86from .streams import FlowControlDataQueue87from .tracing import Trace, TraceConfig88from .typedefs import Final, JSONEncoder, LooseCookies, LooseHeaders, StrOrURL8990__all__ = (91# client_exceptions92"ClientConnectionError",93"ClientConnectorCertificateError",94"ClientConnectorError",95"ClientConnectorSSLError",96"ClientError",97"ClientHttpProxyError",98"ClientOSError",99"ClientPayloadError",100"ClientProxyConnectionError",101"ClientResponseError",102"ClientSSLError",103"ContentTypeError",104"InvalidURL",105"ServerConnectionError",106"ServerDisconnectedError",107"ServerFingerprintMismatch",108"ServerTimeoutError",109"TooManyRedirects",110"WSServerHandshakeError",111# client_reqrep112"ClientRequest",113"ClientResponse",114"Fingerprint",115"RequestInfo",116# connector117"BaseConnector",118"TCPConnector",119"UnixConnector",120"NamedPipeConnector",121# client_ws122"ClientWebSocketResponse",123# client124"ClientSession",125"ClientTimeout",126"request",127)128129130try:131from ssl import SSLContext132except ImportError: # pragma: no cover133SSLContext = object # type: ignore[misc,assignment]134135136@attr.s(auto_attribs=True, frozen=True, slots=True)137class ClientTimeout:138total: Optional[float] = None139connect: Optional[float] = None140sock_read: Optional[float] = None141sock_connect: Optional[float] = None142143# pool_queue_timeout: Optional[float] = None144# dns_resolution_timeout: Optional[float] = None145# socket_connect_timeout: Optional[float] = None146# connection_acquiring_timeout: Optional[float] = None147# new_connection_timeout: Optional[float] = None148# http_header_timeout: Optional[float] = None149# response_body_timeout: Optional[float] = None150151# to create a timeout specific for a single request, either152# - create a completely new one to overwrite the default153# - or use http://www.attrs.org/en/stable/api.html#attr.evolve154# to overwrite the defaults155156157# 5 Minute default read timeout158DEFAULT_TIMEOUT: Final[ClientTimeout] = ClientTimeout(total=5 * 60)159160_RetType = TypeVar("_RetType")161162163class ClientSession:164"""First-class interface for making HTTP requests."""165166ATTRS = frozenset(167[168"_base_url",169"_source_traceback",170"_connector",171"requote_redirect_url",172"_loop",173"_cookie_jar",174"_connector_owner",175"_default_auth",176"_version",177"_json_serialize",178"_requote_redirect_url",179"_timeout",180"_raise_for_status",181"_auto_decompress",182"_trust_env",183"_default_headers",184"_skip_auto_headers",185"_request_class",186"_response_class",187"_ws_response_class",188"_trace_configs",189"_read_bufsize",190]191)192193_source_traceback = None194195def __init__(196self,197base_url: Optional[StrOrURL] = None,198*,199connector: Optional[BaseConnector] = None,200loop: Optional[asyncio.AbstractEventLoop] = None,201cookies: Optional[LooseCookies] = None,202headers: Optional[LooseHeaders] = None,203skip_auto_headers: Optional[Iterable[str]] = None,204auth: Optional[BasicAuth] = None,205json_serialize: JSONEncoder = json.dumps,206request_class: Type[ClientRequest] = ClientRequest,207response_class: Type[ClientResponse] = ClientResponse,208ws_response_class: Type[ClientWebSocketResponse] = ClientWebSocketResponse,209version: HttpVersion = http.HttpVersion11,210cookie_jar: Optional[AbstractCookieJar] = None,211connector_owner: bool = True,212raise_for_status: bool = False,213read_timeout: Union[float, object] = sentinel,214conn_timeout: Optional[float] = None,215timeout: Union[object, ClientTimeout] = sentinel,216auto_decompress: bool = True,217trust_env: bool = False,218requote_redirect_url: bool = True,219trace_configs: Optional[List[TraceConfig]] = None,220read_bufsize: int = 2 ** 16,221) -> None:222if loop is None:223if connector is not None:224loop = connector._loop225226loop = get_running_loop(loop)227228if base_url is None or isinstance(base_url, URL):229self._base_url: Optional[URL] = base_url230else:231self._base_url = URL(base_url)232assert (233self._base_url.origin() == self._base_url234), "Only absolute URLs without path part are supported"235236if connector is None:237connector = TCPConnector(loop=loop)238239if connector._loop is not loop:240raise RuntimeError("Session and connector has to use same event loop")241242self._loop = loop243244if loop.get_debug():245self._source_traceback = traceback.extract_stack(sys._getframe(1))246247if cookie_jar is None:248cookie_jar = CookieJar(loop=loop)249self._cookie_jar = cookie_jar250251if cookies is not None:252self._cookie_jar.update_cookies(cookies)253254self._connector = connector # type: Optional[BaseConnector]255self._connector_owner = connector_owner256self._default_auth = auth257self._version = version258self._json_serialize = json_serialize259if timeout is sentinel:260self._timeout = DEFAULT_TIMEOUT261if read_timeout is not sentinel:262warnings.warn(263"read_timeout is deprecated, " "use timeout argument instead",264DeprecationWarning,265stacklevel=2,266)267self._timeout = attr.evolve(self._timeout, total=read_timeout)268if conn_timeout is not None:269self._timeout = attr.evolve(self._timeout, connect=conn_timeout)270warnings.warn(271"conn_timeout is deprecated, " "use timeout argument instead",272DeprecationWarning,273stacklevel=2,274)275else:276self._timeout = timeout # type: ignore[assignment]277if read_timeout is not sentinel:278raise ValueError(279"read_timeout and timeout parameters "280"conflict, please setup "281"timeout.read"282)283if conn_timeout is not None:284raise ValueError(285"conn_timeout and timeout parameters "286"conflict, please setup "287"timeout.connect"288)289self._raise_for_status = raise_for_status290self._auto_decompress = auto_decompress291self._trust_env = trust_env292self._requote_redirect_url = requote_redirect_url293self._read_bufsize = read_bufsize294295# Convert to list of tuples296if headers:297real_headers = CIMultiDict(headers) # type: CIMultiDict[str]298else:299real_headers = CIMultiDict()300self._default_headers = real_headers # type: CIMultiDict[str]301if skip_auto_headers is not None:302self._skip_auto_headers = frozenset(istr(i) for i in skip_auto_headers)303else:304self._skip_auto_headers = frozenset()305306self._request_class = request_class307self._response_class = response_class308self._ws_response_class = ws_response_class309310self._trace_configs = trace_configs or []311for trace_config in self._trace_configs:312trace_config.freeze()313314def __init_subclass__(cls: Type["ClientSession"]) -> None:315warnings.warn(316"Inheritance class {} from ClientSession "317"is discouraged".format(cls.__name__),318DeprecationWarning,319stacklevel=2,320)321322if DEBUG:323324def __setattr__(self, name: str, val: Any) -> None:325if name not in self.ATTRS:326warnings.warn(327"Setting custom ClientSession.{} attribute "328"is discouraged".format(name),329DeprecationWarning,330stacklevel=2,331)332super().__setattr__(name, val)333334def __del__(self, _warnings: Any = warnings) -> None:335if not self.closed:336if PY_36:337kwargs = {"source": self}338else:339kwargs = {}340_warnings.warn(341f"Unclosed client session {self!r}", ResourceWarning, **kwargs342)343context = {"client_session": self, "message": "Unclosed client session"}344if self._source_traceback is not None:345context["source_traceback"] = self._source_traceback346self._loop.call_exception_handler(context)347348def request(349self, method: str, url: StrOrURL, **kwargs: Any350) -> "_RequestContextManager":351"""Perform HTTP request."""352return _RequestContextManager(self._request(method, url, **kwargs))353354def _build_url(self, str_or_url: StrOrURL) -> URL:355url = URL(str_or_url)356if self._base_url is None:357return url358else:359assert not url.is_absolute() and url.path.startswith("/")360return self._base_url.join(url)361362async def _request(363self,364method: str,365str_or_url: StrOrURL,366*,367params: Optional[Mapping[str, str]] = None,368data: Any = None,369json: Any = None,370cookies: Optional[LooseCookies] = None,371headers: Optional[LooseHeaders] = None,372skip_auto_headers: Optional[Iterable[str]] = None,373auth: Optional[BasicAuth] = None,374allow_redirects: bool = True,375max_redirects: int = 10,376compress: Optional[str] = None,377chunked: Optional[bool] = None,378expect100: bool = False,379raise_for_status: Optional[bool] = None,380read_until_eof: bool = True,381proxy: Optional[StrOrURL] = None,382proxy_auth: Optional[BasicAuth] = None,383timeout: Union[ClientTimeout, object] = sentinel,384verify_ssl: Optional[bool] = None,385fingerprint: Optional[bytes] = None,386ssl_context: Optional[SSLContext] = None,387ssl: Optional[Union[SSLContext, bool, Fingerprint]] = None,388proxy_headers: Optional[LooseHeaders] = None,389trace_request_ctx: Optional[SimpleNamespace] = None,390read_bufsize: Optional[int] = None,391) -> ClientResponse:392393# NOTE: timeout clamps existing connect and read timeouts. We cannot394# set the default to None because we need to detect if the user wants395# to use the existing timeouts by setting timeout to None.396397if self.closed:398raise RuntimeError("Session is closed")399400ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint)401402if data is not None and json is not None:403raise ValueError(404"data and json parameters can not be used at the same time"405)406elif json is not None:407data = payload.JsonPayload(json, dumps=self._json_serialize)408409if not isinstance(chunked, bool) and chunked is not None:410warnings.warn("Chunk size is deprecated #1615", DeprecationWarning)411412redirects = 0413history = []414version = self._version415416# Merge with default headers and transform to CIMultiDict417headers = self._prepare_headers(headers)418proxy_headers = self._prepare_headers(proxy_headers)419420try:421url = self._build_url(str_or_url)422except ValueError as e:423raise InvalidURL(str_or_url) from e424425skip_headers = set(self._skip_auto_headers)426if skip_auto_headers is not None:427for i in skip_auto_headers:428skip_headers.add(istr(i))429430if proxy is not None:431try:432proxy = URL(proxy)433except ValueError as e:434raise InvalidURL(proxy) from e435436if timeout is sentinel:437real_timeout = self._timeout # type: ClientTimeout438else:439if not isinstance(timeout, ClientTimeout):440real_timeout = ClientTimeout(total=timeout) # type: ignore[arg-type]441else:442real_timeout = timeout443# timeout is cumulative for all request operations444# (request, redirects, responses, data consuming)445tm = TimeoutHandle(self._loop, real_timeout.total)446handle = tm.start()447448if read_bufsize is None:449read_bufsize = self._read_bufsize450451traces = [452Trace(453self,454trace_config,455trace_config.trace_config_ctx(trace_request_ctx=trace_request_ctx),456)457for trace_config in self._trace_configs458]459460for trace in traces:461await trace.send_request_start(method, url.update_query(params), headers)462463timer = tm.timer()464try:465with timer:466while True:467url, auth_from_url = strip_auth_from_url(url)468if auth and auth_from_url:469raise ValueError(470"Cannot combine AUTH argument with "471"credentials encoded in URL"472)473474if auth is None:475auth = auth_from_url476if auth is None:477auth = self._default_auth478# It would be confusing if we support explicit479# Authorization header with auth argument480if (481headers is not None482and auth is not None483and hdrs.AUTHORIZATION in headers484):485raise ValueError(486"Cannot combine AUTHORIZATION header "487"with AUTH argument or credentials "488"encoded in URL"489)490491all_cookies = self._cookie_jar.filter_cookies(url)492493if cookies is not None:494tmp_cookie_jar = CookieJar()495tmp_cookie_jar.update_cookies(cookies)496req_cookies = tmp_cookie_jar.filter_cookies(url)497if req_cookies:498all_cookies.load(req_cookies)499500if proxy is not None:501proxy = URL(proxy)502elif self._trust_env:503with suppress(LookupError):504proxy, proxy_auth = get_env_proxy_for_url(url)505506req = self._request_class(507method,508url,509params=params,510headers=headers,511skip_auto_headers=skip_headers,512data=data,513cookies=all_cookies,514auth=auth,515version=version,516compress=compress,517chunked=chunked,518expect100=expect100,519loop=self._loop,520response_class=self._response_class,521proxy=proxy,522proxy_auth=proxy_auth,523timer=timer,524session=self,525ssl=ssl,526proxy_headers=proxy_headers,527traces=traces,528)529530# connection timeout531try:532async with ceil_timeout(real_timeout.connect):533assert self._connector is not None534conn = await self._connector.connect(535req, traces=traces, timeout=real_timeout536)537except asyncio.TimeoutError as exc:538raise ServerTimeoutError(539"Connection timeout " "to host {}".format(url)540) from exc541542assert conn.transport is not None543544assert conn.protocol is not None545conn.protocol.set_response_params(546timer=timer,547skip_payload=method.upper() == "HEAD",548read_until_eof=read_until_eof,549auto_decompress=self._auto_decompress,550read_timeout=real_timeout.sock_read,551read_bufsize=read_bufsize,552)553554try:555try:556resp = await req.send(conn)557try:558await resp.start(conn)559except BaseException:560resp.close()561raise562except BaseException:563conn.close()564raise565except ClientError:566raise567except OSError as exc:568raise ClientOSError(*exc.args) from exc569570self._cookie_jar.update_cookies(resp.cookies, resp.url)571572# redirects573if resp.status in (301, 302, 303, 307, 308) and allow_redirects:574575for trace in traces:576await trace.send_request_redirect(577method, url.update_query(params), headers, resp578)579580redirects += 1581history.append(resp)582if max_redirects and redirects >= max_redirects:583resp.close()584raise TooManyRedirects(585history[0].request_info, tuple(history)586)587588# For 301 and 302, mimic IE, now changed in RFC589# https://github.com/kennethreitz/requests/pull/269590if (resp.status == 303 and resp.method != hdrs.METH_HEAD) or (591resp.status in (301, 302) and resp.method == hdrs.METH_POST592):593method = hdrs.METH_GET594data = None595if headers.get(hdrs.CONTENT_LENGTH):596headers.pop(hdrs.CONTENT_LENGTH)597598r_url = resp.headers.get(hdrs.LOCATION) or resp.headers.get(599hdrs.URI600)601if r_url is None:602# see github.com/aio-libs/aiohttp/issues/2022603break604else:605# reading from correct redirection606# response is forbidden607resp.release()608609try:610parsed_url = URL(611r_url, encoded=not self._requote_redirect_url612)613614except ValueError as e:615raise InvalidURL(r_url) from e616617scheme = parsed_url.scheme618if scheme not in ("http", "https", ""):619resp.close()620raise ValueError("Can redirect only to http or https")621elif not scheme:622parsed_url = url.join(parsed_url)623624if url.origin() != parsed_url.origin():625auth = None626headers.pop(hdrs.AUTHORIZATION, None)627628url = parsed_url629params = None630resp.release()631continue632633break634635# check response status636if raise_for_status is None:637raise_for_status = self._raise_for_status638if raise_for_status:639resp.raise_for_status()640641# register connection642if handle is not None:643if resp.connection is not None:644resp.connection.add_callback(handle.cancel)645else:646handle.cancel()647648resp._history = tuple(history)649650for trace in traces:651await trace.send_request_end(652method, url.update_query(params), headers, resp653)654return resp655656except BaseException as e:657# cleanup timer658tm.close()659if handle:660handle.cancel()661handle = None662663for trace in traces:664await trace.send_request_exception(665method, url.update_query(params), headers, e666)667raise668669def ws_connect(670self,671url: StrOrURL,672*,673method: str = hdrs.METH_GET,674protocols: Iterable[str] = (),675timeout: float = 10.0,676receive_timeout: Optional[float] = None,677autoclose: bool = True,678autoping: bool = True,679heartbeat: Optional[float] = None,680auth: Optional[BasicAuth] = None,681origin: Optional[str] = None,682params: Optional[Mapping[str, str]] = None,683headers: Optional[LooseHeaders] = None,684proxy: Optional[StrOrURL] = None,685proxy_auth: Optional[BasicAuth] = None,686ssl: Union[SSLContext, bool, None, Fingerprint] = None,687verify_ssl: Optional[bool] = None,688fingerprint: Optional[bytes] = None,689ssl_context: Optional[SSLContext] = None,690proxy_headers: Optional[LooseHeaders] = None,691compress: int = 0,692max_msg_size: int = 4 * 1024 * 1024,693) -> "_WSRequestContextManager":694"""Initiate websocket connection."""695return _WSRequestContextManager(696self._ws_connect(697url,698method=method,699protocols=protocols,700timeout=timeout,701receive_timeout=receive_timeout,702autoclose=autoclose,703autoping=autoping,704heartbeat=heartbeat,705auth=auth,706origin=origin,707params=params,708headers=headers,709proxy=proxy,710proxy_auth=proxy_auth,711ssl=ssl,712verify_ssl=verify_ssl,713fingerprint=fingerprint,714ssl_context=ssl_context,715proxy_headers=proxy_headers,716compress=compress,717max_msg_size=max_msg_size,718)719)720721async def _ws_connect(722self,723url: StrOrURL,724*,725method: str = hdrs.METH_GET,726protocols: Iterable[str] = (),727timeout: float = 10.0,728receive_timeout: Optional[float] = None,729autoclose: bool = True,730autoping: bool = True,731heartbeat: Optional[float] = None,732auth: Optional[BasicAuth] = None,733origin: Optional[str] = None,734params: Optional[Mapping[str, str]] = None,735headers: Optional[LooseHeaders] = None,736proxy: Optional[StrOrURL] = None,737proxy_auth: Optional[BasicAuth] = None,738ssl: Union[SSLContext, bool, None, Fingerprint] = None,739verify_ssl: Optional[bool] = None,740fingerprint: Optional[bytes] = None,741ssl_context: Optional[SSLContext] = None,742proxy_headers: Optional[LooseHeaders] = None,743compress: int = 0,744max_msg_size: int = 4 * 1024 * 1024,745) -> ClientWebSocketResponse:746747if headers is None:748real_headers = CIMultiDict() # type: CIMultiDict[str]749else:750real_headers = CIMultiDict(headers)751752default_headers = {753hdrs.UPGRADE: "websocket",754hdrs.CONNECTION: "upgrade",755hdrs.SEC_WEBSOCKET_VERSION: "13",756}757758for key, value in default_headers.items():759real_headers.setdefault(key, value)760761sec_key = base64.b64encode(os.urandom(16))762real_headers[hdrs.SEC_WEBSOCKET_KEY] = sec_key.decode()763764if protocols:765real_headers[hdrs.SEC_WEBSOCKET_PROTOCOL] = ",".join(protocols)766if origin is not None:767real_headers[hdrs.ORIGIN] = origin768if compress:769extstr = ws_ext_gen(compress=compress)770real_headers[hdrs.SEC_WEBSOCKET_EXTENSIONS] = extstr771772ssl = _merge_ssl_params(ssl, verify_ssl, ssl_context, fingerprint)773774# send request775resp = await self.request(776method,777url,778params=params,779headers=real_headers,780read_until_eof=False,781auth=auth,782proxy=proxy,783proxy_auth=proxy_auth,784ssl=ssl,785proxy_headers=proxy_headers,786)787788try:789# check handshake790if resp.status != 101:791raise WSServerHandshakeError(792resp.request_info,793resp.history,794message="Invalid response status",795status=resp.status,796headers=resp.headers,797)798799if resp.headers.get(hdrs.UPGRADE, "").lower() != "websocket":800raise WSServerHandshakeError(801resp.request_info,802resp.history,803message="Invalid upgrade header",804status=resp.status,805headers=resp.headers,806)807808if resp.headers.get(hdrs.CONNECTION, "").lower() != "upgrade":809raise WSServerHandshakeError(810resp.request_info,811resp.history,812message="Invalid connection header",813status=resp.status,814headers=resp.headers,815)816817# key calculation818r_key = resp.headers.get(hdrs.SEC_WEBSOCKET_ACCEPT, "")819match = base64.b64encode(hashlib.sha1(sec_key + WS_KEY).digest()).decode()820if r_key != match:821raise WSServerHandshakeError(822resp.request_info,823resp.history,824message="Invalid challenge response",825status=resp.status,826headers=resp.headers,827)828829# websocket protocol830protocol = None831if protocols and hdrs.SEC_WEBSOCKET_PROTOCOL in resp.headers:832resp_protocols = [833proto.strip()834for proto in resp.headers[hdrs.SEC_WEBSOCKET_PROTOCOL].split(",")835]836837for proto in resp_protocols:838if proto in protocols:839protocol = proto840break841842# websocket compress843notakeover = False844if compress:845compress_hdrs = resp.headers.get(hdrs.SEC_WEBSOCKET_EXTENSIONS)846if compress_hdrs:847try:848compress, notakeover = ws_ext_parse(compress_hdrs)849except WSHandshakeError as exc:850raise WSServerHandshakeError(851resp.request_info,852resp.history,853message=exc.args[0],854status=resp.status,855headers=resp.headers,856) from exc857else:858compress = 0859notakeover = False860861conn = resp.connection862assert conn is not None863conn_proto = conn.protocol864assert conn_proto is not None865transport = conn.transport866assert transport is not None867reader = FlowControlDataQueue(868conn_proto, 2 ** 16, loop=self._loop869) # type: FlowControlDataQueue[WSMessage]870conn_proto.set_parser(WebSocketReader(reader, max_msg_size), reader)871writer = WebSocketWriter(872conn_proto,873transport,874use_mask=True,875compress=compress,876notakeover=notakeover,877)878except BaseException:879resp.close()880raise881else:882return self._ws_response_class(883reader,884writer,885protocol,886resp,887timeout,888autoclose,889autoping,890self._loop,891receive_timeout=receive_timeout,892heartbeat=heartbeat,893compress=compress,894client_notakeover=notakeover,895)896897def _prepare_headers(self, headers: Optional[LooseHeaders]) -> "CIMultiDict[str]":898"""Add default headers and transform it to CIMultiDict"""899# Convert headers to MultiDict900result = CIMultiDict(self._default_headers)901if headers:902if not isinstance(headers, (MultiDictProxy, MultiDict)):903headers = CIMultiDict(headers)904added_names = set() # type: Set[str]905for key, value in headers.items():906if key in added_names:907result.add(key, value)908else:909result[key] = value910added_names.add(key)911return result912913def get(914self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any915) -> "_RequestContextManager":916"""Perform HTTP GET request."""917return _RequestContextManager(918self._request(hdrs.METH_GET, url, allow_redirects=allow_redirects, **kwargs)919)920921def options(922self, url: StrOrURL, *, allow_redirects: bool = True, **kwargs: Any923) -> "_RequestContextManager":924"""Perform HTTP OPTIONS request."""925return _RequestContextManager(926self._request(927hdrs.METH_OPTIONS, url, allow_redirects=allow_redirects, **kwargs928)929)930931def head(932self, url: StrOrURL, *, allow_redirects: bool = False, **kwargs: Any933) -> "_RequestContextManager":934"""Perform HTTP HEAD request."""935return _RequestContextManager(936self._request(937hdrs.METH_HEAD, url, allow_redirects=allow_redirects, **kwargs938)939)940941def post(942self, url: StrOrURL, *, data: Any = None, **kwargs: Any943) -> "_RequestContextManager":944"""Perform HTTP POST request."""945return _RequestContextManager(946self._request(hdrs.METH_POST, url, data=data, **kwargs)947)948949def put(950self, url: StrOrURL, *, data: Any = None, **kwargs: Any951) -> "_RequestContextManager":952"""Perform HTTP PUT request."""953return _RequestContextManager(954self._request(hdrs.METH_PUT, url, data=data, **kwargs)955)956957def patch(958self, url: StrOrURL, *, data: Any = None, **kwargs: Any959) -> "_RequestContextManager":960"""Perform HTTP PATCH request."""961return _RequestContextManager(962self._request(hdrs.METH_PATCH, url, data=data, **kwargs)963)964965def delete(self, url: StrOrURL, **kwargs: Any) -> "_RequestContextManager":966"""Perform HTTP DELETE request."""967return _RequestContextManager(self._request(hdrs.METH_DELETE, url, **kwargs))968969async def close(self) -> None:970"""Close underlying connector.971972Release all acquired resources.973"""974if not self.closed:975if self._connector is not None and self._connector_owner:976await self._connector.close()977self._connector = None978979@property980def closed(self) -> bool:981"""Is client session closed.982983A readonly property.984"""985return self._connector is None or self._connector.closed986987@property988def connector(self) -> Optional[BaseConnector]:989"""Connector instance used for the session."""990return self._connector991992@property993def cookie_jar(self) -> AbstractCookieJar:994"""The session cookies."""995return self._cookie_jar996997@property998def version(self) -> Tuple[int, int]:999"""The session HTTP protocol version."""1000return self._version10011002@property1003def requote_redirect_url(self) -> bool:1004"""Do URL requoting on redirection handling."""1005return self._requote_redirect_url10061007@requote_redirect_url.setter1008def requote_redirect_url(self, val: bool) -> None:1009"""Do URL requoting on redirection handling."""1010warnings.warn(1011"session.requote_redirect_url modification " "is deprecated #2778",1012DeprecationWarning,1013stacklevel=2,1014)1015self._requote_redirect_url = val10161017@property1018def loop(self) -> asyncio.AbstractEventLoop:1019"""Session's loop."""1020warnings.warn(1021"client.loop property is deprecated", DeprecationWarning, stacklevel=21022)1023return self._loop10241025@property1026def timeout(self) -> Union[object, ClientTimeout]:1027"""Timeout for the session."""1028return self._timeout10291030@property1031def headers(self) -> "CIMultiDict[str]":1032"""The default headers of the client session."""1033return self._default_headers10341035@property1036def skip_auto_headers(self) -> FrozenSet[istr]:1037"""Headers for which autogeneration should be skipped"""1038return self._skip_auto_headers10391040@property1041def auth(self) -> Optional[BasicAuth]:1042"""An object that represents HTTP Basic Authorization"""1043return self._default_auth10441045@property1046def json_serialize(self) -> JSONEncoder:1047"""Json serializer callable"""1048return self._json_serialize10491050@property1051def connector_owner(self) -> bool:1052"""Should connector be closed on session closing"""1053return self._connector_owner10541055@property1056def raise_for_status(1057self,1058) -> Union[bool, Callable[[ClientResponse], Awaitable[None]]]:1059"""Should `ClientResponse.raise_for_status()` be called for each response."""1060return self._raise_for_status10611062@property1063def auto_decompress(self) -> bool:1064"""Should the body response be automatically decompressed."""1065return self._auto_decompress10661067@property1068def trust_env(self) -> bool:1069"""1070Should proxies information from environment or netrc be trusted.10711072Information is from HTTP_PROXY / HTTPS_PROXY environment variables1073or ~/.netrc file if present.1074"""1075return self._trust_env10761077@property1078def trace_configs(self) -> List[TraceConfig]:1079"""A list of TraceConfig instances used for client tracing"""1080return self._trace_configs10811082def detach(self) -> None:1083"""Detach connector from session without closing the former.10841085Session is switched to closed state anyway.1086"""1087self._connector = None10881089def __enter__(self) -> None:1090raise TypeError("Use async with instead")10911092def __exit__(1093self,1094exc_type: Optional[Type[BaseException]],1095exc_val: Optional[BaseException],1096exc_tb: Optional[TracebackType],1097) -> None:1098# __exit__ should exist in pair with __enter__ but never executed1099pass # pragma: no cover11001101async def __aenter__(self) -> "ClientSession":1102return self11031104async def __aexit__(1105self,1106exc_type: Optional[Type[BaseException]],1107exc_val: Optional[BaseException],1108exc_tb: Optional[TracebackType],1109) -> None:1110await self.close()111111121113class _BaseRequestContextManager(Coroutine[Any, Any, _RetType], Generic[_RetType]):11141115__slots__ = ("_coro", "_resp")11161117def __init__(self, coro: Coroutine["asyncio.Future[Any]", None, _RetType]) -> None:1118self._coro = coro11191120def send(self, arg: None) -> "asyncio.Future[Any]":1121return self._coro.send(arg)11221123def throw(self, arg: BaseException) -> None: # type: ignore[arg-type,override]1124self._coro.throw(arg)11251126def close(self) -> None:1127return self._coro.close()11281129def __await__(self) -> Generator[Any, None, _RetType]:1130ret = self._coro.__await__()1131return ret11321133def __iter__(self) -> Generator[Any, None, _RetType]:1134return self.__await__()11351136async def __aenter__(self) -> _RetType:1137self._resp = await self._coro1138return self._resp113911401141class _RequestContextManager(_BaseRequestContextManager[ClientResponse]):1142__slots__ = ()11431144async def __aexit__(1145self,1146exc_type: Optional[Type[BaseException]],1147exc: Optional[BaseException],1148tb: Optional[TracebackType],1149) -> None:1150# We're basing behavior on the exception as it can be caused by1151# user code unrelated to the status of the connection. If you1152# would like to close a connection you must do that1153# explicitly. Otherwise connection error handling should kick in1154# and close/recycle the connection as required.1155self._resp.release()115611571158class _WSRequestContextManager(_BaseRequestContextManager[ClientWebSocketResponse]):1159__slots__ = ()11601161async def __aexit__(1162self,1163exc_type: Optional[Type[BaseException]],1164exc: Optional[BaseException],1165tb: Optional[TracebackType],1166) -> None:1167await self._resp.close()116811691170class _SessionRequestContextManager:11711172__slots__ = ("_coro", "_resp", "_session")11731174def __init__(1175self,1176coro: Coroutine["asyncio.Future[Any]", None, ClientResponse],1177session: ClientSession,1178) -> None:1179self._coro = coro1180self._resp = None # type: Optional[ClientResponse]1181self._session = session11821183async def __aenter__(self) -> ClientResponse:1184try:1185self._resp = await self._coro1186except BaseException:1187await self._session.close()1188raise1189else:1190return self._resp11911192async def __aexit__(1193self,1194exc_type: Optional[Type[BaseException]],1195exc: Optional[BaseException],1196tb: Optional[TracebackType],1197) -> None:1198assert self._resp is not None1199self._resp.close()1200await self._session.close()120112021203def request(1204method: str,1205url: StrOrURL,1206*,1207params: Optional[Mapping[str, str]] = None,1208data: Any = None,1209json: Any = None,1210headers: Optional[LooseHeaders] = None,1211skip_auto_headers: Optional[Iterable[str]] = None,1212auth: Optional[BasicAuth] = None,1213allow_redirects: bool = True,1214max_redirects: int = 10,1215compress: Optional[str] = None,1216chunked: Optional[bool] = None,1217expect100: bool = False,1218raise_for_status: Optional[bool] = None,1219read_until_eof: bool = True,1220proxy: Optional[StrOrURL] = None,1221proxy_auth: Optional[BasicAuth] = None,1222timeout: Union[ClientTimeout, object] = sentinel,1223cookies: Optional[LooseCookies] = None,1224version: HttpVersion = http.HttpVersion11,1225connector: Optional[BaseConnector] = None,1226read_bufsize: Optional[int] = None,1227loop: Optional[asyncio.AbstractEventLoop] = None,1228) -> _SessionRequestContextManager:1229"""Constructs and sends a request.12301231Returns response object.1232method - HTTP method1233url - request url1234params - (optional) Dictionary or bytes to be sent in the query1235string of the new request1236data - (optional) Dictionary, bytes, or file-like object to1237send in the body of the request1238json - (optional) Any json compatible python object1239headers - (optional) Dictionary of HTTP Headers to send with1240the request1241cookies - (optional) Dict object to send with the request1242auth - (optional) BasicAuth named tuple represent HTTP Basic Auth1243auth - aiohttp.helpers.BasicAuth1244allow_redirects - (optional) If set to False, do not follow1245redirects1246version - Request HTTP version.1247compress - Set to True if request has to be compressed1248with deflate encoding.1249chunked - Set to chunk size for chunked transfer encoding.1250expect100 - Expect 100-continue response from server.1251connector - BaseConnector sub-class instance to support1252connection pooling.1253read_until_eof - Read response until eof if response1254does not have Content-Length header.1255loop - Optional event loop.1256timeout - Optional ClientTimeout settings structure, 5min1257total timeout by default.1258Usage::1259>>> import aiohttp1260>>> resp = await aiohttp.request('GET', 'http://python.org/')1261>>> resp1262<ClientResponse(python.org/) [200]>1263>>> data = await resp.read()1264"""1265connector_owner = False1266if connector is None:1267connector_owner = True1268connector = TCPConnector(loop=loop, force_close=True)12691270session = ClientSession(1271loop=loop,1272cookies=cookies,1273version=version,1274timeout=timeout,1275connector=connector,1276connector_owner=connector_owner,1277)12781279return _SessionRequestContextManager(1280session._request(1281method,1282url,1283params=params,1284data=data,1285json=json,1286headers=headers,1287skip_auto_headers=skip_auto_headers,1288auth=auth,1289allow_redirects=allow_redirects,1290max_redirects=max_redirects,1291compress=compress,1292chunked=chunked,1293expect100=expect100,1294raise_for_status=raise_for_status,1295read_until_eof=read_until_eof,1296proxy=proxy,1297proxy_auth=proxy_auth,1298read_bufsize=read_bufsize,1299),1300session,1301)130213031304