class RequestsClient(interfaces.HttpClientAdapter):
    """
    A :py:mod:`requests` client that returns
    :py:class:`requests.Response` responses.

    Args:
        session (:py:class:`requests.Session`, optional): The session
            that should handle sending requests. If this argument is
            omitted or set to :py:obj:`None`, a new session will be
            created.
    """

    exceptions = exceptions.Exceptions()

    def __init__(self, session=None, **kwargs):
        if session is None:
            session = self._create_session(**kwargs)
        self.__session = session

    def create_request(self):
        return Request(self.__session)

    @staticmethod
    @register.handler
    def with_session(session, *args, **kwargs):
        if isinstance(session, requests.Session):
            return RequestsClient(session, *args, **kwargs)

    @staticmethod
    def _create_session(**kwargs):
        session = requests.Session()
        atexit.register(session.close)
        for key in kwargs:
            setattr(session, key, kwargs[key])
        return session
示例#2
0
class HttpClientAdapter(object):
    """An adapter of an HTTP client library."""

    __exceptions = exceptions.Exceptions()

    def create_request(self):
        raise NotImplementedError

    def io(self):
        """Returns the execution strategy for this client."""
        raise NotImplementedError

    @property
    def exceptions(self):
        """
        uplink.clients.exceptions.Exceptions: An enum of standard HTTP
        client errors that have been mapped to client specific
        exceptions.
        """
        return self.__exceptions

    def send(self, request, template, data):
        class Client(io.Client):
            def send(self, r):
                return request.send(*r)

        return io.execute(Client(), self.io(), template, data)
示例#3
0
class RequestsClient(interfaces.HttpClientAdapter):
    """
    A :py:mod:`requests` client that returns
    :py:class:`requests.Response` responses.

    Args:
        session (:py:class:`requests.Session`, optional): The session
            that should handle sending requests. If this argument is
            omitted or set to :py:obj:`None`, a new session will be
            created.
    """

    exceptions = exceptions.Exceptions()

    def __init__(self, session=None, **kwargs):
        self.__auto_created_session = False
        if session is None:
            session = self._create_session(**kwargs)
            self.__auto_created_session = True
        self.__session = session

    def __del__(self):
        if self.__auto_created_session:
            self.__session.close()

    @staticmethod
    @register.handler
    def with_session(session, *args, **kwargs):
        if isinstance(session, requests.Session):
            return RequestsClient(session, *args, **kwargs)

    @staticmethod
    def _create_session(**kwargs):
        session = requests.Session()
        for key in kwargs:
            setattr(session, key, kwargs[key])
        return session

    def send(self, request):
        method, url, extras = request
        return self.__session.request(method=method, url=url, **extras)

    def apply_callback(self, callback, response):
        return callback(response)

    @staticmethod
    def io():
        return io.BlockingStrategy()
class HttpClientAdapter(object):
    """An adapter of an HTTP client library."""

    __exceptions = exceptions.Exceptions()

    def create_request(self):
        raise NotImplementedError

    @property
    def exceptions(self):
        """
        uplink.clients.exceptions.Exceptions: An enum of standard HTTP
        client errors that have been mapped to client specific
        exceptions.
        """
        return self.__exceptions
示例#5
0
class HttpxClient(interfaces.HttpClientAdapter):
    exceptions = exceptions.Exceptions()

    def __init__(self, session=None, **kwargs):
        if httpx is None:
            raise NotImplementedError("httpx is not installed.")
        self._auto_created_session = False
        if session is None:
            session = httpx.AsyncClient(**kwargs)
            self._auto_created_session = True
        self._session = session
        self._sync_callback_adapter = threaded_callback

    def __del__(self):
        if self._auto_created_session:
            try:
                asyncio.get_event_loop().create_task(self._session.aclose())
            except RuntimeError:
                asyncio.get_event_loop().run_until_complete(
                    self._session.aclose())

    @staticmethod
    @register.handler
    def with_session(session, *args, **kwargs):
        if isinstance(session, httpx.AsyncClient):
            return HttpxClient(session, *args, **kwargs)

    async def send(self, request):
        method, url, extras = request
        response = await self._session.request(method=method,
                                               url=url,
                                               **extras)
        return response

    def wrap_callback(self, callback):
        if not asyncio.iscoroutinefunction(callback):
            callback = self._sync_callback_adapter(callback)
        return callback

    def apply_callback(self, callback, response):
        return self.wrap_callback(callback)(response)

    @staticmethod
    def io():
        return io.AsyncioStrategy()
