about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/msrest/pipeline
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/msrest/pipeline
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/msrest/pipeline')
-rw-r--r--.venv/lib/python3.12/site-packages/msrest/pipeline/__init__.py329
-rw-r--r--.venv/lib/python3.12/site-packages/msrest/pipeline/aiohttp.py62
-rw-r--r--.venv/lib/python3.12/site-packages/msrest/pipeline/async_abc.py165
-rw-r--r--.venv/lib/python3.12/site-packages/msrest/pipeline/async_requests.py129
-rw-r--r--.venv/lib/python3.12/site-packages/msrest/pipeline/requests.py194
-rw-r--r--.venv/lib/python3.12/site-packages/msrest/pipeline/universal.py253
6 files changed, 1132 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/msrest/pipeline/__init__.py b/.venv/lib/python3.12/site-packages/msrest/pipeline/__init__.py
new file mode 100644
index 00000000..428cf8cf
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/msrest/pipeline/__init__.py
@@ -0,0 +1,329 @@
+# --------------------------------------------------------------------------
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+# The MIT License (MIT)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the ""Software""), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# --------------------------------------------------------------------------
+from __future__ import absolute_import  # we have a "requests" module that conflicts with "requests" on Py2.7
+import abc
+try:
+    import configparser
+    from configparser import NoOptionError
+except ImportError:
+    import ConfigParser as configparser  # type: ignore
+    from ConfigParser import NoOptionError  # type: ignore
+import json
+import logging
+import os.path
+try:
+    from urlparse import urlparse
+except ImportError:
+    from urllib.parse import urlparse
+import xml.etree.ElementTree as ET
+
+from typing import TYPE_CHECKING, Generic, TypeVar, cast, IO, List, Union, Any, Mapping, Dict, Optional, Tuple, Callable, Iterator  # pylint: disable=unused-import
+
+HTTPResponseType = TypeVar("HTTPResponseType")
+HTTPRequestType = TypeVar("HTTPRequestType")
+
+# This file is NOT using any "requests" HTTP implementation
+# However, the CaseInsensitiveDict is handy.
+# If one day we reach the point where "requests" can be skip totally,
+# might provide our own implementation
+from requests.structures import CaseInsensitiveDict
+
+
+_LOGGER = logging.getLogger(__name__)
+
+try:
+    ABC = abc.ABC
+except AttributeError: # Python 2.7, abc exists, but not ABC
+    ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()})  # type: ignore
+
+try:
+    from contextlib import AbstractContextManager  # type: ignore
+except ImportError: # Python <= 3.5
+    class AbstractContextManager(object):  # type: ignore
+        def __enter__(self):
+            """Return `self` upon entering the runtime context."""
+            return self
+
+        @abc.abstractmethod
+        def __exit__(self, exc_type, exc_value, traceback):
+            """Raise any exception triggered within the runtime context."""
+            return None
+
+class HTTPPolicy(ABC, Generic[HTTPRequestType, HTTPResponseType]):
+    """An http policy ABC.
+    """
+    def __init__(self):
+        self.next = None
+
+    @abc.abstractmethod
+    def send(self, request, **kwargs):
+        # type: (Request[HTTPRequestType], Any) -> Response[HTTPRequestType, HTTPResponseType]
+        """Mutate the request.
+
+        Context content is dependent of the HTTPSender.
+        """
+        pass
+
+class SansIOHTTPPolicy(Generic[HTTPRequestType, HTTPResponseType]):
+    """Represents a sans I/O policy.
+
+    This policy can act before the I/O, and after the I/O.
+    Use this policy if the actual I/O in the middle is an implementation
+    detail.
+
+    Context is not available, since it's implementation dependent.
+    if a policy needs a context of the Sender, it can't be universal.
+
+    Example: setting a UserAgent does not need to be tight to
+    sync or async implementation or specific HTTP lib
+    """
+    def on_request(self, request, **kwargs):
+        # type: (Request[HTTPRequestType], Any) -> None
+        """Is executed before sending the request to next policy.
+        """
+        pass
+
+    def on_response(self, request, response, **kwargs):
+        # type: (Request[HTTPRequestType], Response[HTTPRequestType, HTTPResponseType], Any) -> None
+        """Is executed after the request comes back from the policy.
+        """
+        pass
+
+    def on_exception(self, request, **kwargs):
+        # type: (Request[HTTPRequestType], Any) -> bool
+        """Is executed if an exception comes back from the following
+        policy.
+
+        Return True if the exception has been handled and should not
+        be forwarded to the caller.
+
+        This method is executed inside the exception handler.
+        To get the exception, raise and catch it:
+
+            try:
+                raise
+            except MyError:
+                do_something()
+
+        or use
+
+            exc_type, exc_value, exc_traceback = sys.exc_info()
+        """
+        return False
+
+class _SansIOHTTPPolicyRunner(HTTPPolicy, Generic[HTTPRequestType, HTTPResponseType]):
+    """Sync implementation of the SansIO policy.
+    """
+
+    def __init__(self, policy):
+        # type: (SansIOHTTPPolicy) -> None
+        super(_SansIOHTTPPolicyRunner, self).__init__()
+        self._policy = policy
+
+    def send(self, request, **kwargs):
+        # type: (Request[HTTPRequestType], Any) -> Response[HTTPRequestType, HTTPResponseType]
+        self._policy.on_request(request, **kwargs)
+        try:
+            response = self.next.send(request, **kwargs)
+        except Exception:
+            if not self._policy.on_exception(request, **kwargs):
+                raise
+        else:
+            self._policy.on_response(request, response, **kwargs)
+        return response
+
+class Pipeline(AbstractContextManager, Generic[HTTPRequestType, HTTPResponseType]):
+    """A pipeline implementation.
+
+    This is implemented as a context manager, that will activate the context
+    of the HTTP sender.
+    """
+
+    def __init__(self, policies=None, sender=None):
+        # type: (List[Union[HTTPPolicy, SansIOHTTPPolicy]], HTTPSender) -> None
+        self._impl_policies = []  # type: List[HTTPPolicy]
+        if not sender:
+            # Import default only if nothing is provided
+            from .requests import PipelineRequestsHTTPSender
+            self._sender = cast(HTTPSender, PipelineRequestsHTTPSender())
+        else:
+            self._sender = sender
+        for policy in (policies or []):
+            if isinstance(policy, SansIOHTTPPolicy):
+                self._impl_policies.append(_SansIOHTTPPolicyRunner(policy))
+            else:
+                self._impl_policies.append(policy)
+        for index in range(len(self._impl_policies)-1):
+            self._impl_policies[index].next = self._impl_policies[index+1]
+        if self._impl_policies:
+            self._impl_policies[-1].next = self._sender
+
+    def __enter__(self):
+        # type: () -> Pipeline
+        self._sender.__enter__()
+        return self
+
+    def __exit__(self, *exc_details):  # pylint: disable=arguments-differ
+        self._sender.__exit__(*exc_details)
+
+    def run(self, request, **kwargs):
+        # type: (HTTPRequestType, Any) -> Response
+        context = self._sender.build_context()
+        pipeline_request = Request(request, context)  # type: Request[HTTPRequestType]
+        first_node = self._impl_policies[0] if self._impl_policies else self._sender
+        return first_node.send(pipeline_request, **kwargs)  # type: ignore
+
+class HTTPSender(AbstractContextManager, ABC, Generic[HTTPRequestType, HTTPResponseType]):
+    """An http sender ABC.
+    """
+
+    @abc.abstractmethod
+    def send(self, request, **config):
+        # type: (Request[HTTPRequestType], Any) -> Response[HTTPRequestType, HTTPResponseType]
+        """Send the request using this HTTP sender.
+        """
+        pass
+
+    def build_context(self):
+        # type: () -> Any
+        """Allow the sender to build a context that will be passed
+        across the pipeline with the request.
+
+        Return type has no constraints. Implementation is not
+        required and None by default.
+        """
+        return None
+
+
+class Request(Generic[HTTPRequestType]):
+    """Represents a HTTP request in a Pipeline.
+
+    URL can be given without query parameters, to be added later using "format_parameters".
+
+    Instance can be created without data, to be added later using "add_content"
+
+    Instance can be created without files, to be added later using "add_formdata"
+
+    :param str method: HTTP method (GET, HEAD, etc.)
+    :param str url: At least complete scheme/host/path
+    :param dict[str,str] headers: HTTP headers
+    :param files: Files list.
+    :param data: Body to be sent.
+    :type data: bytes or str.
+    """
+    def __init__(self, http_request, context=None):
+        # type: (HTTPRequestType, Optional[Any]) -> None
+        self.http_request = http_request
+        self.context = context
+
+
+class Response(Generic[HTTPRequestType, HTTPResponseType]):
+    """A pipeline response object.
+
+    The Response interface exposes an HTTP response object as it returns through the pipeline of Policy objects.
+    This ensures that Policy objects have access to the HTTP response.
+
+    This also have a "context" dictionary where policy can put additional fields.
+    Policy SHOULD update the "context" dictionary with additional post-processed field if they create them.
+    However, nothing prevents a policy to actually sub-class this class a return it instead of the initial instance.
+    """
+    def __init__(self, request, http_response, context=None):
+        # type: (Request[HTTPRequestType], HTTPResponseType, Optional[Dict[str, Any]]) -> None
+        self.request = request
+        self.http_response = http_response
+        self.context = context or {}
+
+
+# ClientRawResponse is in Pipeline for compat, but technically there is nothing Pipeline here, this is deserialization
+
+if TYPE_CHECKING:
+    from ..universal_http import ClientResponse
+
+class ClientRawResponse(object):
+    """Wrapper for response object.
+    This allows for additional data to be gathereded from the response,
+    for example deserialized headers.
+    It also allows the raw response object to be passed back to the user.
+
+    :param output: Deserialized response object. This is the type that would have been returned
+     directly by the main operation without raw=True.
+    :param response: Raw response object (by default requests.Response instance)
+    :type response: ~requests.Response
+    """
+
+    def __init__(self, output, response):
+        # type: (Union[Any], Optional[Union[Response, ClientResponse]]) -> None
+        from ..serialization import Deserializer
+
+        if isinstance(response, Response):
+            # If pipeline response, remove that layer
+            response = response.http_response
+
+        try:
+            # If universal driver, remove that layer
+            self.response = response.internal_response  # type: ignore
+        except AttributeError:
+            self.response = response
+
+        self.output = output
+        self.headers = {}  # type: Dict[str, Optional[Any]]
+        self._deserialize = Deserializer()
+
+    def add_headers(self, header_dict):
+        # type: (Dict[str, str]) -> None
+        """Deserialize a specific header.
+
+        :param dict header_dict: A dictionary containing the name of the
+         header and the type to deserialize to.
+        """
+        if not self.response:
+            return
+        for name, data_type in header_dict.items():
+            value = self.response.headers.get(name)
+            value = self._deserialize(data_type, value)
+            self.headers[name] = value
+
+
+
+__all__ = [
+    'Request',
+    'Response',
+    'Pipeline',
+    'HTTPPolicy',
+    'SansIOHTTPPolicy',
+    'HTTPSender',
+    # backward compat
+    'ClientRawResponse',
+]
+
+try:
+    from .async_abc import AsyncPipeline, AsyncHTTPPolicy, AsyncHTTPSender  # pylint: disable=unused-import
+    from .async_abc import __all__ as _async_all
+    __all__ += _async_all
+except SyntaxError: # Python 2
+    pass
+except ImportError: # pyinstaller won't include Py3 files in Py2.7 mode
+    pass
diff --git a/.venv/lib/python3.12/site-packages/msrest/pipeline/aiohttp.py b/.venv/lib/python3.12/site-packages/msrest/pipeline/aiohttp.py
new file mode 100644
index 00000000..cefb1a5a
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/msrest/pipeline/aiohttp.py
@@ -0,0 +1,62 @@
+# --------------------------------------------------------------------------
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+# The MIT License (MIT)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the ""Software""), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# --------------------------------------------------------------------------
+from typing import Any, Optional
+
+from ..universal_http.aiohttp import AioHTTPSender as _AioHTTPSenderDriver
+from . import AsyncHTTPSender, Request, Response
+
+# Matching requests, because why not?
+CONTENT_CHUNK_SIZE = 10 * 1024
+
+class AioHTTPSender(AsyncHTTPSender):
+    """AioHttp HTTP sender implementation.
+    """
+
+    def __init__(self, driver: Optional[_AioHTTPSenderDriver] = None, *, loop=None) -> None:
+        self.driver = driver or _AioHTTPSenderDriver(loop=loop)
+
+    async def __aenter__(self):
+        await self.driver.__aenter__()
+
+    async def __aexit__(self, *exc_details):  # pylint: disable=arguments-differ
+        await self.driver.__aexit__(*exc_details)
+
+    def build_context(self) -> Any:
+        """Allow the sender to build a context that will be passed
+        across the pipeline with the request.
+
+        Return type has no constraints. Implementation is not
+        required and None by default.
+        """
+        return None
+
+    async def send(self, request: Request, **config: Any) -> Response:
+        """Send the request using this HTTP sender.
+        """
+        return Response(
+            request,
+            await self.driver.send(request.http_request)
+        )
diff --git a/.venv/lib/python3.12/site-packages/msrest/pipeline/async_abc.py b/.venv/lib/python3.12/site-packages/msrest/pipeline/async_abc.py
new file mode 100644
index 00000000..3fa73dda
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/msrest/pipeline/async_abc.py
@@ -0,0 +1,165 @@
+# --------------------------------------------------------------------------
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+# The MIT License (MIT)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the ""Software""), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# --------------------------------------------------------------------------
+import abc
+
+from typing import Any, List, Union, Callable, AsyncIterator, Optional, Generic, TypeVar
+
+from . import Request, Response, Pipeline, SansIOHTTPPolicy
+
+
+AsyncHTTPResponseType = TypeVar("AsyncHTTPResponseType")
+HTTPRequestType = TypeVar("HTTPRequestType")
+
+try:
+    from contextlib import AbstractAsyncContextManager  # type: ignore
+except ImportError: # Python <= 3.7
+    class AbstractAsyncContextManager(object):  # type: ignore
+        async def __aenter__(self):
+            """Return `self` upon entering the runtime context."""
+            return self
+
+        @abc.abstractmethod
+        async def __aexit__(self, exc_type, exc_value, traceback):
+            """Raise any exception triggered within the runtime context."""
+            return None
+
+
+
+
+class AsyncHTTPPolicy(abc.ABC, Generic[HTTPRequestType, AsyncHTTPResponseType]):
+    """An http policy ABC.
+    """
+    def __init__(self) -> None:
+        # next will be set once in the pipeline
+        self.next = None  # type: Optional[Union[AsyncHTTPPolicy[HTTPRequestType, AsyncHTTPResponseType], AsyncHTTPSender[HTTPRequestType, AsyncHTTPResponseType]]]
+
+    @abc.abstractmethod
+    async def send(self, request: Request, **kwargs: Any) -> Response[HTTPRequestType, AsyncHTTPResponseType]:
+        """Mutate the request.
+
+        Context content is dependent of the HTTPSender.
+        """
+        pass
+
+
+class _SansIOAsyncHTTPPolicyRunner(AsyncHTTPPolicy[HTTPRequestType, AsyncHTTPResponseType]):
+    """Async implementation of the SansIO policy.
+    """
+
+    def __init__(self, policy: SansIOHTTPPolicy) -> None:
+        super(_SansIOAsyncHTTPPolicyRunner, self).__init__()
+        self._policy = policy
+
+    async def send(self, request: Request, **kwargs: Any) -> Response[HTTPRequestType, AsyncHTTPResponseType]:
+        self._policy.on_request(request, **kwargs)
+        try:
+            response = await self.next.send(request, **kwargs)  # type: ignore
+        except Exception:
+            if not self._policy.on_exception(request, **kwargs):
+                raise
+        else:
+            self._policy.on_response(request, response, **kwargs)
+        return response
+
+
+class AsyncHTTPSender(AbstractAsyncContextManager, abc.ABC, Generic[HTTPRequestType, AsyncHTTPResponseType]):
+    """An http sender ABC.
+    """
+
+    @abc.abstractmethod
+    async def send(self, request: Request[HTTPRequestType], **config: Any) -> Response[HTTPRequestType, AsyncHTTPResponseType]:
+        """Send the request using this HTTP sender.
+        """
+        pass
+
+    def build_context(self) -> Any:
+        """Allow the sender to build a context that will be passed
+        across the pipeline with the request.
+
+        Return type has no constraints. Implementation is not
+        required and None by default.
+        """
+        return None
+
+    def __enter__(self):
+        raise TypeError("Use async with instead")
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        # __exit__ should exist in pair with __enter__ but never executed
+        pass  # pragma: no cover
+
+
+class AsyncPipeline(AbstractAsyncContextManager, Generic[HTTPRequestType, AsyncHTTPResponseType]):
+    """A pipeline implementation.
+
+    This is implemented as a context manager, that will activate the context
+    of the HTTP sender.
+    """
+
+    def __init__(self, policies: List[Union[AsyncHTTPPolicy, SansIOHTTPPolicy]] = None, sender: Optional[AsyncHTTPSender[HTTPRequestType, AsyncHTTPResponseType]] = None) -> None:
+        self._impl_policies = []  # type: List[AsyncHTTPPolicy[HTTPRequestType, AsyncHTTPResponseType]]
+        if sender:
+            self._sender = sender
+        else:
+            # Import default only if nothing is provided
+            from .aiohttp import AioHTTPSender
+            self._sender = AioHTTPSender()
+
+        for policy in (policies or []):
+            if isinstance(policy, SansIOHTTPPolicy):
+                self._impl_policies.append(_SansIOAsyncHTTPPolicyRunner(policy))
+            else:
+                self._impl_policies.append(policy)
+        for index in range(len(self._impl_policies)-1):
+            self._impl_policies[index].next = self._impl_policies[index+1]
+        if self._impl_policies:
+            self._impl_policies[-1].next = self._sender
+
+    def __enter__(self):
+        raise TypeError("Use 'async with' instead")
+
+    def __exit__(self, exc_type, exc_val, exc_tb):
+        # __exit__ should exist in pair with __enter__ but never executed
+        pass  # pragma: no cover
+
+    async def __aenter__(self) -> 'AsyncPipeline':
+        await self._sender.__aenter__()
+        return self
+
+    async def __aexit__(self, *exc_details):  # pylint: disable=arguments-differ
+        await self._sender.__aexit__(*exc_details)
+
+    async def run(self, request: Request, **kwargs: Any) -> Response[HTTPRequestType, AsyncHTTPResponseType]:
+        context = self._sender.build_context()
+        pipeline_request = Request(request, context)
+        first_node = self._impl_policies[0] if self._impl_policies else self._sender
+        return await first_node.send(pipeline_request, **kwargs)  # type: ignore
+
+__all__ = [
+    'AsyncHTTPPolicy',
+    'AsyncHTTPSender',
+    'AsyncPipeline',
+]
\ No newline at end of file
diff --git a/.venv/lib/python3.12/site-packages/msrest/pipeline/async_requests.py b/.venv/lib/python3.12/site-packages/msrest/pipeline/async_requests.py
new file mode 100644
index 00000000..d5d9ec2f
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/msrest/pipeline/async_requests.py
@@ -0,0 +1,129 @@
+# --------------------------------------------------------------------------
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+# The MIT License (MIT)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the ""Software""), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# --------------------------------------------------------------------------
+import asyncio
+from collections.abc import AsyncIterator
+import functools
+import logging
+from typing import Any, Callable, Optional, AsyncIterator as AsyncIteratorType
+
+from oauthlib import oauth2
+import requests
+from requests.models import CONTENT_CHUNK_SIZE
+
+from ..exceptions import (
+    TokenExpiredError,
+    ClientRequestError,
+    raise_with_traceback
+)
+from ..universal_http.async_requests import AsyncBasicRequestsHTTPSender
+from . import AsyncHTTPSender, AsyncHTTPPolicy, Response, Request
+from .requests import RequestsContext
+
+
+_LOGGER = logging.getLogger(__name__)
+
+
+class AsyncPipelineRequestsHTTPSender(AsyncHTTPSender):
+    """Implements a basic Pipeline, that supports universal HTTP lib "requests" driver.
+    """
+
+    def __init__(self, universal_http_requests_driver: Optional[AsyncBasicRequestsHTTPSender]=None) -> None:
+        self.driver = universal_http_requests_driver or AsyncBasicRequestsHTTPSender()
+
+    async def __aenter__(self) -> 'AsyncPipelineRequestsHTTPSender':
+        await self.driver.__aenter__()
+        return self
+
+    async def __aexit__(self, *exc_details):  # pylint: disable=arguments-differ
+        await self.driver.__aexit__(*exc_details)
+
+    async def close(self):
+        await self.__aexit__()
+
+    def build_context(self):
+        # type: () -> RequestsContext
+        return RequestsContext(
+            session=self.driver.session,
+        )
+
+    async def send(self, request: Request, **kwargs) -> Response:
+        """Send request object according to configuration.
+
+        :param Request request: The request object to be sent.
+        """
+        if request.context is None:  # Should not happen, but make mypy happy and does not hurt
+            request.context = self.build_context()
+
+        if request.context.session is not self.driver.session:
+            kwargs['session'] = request.context.session
+
+        return Response(
+            request,
+            await self.driver.send(request.http_request, **kwargs)
+        )
+
+
+class AsyncRequestsCredentialsPolicy(AsyncHTTPPolicy):
+    """Implementation of request-oauthlib except and retry logic.
+    """
+    def __init__(self, credentials):
+        super(AsyncRequestsCredentialsPolicy, self).__init__()
+        self._creds = credentials
+
+    async def send(self, request, **kwargs):
+        session = request.context.session
+        try:
+            self._creds.signed_session(session)
+        except TypeError: # Credentials does not support session injection
+            _LOGGER.warning("Your credentials class does not support session injection. Performance will not be at the maximum.")
+            request.context.session = session = self._creds.signed_session()
+
+        try:
+            try:
+                return await self.next.send(request, **kwargs)
+            except (oauth2.rfc6749.errors.InvalidGrantError,
+                    oauth2.rfc6749.errors.TokenExpiredError) as err:
+                error = "Token expired or is invalid. Attempting to refresh."
+                _LOGGER.warning(error)
+
+            try:
+                try:
+                    self._creds.refresh_session(session)
+                except TypeError: # Credentials does not support session injection
+                    _LOGGER.warning("Your credentials class does not support session injection. Performance will not be at the maximum.")
+                    request.context.session = session = self._creds.refresh_session()
+
+                return await self.next.send(request, **kwargs)
+            except (oauth2.rfc6749.errors.InvalidGrantError,
+                    oauth2.rfc6749.errors.TokenExpiredError) as err:
+                msg = "Token expired or is invalid."
+                raise_with_traceback(TokenExpiredError, msg, err)
+
+        except (requests.RequestException,
+                oauth2.rfc6749.errors.OAuth2Error) as err:
+            msg = "Error occurred in request."
+            raise_with_traceback(ClientRequestError, msg, err)
+
diff --git a/.venv/lib/python3.12/site-packages/msrest/pipeline/requests.py b/.venv/lib/python3.12/site-packages/msrest/pipeline/requests.py
new file mode 100644
index 00000000..2dac5a3b
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/msrest/pipeline/requests.py
@@ -0,0 +1,194 @@
+# --------------------------------------------------------------------------
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+# The MIT License (MIT)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the ""Software""), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# --------------------------------------------------------------------------
+"""
+This module is the requests implementation of Pipeline ABC
+"""
+from __future__ import absolute_import  # we have a "requests" module that conflicts with "requests" on Py2.7
+import contextlib
+import logging
+import threading
+from typing import TYPE_CHECKING, List, Callable, Iterator, Any, Union, Dict, Optional  # pylint: disable=unused-import
+import warnings
+
+from oauthlib import oauth2
+import requests
+from requests.models import CONTENT_CHUNK_SIZE
+
+from urllib3 import Retry  # Needs requests 2.16 at least to be safe
+
+from ..exceptions import (
+    TokenExpiredError,
+    ClientRequestError,
+    raise_with_traceback
+)
+from ..universal_http import ClientRequest
+from ..universal_http.requests import BasicRequestsHTTPSender
+from . import HTTPSender, HTTPPolicy, Response, Request
+
+
+_LOGGER = logging.getLogger(__name__)
+
+
+class RequestsCredentialsPolicy(HTTPPolicy):
+    """Implementation of request-oauthlib except and retry logic.
+    """
+    def __init__(self, credentials):
+        super(RequestsCredentialsPolicy, self).__init__()
+        self._creds = credentials
+
+    def send(self, request, **kwargs):
+        session = request.context.session
+        try:
+            self._creds.signed_session(session)
+        except TypeError: # Credentials does not support session injection
+            _LOGGER.warning("Your credentials class does not support session injection. Performance will not be at the maximum.")
+            request.context.session = session = self._creds.signed_session()
+
+        try:
+            try:
+                return self.next.send(request, **kwargs)
+            except (oauth2.rfc6749.errors.InvalidGrantError,
+                    oauth2.rfc6749.errors.TokenExpiredError) as err:
+                error = "Token expired or is invalid. Attempting to refresh."
+                _LOGGER.warning(error)
+
+            try:
+                try:
+                    self._creds.refresh_session(session)
+                except TypeError: # Credentials does not support session injection
+                    _LOGGER.warning("Your credentials class does not support session injection. Performance will not be at the maximum.")
+                    request.context.session = session = self._creds.refresh_session()
+
+                return self.next.send(request, **kwargs)
+            except (oauth2.rfc6749.errors.InvalidGrantError,
+                    oauth2.rfc6749.errors.TokenExpiredError) as err:
+                msg = "Token expired or is invalid."
+                raise_with_traceback(TokenExpiredError, msg, err)
+
+        except (requests.RequestException,
+                oauth2.rfc6749.errors.OAuth2Error) as err:
+            msg = "Error occurred in request."
+            raise_with_traceback(ClientRequestError, msg, err)
+
+class RequestsPatchSession(HTTPPolicy):
+    """Implements request level configuration
+    that are actually to be done at the session level.
+
+    This is highly deprecated, and is totally legacy.
+    The pipeline structure allows way better design for this.
+    """
+    _protocols = ['http://', 'https://']
+
+    def send(self, request, **kwargs):
+        """Patch the current session with Request level operation config.
+
+        This is deprecated, we shouldn't patch the session with
+        arguments at the Request, and "config" should be used.
+        """
+        session = request.context.session
+
+        old_max_redirects = None
+        if 'max_redirects' in kwargs:
+            warnings.warn("max_redirects in operation kwargs is deprecated, use config.redirect_policy instead",
+                          DeprecationWarning)
+            old_max_redirects = session.max_redirects
+            session.max_redirects = int(kwargs['max_redirects'])
+
+        old_trust_env = None
+        if 'use_env_proxies' in kwargs:
+            warnings.warn("use_env_proxies in operation kwargs is deprecated, use config.proxies instead",
+                          DeprecationWarning)
+            old_trust_env = session.trust_env
+            session.trust_env = bool(kwargs['use_env_proxies'])
+
+        old_retries = {}
+        if 'retries' in kwargs:
+            warnings.warn("retries in operation kwargs is deprecated, use config.retry_policy instead",
+                          DeprecationWarning)
+            max_retries = kwargs['retries']
+            for protocol in self._protocols:
+                old_retries[protocol] = session.adapters[protocol].max_retries
+                session.adapters[protocol].max_retries = max_retries
+
+        try:
+            return self.next.send(request, **kwargs)
+        finally:
+            if old_max_redirects:
+                session.max_redirects = old_max_redirects
+
+            if old_trust_env:
+                session.trust_env = old_trust_env
+
+            if old_retries:
+                for protocol in self._protocols:
+                    session.adapters[protocol].max_retries = old_retries[protocol]
+
+class RequestsContext(object):
+    def __init__(self, session):
+        self.session = session
+
+
+class PipelineRequestsHTTPSender(HTTPSender):
+    """Implements a basic Pipeline, that supports universal HTTP lib "requests" driver.
+    """
+
+    def __init__(self, universal_http_requests_driver=None):
+        # type: (Optional[BasicRequestsHTTPSender]) -> None
+        self.driver = universal_http_requests_driver or BasicRequestsHTTPSender()
+
+    def __enter__(self):
+        # type: () -> PipelineRequestsHTTPSender
+        self.driver.__enter__()
+        return self
+
+    def __exit__(self, *exc_details):  # pylint: disable=arguments-differ
+        self.driver.__exit__(*exc_details)
+
+    def close(self):
+        self.__exit__()
+
+    def build_context(self):
+        # type: () -> RequestsContext
+        return RequestsContext(
+            session=self.driver.session,
+        )
+
+    def send(self, request, **kwargs):
+        # type: (Request[ClientRequest], Any) -> Response
+        """Send request object according to configuration.
+
+        :param Request request: The request object to be sent.
+        """
+        if request.context is None:  # Should not happen, but make mypy happy and does not hurt
+            request.context = self.build_context()
+
+        if request.context.session is not self.driver.session:
+            kwargs['session'] = request.context.session
+
+        return Response(
+            request,
+            self.driver.send(request.http_request, **kwargs)
+        )
diff --git a/.venv/lib/python3.12/site-packages/msrest/pipeline/universal.py b/.venv/lib/python3.12/site-packages/msrest/pipeline/universal.py
new file mode 100644
index 00000000..b8dc40c9
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/msrest/pipeline/universal.py
@@ -0,0 +1,253 @@
+# --------------------------------------------------------------------------
+#
+# Copyright (c) Microsoft Corporation. All rights reserved.
+#
+# The MIT License (MIT)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the ""Software""), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# --------------------------------------------------------------------------
+"""
+This module represents universal policy that works whatever the HTTPSender implementation
+"""
+import json
+import logging
+import os
+import xml.etree.ElementTree as ET
+import platform
+import codecs
+import re
+
+from typing import Mapping, Any, Optional, AnyStr, Union, IO, cast, TYPE_CHECKING  # pylint: disable=unused-import
+
+from ..version import msrest_version as _msrest_version
+from . import SansIOHTTPPolicy
+from ..exceptions import DeserializationError, raise_with_traceback
+from ..http_logger import log_request, log_response
+
+if TYPE_CHECKING:
+    from . import Request, Response  # pylint: disable=unused-import
+
+
+_LOGGER = logging.getLogger(__name__)
+
+_BOM = codecs.BOM_UTF8.decode(encoding='utf-8')
+
+
+class HeadersPolicy(SansIOHTTPPolicy):
+    """A simple policy that sends the given headers
+    with the request.
+
+    This overwrite any headers already defined in the request.
+    """
+    def __init__(self, headers):
+        # type: (Mapping[str, str]) -> None
+        self.headers = headers
+
+    def on_request(self, request, **kwargs):
+        # type: (Request, Any) -> None
+        http_request = request.http_request
+        http_request.headers.update(self.headers)
+
+class UserAgentPolicy(SansIOHTTPPolicy):
+    _USERAGENT = "User-Agent"
+    _ENV_ADDITIONAL_USER_AGENT = 'AZURE_HTTP_USER_AGENT'
+
+    def __init__(self, user_agent=None, overwrite=False):
+        # type: (Optional[str], bool) -> None
+        self._overwrite = overwrite
+        if user_agent is None:
+            self._user_agent = "python/{} ({}) msrest/{}".format(
+                platform.python_version(),
+                platform.platform(),
+                _msrest_version
+            )
+        else:
+            self._user_agent = user_agent
+
+        # Whatever you gave me a header explicitly or not,
+        # if the env variable is set, add to it.
+        add_user_agent_header = os.environ.get(self._ENV_ADDITIONAL_USER_AGENT, None)
+        if add_user_agent_header is not None:
+            self.add_user_agent(add_user_agent_header)
+
+    @property
+    def user_agent(self):
+        # type: () -> str
+        """The current user agent value."""
+        return self._user_agent
+
+    def add_user_agent(self, value):
+        # type: (str) -> None
+        """Add value to current user agent with a space.
+
+        :param str value: value to add to user agent.
+        """
+        self._user_agent = "{} {}".format(self._user_agent, value)
+
+    def on_request(self, request, **kwargs):
+        # type: (Request, Any) -> None
+        http_request = request.http_request
+        if self._overwrite or self._USERAGENT not in http_request.headers:
+            http_request.headers[self._USERAGENT] = self._user_agent
+
+class HTTPLogger(SansIOHTTPPolicy):
+    """A policy that logs HTTP request and response to the DEBUG logger.
+
+    This accepts both global configuration, and kwargs request level with "enable_http_logger"
+    """
+    def __init__(self, enable_http_logger = False):
+        self.enable_http_logger = enable_http_logger
+
+    def on_request(self, request, **kwargs):
+        # type: (Request, Any) -> None
+        http_request = request.http_request
+        if kwargs.get("enable_http_logger", self.enable_http_logger):
+            log_request(None, http_request)
+
+    def on_response(self, request, response, **kwargs):
+        # type: (Request, Response, Any) -> None
+        http_request = request.http_request
+        if kwargs.get("enable_http_logger", self.enable_http_logger):
+            log_response(None, http_request, response.http_response, result=response)
+
+
+class RawDeserializer(SansIOHTTPPolicy):
+
+    # Accept "text" because we're open minded people...
+    JSON_REGEXP = re.compile(r'^(application|text)/([a-z+.]+\+)?json$')
+
+    # Name used in context
+    CONTEXT_NAME = "deserialized_data"
+
+    @classmethod
+    def deserialize_from_text(cls, data, content_type=None):
+        # type: (Optional[Union[AnyStr, IO]], Optional[str]) -> Any
+        """Decode data according to content-type.
+
+        Accept a stream of data as well, but will be load at once in memory for now.
+
+        If no content-type, will return the string version (not bytes, not stream)
+
+        :param data: Input, could be bytes or stream (will be decoded with UTF8) or text
+        :type data: str or bytes or IO
+        :param str content_type: The content type.
+        """
+        if hasattr(data, 'read'):
+            # Assume a stream
+            data = cast(IO, data).read()
+
+        if isinstance(data, bytes):
+            data_as_str = data.decode(encoding='utf-8-sig')
+        else:
+            # Explain to mypy the correct type.
+            data_as_str = cast(str, data)
+
+            # Remove Byte Order Mark if present in string
+            data_as_str = data_as_str.lstrip(_BOM)
+
+        if content_type is None:
+            return data
+
+        if cls.JSON_REGEXP.match(content_type):
+            try:
+                return json.loads(data_as_str)
+            except ValueError as err:
+                raise DeserializationError("JSON is invalid: {}".format(err), err)
+        elif "xml" in (content_type or []):
+            try:
+
+                try:
+                    if isinstance(data, unicode):  # type: ignore
+                        # If I'm Python 2.7 and unicode XML will scream if I try a "fromstring" on unicode string
+                        data_as_str = data_as_str.encode(encoding="utf-8")  # type: ignore
+                except NameError:
+                    pass
+
+                return ET.fromstring(data_as_str)
+            except ET.ParseError:
+                # It might be because the server has an issue, and returned JSON with
+                # content-type XML....
+                # So let's try a JSON load, and if it's still broken
+                # let's flow the initial exception
+                def _json_attemp(data):
+                    try:
+                        return True, json.loads(data)
+                    except ValueError:
+                        return False, None # Don't care about this one
+                success, json_result = _json_attemp(data)
+                if success:
+                    return json_result
+                # If i'm here, it's not JSON, it's not XML, let's scream
+                # and raise the last context in this block (the XML exception)
+                # The function hack is because Py2.7 messes up with exception
+                # context otherwise.
+                _LOGGER.critical("Wasn't XML not JSON, failing")
+                raise_with_traceback(DeserializationError, "XML is invalid")
+        raise DeserializationError("Cannot deserialize content-type: {}".format(content_type))
+
+    @classmethod
+    def deserialize_from_http_generics(cls, body_bytes, headers):
+        # type: (Optional[Union[AnyStr, IO]], Mapping) -> Any
+        """Deserialize from HTTP response.
+
+        Use bytes and headers to NOT use any requests/aiohttp or whatever
+        specific implementation.
+        Headers will tested for "content-type"
+        """
+        # Try to use content-type from headers if available
+        content_type = None
+        if 'content-type' in headers:
+            content_type = headers['content-type'].split(";")[0].strip().lower()
+        # Ouch, this server did not declare what it sent...
+        # Let's guess it's JSON...
+        # Also, since Autorest was considering that an empty body was a valid JSON,
+        # need that test as well....
+        else:
+            content_type = "application/json"
+
+        if body_bytes:
+            return cls.deserialize_from_text(body_bytes, content_type)
+        return None
+
+    def on_response(self, request, response, **kwargs):
+        # type: (Request, Response, Any) -> None
+        """Extract data from the body of a REST response object.
+
+        This will load the entire payload in memory.
+
+        Will follow Content-Type to parse.
+        We assume everything is UTF8 (BOM acceptable).
+
+        :param raw_data: Data to be processed.
+        :param content_type: How to parse if raw_data is a string/bytes.
+        :raises JSONDecodeError: If JSON is requested and parsing is impossible.
+        :raises UnicodeDecodeError: If bytes is not UTF8
+        :raises xml.etree.ElementTree.ParseError: If bytes is not valid XML
+        """
+        # If response was asked as stream, do NOT read anything and quit now
+        if kwargs.get("stream", True):
+            return
+
+        http_response = response.http_response
+
+        response.context[self.CONTEXT_NAME] = self.deserialize_from_http_generics(
+            http_response.text(),
+            http_response.headers
+        )