Propan
Propan is a powerful and easy-to-use Python framework for building event-driven applications that interact with any MQ Broker
Install / Use
/learn @Lancetnik/PropanREADME
Propan
Propan - just ~~an another one HTTP~~ a declarative Python Messaging Framework. It's inspired by <a href="https://FastAPI.tiangolo.com/ru/" target="_blank">FastAPI</a> and <a href="https://docs.celeryq.dev/projects/kombu/en/stable/" target="_blank">Kombu</a>, simplify Message Brokers around code writing and provides a helpful development toolkit, which existed only in HTTP-frameworks world until now.
It's designed to create reactive microservices around <a href="https://microservices.io/patterns/communication-style/messaging.html" target="_blank">Messaging Architecture</a>.
It is a modern, high-level framework on top of popular specific Python brokers libraries, based on <a href="https://docs.pydantic.dev/" target="_blank">pydantic</a> and <a href="https://FastAPI.tiangolo.com/ru/" target="_blank">FastAPI</a>, <a href="https://docs.pytest.org/en/latest/" target="_blank">pytest</a> concepts.
:warning::warning::warning: Deprecation notice :warning::warning::warning:
This project is superceeded by FastStream.
FastStream is a new package based on the ideas and experiences gained from FastKafka and Propan. By joining our forces, we picked up the best from both packages and created a unified way to write services capable of processing streamed data regardless of the underlying protocol.
I’ll continue to maintain Propan package, but new development will be in FastStream. If you are starting a new service, FastStream is the recommended way to do it.
For now FastStream supports Kafka and RabbitMQ. Other brokers support will be added in a few months.
You can find a detail migration guide in the documentation
Documentation: <a href="https://lancetnik.github.io/Propan/" target="_blank">https://lancetnik.github.io/Propan/</a>
The key features are
- Simple: Designed to be easy to use and learn.
- Intuitive: Great editor support. Autocompletion everywhere.
- Dependencies management: Minimization of code duplication. Access to dependencies at any level of the call stack.
- Integrations: Propan is fully compatible with <a href="https://lancetnik.github.io/Propan/integrations/1_integrations-index/" target="_blank">any HTTP framework</a> you want
- MQ independent: Single interface to popular MQ:
- Redis (based on <a href="https://redis.readthedocs.io/en/stable/index.html" target="_blank">redis-py</a>)
- RabbitMQ (based on <a href="https://aio-pika.readthedocs.io/en/latest/" target="_blank">aio-pika</a>)
- Kafka (based on <a href="https://aiokafka.readthedocs.io/en/stable/" target="_blank">aiokafka</a>)
- SQS (based on <a href="https://aiobotocore.readthedocs.io/en/latest/" target="_blank">aiobotocore</a>)
- Nats (based on <a href="https://github.com/nats-io/nats.py" target="_blank">nats-py</a>)
- <a href="https://lancetnik.github.io/Propan/getting_started/4_broker/6_rpc/" target="_blank">RPC</a>: The framework supports RPC requests over MQ, which will allow performing long operations on remote services asynchronously.
- Great to develop: CLI tool provides great development experience:
- framework-independent way to manage the project environment
- application code hot reload
- robust application templates
- Documentation: Propan automatically generates and presents an interactive <a href="https://www.asyncapi.com/" target="_blank">AsyncAPI</a> documentation for your project
- <a href="https://lancetnik.github.io/Propan/getting_started/7_testing" target="_blank">Testability</a>: Propan allows you to test your app without external dependencies: you do not have to set up a Message Broker, you can use a virtual one!
Supported MQ brokers
| | async | sync | |-------------------|:-------------------------------------------------------:|:-------------------------------------------:| | RabbitMQ | :heavy_check_mark: stable :heavy_check_mark: | :hammer_and_wrench: WIP :hammer_and_wrench: | | Redis | :heavy_check_mark: stable :heavy_check_mark: | :mag: planning :mag: | | Nats | :heavy_check_mark: stable :heavy_check_mark: | :mag: planning :mag: | | Kafka | :warning: beta :warning: | :mag: planning :mag: | | SQS | :warning: beta :warning: | :mag: planning :mag: | | NatsJS | :warning: beta :warning: | :mag: planning :mag: | | ZeroMQ | :hammer_and_wrench: WIP :hammer_and_wrench: | :mag: planning :mag: | | MQTT | :mag: planning :mag: | :mag: planning :mag: | | Redis Streams | :mag: planning :mag: | :mag: planning :mag: | | Pulsar | :mag: planning :mag: | :mag: planning :mag: | | ActiveMQ | :mag: planning :mag: | :mag: planning :mag: | | AzureSB | :mag: planning :mag: | :mag: planning :mag: |
⭐ Support the project ⭐
If you are interested in this project, please give me feedback by:
-
giving the repository a star
-
tweet about <a href="https://twitter.com/compose/tweet?text=I'm like @PropanFramework because... https://github.com/Lancetnik/Propan" class="external-link" target="_blank">Propan</a> and let me and others know why you use it
-
joining <a href="https://discord.gg/qFm6aSqq59" target="_blank">Discord server</a>
Your support helps me to stay in touch with you and encourages to continue developing and improving the library. Thank you for your support!
Really, share information about this project with others. The bigger community we have - the better project will be!
Declarative?
With declarative tools you can define what you need to get. With traditional imperative tools you must write what you need to do.
Take a look at classic imperative tools, such as <a href="https://aio-pika.readthedocs.io/en/latest/" target="_blank">aio-pika</a>, <a href="https://pika.readthedocs.io/en/stable/" target="_blank">pika</a>, <a href="https://redis.readthedocs.io/en/stable/index.html" target="_blank">redis-py</a>, <a href="https://github.com/nats-io/nats.py" target="_blank">nats-py</a>, etc.
This is the Quickstart with the aio-pika:
import asyncio
import aio_pika
async def main():
connection = await aio_pika.connect_robust(
"amqp://guest:guest@127.0.0.1/"
)
queue_name = "test_queue"
async with connection:
channel = await connection.channel()
queue = await channel.declare_queue(queue_name)
async with queue.iterator() as queue_iter:
async for message in queue_iter:
async with message.process():
print(message.body)
asyncio.run(main())
aio-pika is a great tool with a really easy learning curve. But it's still imperative. You need to connect, declare channel, queues, exchanges by yourself. Also, you need to manage connection, message, queue context to avoid any troubles.
It is not a bad way, but it can be much easier.
from propan import PropanApp, RabbitBroker
broker = RabbitBroker("amqp://guest:guest@localhost:5672/")
app = PropanApp(broker)
@broker.handle("test_queue")
async def base_handler(body):
print(body)
This is the Propan declarative way to write the same code. That is so much easier, isn't it?
Quickstart
Install using pip:
pip install "p
