Give AlbumentationsX a star on GitHub — it powers this leaderboard

Star on GitHub

responses

A utility library for mocking out the `requests` Python library.

Downloads: 0 (30 days)

Description

Responses
=========

.. image:: https://img.shields.io/pypi/v/responses.svg
    :target: https://pypi.python.org/pypi/responses/

.. image:: https://img.shields.io/pypi/pyversions/responses.svg
    :target: https://pypi.org/project/responses/

.. image:: https://img.shields.io/pypi/dm/responses
   :target: https://pypi.python.org/pypi/responses/

.. image:: https://codecov.io/gh/getsentry/responses/branch/master/graph/badge.svg
    :target: https://codecov.io/gh/getsentry/responses/

A utility library for mocking out the ``requests`` Python library.

..  note::

    Responses requires Python 3.8 or newer, and requests >= 2.30.0


Table of Contents
-----------------

.. contents::


Installing
----------

``pip install responses``


Deprecations and Migration Path
-------------------------------

Here you will find a list of deprecated functionality and a migration path for each.
Please ensure to update your code according to the guidance.

.. list-table:: Deprecation and Migration
   :widths: 50 25 50
   :header-rows: 1

   * - Deprecated Functionality
     - Deprecated in Version
     - Migration Path
   * - ``responses.json_params_matcher``
     - 0.14.0
     - ``responses.matchers.json_params_matcher``
   * - ``responses.urlencoded_params_matcher``
     - 0.14.0
     - ``responses.matchers.urlencoded_params_matcher``
   * - ``stream`` argument in ``Response`` and ``CallbackResponse``
     - 0.15.0
     - Use ``stream`` argument in request directly.
   * - ``match_querystring`` argument in ``Response`` and ``CallbackResponse``.
     - 0.17.0
     - Use ``responses.matchers.query_param_matcher`` or ``responses.matchers.query_string_matcher``
   * - ``responses.assert_all_requests_are_fired``, ``responses.passthru_prefixes``, ``responses.target``
     - 0.20.0
     - Use ``responses.mock.assert_all_requests_are_fired``,
       ``responses.mock.passthru_prefixes``, ``responses.mock.target`` instead.

Basics
------

The core of ``responses`` comes from registering mock responses and covering test function
with ``responses.activate`` decorator. ``responses`` provides similar interface as ``requests``.

Main Interface
^^^^^^^^^^^^^^

* responses.add(``Response`` or ``Response args``) - allows either to register ``Response`` object or directly
  provide arguments of ``Response`` object. See `Response Parameters`_

.. code-block:: python

    import responses
    import requests


    @responses.activate
    def test_simple():
        # Register via 'Response' object
        rsp1 = responses.Response(
            method="PUT",
            url="http://example.com",
        )
        responses.add(rsp1)
        # register via direct arguments
        responses.add(
            responses.GET,
            "http://twitter.com/api/1/foobar",
            json={"error": "not found"},
            status=404,
        )

        resp = requests.get("http://twitter.com/api/1/foobar")
        resp2 = requests.put("http://example.com")

        assert resp.json() == {"error": "not found"}
        assert resp.status_code == 404

        assert resp2.status_code == 200
        assert resp2.request.method == "PUT"


If you attempt to fetch a url which doesn't hit a match, ``responses`` will raise
a ``ConnectionError``:

.. code-block:: python

    import responses
    import requests

    from requests.exceptions import ConnectionError


    @responses.activate
    def test_simple():
        with pytest.raises(ConnectionError):
            requests.get("http://twitter.com/api/1/foobar")


Shortcuts
^^^^^^^^^

Shortcuts provide a shorten version of ``responses.add()`` where method argument is prefilled

* responses.delete(``Response args``) - register DELETE response
* responses.get(``Response args``) - register GET response
* responses.head(``Response args``) - register HEAD response
* responses.options(``Response args``) - register OPTIONS response
* responses.patch(``Response args``) - register PATCH response
* responses.post(``Response args``) - register POST response
* responses.put(``Response args``) - register PUT response

.. code-block:: python

    import responses
    import requests


    @responses.activate
    def test_simple():
        responses.get(
            "http://twitter.com/api/1/foobar",
            json={"type": "get"},
        )

        responses.post(
            "http://twitter.com/api/1/foobar",
            json={"type": "post"},
        )

        responses.patch(
            "http://twitter.com/api/1/foobar",
            json={"type": "patch"},
        )

        resp_get = requests.get("http://twitter.com/api/1/foobar")
        resp_post = requests.post("http://twitter.com/api/1/foobar")
        resp_patch = requests.patch("http://twitter.com/api/1/foobar")

        assert resp_get.json() == {"type": "get"}
        assert resp_post.json() == {"type": "post"}
        assert resp_patch.json() == {"type": "patch"}

