Skip to content

Instantly share code, notes, and snippets.

@dalf
Forked from florimondmanca/README.md
Last active July 2, 2020 17:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dalf/90129096b4cccdeb6d2f504a18b81b2b to your computer and use it in GitHub Desktop.
Save dalf/90129096b4cccdeb6d2f504a18b81b2b to your computer and use it in GitHub Desktop.
HTTPX vs aiohttp (over HTTPS)

Usage

  • Generate TLS certificates for localhost:
pip install trustme-cli
trustme-cli
  • Run wrk on each endpoint, eg:
wrk http://localhost:4000/aiohttp/single

Results

aiohttp httpx aiohttp/httpx
single (req/s) 355 234 1.5
client (req/s) 1447 675 2.1
client/single 4.1 2.9
import ssl
from starlette.applications import Starlette
from starlette.routing import Route
from starlette.responses import PlainTextResponse
import httpx
import aiohttp
import multiprocessing
URL = "https://localhost:8000"
ssl_context = ssl.create_default_context(cafile="client.pem")
session = None
client = httpx.AsyncClient(verify=ssl_context)
async def startup():
global session
session = aiohttp.ClientSession()
async def index(request):
return PlainTextResponse("world")
async def aiohttp_single(request):
async with aiohttp.ClientSession() as session:
async with session.get(URL, ssl=ssl_context) as r:
return _response(await r.text())
async def aiohttp_session(request):
async with session.get(URL, ssl=ssl_context) as r:
return _response(await r.text())
async def httpx_single(request):
async with httpx.AsyncClient(verify=ssl_context) as client:
r = await client.get(URL)
return _response(r.text)
async def httpx_client(request):
r = await client.get(URL)
return _response(r.text)
def _response(name):
return PlainTextResponse("Hello, " + name)
routes = [
Route("/", endpoint=index),
Route("/aiohttp/single", endpoint=aiohttp_single),
Route("/aiohttp/session", endpoint=aiohttp_session),
Route("/httpx/single", endpoint=httpx_single),
Route("/httpx/client", endpoint=httpx_client),
]
app = Starlette(routes=routes, on_startup=[startup])
if __name__ == "__main__":
import uvicorn
def http():
uvicorn.run(
app,
host="localhost",
port=4000,
log_level="error",
)
p = multiprocessing.Process(target=http)
p.start()
uvicorn.run(
app,
host="localhost",
port=8000,
ssl_keyfile="server.key",
ssl_certfile="server.pem",
log_level="error",
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment