Skip to main content

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

Project description

https://travis-ci.org/getsentry/responses.png?branch=master

A utility library for mocking out the requests Python library.

Response body as string

import responses
import requests

@responses.activate
def test_my_api():
    responses.add(responses.GET, 'http://twitter.com/api/1/foobar',
                  body='{"error": "not found"}', status=404,
                  content_type='application/json')

    resp = requests.get('http://twitter.com/api/1/foobar')

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

    assert len(responses.calls) == 1
    assert responses.calls[0].request.url == 'http://twitter.com/api/1/foobar'
    assert responses.calls[0].response.text == '{"error": "not found"}'

You can also specify a JSON object instead of a body string.

import responses
import requests

@responses.activate
def test_my_api():
    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')

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

    assert len(responses.calls) == 1
    assert responses.calls[0].request.url == 'http://twitter.com/api/1/foobar'
    assert responses.calls[0].response.text == '{"error": "not found"}'

Request callback

import json

import responses
import requests

@responses.activate
def test_calc_api():

    def request_callback(request):
        payload = json.loads(request.body)
        resp_body = {'value': sum(payload['numbers'])}
        headers = {'request-id': '728d329e-0e86-11e4-a748-0c84dc037c13'}
        return (200, headers, json.dumps(resp_body))

    responses.add_callback(
        responses.POST, 'http://calc.com/sum',
        callback=request_callback,
        content_type='application/json',
    )

    resp = requests.post(
        'http://calc.com/sum',
        json.dumps({'numbers': [1, 2, 3]}),
        headers={'content-type': 'application/json'},
    )

    assert resp.json() == {'value': 6}

    assert len(responses.calls) == 1
    assert responses.calls[0].request.url == 'http://calc.com/sum'
    assert responses.calls[0].response.text == '{"value": 6}'
    assert (
        responses.calls[0].response.headers['request-id'] ==
        '728d329e-0e86-11e4-a748-0c84dc037c13'
    )

Instead of passing a string URL into responses.add or responses.add_callback you can also supply a compiled regular expression.

import re
import responses
import requests

# Instead of
responses.add(responses.GET, 'http://twitter.com/api/1/foobar',
              body='{"error": "not found"}', status=404,
              content_type='application/json')

# You can do the following
url_re = re.compile(r'https?://twitter.com/api/\d+/foobar')
responses.add(responses.GET, url_re,
              body='{"error": "not found"}', status=404,
              content_type='application/json')

A response can also throw an exception as follows.

import responses
import requests
from requests.exceptions import HTTPError

exception = HTTPError('Something went wrong')
responses.add(responses.GET, 'http://twitter.com/api/1/foobar',
              body=exception)
# All calls to 'http://twitter.com/api/1/foobar' will throw exception.

Responses as a context manager

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

Assertions on declared responses

By default Responses will raise an assertion error if a url was registered but not accessed. This can be disabled by passing the assert_all_requests_are_fired value:

import responses
import requests


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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

responses-0.5.1.tar.gz (10.2 kB view details)

Uploaded Source

Built Distribution

responses-0.5.1-py2.py3-none-any.whl (7.5 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file responses-0.5.1.tar.gz.

File metadata

  • Download URL: responses-0.5.1.tar.gz
  • Upload date:
  • Size: 10.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for responses-0.5.1.tar.gz
Algorithm Hash digest
SHA256 8cad64c45959a651ceaf0023484bd26180c927fea64a81e63d334ddf6377ecea
MD5 f1962b295b18128c522e83901556deac
BLAKE2b-256 09e4ae639e37d9d35903fdeda416d7f9c9e3a0331895d574b4fe6632a27c9190

See more details on using hashes here.

File details

Details for the file responses-0.5.1-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for responses-0.5.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 3a907f7aae2fd2286d06cfdf238957786c38bbcadc451adceecc769a4ef882b7
MD5 1833cc5ae0fcfb5954c53a6ae79caa16
BLAKE2b-256 60ffd99b0ef8e5169fbde76f9de6bcc7cad4e4b60e07ff8077cb64ad992314f8

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page