What is asks?

asks is an async HTTP lib that can best be described as an effort to bring the same level of usable abstraction that requests offers synchronous Python, to asynchronous Python programming. Ideal for API interactions, webscraping etc.

asks is compatible with curio and trio.

It is important to note that the code examples in this documentation are to showcase asks, and not curio or trio. In real code, it would be beneficial to use things like taskgroups/nurserys and other neat tools to manage your requests. Here’s a link to curio and trio’s docs for reference:


asks requires Python 3.6.2 or newer.

The easiest way to install asks is to pip it:

pip install asks

Internally asks uses the excellent h11. It will be installed automatically.

asks was built for use with curio and trio

Importing asks

The following code will run the example coroutine once with curio and once with trio:

import asks
import curio
import trio

async def example():
    r = await asks.get('')

A quick note on the examples in these docs

asks began by only supporting curio, and the code examples use curio throughout. At any point in the examples you could switch say, async with curio.TaskGroup to async with trio.open_nursery, and everything would be the same bar curio/trio’s API differences. Internally, asks has no bias for either library. Both are beautiful creatures.

A little example:

Here’s how to grab a single request and print its content:

import asks
import curio

async def grabber(url):
    r = await asks.get(url)

# Results in:
# b'<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n

Making one request in an async program is a little weird, but not without its uses. This sort of basic asks.get() would slot in quite nicely in a greater program that makes some calls here and there.

A bigger little example:

Here’s an example of making 1000 calls to an API and storing the results in a list. We’ll use the Session class here to take advantage of connection pooling.:

# make a whole pile of api calls and store
# their response objects in a list.
# Using the homogeneous-session.

import asks
import curio

path_list = ['a', 'list', 'of', '1000', 'paths']

retrieved_responses = []

s = asks.Session('',

async def grabber(a_path):
    r = await s.get(path=a_path)

async def main(path_list):
    for path in path_list:

Now we’re talkin’.

A thousand requests running async at the drop of a hat, using clean burning connection pooling to play nicely with the target server.

Why asks?

If you like async, but don’t like the spaghetti-docs future-laden many-looped asyncio lib, you’ll probably love curio and trio. If you wish you could marry them with requests, you’ll probably love asks.

Nice libs like aiohttp suffer the side effect of ugliness due to being specifically for asyncio. Inspired by requests and the fancy new-age async libs, I wanted to take that lovely ultra abstraction and apply it to an async HTTP lib to alleviate some of the pain in dealing with async HTTP.


asks packs most if not all of the features requests does. The usual .json()-ing of responses and such. You can take a more in-depth look here.

Because asks is aimed at crunching large piles of requests, its Session has some features you may not be aware of. Sessions in asks are the main focus. More detail can be found here

The Future

Now that trio support has been implemented, it’s housecleaning time. asks has some cobwebs that need clearing, and refactoring those in to a nice silk dress is the current focus.


Contributions are very welcome :)


asks was created by Mark Jameson

Shoutout to the fine folks of 8banana and co.