示例#6
0
class HttpClientAdapter(io.Client):
    """An adapter of an HTTP client library."""

    __exceptions = exceptions.Exceptions()

    def io(self):
        """Returns the execution strategy for this client."""
        raise NotImplementedError

    @property
    def exceptions(self):
        """
        uplink.clients.exceptions.Exceptions: An enum of standard HTTP
        client errors that have been mapped to client specific
        exceptions.
        """
        return self.__exceptions

    def send(self, request):
        raise NotImplementedError

    def apply_callback(self, callback, response):
        raise NotImplementedError
示例#7
0
class AiohttpClient(interfaces.HttpClientAdapter):
    """
    An :py:mod:`aiohttp` client that creates awaitable responses.

    Note:
        This client is an optional feature and requires the :py:mod:`aiohttp`
        package. For example, here's how to install this extra using pip::

            $ pip install uplink[aiohttp]

    Args:
        session (:py:class:`aiohttp.ClientSession`, optional):
            The session that should handle sending requests. If this
            argument is omitted or set to :py:obj:`None`, a new session
            will be created.
    """

    exceptions = exceptions.Exceptions()

    # TODO: Update docstrings to include aiohttp constructor parameters.

    __ARG_SPEC = collections.namedtuple("__ARG_SPEC", "args kwargs")

    def __init__(self, session=None, **kwargs):
        if aiohttp is None:
            raise NotImplementedError("aiohttp is not installed.")
        if session is None:
            session = self._create_session(**kwargs)
        self._session = session
        self._sync_callback_adapter = threaded_callback

    def create_request(self):
        return Request(self)

    @asyncio.coroutine
    def session(self):
        """Returns the underlying `aiohttp.ClientSession`."""
        if isinstance(self._session, self.__ARG_SPEC):
            args, kwargs = self._session
            self._session = aiohttp.ClientSession(*args, **kwargs)

            # aiohttp v3.0 has made ClientSession.close a coroutine,
            # so we check whether it is one here and register it
            # to run appropriately at exit
            if asyncio.iscoroutinefunction(self._session.close):
                atexit.register(
                    partial(
                        asyncio.get_event_loop().run_until_complete,
                        self._session.close(),
                    ))
            else:
                atexit.register(self._session.close)

        return self._session

    def wrap_callback(self, callback):
        if not asyncio.iscoroutinefunction(callback):
            callback = self._sync_callback_adapter(callback)
        return callback

    @staticmethod
    @register.handler
    def with_session(session, *args, **kwargs):
        """
        Builds a client instance if the first argument is a
        :py:class:`aiohttp.ClientSession`. Otherwise, return :py:obj:`None`.
        """
        if isinstance(session, aiohttp.ClientSession):
            return AiohttpClient(session, *args, **kwargs)

    @classmethod
    def _create_session(cls, *args, **kwargs):
        return cls.__ARG_SPEC(args, kwargs)

    @classmethod
    def create(cls, *args, **kwargs):
        """
        Builds a client instance with
        :py:class:`aiohttp.ClientSession` arguments.

        Instead of directly initializing this class with a
        :py:class:`aiohttp.ClientSession`, use this method to have the
        client lazily construct a session when sending the first
        request. Hence, this method guarantees that the creation of the
        underlying session happens inside of a coroutine.

        Args:
            *args: positional arguments that
                :py:class:`aiohttp.ClientSession` takes.
            **kwargs: keyword arguments that
                :py:class:`aiohttp.ClientSession` takes.
        """
        session_build_args = cls._create_session(*args, **kwargs)
        return AiohttpClient(session=session_build_args)
示例#8
0
文件: __init__.py 项目: yyolk/uplink
 def __init__(self, mock_client):
     self._mock_client = mock_client
     self._exceptions = client_exceptions.Exceptions()
     self._history = []
     self._io = io.BlockingStrategy()
示例#9
0
 def __init__(self, request):
     self._mocked_request = request
     self._request = _HistoryMaintainingRequest(_MockRequest(request))
     self._exceptions = client_exceptions.Exceptions()
     self._io = io.BlockingStrategy()