Library / SDK
mosquito/aio-pika avatar
mosquito/aio-pika

aio-pika: the object-oriented async AMQP client most asyncio code ends up using

AMQP 0.9 client designed for asyncio and humans.

1,478 stars210 forksPythonApache-2.0

At a glance

What is it?
A wrapper around aiormq that gives RabbitMQ an object model, transparent publisher confirms, transactions and reconnect-with-state-recovery, on Python 3.11 and newer. The README is short because the real documentation lives elsewhere.
Who is it for?
aio-pika is the layer most asyncio services put over RabbitMQ, and it earns that position with a specific combination: an object model instead of channel method calls, `connect_robust` that restores declared entities and consuming state after a drop, and complete type hints. Two things to know before committing.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 92 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two layers, one author, and a deliberate split

aio-pika is a wrapper around aiormq, which is the same author's pure Python AMQP client. The README is explicit about the division: aiormq is the low-level protocol library and sits under aio-pika, and the two have separate examples in the same README so you can see the difference in shape.

The aiormq examples look like the AMQP spec. You call `connect`, then `channel()`, then `queue_declare`, and `basic_publish` takes a raw body plus a routing key. The aio-pika examples look like objects: you get a `queue` back from `declare_queue`, and publishing goes through `exchange.publish` with a `Message` object that carries a body, a content type and headers.

Both libraries sit under the mosquito organisation, which means the layering decision was made by the same person who wrote the protocol code. It also means a bug fixed in aiormq propagates upward, and the dependency is pinned as `aiormq>=7,<8` with `yarl` for URL handling, so a breaking change in the lower layer is deliberately blocked from arriving silently.

The README also carries two historical notes that explain a lot of confusion in search results. Since version 5.0.0 the library no longer uses pika as its AMQP connector, and versions below 5.0.0 contained or required pika's source code. And version 7.0.0 has breaking API changes, with migration hints in the changelog. If you are reading an older tutorial or a pre-5.0 stack trace, that is why it does not match.

Python 3.11 is the floor, and the metadata has not caught up

`pyproject.toml` declares `requires-python = ">=3.11,<4"`, and the classifiers list Python 3.11, 3.12, 3.13 and 3.14 alongside both CPython and PyPy implementations, plus a `Typing :: Typed` marker. That is a modern, well-maintained package definition, and the 10.0.0 release that introduced it is a real floor for new work.

The repository topics tell a different story. They include python-3-6, python-3-7, python-3-8, python-3-9 and python3-10 alongside the asyncio and amqp terms. Those topics are stale search metadata rather than a statement about current support, but they matter practically: people still land here from searches for older interpreter support, and the answer for anyone on 3.10 or below is that 10.x will not install and they need the 9.x line.

There is a second version discrepancy worth knowing about. The project file carries `version = "10.0.0"`, while the published releases include 10.0.0 and 10.0.1, the latter dated 2026-07-09. So the source tree declares a version that has already been superseded by a patch release on the index. Practically that means building from a checkout gives you something labelled 10.0.0 even though 10.0.1 exists, and it is a reminder to install from the package index rather than a clone when you want the fixes.

Installation is one command:

shell
pip install aio-pika

Apache-2.0 with the license text in a `COPYING` file, which is the GNU convention rather than the usual LICENSE name.

connect_robust is the feature that justifies the wrapper

The headline capability is transparent auto-reconnect with complete state recovery, and the README specifies what that state is: declared queues or exchanges, consuming state, and bindings. That is a stronger promise than reconnecting a socket.

A plain async AMQP reconnect gives you a new channel and an empty world. Your program still holds references to a queue object that no longer exists server-side, and to a consumer that stopped being consumed when the connection dropped. `connect_robust` exists to close that gap, which means the failure mode it handles is not hypothetical in production. RabbitMQ nodes restart, load balancer health checks flap, and containers get rescheduled.

python
connection: aio_pika.abc.AbstractRobustConnection = await aio_pika.connect_robust(
    "amqp://guest:[email protected]/", loop=loop
)

The return type is annotated as an `AbstractRobustConnection` rather than a plain connection, and the type aliases live in `aio_pika.abc`, so the abstract interfaces are a public surface you can type against. The README notes you can pass keyword parameters instead of a URL, such as host, login and password, but that you must pick one style: a URL or keyword arguments, not both.

Alongside that, the feature list names transparent publisher confirms, transactions, and complete type-hints coverage. Publisher confirms matter more than they sound: without them, a publish that returns successfully only means the message was written to a socket. With confirms, the broker has accepted it, which is the difference between a queue and a log that might lose messages.

Three README examples: consume, publish, fetch one message

The README carries three aio-pika examples and two aiormq ones. The first aio-pika example is a consumer that declares an auto-delete queue, iterates over it, and wraps each message in `message.process()`, which handles acknowledgement and rejection for you on context exit:

python
queue = await channel.declare_queue(queue_name, auto_delete=True)

async with queue.iterator() as queue_iter:
    async for message in queue_iter:
        async with message.process():
            print(message.body)

The example's own comment points out that cancelling happens after the `__aexit__`, which is worth understanding before you copy it. `message.process()` is the main ergonomic argument for the wrapper: it guarantees the message is acked when the block exits normally and nacked or requeued if it raises, which is exactly the bookkeeping that gets hand-rolled wrong in raw AMQP code.

The publisher example goes through `channel.default_exchange.publish` with a `routing_key`, so no exchange has to be declared at all when routing directly to a queue name.

The third example is the one to look at if you need fire-and-forget semantics. It declares a `direct` exchange, binds a queue to it, publishes a message with a content type and headers, then does `queue.get(timeout=5)` and acks. It also unbinds and deletes the queue at the end, which makes it a complete round trip in one function and a decent template for a job submission endpoint.

