(compatibility)=

{fa}plus-square Usage with other requests-based libraries

This library works by patching and/or extending {py:class}requests.Session. Many other libraries out there do the same thing, making it potentially difficult to combine them.

For that scenario, a mixin class is provided, so you can create a custom class with behavior from multiple Session-modifying libraries:

>>> from requests import Session
>>> from requests_cache import CacheMixin
>>> from some_other_lib import SomeOtherMixin

>>> class CustomSession(CacheMixin, SomeOtherMixin, Session):
...     """Session class with features from both some_other_lib and requests-cache"""

Requests-HTML

requests-html is one library that works with this method:

>>> import requests
>>> from requests_cache import CacheMixin, install_cache
>>> from requests_html import HTMLSession

>>> class CachedHTMLSession(CacheMixin, HTMLSession):
...     """Session with features from both CachedSession and HTMLSession"""

>>> session = CachedHTMLSession()
>>> response = session.get('https://github.com/')
>>> print(response.from_cache, response.html.links)

Or if you are using {py:func}.install_cache, you can use the session_factory argument:

>>> install_cache(session_factory=CachedHTMLSession)
>>> response = requests.get('https://github.com/')
>>> print(response.from_cache, response.html.links)

The same approach can be used with other libraries that subclass {py:class}requests.Session.

Requests-Futures

Some libraries, including requests-futures, support wrapping an existing session object:

>>> from requests_cache import CachedSession
>>> from requests_futures.sessions import FuturesSession

>>> session = FutureSession(session=CachedSession())

In this case, FutureSession must wrap CachedSession rather than the other way around, since FutureSession returns (as you might expect) futures rather than response objects. See issue #135 for more notes on this.

Requests-OAuthlib

Usage with requests-oauthlib is the same as other libraries that subclass requests.Session:

>>> from requests_cache import CacheMixin
>>> from requests_oauthlib import OAuth2Session

>>> class CachedOAuth2Session(CacheMixin, OAuth2Session):
...     """Session with features from both CachedSession and OAuth2Session"""

>>> session = CachedOAuth2Session('my_client_id')

Requests-Ratelimiter

requests-ratelimiter adds rate-limiting to requests via the pyrate-limiter library. It also provides a mixin, but note that the inheritance order is important: If rate-limiting is applied after caching, you get the added benefit of not counting cache hits against your rate limit.

>>> from pyrate_limiter import RedisBucket, RequestRate, Duration
>>> from requests import Session
>>> from requests_cache import CacheMixin, RedisCache
>>> from requests_ratelimiter import LimiterMixin

>>> class CachedLimiterSession(CacheMixin, LimiterMixin, Session):
...     """Session class with caching and rate-limiting behavior. Accepts arguments for both
...     LimiterSession and CachedSession.
...     """

>>> # Limit non-cached requests to 5 requests per second, with unlimited cached requests
>>> # Optionally use Redis as both the bucket backend and the cache backend
>>> session = CachedLimiterSession(
...     rates=RequestRate(5, Duration.SECOND),
...     bucket_class=RedisBucket,
...     backend=RedisCache(),
... )

Internet Archive

Usage with internetarchive is the same as other libraries that subclass requests.Session:

>>> from requests_cache import CacheMixin
>>> from internetarchive.session import ArchiveSession

>>> class CachedArchiveSession(CacheMixin, ArchiveSession):
...     """Session with features from both CachedSession and ArchiveSession"""

>>> session = CachedArchiveSession()

Requests-Mock

requests-mock has multiple methods for mocking requests, including a contextmanager, decorator, fixture, and adapter. There are a few different options for using it with requests-cache, depending on how you want your tests to work.

Disabling requests-cache

If you have an application that uses requests-cache and you just want to use requests-mock in your tests, the easiest thing to do is to disable requests-cache.

For example, if you are using {py:func}.install_cache in your application and the requests-mock pytest fixture in your tests, you could wrap it in another fixture that uses {py:func}.uninstall_cache or {py:func}.disabled: :::{admonition} Example: test_requests_mock_disable_cache.py :class: toggle

:::

Or if you use a CachedSession object, you could replace it with a regular Session, for example:

>>> import unittest
>>> import pytest
>>> import requests

>>> @pytest.fixure(scope='function', autouse=True)
>>> def disable_requests_cache():
...     """Replace CachedSession with a regular Session for all test functions"""
...     with unittest.mock.patch('requests_cache.CachedSession', requests.Session):
...         yield

Combining requests-cache with requests-mock

If you want both caching and mocking features at the same time, you can attach requests-mock's adapter to a CachedSession:

:::{admonition} Example: test_requests_mock_combine_cache.py :class: toggle

:::

Building a mocker using requests-cache data

Another approach is to use cached data to dynamically define mock requests + responses. This has the advantage of only using request-mock's behavior for request matching.

:lines: 21-40

To turn that into a complete example: :::{admonition} Example: test_requests_mock_load_cache.py :class: toggle

:::

Responses

Usage with the responses library is similar to the requests-mock examples above.

:::{admonition} Example: test_responses_load_cache.py :class: toggle

:::

VCR

If you would like to reuse your cached response data for unit tests, one option is to convert your cache into a format compatible with VCR-vased libraries like vcrpy and betamax. :::{admonition} Example: vcr.py :class: toggle

:lines: 7-

:::