Skip to main content

Async http client/server framework (asyncio)

Project description

Async http client/server framework

aiohttp logo Travis status for master branch status for master branch Latest PyPI package version Latest Read The Docs Chat on Gitter

Key Features

  • Supports both client and server side of HTTP protocol.
  • Supports both client and server Web-Sockets out-of-the-box without the Callback Hell.
  • Web-server has middlewares and pluggable routing.

Getting started


To retrieve something from the web:

import aiohttp
import asyncio
import async_timeout

async def fetch(session, url):
    async with async_timeout.timeout(10):
        async with session.get(url) as response:
            return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, '')

if __name__ == '__main__':
    loop = asyncio.get_event_loop()


This is simple usage example:

from aiohttp import web

async def handle(request):
    name = request.match_info.get('name', "Anonymous")
    text = "Hello, " + name
    return web.Response(text=text)

async def wshandle(request):
    ws = web.WebSocketResponse()
    await ws.prepare(request)

    async for msg in ws:
        if msg.type == web.MsgType.text:
            await ws.send_str("Hello, {}".format(
        elif msg.type == web.MsgType.binary:
            await ws.send_bytes(
        elif msg.type == web.MsgType.close:

    return ws

app = web.Application()
app.add_routes([web.get('/', handle),
                web.get('/echo', wshandle),
                web.get('/{name}', handle)])


Communication channels

aio-libs google group:!forum/aio-libs

Feel free to post your questions and ideas here.

gitter chat

We support Stack Overflow. Please add aiohttp tag to your question there.


Optionally you may install the cChardet and aiodns libraries (highly recommended for sake of speed).


aiohttp is offered under the Apache 2 license.


The aiohttp community would like to thank Keepsafe ( for it’s support in the early days of the project.

Source code

The latest developer version is available in a github repository:


If you are interested in by efficiency, AsyncIO community maintains a list of benchmarks on the official wiki:


3.1.3 (2018-04-12)

  • Fix cancellation broadcast during DNS resolve (#2910)

3.1.2 (2018-04-05)

  • Make LineTooLong exception more detailed about actual data size (#2863)
  • Call on_chunk_sent when write_eof takes as a param the last chunk (#2909)

3.1.1 (2018-03-27)

  • Support asynchronous iterators (and asynchronous generators as well) in both client and server API as request / response BODY payloads. (#2802)

3.1.0 (2018-03-21)

Welcome to aiohttp 3.1 release.

This is an incremental release, fully backward compatible with aiohttp 3.0.

But we have added several new features.

The most visible one is app.add_routes() (an alias for existing app.router.add_routes(). The addition is very important because all aiohttp docs now uses app.add_routes() call in code snippets. All your existing code still do register routes / resource without any warning but you’ve got the idea for a favorite way: noisy app.router.add_get() is replaced by app.add_routes().

The library does not make a preference between decorators:

routes = web.RouteTableDef()

async def hello(request):
    return web.Response(text="Hello, world")


and route tables as a list:

async def hello(request):
    return web.Response(text="Hello, world")

app.add_routes([web.get('/', hello)])

Both ways are equal, user may decide basing on own code taste.

Also we have a lot of minor features, bug fixes and documentation updates, see below.


  • Relax JSON content-type checking in the ClientResponse.json() to allow “application/xxx+json” instead of strict “application/json”. (#2206)
  • Bump C HTTP parser to version 2.8 (#2730)
  • Accept a coroutine as an application factory in web.run_app and gunicorn worker. (#2739)
  • Implement application cleanup context (app.cleanup_ctx property). (#2747)
  • Make writer.write_headers a coroutine. (#2762)
  • Add tracking signals for getting request/response bodies. (#2767)
  • Deprecate ClientResponseError.code in favor of .status to keep similarity with response classes. (#2781)
  • Implement app.add_routes() method. (#2787)
  • Implement web.static() and RouteTableDef.static() API. (#2795)
  • Install a test event loop as default by asyncio.set_event_loop(). The change affects aiohttp test utils but backward compatibility is not broken for 99.99% of use cases. (#2804)
  • Refactor ClientResponse constructor: make logically required constructor arguments mandatory, drop _post_init() method. (#2820)
  • Use app.add_routes() in server docs everywhere (#2830)
  • Websockets refactoring, all websocket writer methods are converted into coroutines. (#2836)
  • Provide Content-Range header for Range requests (#2844)


  • Fix websocket client return EofStream. (#2784)
  • Fix websocket demo. (#2789)
  • Property BaseRequest.http_range now returns a python-like slice when requesting the tail of the range. It’s now indicated by a negative value in range.start rather then in range.stop (#2805)
  • Close a connection if an unexpected exception occurs while sending a request (#2827)
  • Fix firing DNS tracing events. (#2841)

Improved Documentation

  • Document behavior when cchardet detects encodings that are unknown to Python. (#2732)
  • Add diagrams for tracing request life style. (#2748)
  • Drop removed functionality for passing StreamReader as data at client side. (#2793)

Project details

Release history Release notifications

Download files

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

Filename, size & hash SHA256 hash help File type Python version Upload date
aiohttp-3.1.3-cp35-cp35m-macosx_10_10_x86_64.whl (374.6 kB) Copy SHA256 hash SHA256 Wheel cp35 Apr 13, 2018
aiohttp-3.1.3-cp35-cp35m-macosx_10_11_x86_64.whl (372.8 kB) Copy SHA256 hash SHA256 Wheel cp35 Apr 13, 2018
aiohttp-3.1.3-cp35-cp35m-macosx_10_12_x86_64.whl (366.8 kB) Copy SHA256 hash SHA256 Wheel cp35 Apr 13, 2018
aiohttp-3.1.3-cp35-cp35m-manylinux1_i686.whl (624.2 kB) Copy SHA256 hash SHA256 Wheel cp35 Apr 13, 2018
aiohttp-3.1.3-cp35-cp35m-manylinux1_x86_64.whl (647.2 kB) Copy SHA256 hash SHA256 Wheel cp35 Apr 13, 2018
aiohttp-3.1.3-cp35-cp35m-win32.whl (350.8 kB) Copy SHA256 hash SHA256 Wheel cp35 Apr 13, 2018
aiohttp-3.1.3-cp35-cp35m-win_amd64.whl (362.4 kB) Copy SHA256 hash SHA256 Wheel cp35 Apr 13, 2018
aiohttp-3.1.3-cp36-cp36m-macosx_10_10_x86_64.whl (377.2 kB) Copy SHA256 hash SHA256 Wheel cp36 Apr 13, 2018
aiohttp-3.1.3-cp36-cp36m-macosx_10_11_x86_64.whl (375.2 kB) Copy SHA256 hash SHA256 Wheel cp36 Apr 13, 2018
aiohttp-3.1.3-cp36-cp36m-macosx_10_12_x86_64.whl (367.6 kB) Copy SHA256 hash SHA256 Wheel cp36 Apr 13, 2018
aiohttp-3.1.3-cp36-cp36m-manylinux1_i686.whl (638.8 kB) Copy SHA256 hash SHA256 Wheel cp36 Apr 13, 2018
aiohttp-3.1.3-cp36-cp36m-manylinux1_x86_64.whl (661.2 kB) Copy SHA256 hash SHA256 Wheel cp36 Apr 13, 2018
aiohttp-3.1.3-cp36-cp36m-win32.whl (352.2 kB) Copy SHA256 hash SHA256 Wheel cp36 Apr 13, 2018
aiohttp-3.1.3-cp36-cp36m-win_amd64.whl (364.1 kB) Copy SHA256 hash SHA256 Wheel cp36 Apr 13, 2018
aiohttp-3.1.3.tar.gz (756.9 kB) Copy SHA256 hash SHA256 Source None Apr 13, 2018

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page