diff --git a/sdk/core/corehttp/corehttp/runtime/_base.py b/sdk/core/corehttp/corehttp/runtime/_base.py index 4566c971444b..93588e17f947 100644 --- a/sdk/core/corehttp/corehttp/runtime/_base.py +++ b/sdk/core/corehttp/corehttp/runtime/_base.py @@ -36,7 +36,6 @@ def _format_url_section(template, **kwargs): This is used for API like Storage, where when Swagger has template section not defined as parameter. :param str template: a string template to fill - :keyword dict[str,str] kwargs: Template values as string :rtype: str :returns: Template completed """ diff --git a/sdk/core/corehttp/corehttp/runtime/_pipeline_client.py b/sdk/core/corehttp/corehttp/runtime/_pipeline_client.py index feda93caf4fb..086413c2fa3d 100644 --- a/sdk/core/corehttp/corehttp/runtime/_pipeline_client.py +++ b/sdk/core/corehttp/corehttp/runtime/_pipeline_client.py @@ -140,7 +140,7 @@ def _build_pipeline( return Pipeline(transport, policies) - def send_request(self, request: HTTPRequestType, **kwargs: Any) -> HTTPResponseType: + def send_request(self, request: HTTPRequestType, *, stream: bool = False, **kwargs: Any) -> HTTPResponseType: """Method that runs the network request through the client's chained policies. >>> from corehttp.rest import HttpRequest @@ -155,6 +155,5 @@ def send_request(self, request: HTTPRequestType, **kwargs: Any) -> HTTPResponseT :return: The response of your network call. Does not do error handling on your response. :rtype: ~corehttp.rest.HttpResponse """ - stream = kwargs.pop("stream", False) # want to add default value pipeline_response = self.pipeline.run(request, stream=stream, **kwargs) return pipeline_response.http_response diff --git a/sdk/core/corehttp/corehttp/transport/aiohttp/_aiohttp.py b/sdk/core/corehttp/corehttp/transport/aiohttp/_aiohttp.py index 675e8202ae1f..ed82439f5e91 100644 --- a/sdk/core/corehttp/corehttp/transport/aiohttp/_aiohttp.py +++ b/sdk/core/corehttp/corehttp/transport/aiohttp/_aiohttp.py @@ -24,7 +24,7 @@ # # -------------------------------------------------------------------------- from __future__ import annotations -from typing import Optional, TYPE_CHECKING, Type, cast +from typing import Optional, TYPE_CHECKING, Type, cast, MutableMapping from types import TracebackType import logging @@ -109,7 +109,7 @@ def _build_ssl_config(self, cert, verify): :param tuple cert: Cert information :param bool verify: SSL verification or path to CA file or directory - :rtype: bool or str or :class:`ssl.SSLContext` + :rtype: bool or str or ssl.SSLContext :return: SSL configuration """ ssl_ctx = None @@ -145,7 +145,14 @@ def _get_request_data(self, request: RestHttpRequest): return form_data return request.content - async def send(self, request: RestHttpRequest, **config) -> RestAsyncHttpResponse: + async def send( + self, + request: RestHttpRequest, + *, + stream: bool = False, + proxies: Optional[MutableMapping[str, str]] = None, + **config, + ) -> RestAsyncHttpResponse: """Send the request using this HTTP sender. Will pre-load the body into memory to be available with a sync method. @@ -153,13 +160,10 @@ async def send(self, request: RestHttpRequest, **config) -> RestAsyncHttpRespons :param request: The HttpRequest object :type request: ~corehttp.rest.HttpRequest - :keyword any config: Any keyword arguments + :keyword bool stream: Defaults to False. + :keyword MutableMapping proxies: dict of proxies to use based on protocol. Proxy is a dict (protocol, url). :return: The AsyncHttpResponse :rtype: ~corehttp.rest.AsyncHttpResponse - - :keyword bool stream: Defaults to False. - :keyword dict proxies: dict of proxy to used based on protocol. Proxy is a dict (protocol, url) - :keyword str proxy: will define the proxy to use all the time """ await self.open() try: @@ -168,14 +172,14 @@ async def send(self, request: RestHttpRequest, **config) -> RestAsyncHttpRespons # auto_decompress is introduced in aiohttp 3.7. We need this to handle aiohttp 3.6-. auto_decompress = False - proxies = config.pop("proxies", None) - if proxies and "proxy" not in config: + proxy = config.pop("proxy", None) + if proxies and not proxy: # aiohttp needs a single proxy, so iterating until we found the right protocol # Sort by longest string first, so "http" is not used for "https" ;-) for protocol in sorted(proxies.keys(), reverse=True): if request.url.startswith(protocol): - config["proxy"] = proxies[protocol] + proxy = proxies[protocol] break response: Optional[RestAsyncHttpResponse] = None @@ -194,7 +198,6 @@ async def send(self, request: RestHttpRequest, **config) -> RestAsyncHttpRespons if not request.content: config["skip_auto_headers"] = ["Content-Type"] try: - stream_response = config.pop("stream", False) timeout = config.pop("connection_timeout", self.connection_config.get("connection_timeout")) read_timeout = config.pop("read_timeout", self.connection_config.get("read_timeout")) socket_timeout = aiohttp.ClientTimeout(sock_connect=timeout, sock_read=read_timeout) @@ -205,6 +208,7 @@ async def send(self, request: RestHttpRequest, **config) -> RestAsyncHttpRespons data=self._get_request_data(request), timeout=socket_timeout, allow_redirects=False, + proxy=proxy, **config, ) @@ -214,7 +218,7 @@ async def send(self, request: RestHttpRequest, **config) -> RestAsyncHttpRespons block_size=self.connection_config.get("data_block_size"), decompress=not auto_decompress, ) - if not stream_response: + if not stream: await _handle_non_stream_rest_response(response) except aiohttp.client_exceptions.ClientResponseError as err: diff --git a/sdk/core/corehttp/corehttp/transport/httpx/_httpx.py b/sdk/core/corehttp/corehttp/transport/httpx/_httpx.py index 97e6b9578ba1..de07e59c0803 100644 --- a/sdk/core/corehttp/corehttp/transport/httpx/_httpx.py +++ b/sdk/core/corehttp/corehttp/transport/httpx/_httpx.py @@ -80,7 +80,7 @@ def __enter__(self) -> "HttpXTransport": def __exit__(self, *args) -> None: self.close() - def send(self, request: HttpRequest, **kwargs) -> HttpResponse: + def send(self, request: HttpRequest, *, stream: bool = False, **kwargs) -> HttpResponse: """Send a request and get back a response. :param request: The request object to be sent. @@ -90,7 +90,6 @@ def send(self, request: HttpRequest, **kwargs) -> HttpResponse: :rtype: ~corehttp.rest.HttpResponse """ self.open() - stream_response = kwargs.pop("stream", False) connect_timeout = kwargs.pop("connection_timeout", self.connection_config.get("connection_timeout")) read_timeout = kwargs.pop("read_timeout", self.connection_config.get("read_timeout")) # not needed here as its already handled during init @@ -112,9 +111,9 @@ def send(self, request: HttpRequest, **kwargs) -> HttpResponse: # Cast for typing since we know it's not None after the open call client = cast(httpx.Client, self.client) try: - if stream_response: + if stream: req = client.build_request(**parameters) - response = client.send(req, stream=stream_response) + response = client.send(req, stream=stream) else: response = client.request(**parameters) except (httpx.ReadTimeout, httpx.ProtocolError) as err: @@ -123,7 +122,7 @@ def send(self, request: HttpRequest, **kwargs) -> HttpResponse: raise ServiceRequestError(err, error=err) from err retval = HttpXTransportResponse(request, response) - if not stream_response: + if not stream: _handle_non_stream_rest_response(retval) return retval @@ -169,7 +168,7 @@ async def __aenter__(self) -> "AsyncHttpXTransport": async def __aexit__(self, *args) -> None: await self.close() - async def send(self, request: HttpRequest, **kwargs) -> AsyncHttpResponse: + async def send(self, request: HttpRequest, *, stream: bool = False, **kwargs) -> AsyncHttpResponse: """Send the request using this HTTP sender. :param request: The request object to be sent. @@ -179,7 +178,6 @@ async def send(self, request: HttpRequest, **kwargs) -> AsyncHttpResponse: :rtype: ~corehttp.rest.AsyncHttpResponse """ await self.open() - stream_response = kwargs.pop("stream", False) connect_timeout = kwargs.pop("connection_timeout", self.connection_config.get("connection_timeout")) read_timeout = kwargs.pop("read_timeout", self.connection_config.get("read_timeout")) # not needed here as its already handled during init @@ -198,9 +196,9 @@ async def send(self, request: HttpRequest, **kwargs) -> AsyncHttpResponse: response = None client = cast(httpx.AsyncClient, self.client) try: - if stream_response: + if stream: req = client.build_request(**parameters) - response = await client.send(req, stream=stream_response) + response = await client.send(req, stream=stream) else: response = await client.request(**parameters) except (httpx.ReadTimeout, httpx.ProtocolError) as err: @@ -209,6 +207,6 @@ async def send(self, request: HttpRequest, **kwargs) -> AsyncHttpResponse: raise ServiceRequestError(err, error=err) from err retval = AsyncHttpXTransportResponse(request, response) - if not stream_response: + if not stream: await _handle_non_stream_rest_response_async(retval) return retval diff --git a/sdk/core/corehttp/corehttp/transport/requests/_requests_basic.py b/sdk/core/corehttp/corehttp/transport/requests/_requests_basic.py index 674ba87055f4..24d820c475a7 100644 --- a/sdk/core/corehttp/corehttp/transport/requests/_requests_basic.py +++ b/sdk/core/corehttp/corehttp/transport/requests/_requests_basic.py @@ -24,7 +24,7 @@ # # -------------------------------------------------------------------------- import logging -from typing import Optional, Union, TypeVar, cast, TYPE_CHECKING +from typing import Optional, Union, TypeVar, cast, MutableMapping, TYPE_CHECKING from urllib3.util.retry import Retry from urllib3.exceptions import ( ProtocolError, @@ -118,17 +118,22 @@ def close(self): self._session_owner = False self.session = None - def send(self, request: "RestHttpRequest", **kwargs) -> "RestHttpResponse": + def send( + self, + request: "RestHttpRequest", + *, + stream: bool = False, + proxies: Optional[MutableMapping[str, str]] = None, + **kwargs + ) -> "RestHttpResponse": """Send request object according to configuration. :param request: The request object to be sent. :type request: ~corehttp.rest.HttpRequest + :keyword bool stream: Defaults to False. + :keyword MutableMapping proxies: dict of proxies to use based on protocol. Proxy is a dict (protocol, url). :return: An HTTPResponse object. :rtype: ~corehttp.rest.HttpResponse - - :keyword requests.Session session: will override the driver session and use yours. - Should NOT be done unless really required. Anything else is sent straight to requests. - :keyword dict proxies: will define the proxy to use. Proxy is a dict (protocol, url) """ self.open() response = None @@ -154,6 +159,8 @@ def send(self, request: "RestHttpRequest", **kwargs) -> "RestHttpResponse": timeout=timeout, cert=kwargs.pop("connection_cert", self.connection_config.get("connection_cert")), allow_redirects=False, + stream=stream, + proxies=proxies, **kwargs ) response.raw.enforce_content_length = True @@ -189,6 +196,6 @@ def send(self, request: "RestHttpRequest", **kwargs) -> "RestHttpResponse": internal_response=response, block_size=self.connection_config.get("data_block_size"), ) - if not kwargs.get("stream"): + if not stream: _handle_non_stream_rest_response(retval) return retval