HTTPretty’s - HTTP Client Mocking for Python¶
HTTP Client mocking tool for Python. Provides a full fake TCP socket module. Inspired by FakeWeb
Looking for the Github Repository ?
Python Support:
3.6
3.7
What is HTTPretty ?¶
Once upon a time a python developer wanted to use a RESTful api, everything was fine but until the day he needed to test the code that hits the RESTful API: what if the API server is down? What if its content has changed ?
Don’t worry, HTTPretty is here for you:
import requests
import httpretty
from sure import expect
@httpretty.activate
def test_yipit_api_returning_deals():
httpretty.register_uri(httpretty.GET, "http://api.yipit.com/v1/deals/",
body='[{"title": "Test Deal"}]',
content_type="application/json")
response = requests.get('http://api.yipit.com/v1/deals/')
expect(response.json()).to.equal([{"title": "Test Deal"}])
A more technical description¶
HTTPretty is a HTTP client mock library for Python 100% inspired on ruby’s [FakeWeb](http://fakeweb.rubyforge.org/). If you come from ruby this would probably sound familiar :smiley:
Demo¶
expecting a simple response body¶
import requests
import httpretty
def test_one():
httpretty.enable() # enable HTTPretty so that it will monkey patch the socket module
httpretty.register_uri(httpretty.GET, "http://yipit.com/",
body="Find the best daily deals")
response = requests.get('http://yipit.com')
assert response.text == "Find the best daily deals"
httpretty.disable() # disable afterwards, so that you will have no problems in code that uses that socket module
httpretty.reset() # reset HTTPretty state (clean up registered urls and request history)
making assertions in a callback that generates the response body¶
import requests
import json
import httpretty
@httpretty.activate
def test_with_callback_response():
def request_callback(request, uri, response_headers):
content_type = request.headers.get('Content-Type')
assert request.body == '{"nothing": "here"}', 'unexpected body: {}'.format(request.body)
assert content_type == 'application/json', 'expected application/json but received Content-Type: {}'.format(content_type)
return [200, response_headers, json.dumps({"hello": "world"})]
httpretty.register_uri(
httpretty.POST, "https://httpretty.example.com/api",
body=request_callback)
response = requests.post('https://httpretty.example.com/api', headers={'Content-Type': 'application/json'}, data='{"nothing": "here"}')
expect(response.json()).to.equal({"hello": "world"})
Link headers¶
Tests link headers by using the adding_headers parameter.
import requests from sure import expect import httpretty @httpretty.activate def test_link_response(): first_url = "http://foo-api.com/data" second_url = "http://foo-api.com/data?page=2" link_str = "<%s>; rel='next'" % second_url httpretty.register_uri( httpretty.GET, first_url, body='{"success": true}', status=200, content_type="text/json", adding_headers={"Link": link_str}, ) httpretty.register_uri( httpretty.GET, second_url, body='{"success": false}', status=500, content_type="text/json", ) # Performs a request to `first_url` followed by some testing response = requests.get(first_url) expect(response.json()).to.equal({"success": True}) expect(response.status_code).to.equal(200) next_url = response.links["next"]["url"] expect(next_url).to.equal(second_url) # Follow the next URL and perform some testing. response2 = requests.get(next_url) expect(response2.json()).to.equal({"success": False}) expect(response2.status_code).to.equal(500)
Motivation¶
When building systems that access external resources such as RESTful webservices, XMLRPC or even simple HTTP requests, we stumble in the problem:
“I’m gonna need to mock all those requests”
It brings a lot of hassle, you will need to use a generic mocking tool, mess with scope and so on.
The idea behind HTTPretty (how it works)¶
HTTPretty monkey patches Python’s socket core module, reimplementing the HTTP protocol, by mocking requests and responses.
As for how it works this way, you don’t need to worry what http library you’re gonna use.
HTTPretty will mock the response for you :) (and also give you the latest requests so that you can check them)
Acknowledgements¶
caveats¶
forcing_headers
+ Content-Length
¶
When using the forcing_headers
option make sure to add the header
Content-Length
otherwise calls using requests
will try
to load the response endlessly.
supported libraries¶
Because HTTPretty works in the socket level it should work with any HTTP client libraries, although it is battle tested against:
API Reference¶
register_uri¶
-
classmethod
httpretty.
register_uri
(method, uri, body='{"message": "HTTPretty :)"}', adding_headers=None, forcing_headers=None, status=200, responses=None, match_querystring=False, priority=0, **headers)[source]¶ import httpretty def request_callback(request, uri, response_headers): content_type = request.headers.get('Content-Type') assert request.body == '{"nothing": "here"}', 'unexpected body: {}'.format(request.body) assert content_type == 'application/json', 'expected application/json but received Content-Type: {}'.format(content_type) return [200, response_headers, json.dumps({"hello": "world"})] httpretty.register_uri( HTTPretty.POST, "https://httpretty.example.com/api", body=request_callback) with httpretty.enabled(): requests.post('https://httpretty.example.com/api', data='{"nothing": "here"}', headers={'Content-Type': 'application/json'}) assert httpretty.latest_requests[-1].url == 'https://httpbin.org/ip'
- Parameters
method – one of
httpretty.GET
,httpretty.PUT
,httpretty.POST
,httpretty.DELETE
,httpretty.HEAD
,httpretty.PATCH
,httpretty.OPTIONS
,httpretty.CONNECT
uri – a string or regex pattern (e.g.: “https://httpbin.org/ip”)
body – a string, defaults to
{"message": "HTTPretty :)"}
adding_headers – dict - headers to be added to the response
forcing_headers – dict - headers to be forcefully set in the response
status – an integer, defaults to 200
responses – a list of entries, ideally each created with
Response()
priority – an integer, useful for setting higher priority over previously registered urls. defaults to zero
match_querystring – bool - whether to take the querystring into account when matching an URL
headers – headers to be added to the response
Warning
When using a port in the request, add a trailing slash if no path is provided otherwise Httpretty will not catch the request. Ex:
httpretty.register_uri(httpretty.GET, 'http://fakeuri.com:8080/', body='{"hello":"world"}')
enable¶
-
classmethod
httpretty.
enable
(allow_net_connect=True)[source]¶ Enables HTTPretty. When
allow_net_connect
isFalse
any connection to an unregistered uri will throwhttpretty.errors.UnmockedError
.import re, json import httpretty httpretty.enable() httpretty.register_uri( httpretty.GET, re.compile(r'http://.*'), body=json.dumps({'man': 'in', 'the': 'middle'}) ) response = requests.get('https://foo.bar/foo/bar') response.json().should.equal({ "man": "in", "the": "middle", })
Warning
after calling this method the original
socket
is replaced withhttpretty.core.fakesock
. Make sure to calldisable()
after done with your tests or use thehttpretty.enabled
as decorator or context-manager
disable¶
-
classmethod
httpretty.
disable
()[source]¶ Disables HTTPretty entirely, putting the original
socket
module back in its place.import re, json import httpretty httpretty.enable() # request passes through fake socket response = requests.get('https://httpbin.org') httpretty.disable() # request uses real python socket module response = requests.get('https://httpbin.org')
Note
This method does not call
httpretty.core.reset()
automatically.
is_enabled¶
last_request¶
-
httpretty.
last_request
()[source]¶ - Returns
the last
HTTPrettyRequest
activate¶
-
httpretty.
activate
¶ alias of
httpretty.core.httprettified
httprettified¶
-
httpretty.core.
httprettified
(test=None, allow_net_connect=True)[source]¶ decorator for test functions
Tip
Also available under the alias
httpretty.activate()
- Parameters
test – a callable
example usage with nosetests
import sure from httpretty import httprettified @httprettified def test_using_nosetests(): httpretty.register_uri( httpretty.GET, 'https://httpbin.org/ip' ) response = requests.get('https://httpbin.org/ip') response.json().should.equal({ "message": "HTTPretty :)" })
example usage with unittest module
import unittest from sure import expect from httpretty import httprettified @httprettified class TestWithPyUnit(unittest.TestCase): def test_httpbin(self): httpretty.register_uri(httpretty.GET, 'https://httpbin.org/ip') response = requests.get('https://httpbin.org/ip') expect(response.json()).to.equal({ "message": "HTTPretty :)" })
enabled¶
-
httpretty.
enabled
¶ alias of
httpretty.core.httprettized
httprettized¶
-
class
httpretty.core.
httprettized
(allow_net_connect=True)[source]¶ context-manager for enabling HTTPretty.
Tip
Also available under the alias
httpretty.enabled()
import json import httpretty httpretty.register_uri(httpretty.GET, 'https://httpbin.org/ip', body=json.dumps({'origin': '42.42.42.42'})) with httpretty.enabled(): response = requests.get('https://httpbin.org/ip') assert httpretty.latest_requests[-1].url == 'https://httpbin.org/ip' assert response.json() == {'origin': '42.42.42.42'}
HTTPrettyRequest¶
-
class
httpretty.core.
HTTPrettyRequest
(headers, body='')[source]¶ Represents a HTTP request. It takes a valid multi-line,
\r\n
separated string with HTTP headers and parse them out using the internal parse_request method.It also replaces the rfile and wfile attributes with
io.BytesIO
instances so that we guarantee that it won’t make any I/O, neither for writing nor reading.It has some convenience attributes:
headers
-> a mimetype object that can be cast into a dictionary, contains all the request headersmethod
-> the HTTP method used in this requestquerystring
-> a dictionary containing lists with the attributes. Please notice that if you need a single value from a query string you will need to get it manually like:body
-> the request body as a stringparsed_body
-> the request body parsed byparse_request_body
>>> request.querystring {'name': ['Gabriel Falcao']} >>> print request.querystring['name'][0]
-
parse_querystring
(qs)[source]¶ parses an UTF-8 encoded query string into a dict of string lists
- Parameters
qs – a querystring
- Returns
a dict of lists
-
parse_request_body
(body)[source]¶ Attempt to parse the post based on the content-type passed. Return the regular body if not
- Parameters
body – string
- Returns
a python object such as dict or list in case the deserialization suceeded. Else returns the given param
body
-
querystring
¶ a dictionary containing parsed request body or None if HTTPrettyRequest doesn’t know how to parse it. It currently supports parsing body data that was sent under the
content`-type` headers values: ``application/json
orapplication/x-www-form-urlencoded
-
HTTPrettyRequestEmpty¶
-
class
httpretty.core.
HTTPrettyRequestEmpty
[source]¶ Represents an empty
HTTPrettyRequest
where all its properties are somehow empty orNone
FakeSockFile¶
FakeSSLSocket¶
URIInfo¶
-
class
httpretty.
URIInfo
(username='', password='', hostname='', port=80, path='/', query='', fragment='', scheme='', last_request=None)[source]¶ Internal representation of URIs
Tip
all arguments are optional
- Parameters
username –
password –
hostname –
port –
path –
query –
fragment –
scheme –
last_request –
URIMatcher¶
Entry¶
-
class
httpretty.
Entry
(method, uri, body, adding_headers=None, forcing_headers=None, status=200, streaming=False, **headers)[source]¶ Created by
register_uri()
and stored in memory as internal representation of a HTTP request/response definition.- Parameters
method (str) – One of
httpretty.GET
,httpretty.PUT
,httpretty.POST
,httpretty.DELETE
,httpretty.HEAD
,httpretty.PATCH
,httpretty.OPTIONS
,httpretty.CONNECT
.uri (str|re.Pattern) – The URL to match
adding_headers (dict) – Extra headers to be added to the response
forcing_headers (dict) – Overwrite response headers.
status (int) – The status code for the response, defaults to
200
.streaming (bool) – Whether should stream the response into chunks via generator.
headers – Headers to inject in the faked response.
- Returns
containing the request-matching metadata.
- Return type
Warning
When using the
forcing_headers
option make sure to add the headerContent-Length
to match at most the total body length, otherwise some HTTP clients can hang indefinitely.-
fill_filekind
(fk)[source]¶ writes HTTP Response data to a file descriptor
- Parm fk
a file-like object
Warning
side-effect: this method moves the cursor of the given file object to zero
Modules¶
Core¶
-
class
httpretty.core.
EmptyRequestHeaders
[source]¶ A dict subclass used as internal representation of empty request headers
-
class
httpretty.core.
Entry
(method, uri, body, adding_headers=None, forcing_headers=None, status=200, streaming=False, **headers)[source]¶ Created by
register_uri()
and stored in memory as internal representation of a HTTP request/response definition.- Parameters
method (str) – One of
httpretty.GET
,httpretty.PUT
,httpretty.POST
,httpretty.DELETE
,httpretty.HEAD
,httpretty.PATCH
,httpretty.OPTIONS
,httpretty.CONNECT
.uri (str|re.Pattern) – The URL to match
adding_headers (dict) – Extra headers to be added to the response
forcing_headers (dict) – Overwrite response headers.
status (int) – The status code for the response, defaults to
200
.streaming (bool) – Whether should stream the response into chunks via generator.
headers – Headers to inject in the faked response.
- Returns
containing the request-matching metadata.
- Return type
Warning
When using the
forcing_headers
option make sure to add the headerContent-Length
to match at most the total body length, otherwise some HTTP clients can hang indefinitely.-
fill_filekind
(fk)[source]¶ writes HTTP Response data to a file descriptor
- Parm fk
a file-like object
Warning
side-effect: this method moves the cursor of the given file object to zero
-
class
httpretty.core.
FakeSockFile
[source]¶ Fake socket file descriptor. Under the hood all data is written in a temporary file, giving it a real file descriptor number.
-
class
httpretty.core.
HTTPrettyRequest
(headers, body='')[source]¶ Represents a HTTP request. It takes a valid multi-line,
\r\n
separated string with HTTP headers and parse them out using the internal parse_request method.It also replaces the rfile and wfile attributes with
io.BytesIO
instances so that we guarantee that it won’t make any I/O, neither for writing nor reading.It has some convenience attributes:
headers
-> a mimetype object that can be cast into a dictionary, contains all the request headersmethod
-> the HTTP method used in this requestquerystring
-> a dictionary containing lists with the attributes. Please notice that if you need a single value from a query string you will need to get it manually like:body
-> the request body as a stringparsed_body
-> the request body parsed byparse_request_body
>>> request.querystring {'name': ['Gabriel Falcao']} >>> print request.querystring['name'][0]
-
parse_querystring
(qs)[source]¶ parses an UTF-8 encoded query string into a dict of string lists
- Parameters
qs – a querystring
- Returns
a dict of lists
-
parse_request_body
(body)[source]¶ Attempt to parse the post based on the content-type passed. Return the regular body if not
- Parameters
body – string
- Returns
a python object such as dict or list in case the deserialization suceeded. Else returns the given param
body
-
querystring
¶ a dictionary containing parsed request body or None if HTTPrettyRequest doesn’t know how to parse it. It currently supports parsing body data that was sent under the
content`-type` headers values: ``application/json
orapplication/x-www-form-urlencoded
-
-
class
httpretty.core.
HTTPrettyRequestEmpty
[source]¶ Represents an empty
HTTPrettyRequest
where all its properties are somehow empty orNone
-
class
httpretty.core.
URIInfo
(username='', password='', hostname='', port=80, path='/', query='', fragment='', scheme='', last_request=None)[source]¶ Internal representation of URIs
Tip
all arguments are optional
- Parameters
username –
password –
hostname –
port –
path –
query –
fragment –
scheme –
last_request –
-
httpretty.core.
create_fake_connection
(address, timeout=<object object>, source_address=None)[source]¶ drop-in replacement for
socket.create_connection()
-
httpretty.core.
fake_getaddrinfo
(host, port, family=None, socktype=None, proto=None, flags=None)[source]¶ drop-in replacement for
socket.getaddrinfo()
-
httpretty.core.
fake_gethostbyname
(host)[source]¶ drop-in replacement for
socket.gethostbyname()
-
httpretty.core.
fake_gethostname
()[source]¶ drop-in replacement for
socket.gethostname()
-
httpretty.core.
fake_wrap_socket
(orig_wrap_socket_fn, *args, **kw)[source]¶ drop-in replacement for py:func:ssl.wrap_socket
-
class
httpretty.core.
fakesock
[source]¶ fake
socket
-
class
socket
(family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, proto=0, fileno=None)[source]¶ drop-in replacement for
socket.socket
-
makefile
(mode='r', bufsize=- 1)[source]¶ Returns this fake socket’s own tempfile buffer.
If there is an entry associated with the socket, the file descriptor gets filled in with the entry data before being returned.
-
-
class
-
httpretty.core.
httprettified
(test=None, allow_net_connect=True)[source]¶ decorator for test functions
Tip
Also available under the alias
httpretty.activate()
- Parameters
test – a callable
example usage with nosetests
import sure from httpretty import httprettified @httprettified def test_using_nosetests(): httpretty.register_uri( httpretty.GET, 'https://httpbin.org/ip' ) response = requests.get('https://httpbin.org/ip') response.json().should.equal({ "message": "HTTPretty :)" })
example usage with unittest module
import unittest from sure import expect from httpretty import httprettified @httprettified class TestWithPyUnit(unittest.TestCase): def test_httpbin(self): httpretty.register_uri(httpretty.GET, 'https://httpbin.org/ip') response = requests.get('https://httpbin.org/ip') expect(response.json()).to.equal({ "message": "HTTPretty :)" })
-
class
httpretty.core.
httprettized
(allow_net_connect=True)[source]¶ context-manager for enabling HTTPretty.
Tip
Also available under the alias
httpretty.enabled()
import json import httpretty httpretty.register_uri(httpretty.GET, 'https://httpbin.org/ip', body=json.dumps({'origin': '42.42.42.42'})) with httpretty.enabled(): response = requests.get('https://httpbin.org/ip') assert httpretty.latest_requests[-1].url == 'https://httpbin.org/ip' assert response.json() == {'origin': '42.42.42.42'}
-
class
httpretty.core.
httpretty
[source]¶ manages HTTPretty’s internal request/response registry and request matching.
-
classmethod
Response
(body, method=None, uri=None, adding_headers=None, forcing_headers=None, status=200, streaming=False, **kw)[source]¶ Shortcut to create an
Entry
that takes the body as first positional argument.See also
the parameters of this function match those of the
Entry
constructor.- Parameters
body (str) – The body to return as response..
method (str) – One of
httpretty.GET
,httpretty.PUT
,httpretty.POST
,httpretty.DELETE
,httpretty.HEAD
,httpretty.PATCH
,httpretty.OPTIONS
,httpretty.CONNECT
.uri (str|re.Pattern) – The URL to match
adding_headers (dict) – Extra headers to be added to the response
forcing_headers (dict) – Overwrite any response headers, even “Content-Length”.
status (int) – The status code for the response, defaults to
200
.streaming (bool) – Whether should stream the response into chunks via generator.
kwargs – Keyword-arguments are forwarded to
Entry
- Returns
containing the request-matching metadata.
- Return type
-
classmethod
disable
()[source]¶ Disables HTTPretty entirely, putting the original
socket
module back in its place.import re, json import httpretty httpretty.enable() # request passes through fake socket response = requests.get('https://httpbin.org') httpretty.disable() # request uses real python socket module response = requests.get('https://httpbin.org')
Note
This method does not call
httpretty.core.reset()
automatically.
-
classmethod
enable
(allow_net_connect=True)[source]¶ Enables HTTPretty. When
allow_net_connect
isFalse
any connection to an unregistered uri will throwhttpretty.errors.UnmockedError
.import re, json import httpretty httpretty.enable() httpretty.register_uri( httpretty.GET, re.compile(r'http://.*'), body=json.dumps({'man': 'in', 'the': 'middle'}) ) response = requests.get('https://foo.bar/foo/bar') response.json().should.equal({ "man": "in", "the": "middle", })
Warning
after calling this method the original
socket
is replaced withhttpretty.core.fakesock
. Make sure to calldisable()
after done with your tests or use thehttpretty.enabled
as decorator or context-manager
-
classmethod
historify_request
(headers, body='', append=True)[source]¶ appends request to a list for later retrieval
import httpretty httpretty.register_uri(httpretty.GET, 'https://httpbin.org/ip', body='') with httpretty.enabled(): requests.get('https://httpbin.org/ip') assert httpretty.latest_requests[-1].url == 'https://httpbin.org/ip'
-
classmethod
is_enabled
()[source]¶ Check if HTTPretty is enabled
- Returns
bool
import httpretty httpretty.enable() assert httpretty.is_enabled() == True httpretty.disable() assert httpretty.is_enabled() == False
-
classmethod
match_http_address
(hostname, port)[source]¶ - Parameters
hostname – a string
port – an integer
- Returns
an
URLMatcher
orNone
-
classmethod
match_https_hostname
(hostname)[source]¶ - Parameters
hostname – a string
- Returns
an
URLMatcher
orNone
-
classmethod
playback
(filename)[source]¶ import io import json import requests import httpretty with httpretty.record('/tmp/ip.json'): data = requests.get('https://httpbin.org/ip').json() with io.open('/tmp/ip.json') as fd: assert data == json.load(fd)
- Parameters
filename – a string
- Returns
-
classmethod
record
(filename, indentation=4, encoding='utf-8')[source]¶ import io import json import requests import httpretty with httpretty.record('/tmp/ip.json'): data = requests.get('https://httpbin.org/ip').json() with io.open('/tmp/ip.json') as fd: assert data == json.load(fd)
- Parameters
filename – a string
indentation – an integer, defaults to 4
encoding – a string, defaults to “utf-8”
- Returns
-
classmethod
register_uri
(method, uri, body='{"message": "HTTPretty :)"}', adding_headers=None, forcing_headers=None, status=200, responses=None, match_querystring=False, priority=0, **headers)[source]¶ import httpretty def request_callback(request, uri, response_headers): content_type = request.headers.get('Content-Type') assert request.body == '{"nothing": "here"}', 'unexpected body: {}'.format(request.body) assert content_type == 'application/json', 'expected application/json but received Content-Type: {}'.format(content_type) return [200, response_headers, json.dumps({"hello": "world"})] httpretty.register_uri( HTTPretty.POST, "https://httpretty.example.com/api", body=request_callback) with httpretty.enabled(): requests.post('https://httpretty.example.com/api', data='{"nothing": "here"}', headers={'Content-Type': 'application/json'}) assert httpretty.latest_requests[-1].url == 'https://httpbin.org/ip'
- Parameters
method – one of
httpretty.GET
,httpretty.PUT
,httpretty.POST
,httpretty.DELETE
,httpretty.HEAD
,httpretty.PATCH
,httpretty.OPTIONS
,httpretty.CONNECT
uri – a string or regex pattern (e.g.: “https://httpbin.org/ip”)
body – a string, defaults to
{"message": "HTTPretty :)"}
adding_headers – dict - headers to be added to the response
forcing_headers – dict - headers to be forcefully set in the response
status – an integer, defaults to 200
responses – a list of entries, ideally each created with
Response()
priority – an integer, useful for setting higher priority over previously registered urls. defaults to zero
match_querystring – bool - whether to take the querystring into account when matching an URL
headers – headers to be added to the response
Warning
When using a port in the request, add a trailing slash if no path is provided otherwise Httpretty will not catch the request. Ex:
httpretty.register_uri(httpretty.GET, 'http://fakeuri.com:8080/', body='{"hello":"world"}')
-
classmethod
Http¶
-
httpretty.http.
last_requestline
(sent_data)[source]¶ Find the last line in sent_data that can be parsed with parse_requestline
-
httpretty.http.
parse_requestline
(s)[source]¶ http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5
>>> parse_requestline('GET / HTTP/1.0') ('GET', '/', '1.0') >>> parse_requestline('post /testurl htTP/1.1') ('POST', '/testurl', '1.1') >>> parse_requestline('Im not a RequestLine') Traceback (most recent call last): ... ValueError: Not a Request-Line
Utils¶
Hacking on HTTPretty¶
License¶
<HTTPretty - HTTP client mock for Python>
Copyright (C) <2011-2020> Gabriel Falcão <gabriel@nacaolivre.org>
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.
Main contributors¶
HTTPretty has received many contributions but some folks made remarkable contributions and deserve extra credit:
Andrew Gross ~> @andrewgross
Hugh Saunders ~> @hughsaunders
James Rowe ~> @JNRowe
Matt Luongo ~> @mhluongo
Steve Pulec ~> @spulec
Release Notes¶
1.0.5¶
Bugfix: Support socket.socketpair() . #402
Bugfix: Prevent exceptions from re-applying monkey patches. #406
1.0.0¶
Drop Python 2 support.
Fix usage with redis and improve overall real-socket passthrough. #271.
Fix TypeError: wrap_socket() missing 1 required positional argument: ‘sock’ (#393)
Merge pull request #364
Merge pull request #371
Merge pull request #379
Merge pull request #386
Merge pull request #302
Merge pull request #373
Merge pull request #383
Merge pull request #385
Merge pull request #389
Merge pull request #391
Fix simple typo: neighter -> neither.
Updated documentation for register_uri concerning using ports.
Clarify relation between
enabled
andhttprettized
in API docs.Align signature with builtin socket.
0.9.4¶
Improvements:
Official Python 3.6 support
Normalized coding style to comform with PEP8 (partially)
Add more API reference coverage in docstrings of members such as
httpretty.core.Entry
Continuous Integration building python 2.7 and 3.6
0.8.4¶
Improvements:
Refactored
core.py
and increased its unit test coverage to 80%. HTTPretty is slightly more robust now.
Bug fixes:
POST requests being called twice #100
0.6.5¶
Applied pull requests:
Add a way to match the querystrings: #98 by ametaireau
Use common string case for URIInfo hostname comparison: #95 by mikewaters
Adding parsed_body parameter to simplify checks: #88 by toumorokoshi
0.6.2¶
0.6.1¶
New API, no more camel case and everything is available through a simple import:
import httpretty
@httpretty.activate
def test_function():
# httpretty.register_uri(...)
# make request...
pass
Re-organized module into submodules
0.5.14¶
Delegate calls to other methods on socket
Normalized header strings
Callbacks are more intelligent now
Normalize urls matching for url quoting
0.5.12¶
HTTPretty doesn’t hang when using other application protocols under a @httprettified decorated test.
0.5.11¶
Ability to know whether HTTPretty is or not enabled through
httpretty.is_enabled()
0.5.10¶
Support to multiple methods per registered URL. Thanks @hughsaunders
0.5.9¶
Fixed python 3 support. Thanks @spulec
0.5.8¶
Support to register regular expressions to match urls
Body callback suppport
Python 3 support