Responses as a context manager
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Instead of wrapping the whole function with decorator you can use a context manager.

.. code-block:: python

    import responses
    import requests


    def test_my_api():
        with responses.RequestsMock() as rsps:
            rsps.add(
                responses.GET,
                "http://twitter.com/api/1/foobar",
                body="{}",
                status=200,
                content_type="application/json",
            )
            resp = requests.get("http://twitter.com/api/1/foobar")

            assert resp.status_code == 200

        # outside the context manager requests will hit the remote server
        resp = requests.get("http://twitter.com/api/1/foobar")
        resp.status_code == 404


Response Parameters
-------------------

The following attributes can be passed to a Response mock:

method (``str``)
    The HTTP method (GET, POST, etc).

url (``str`` or ``compiled regular expression``)
    The full resource URL.

match_querystring (``bool``)
    DEPRECATED: Use ``responses.matchers.query_param_matcher`` or
    ``responses.matchers.query_string_matcher``

    Include the query string when matching requests.
    Enabled by default if the response URL contains a query string,
    disabled if it doesn't or the URL is a regular expression.

body (``str`` or ``BufferedReader`` or ``Exception``)
    The response body. Read more `Exception as Response body`_

json
    A Python object representing the JSON response body. Automatically configures
    the appropriate Content-Type.

status (``int``)
    The HTTP status code.

content_type (``content_type``)
    Defaults to ``text/plain``.

headers (``dict``)
    Response headers.

stream (``bool``)
    DEPRECATED: use ``stream`` argument in request directly

auto_calculate_content_length (``bool``)
    Disabled by default. Automatically calculates the length of a supplied string or JSON body.

match (``tuple``)
    An iterable (``tuple`` is recommended) of callbacks to match requests
    based on request attributes.
    Current module provides multiple matchers that you can use to match:

    * body contents in JSON format
    * body contents in URL encoded data format
    * request query parameters
    * request query string (similar to query parameters but takes string as input)
    * kwargs provided to request e.g. ``stream``, ``verify``
    * 'multipart/form-data' content and headers in request
    * request headers
    * request fragment identifier

    Alternatively user can create custom matcher.
    Read more `Matching Requests`_


Exception as Response body
--------------------------

You can pass an ``Exception`` as the body to trigger an error on the request:

.. code-block:: python

    import responses
    import requests


    @responses.activate
    def test_simple():
        responses.get("http://twitter.com/api/1/foobar", body=Exception("..."))
        with pytest.raises(Exception):
            requests.get("http://twitter.com/api/1/foobar")


Matching Requests
-----------------

Matching Request Body Contents
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When adding responses for endpoints that are sent request data you can add
matchers to ensure your code is sending the right parameters and provide
different responses based on the request body contents. ``responses`` provides
matchers for JSON and URL-encoded request bodies.

URL-encoded data
""""""""""""""""

.. code-block:: python

    import responses
    import requests
    from responses import matchers


    @responses.activate
    def test_calc_api():
        responses.post(
            url="http://calc.com/sum",
            body="4",
            match=[matchers.urlencoded_params_matcher({"left": "1", "right": "3"})],
        )
        requests.post("http://calc.com/sum", data={"left": 1, "right": 3})


JSON encoded data
"""""""""""""""""

Matching JSON encoded data can be done with ``matchers.json_params_matcher()``.

.. code-block:: python

    import responses
    import requests
    from responses import matchers


    @responses.activate
    def test_calc_api():
        responses.post(
            url="http://example.com/",
            body="one",
            match=[
                matchers.json_params_matcher({"page": {"name": "first", "type": "json"}})
            ],
        )
        resp = requests.request(
            "POST",
            "http://example.com/",
            headers={"Content-Type": "application/json"},
            json={"page": {"name": "first", "type": "json"}},
        )


Query Parameters Matcher
^^^^^^^^^^^^^^^^^^^^^^^^

Query Parameters as a Dictionary
""""""""""""""""""""""""""""""""

You can use the ``matchers.query_param_matcher`` function to match
against the ``params`` request parameter. Just use the same dictionary as you
will use in ``params`` argument in ``request``.

Note, do not use query parameters as part of the URL. Avoid using ``match_querystring``
deprecated argument.

.. code-block:: python

    import responses
    import requests
    from responses