Welcome to uvhttp’s documentation!¶
uvhttp is an extremely fast HTTP client written in Python. It uses uvloop and outperforms all known production-quality Python HTTP clients.
Benchmarks¶
All benchmarks running with 8 cores, see bencher.
uvhttp benchmark:
➜ uvhttp git:(master) ✗ ./uvhttp.py
100000 HTTP requests in 3.35 seconds, 29836.38 rps
➜ uvhttp git:(master) ✗
asyncio with aiohttp:
➜ bencher git:(master) ✗ python3 http_test_asyncio_aiohttp.py
10000 HTTP requests in 1.67 seconds, 5991.36 rps
➜ bencher git:(master) ✗
uvloop with aiohttp is still not great:
➜ bencher git:(master) ✗ python3 http_test_uvloop_aiohttp.py
10000 HTTP requests in 1.97 seconds, 5065.03 rps
➜ bencher git:(master) ✗
gevent is even worse:
➜ bencher git:(master) ✗ python3 http_test_gevent.py
10000 HTTP requests in 6.93 seconds, 1443.02 rps
➜ bencher git:(master) ✗
We are striving for go performance:
http_test.go:53: 100000 HTTP requests in 2.274069869 seconds, 43974.02268206211 rps
Installation¶
uvhttp requires Python 3.5 or greater and can be installed from pip:
pip install uvhttp
Usage¶
HTTP requests can be made with a Session object.
-
class
uvhttp.http.Session(conn_limit, loop, resolver=None)[source]¶ A Session is an HTTP request pool that allows up to request_limit requests in flight at once, with up to conn_limit connections per ip/port:
from uvhttp.utils import start_loop import uvhttp.http NUM_CONNS_PER_HOST = 10 @start_loop async def main(loop): session = uvhttp.http.Session(NUM_CONNS_PER_HOST, loop) for _ in range(6): response = await session.get(b'http://www.google.com/', headers={ b'User-Agent': b'fast-af' }) print(response.text) if __name__ == '__main__': main()
The module is designed to send HTTP requests very quickly, so all methods require
bytesobjects instead of strings.-
request(method, url, headers=None, data=None, ssl=None)[source]¶ Make a new HTTP request in the pool.
headerscan be passed as a dictionary ofbyte(notstr).datais a byte array of data to include in the request.sslcan be assl.SSLContextor True and must match the schema in the URL.
-
The Session object will return an HTTPRequest:
-
class
uvhttp.http.HTTPRequest(connection)[source]¶ An HTTP request instantiated from a
Session. HTTP requests are returned by the HTTP session once they are sent and contain all information about the request and response.-
close()[source]¶ Closes the request, signalling that we’re done with the request. The connection is kept open and released back to the pool for re-use.
-
gzipped¶ Return true if the response is gzipped.
-
headers¶ Return the headers from the request in a case-insensitive dictionary.
-
send(method, host, path, headers=None, data=None)[source]¶ Send the request (usually called by the Session object).
-
text¶ The string representation of the response body. It will be ungzipped and encoded as a unicode string.
-
You can also pass a Resolver to the Session:
-
class
uvhttp.dns.Resolver(loop, ipv6=True, nameservers=None)[source]¶ Caching DNS resolver wrapper for aiodns.
-
add_to_cache(host, host_port, ip, ttl, port=80, overwrite=True)[source]¶ Add the address pair
hostandhost_portto the DNS cache pointing toipandport.The result will be cached for
ttl(or forever ifttlis 0).If
overwriteis true, the result will overwrite any previous entries, otherwise it will be appended.
-
Tests¶
It also provides a wrapper around Sanic that makes it easier to use in writing unit tests for uvhttp.
-
class
uvhttp.utils.HttpServer(host=None, port=None, https_host=None, https_port=None)[source]¶ An HTTP server that uses Sanic in the backend to help write unit tests.
-
add_routes()[source]¶ A function for adding all of the routes you need. Implement this in your inherited class to add your endpoints.
-
https_url¶ Return the HTTPS URL of the started server.
-
url¶ Return the URL of the started server.
-
An example of the usage is:
import uvhttp.http
from uvhttp.utils import http_server, HttpServer
from nose.tools import assert_equal
@http_server(HttpServer)
async def test_test_server(server, loop):
session = uvhttp.http.Session(10, loop)
response = await session.get(server.url + b'echo')
assert_equal(response.json()['url'], 'http://127.0.0.1/echo')