All three examples use `asyncio.get_event_loop()` and `loop.run_until_complete`, which was the standard idiom when they were written and is now dated in favour of `asyncio.run`. That is the most likely friction when you paste any of them into a modern service.

Running a broker locally, and a Makefile that has drifted

You need a RabbitMQ to point at. The Makefile has a target for exactly that, which pulls the same author's test image:

bash
docker pull $(RABBITMQ_IMAGE)
docker run --rm -d \
	-l aio-pika.rabbitmq \
	-p 5671:5671 \
	-p 5672:5672 \
	-p 15671:15671 \
	-p 15672:15672 \
	$(RABBITMQ_IMAGE)

Two port pairs are mapped: 5671 and 5672 for AMQP, and 15671 and 15672 for the management interface, with the higher numbers as the defaults and the lower ones presumably kept free for a system install. The container carries a label so the `docker kill` line at the start of the target can find a previous one.

The drift is in the rest of that Makefile, and it is worth naming because it is the kind of thing that wastes an afternoon. The `test` target runs `tox`, and the `upload` target runs `python3.7 setup.py sdist bdist_wheel` followed by `twine upload`. Neither matches the repository as it now stands. There is no `tox.ini` in the tree, there is a `noxfile.py`, and there is no `setup.py` at all because the project builds from `pyproject.toml`. So `make test` and `make upload` will both fail on a fresh checkout, and the real commands are `nox` for sessions and the current build tooling for packaging.

The dev dependency group confirms what the project actually uses: pytest and pytest-cov for tests, mypy and ruff for typing and linting, nox for session management, sphinx with the furo theme for docs, plus `pytest-rst`, which executes Python blocks inside Markdown so the README examples are tested rather than decorative. That last one is a detail worth knowing, because it means the code in the README is verified against the library.

Where to look next, and what the README deliberately omits

The README is short by design and says so. It points at the documentation site for examples and a tutorial, and for newcomers to RabbitMQ it recommends the official RabbitMQ tutorial that the docs host, which is a sensible routing decision given how much of the difficulty in a first AMQP project is protocol concepts rather than Python.

The type hints claim deserves a mention because it is verifiable and unusual. The package is marked `Typing :: Typed`, it ships an `abc` module of abstract interfaces, and every example annotates its objects as `aio_pika.abc.AbstractRobustConnection`, `AbstractChannel` and `AbstractQueue`. That combination means an editor can complete methods on a connection object and a type checker will catch a call to a method that does not exist. If you maintain a codebase with strict typing, that is a real difference from most AMQP clients.

Maintenance is current. The last push was on 2026-07-09, the same day 10.0.1 and 10.0.0 were published, and 9.6.2 came out on 2026-03-22. That cadence suggests an actively maintained line rather than an abandoned wrapper. The remaining gap between releases is the 10.x patch level, so if you are deploying, pin to 10.0.1 or later from the index.

What the README does not cover is error handling, reconnection tuning parameters, heartbeat and blocked-connection behaviour, and the cost of state recovery when a large topology is re-declared after a restart. Those live in the documentation site and in the CHANGELOG that the 7.0.0 note points at. For an evaluation, the questions worth asking are whether your topology is small enough for recovery to be instant, and whether your message processing time is short enough that requeue-on-disconnect will not cause duplicates in your consumers.

Editorial conclusion

aio-pika is the layer most asyncio services put over RabbitMQ, and it earns that position with a specific combination: an object model instead of channel method calls, `connect_robust` that restores declared entities and consuming state after a drop, and complete type hints. Two things to know before committing. The project moved to Python 3.11 or newer at version 10, so anything on 3.8 through 3.10 needs to stay on the 9.x line, and the 7.0.0 release carried breaking API changes you should check in the changelog. Some of the supporting material has not kept up: the Makefile still calls `tox` and `python3.7 setup.py` although the tree ships a noxfile and a pyproject-based build, so the documented local test path is not the real one. Use `make rabbitmq` to get a broker on the four mapped ports and the docs at docs.aio-pika.com for the API detail, because the README deliberately stops at three examples.

Frequently asked questions

What is aio-pika and how does it differ from pika?

aio-pika is an asyncio-native RabbitMQ client, wrapping the author's lower level aiormq library. The blocking pika library has been separate from it since version 5.0.0; versions below 5.0.0 contained or required pika's source code. aio-pika adds an object-oriented API with abstract typed interfaces, robust reconnects and publisher confirms on top of the protocol layer.

How do I install aio-pika and what Python version does it need?

Run `pip install aio-pika`. The project metadata requires Python 3.11 or newer and lists classifiers for 3.11 through 3.14 on both CPython and PyPy, so 10.x will not install on 3.10 or earlier and those users need the 9.x line.

What does connect_robust do differently from a plain connect?

It reconnects and recovers state rather than just reopening a socket: declared queues or exchanges, consuming state and bindings are restored, so your code keeps working with objects that would otherwise point at server-side entities that no longer exist. The returned connection is typed as `AbstractRobustConnection`.

How do I get a RabbitMQ instance to test against locally?

The Makefile has a `rabbitmq` target that pulls the `mosquito/aiormq-rabbitmq` image and runs it with AMQP ports 5671 and 5672 and management ports 15671 and 15672 mapped. The README examples then connect to the standard guest credentials on localhost.

How do I acknowledge messages safely in aio-pika?

Wrap the body in `message.process()` as a context manager, which is what the README consumer example does. Exiting the block normally acknowledges, and an exception causes a rejection or requeue, which removes the manual bookkeeping that raw AMQP code tends to get wrong.

Official sources

  1. License: Apache-2.0
  2. mosquito/aio-pika on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mosquito-aio-pika.svg)](https://hysenlabs.com/projects/mosquito-aio-pika)