From abef3b6febe32888e3cd74ed43890e584078cd69 Mon Sep 17 00:00:00 2001 From: Xiang Yan Date: Fri, 23 Jul 2021 15:26:10 -0700 Subject: [PATCH 1/4] cut hard dependency on requests --- .../azure-core/azure/core/_pipeline_client.py | 2 +- .../azure/core/pipeline/policies/_utils.py | 5 +- .../azure/core/pipeline/transport/__init__.py | 82 ++++++++++++------- .../azure-core/azure/core/utils/_utils.py | 2 + 4 files changed, 58 insertions(+), 33 deletions(-) diff --git a/sdk/core/azure-core/azure/core/_pipeline_client.py b/sdk/core/azure-core/azure/core/_pipeline_client.py index ec32e2b20964..44e5995c5f84 100644 --- a/sdk/core/azure-core/azure/core/_pipeline_client.py +++ b/sdk/core/azure-core/azure/core/_pipeline_client.py @@ -39,7 +39,6 @@ RequestIdPolicy, RetryPolicy, ) -from .pipeline.transport import RequestsTransport from .pipeline._tools import to_rest_response as _to_rest_response try: @@ -181,6 +180,7 @@ def _build_pipeline(self, config, **kwargs): # pylint: disable=no-self-use policies = policies_1 if not transport: + from .pipeline.transport import RequestsTransport transport = RequestsTransport(**kwargs) return Pipeline(transport, policies) diff --git a/sdk/core/azure-core/azure/core/pipeline/policies/_utils.py b/sdk/core/azure-core/azure/core/pipeline/policies/_utils.py index 326b2099bc11..6712178a61b5 100644 --- a/sdk/core/azure-core/azure/core/pipeline/policies/_utils.py +++ b/sdk/core/azure-core/azure/core/pipeline/policies/_utils.py @@ -25,8 +25,7 @@ # -------------------------------------------------------------------------- import datetime import email.utils -from requests.structures import CaseInsensitiveDict -from ...utils._utils import _FixedOffset +from ...utils._utils import _FixedOffset, _case_insensitive_dict def _parse_http_date(text): """Parse a HTTP date format into datetime.""" @@ -58,7 +57,7 @@ def get_retry_after(response): :return: Value of Retry-After in seconds. :rtype: float or None """ - headers = CaseInsensitiveDict(response.http_response.headers) + headers = _case_insensitive_dict(response.http_response.headers) retry_after = headers.get("retry-after") if retry_after: return parse_retry_after(retry_after) diff --git a/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py b/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py index a177dcbc8443..2d8175201499 100644 --- a/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py +++ b/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py @@ -26,31 +26,76 @@ import sys from ._base import HttpTransport, HttpRequest, HttpResponse -from ._requests_basic import RequestsTransport, RequestsTransportResponse __all__ = [ 'HttpTransport', 'HttpRequest', 'HttpResponse', - 'RequestsTransport', - 'RequestsTransportResponse', ] +try: + from ._requests_basic import RequestsTransport, RequestsTransportResponse + __all__.extend([ + 'RequestsTransport', + 'RequestsTransportResponse', + ]) +except (ImportError, SyntaxError): + pass # requests library is not installed + # pylint: disable=unused-import, redefined-outer-name try: from ._base_async import AsyncHttpTransport, AsyncHttpResponse - from ._requests_asyncio import AsyncioRequestsTransport, AsyncioRequestsTransportResponse __all__.extend([ 'AsyncHttpTransport', 'AsyncHttpResponse', - 'AsyncioRequestsTransport', - 'AsyncioRequestsTransportResponse' ]) + try: + from ._requests_asyncio import AsyncioRequestsTransport, AsyncioRequestsTransportResponse + + __all__.extend([ + 'AsyncioRequestsTransport', + 'AsyncioRequestsTransportResponse' + ]) + if sys.version_info >= (3, 7): + __all__.extend([ + 'TrioRequestsTransport', + 'TrioRequestsTransportResponse', + ]) + + def __dir__(): + return __all__ + + def __getattr__(name): + if name == 'TrioRequestsTransport': + try: + from ._requests_trio import TrioRequestsTransport + return TrioRequestsTransport + except ImportError: + raise ImportError("trio package is not installed") + if name == 'TrioRequestsTransportResponse': + try: + from ._requests_trio import TrioRequestsTransportResponse + return TrioRequestsTransportResponse + except ImportError: + raise ImportError("trio package is not installed") + return name + + else: + try: + from ._requests_trio import TrioRequestsTransport, TrioRequestsTransportResponse + + __all__.extend([ + 'TrioRequestsTransport', + 'TrioRequestsTransportResponse' + ]) + except ImportError: + pass # Trio not installed + except (ImportError, SyntaxError): + pass # requests library is not installed + if sys.version_info >= (3, 7): __all__.extend([ - 'TrioRequestsTransport', - 'TrioRequestsTransportResponse', 'AioHttpTransport', 'AioHttpTransportResponse', ]) @@ -71,30 +116,9 @@ def __getattr__(name): return AioHttpTransportResponse except ImportError: raise ImportError("aiohttp package is not installed") - if name == 'TrioRequestsTransport': - try: - from ._requests_trio import TrioRequestsTransport - return TrioRequestsTransport - except ImportError: - raise ImportError("trio package is not installed") - if name == 'TrioRequestsTransportResponse': - try: - from ._requests_trio import TrioRequestsTransportResponse - return TrioRequestsTransportResponse - except ImportError: - raise ImportError("trio package is not installed") return name else: - try: - from ._requests_trio import TrioRequestsTransport, TrioRequestsTransportResponse - __all__.extend([ - 'TrioRequestsTransport', - 'TrioRequestsTransportResponse' - ]) - except ImportError: - pass # Trio not installed - try: from ._aiohttp import AioHttpTransport, AioHttpTransportResponse __all__.extend([ diff --git a/sdk/core/azure-core/azure/core/utils/_utils.py b/sdk/core/azure-core/azure/core/utils/_utils.py index 5f3133e02955..afcc43a18d63 100644 --- a/sdk/core/azure-core/azure/core/utils/_utils.py +++ b/sdk/core/azure-core/azure/core/utils/_utils.py @@ -99,6 +99,8 @@ def _case_insensitive_dict(*args, **kwargs): # multidict is installed by aiohttp from multidict import CIMultiDict + if len(kwargs) == 0 and len(args) == 1 and (not args[0]): + return CIMultiDict() return CIMultiDict(*args, **kwargs) except ImportError: raise ValueError( From 773cb0c542a2a50478532d6bc840b293612cceb0 Mon Sep 17 00:00:00 2001 From: Xiang Yan Date: Fri, 23 Jul 2021 16:25:34 -0700 Subject: [PATCH 2/4] update --- .../azure/core/pipeline/transport/__init__.py | 108 +++++++++++------- 1 file changed, 67 insertions(+), 41 deletions(-) diff --git a/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py b/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py index 2d8175201499..75f7b6ba402d 100644 --- a/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py +++ b/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py @@ -39,34 +39,42 @@ 'RequestsTransport', 'RequestsTransportResponse', ]) -except (ImportError, SyntaxError): - pass # requests library is not installed - -# pylint: disable=unused-import, redefined-outer-name -try: - from ._base_async import AsyncHttpTransport, AsyncHttpResponse - __all__.extend([ - 'AsyncHttpTransport', - 'AsyncHttpResponse', - ]) - + # pylint: disable=unused-import, redefined-outer-name try: + from ._base_async import AsyncHttpTransport, AsyncHttpResponse from ._requests_asyncio import AsyncioRequestsTransport, AsyncioRequestsTransportResponse __all__.extend([ + 'AsyncHttpTransport', + 'AsyncHttpResponse', 'AsyncioRequestsTransport', 'AsyncioRequestsTransportResponse' ]) + if sys.version_info >= (3, 7): __all__.extend([ 'TrioRequestsTransport', 'TrioRequestsTransportResponse', + 'AioHttpTransport', + 'AioHttpTransportResponse', ]) def __dir__(): return __all__ def __getattr__(name): + if name == 'AioHttpTransport': + try: + from ._aiohttp import AioHttpTransport + return AioHttpTransport + except ImportError: + raise ImportError("aiohttp package is not installed") + if name == 'AioHttpTransportResponse': + try: + from ._aiohttp import AioHttpTransportResponse + return AioHttpTransportResponse + except ImportError: + raise ImportError("aiohttp package is not installed") if name == 'TrioRequestsTransport': try: from ._requests_trio import TrioRequestsTransport @@ -91,41 +99,59 @@ def __getattr__(name): ]) except ImportError: pass # Trio not installed - except (ImportError, SyntaxError): - pass # requests library is not installed - if sys.version_info >= (3, 7): + try: + from ._aiohttp import AioHttpTransport, AioHttpTransportResponse + + __all__.extend([ + 'AioHttpTransport', + 'AioHttpTransportResponse', + ]) + except ImportError: + pass # Aiohttp not installed + except (ImportError, SyntaxError): + pass +except (ImportError, SyntaxError): + # pylint: disable=unused-import, redefined-outer-name + try: + from ._base_async import AsyncHttpTransport, AsyncHttpResponse __all__.extend([ - 'AioHttpTransport', - 'AioHttpTransportResponse', + 'AsyncHttpTransport', + 'AsyncHttpResponse', ]) - def __dir__(): - return __all__ - - def __getattr__(name): - if name == 'AioHttpTransport': - try: - from ._aiohttp import AioHttpTransport - return AioHttpTransport - except ImportError: - raise ImportError("aiohttp package is not installed") - if name == 'AioHttpTransportResponse': - try: - from ._aiohttp import AioHttpTransportResponse - return AioHttpTransportResponse - except ImportError: - raise ImportError("aiohttp package is not installed") - return name - - else: - try: - from ._aiohttp import AioHttpTransport, AioHttpTransportResponse + if sys.version_info >= (3, 7): __all__.extend([ 'AioHttpTransport', 'AioHttpTransportResponse', ]) - except ImportError: - pass # Aiohttp not installed -except (ImportError, SyntaxError): - pass # Asynchronous pipelines not supported. + + def __dir__(): + return __all__ + + def __getattr__(name): + if name == 'AioHttpTransport': + try: + from ._aiohttp import AioHttpTransport + return AioHttpTransport + except ImportError: + raise ImportError("aiohttp package is not installed") + if name == 'AioHttpTransportResponse': + try: + from ._aiohttp import AioHttpTransportResponse + return AioHttpTransportResponse + except ImportError: + raise ImportError("aiohttp package is not installed") + return name + + else: + try: + from ._aiohttp import AioHttpTransport, AioHttpTransportResponse + __all__.extend([ + 'AioHttpTransport', + 'AioHttpTransportResponse', + ]) + except ImportError: + pass # Aiohttp not installed + except (ImportError, SyntaxError): + pass # Asynchronous pipelines not supported. From 35a243f092e8db892cfc714084bbe7ec68c8d57d Mon Sep 17 00:00:00 2001 From: Xiang Yan Date: Fri, 23 Jul 2021 17:11:43 -0700 Subject: [PATCH 3/4] update --- sdk/core/azure-core/azure/core/pipeline/transport/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py b/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py index 75f7b6ba402d..4dc787b952a3 100644 --- a/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py +++ b/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py @@ -33,13 +33,13 @@ 'HttpResponse', ] +# pylint: disable=unused-import, redefined-outer-name try: from ._requests_basic import RequestsTransport, RequestsTransportResponse __all__.extend([ 'RequestsTransport', 'RequestsTransportResponse', ]) - # pylint: disable=unused-import, redefined-outer-name try: from ._base_async import AsyncHttpTransport, AsyncHttpResponse from ._requests_asyncio import AsyncioRequestsTransport, AsyncioRequestsTransportResponse @@ -112,7 +112,6 @@ def __getattr__(name): except (ImportError, SyntaxError): pass except (ImportError, SyntaxError): - # pylint: disable=unused-import, redefined-outer-name try: from ._base_async import AsyncHttpTransport, AsyncHttpResponse __all__.extend([ From 390261fc1d86b6358b2a4ba1fcc53ff380fc9427 Mon Sep 17 00:00:00 2001 From: Xiang Yan Date: Fri, 30 Jul 2021 10:35:01 -0700 Subject: [PATCH 4/4] address review feedback --- sdk/core/azure-core/azure/core/pipeline/transport/__init__.py | 2 ++ sdk/core/azure-core/azure/core/utils/_utils.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py b/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py index 4dc787b952a3..57067c36bcbd 100644 --- a/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py +++ b/sdk/core/azure-core/azure/core/pipeline/transport/__init__.py @@ -110,8 +110,10 @@ def __getattr__(name): except ImportError: pass # Aiohttp not installed except (ImportError, SyntaxError): + # requests library is installed but asynchronous pipelines not supported. pass except (ImportError, SyntaxError): + # requests library is not installed try: from ._base_async import AsyncHttpTransport, AsyncHttpResponse __all__.extend([ diff --git a/sdk/core/azure-core/azure/core/utils/_utils.py b/sdk/core/azure-core/azure/core/utils/_utils.py index afcc43a18d63..08ae1ea21da7 100644 --- a/sdk/core/azure-core/azure/core/utils/_utils.py +++ b/sdk/core/azure-core/azure/core/utils/_utils.py @@ -100,7 +100,7 @@ def _case_insensitive_dict(*args, **kwargs): from multidict import CIMultiDict if len(kwargs) == 0 and len(args) == 1 and (not args[0]): - return CIMultiDict() + return CIMultiDict() # in case of case_insensitive_dict(None), we don't want to raise exception return CIMultiDict(*args, **kwargs) except ImportError: raise ValueError(