Skip to main content

Quick, what’s the situation?

To get all the benefits of Happy Eyeballs connection establishment algorithm, simply use async_stagger.open_connection like you would use asyncio.open_connection:

reader, writer = await async_stagger.open_connection('www.example.com', 80)

Now your connections are more dual-stack friendly and will complete faster! A replacement for loop.create_connection is also provided.

The current state of Happy Eyeballs in the Python ecosystem

The native asyncio module had supported happy eyeballs since Python 3.8.1. It’s still not default behavior, though, and must be turned on deliberately. See the docs for details.

[aiohttp](https://github.com/aio-libs/aiohttp)’s HTTP client uses happy eyeballs by default, and the devs maintain a vendored implementation as [aiohappyeyeballs](https://github.com/aio-libs/aiohappyeyeballs).

Along with this repository, the 3 implementations started very similar, but has diverged a lot in time in order to keep up with changes in asyncio, particularly with the introduction of eager_task_factory in Python 3.12.

The long version

What is Happy Eyeballs, and why should I use it?

Happy Eyeballs is an algorithm for establishing TCP connections to destinations specified by host names. It is described in RFC 6555 and RFC 8305. The primary benefit is that when host name resolution returns multiple addresses, and some of the address are unreachable, Happy Eyeballs will establish the connection much faster than conventional algorithms. For more information, check the Wikipedia article on Happy Eyeballs.

Python’s standard library provides several high-level methods of establishing TCP connections towards a host name: The socket module has socket.create_connection, and asyncio has loop.create_connection and asyncio.open_connection. By default, these methods have the same behavior when a host name resolves to several IP addresses: they try to connect to the first address in the list, and only after the attempt fails (which may take tens of seconds) will the second one be tried, and so on. In contrast, the Happy Eyeballs algorithm will start an attempt with the second IP address in parallel to the first one hasn’t completed after some time, typically around 300 milliseconds. As a result several attempts may be in flight at the same time, and whenever one of the attempts succeed, all other connections are cancelled, and the winning connection is used. This means a much shorter wait before one of the IP addresses connect successfully.

Happy Eyeballs is particularly important for dual-stack clients, when some hosts may have resolvable IPv6 addresses that are somehow unreachable.

What does async_stagger has to offer?

async_stagger provides open_connection and create_connection with Happy Eyeballs support. They are mostly drop-in replacements for their asyncio counterparts, and support most existing arguments. (There are small differences: create_connection takes a loop argument instead of being a method on an event loop. Also, these two methods do not support the sock argument.) Another public coroutine create_connected_sock returns a connected socket.socket object. Check the documentation for details.

These methods implements many features specified in RFC 8305 Happy Eyeballs v2, which extends and obsoletes RFC 6555. In particular, asynchronous address resolution, destination address interleaving by family and staggered connection attempts are implemented.

Happy Eyeballs sounds great! I want to use similar logic somewhere else!

You’re in luck! async_stagger actually exposes the underlying scheduling logic as a reusable block: staggered_race. It can be use when:

  • There are several ways to achieve one goal. Some of the ways may fail, but you have to try it to find out.

  • Making attempts strictly in sequence is too slow.

  • You want to parallelize, but also don’t want to start the attempts all at the same time. Maybe you want to give preference to some of the attempts, so they should be started earlier and given more time to complete. Maybe you want to avoid straining the system with simultaneous attempts.

  • An attempt done half-way can be rolled back safely.

Where can I get it?

async_stagger requires Python 3.11 or later from v0.4.0 onwards. Please use v0.3.1 for Python 3.6 - 3.10. It does not have any external dependencies. Install it from PyPI the usual way:

pip install async-stagger

The documentation can be found here: http://async-stagger.readthedocs.io/en/latest/

This project is under active development, and APIs may change in the future. Check out the Changelog in the documentation.

This project is licensed under the MIT license.

Acknowledgments

The Happy Eyeballs scheduling algorithm implementation is inspired by the implementation in trio.

Metadata

Release files for async-stagger 0.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for async-stagger 0.4.1
File Size Uploaded Provenance
async_stagger-0.4.1.tar.gz 22.4 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for async-stagger 0.4.1
File Interpreter ABI Platform
async_stagger-0.4.1-py3-none-any.whl Python 3 none any Details

Total release size: 47.1 kB

Release files / async_stagger-0.4.1.tar.gz

Download URL async_stagger-0.4.1.tar.gz
Size 22.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8966a38583b81266dd88a06e20cf63dafb0727e7dd6f50a3da07e7e698446487
BLAKE2b-256 checksum
How to use checksums
8c8bb9a3e26c5026e8c7fb47f15c098c92bcb87e689a4338787b00f2c2923a02
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 13, 2025.

Transparency log

Release files / async_stagger-0.4.1-py3-none-any.whl

Download URL async_stagger-0.4.1-py3-none-any.whl
Size 24.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a154d2d0e8f06c05c11e1631e18ae2c9e1999d4bd0897b5b647da54c509943ab
BLAKE2b-256 checksum
How to use checksums
88375eafe1d8abc9cb10f00950786e20719aa6e921e49827908101d89f147657
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 13, 2025.

Transparency log

Security for async-stagger 0.4.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for async_stagger-0.4.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 13, 2025.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page