Skip to main content

Propan framework: the simplest way to work with a messaging queues

Project description

Propan logo

Package version downloads Supported Python versions GitHub

Propan

Propan is a modern framework for building Applications based on Messaging Architecture.

The key features are:

  • Easy: Designed to be easy to use and learn.
  • Intuitive: Great editor support. Autocompletion everywhere.
  • Dependencies management: Minimize code duplication. Multiple features from each argument and parameter declaration.
  • Integrations: Propan is ready to using in pair with any http framework you want
  • MQ independent: Single interface to popular MQ:
  • Greate to develop: cli tool provides great development expireince:
    • framework-independent way to rule application environment
    • application code hot reloading

Quickstart

Install using pip:

$ pip install "propan[async-rabbit]"
# or
$ pip install "propan[async-nats]"

Basic usage

Create an application with the following code at serve.py:

from propan import PropanApp
from propan.brokers.rabbit import RabbitBroker
# from propan.brokers.nats import NatsBroker

broker = RabbitBroker("amqp://guest:guest@localhost:5672/")
# broker = NatsBroker("nats://localhost:4222")

app = PropanApp(broker)

@broker.handle("test")
async def base_handler(body):
    '''Handle all default exchange messages with `test` routing key'''
    print(body)

And just run it:

$ propan run serve:app

Type casting

Propan uses pydantic to cast incoming function arguments to type according their type annotation.

from pydantic import BaseModel
from propan import PropanApp, Context
from propan.brokers.rabbit import RabbitBroker

broker = RabbitBroker("amqp://guest:guest@localhost:5672/")
app = PropanApp(broker)

class SimpleMessage(BaseModel):
    key: int

@broker.handle("test2")
async def second_handler(body: SimpleMessage):
    assert isinstance(body.key, int)

Dependencies

Propan has dependencies management policy close to pytest fixtures. You can specify in functions arguments which dependencies you would to use. Framework passes them from the global Context object.

Default context fields are: app, broker, context (itself), logger and message. If you call not existed field it returns None value.

But you can specify your own dependencies, call dependencies functions (like Fastapi Depends) and more.

from logging import Logger

import aio_pika
from propan import PropanApp, Context
from propan.brokers.rabbit import RabbitBroker

rabbit_broker = RabbitBroker("amqp://guest:guest@localhost:5672/")

app = PropanApp(rabbit_broker)

@rabbit_broker.handle("test")
async def base_handler(body: dict,
                       app: PropanApp,
                       broker: RabbitBroker,
                       context: Context,
                       logger: Logger,
                       message: aio_pika.Message,
                       not_existed_field):
    assert broker is rabbit_broker
    assert not_existed_field is None

CLI power

Propan has own cli tool providing following features:

  • project generation
  • multiprocessing workers
  • project hot reloading
  • custom context arguments passing

Context passing

For example: pass your current .env project setting to context

$ propan run serve:app --env=.env.dev
from propan import PropanApp, Context
from propan.brokers.rabbit import RabbitBroker
from pydantic import BaseSettings

broker = RabbitBroker("amqp://guest:guest@localhost:5672/")

app = PropanApp(broker)

class Settings(BaseSettings):
    ...

@app.on_startup
async def setup(env: str, context: Context):
    settings = Settings(_env_file=env)
    context.set_context("settings", settings)

Project template

Also propan cli is able to generate production-ready application template:

$ propan create [projectname]

Notice: project template require pydantic[dotenv] installation.

Run created project:

# Run rabbimq first
$ docker compose --file [projectname]/docker-compose.yaml up -d

# Run project
$ propan run [projectname].app.serve:app --env=.env --reload

Now you can enjoy a new development experience!


HTTP Frameworks integrations

You can use Propan MQBrokers without PropanApp. Just start and stop them according your application lifespan.

from fastapi import FastAPI
from propan.brokers.rabbit import RabbitBroker

broker = RabbitBroker("amqp://guest:guest@localhost:5672/")

app = FastAPI()

@broker.handle("test")
async def base_handler(body):
    print(body)

@app.on_event("startup")
async def start_broker():
    await broker.start()

@app.on_event("shutdown")
async def stop_broker():
    await broker.close()

Examples

To see more framework usages go to examples/

Release history Release notifications | RSS feed

Download files

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

Source Distribution

propan-0.0.8.17.tar.gz (26.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

propan-0.0.8.17-py3-none-any.whl (34.8 kB view details)

Uploaded Python 3

File details

Details for the file propan-0.0.8.17.tar.gz.

File metadata

  • Download URL: propan-0.0.8.17.tar.gz
  • Upload date:
  • Size: 26.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.23.3

File hashes

Hashes for propan-0.0.8.17.tar.gz
Algorithm Hash digest
SHA256 4a6f31b8634468874a16b0dafa59d1c0d224724ab319f9db26e8b9c8678377cf
MD5 1274635355438e84a3ec4681489a876d
BLAKE2b-256 35f62cf90a1b8e13b6024ee5904fbff7b692ab1b28643e8f7a49cabd586b3f0d

See more details on using hashes here.

File details

Details for the file propan-0.0.8.17-py3-none-any.whl.

File metadata

  • Download URL: propan-0.0.8.17-py3-none-any.whl
  • Upload date:
  • Size: 34.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.23.3

File hashes

Hashes for propan-0.0.8.17-py3-none-any.whl
Algorithm Hash digest
SHA256 7bf3415d94ff0c613dd60a48c20f91d88884c4a93de73e294667a1095b8c65e2
MD5 32e880f0ddd081c5f7c399c89f0384eb
BLAKE2b-256 3459e3ad57acc0dba0229490c10eb1d34f8b6545efe8490e9b3edff9ad5875d0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page