This example demonstrates a real-world scenario of using PGMQ with FastAPI for an order management system. It shows how to:
- Use PGMQ with FastAPI and sync SQLAlchemy sessions (psycopg2)
- Publish messages using
PGMQOperation(op) in a web API - Consume messages asynchronously using
PGMQueuewith asyncpg
-
API Server (api.py): FastAPI application that creates orders and publishes them to PGMQ
- Uses sync database driver (psycopg2)
- Uses
PGMQOperation(imported asop) for publishing messages - Provides REST endpoints for creating and retrieving orders
-
Consumer (consumer.py): Async worker that processes orders from the queue
- Uses async database driver (asyncpg)
- Uses
PGMQueueclass for reading messages - Processes messages concurrently with asyncio
- PostgreSQL with PGMQ extension installed
- Python 3.9 or higher
Quick setup:
docker run -d --name postgres -e POSTGRES_PASSWORD=postgres -p 5432:5432 quay.io/tembo/pg16-pgmq:latestInstall required dependencies:
pip install -r requirements.txtpython api.pyThe API will be available at http://localhost:8000
In a separate terminal:
python consumer.pyCreate an order via the API:
curl -X POST "http://localhost:8000/orders" \
-H "Content-Type: application/json" \
-d '{
"customer_name": "John Doe",
"product_name": "Widget",
"quantity": 5,
"price": 29.99
}'You should see:
- The API returns the created order with a message ID
- The consumer logs show the order being processed
Get an order by ID:
curl "http://localhost:8000/orders/1"POST /orders- Create a new orderGET /orders/{order_id}- Get order by IDGET /health- Health check endpoint
-
When an order is created via the API:
- The order is saved to the database
- A message is published to PGMQ using
op.send() - The message contains order details
-
The consumer:
- Continuously polls the queue for new messages
- Processes messages concurrently using asyncio
- Deletes successfully processed messages
- Leaves failed messages in the queue for retry
You can modify the following constants in the files:
DATABASE_URL: PostgreSQL connection stringQUEUE_NAME: Name of the PGMQ queue (default: "order_queue")batch_size: Number of messages to process in each batch (consumer.py)vt: Visibility timeout in seconds (consumer.py)