Skip to content

Instantly share code, notes, and snippets.

@artemonsh
Created November 24, 2023 20:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save artemonsh/ec1df88c6f0f5ee9cf40fe39914dbef5 to your computer and use it in GitHub Desktop.
Save artemonsh/ec1df88c6f0f5ee9cf40fe39914dbef5 to your computer and use it in GitHub Desktop.
FastAPI connect to Redis Pubsub and listen for messages on startup without blocking app
version: '3.8'
services:
cache:
image: redis:6.2-alpine
restart: always
ports:
- '6379:6379'
from fastapi import FastAPI
from contextlib import asynccontextmanager
import asyncio
import redis.asyncio as redis
import uvicorn
r = redis.Redis()
@asynccontextmanager
async def lifespan(app: FastAPI):
asyncio.create_task(reader())
yield
app = FastAPI(lifespan=lifespan)
@app.get("/")
async def main():
return {"ok": True, "data": [1,2,3]}
async def reader():
p = r.pubsub()
await p.subscribe("channel:1")
while True:
message = await p.get_message(ignore_subscribe_messages=True)
if message is not None:
print(f"(Reader) Message Received: {message}")
if __name__ == "__main__":
# asyncio.run(reader())
uvicorn.run(
app="main:app",
reload=True
)
import asyncio
import redis.asyncio as redis
r = redis.Redis()
async def main():
async with r.pubsub() as pubsub:
await pubsub.subscribe("channel:1", "channel:2")
while True:
await r.publish("channel:1", "Hello")
await r.publish("channel:2", "World")
print("sent")
await asyncio.sleep(4)
if __name__ == "__main__":
asyncio.run(main())
redis
fastapi
uvicorn
@artemonsh
Copy link
Author

Для запуска нужно создать окружение, установить зависимости, поднять редис через docker compose up, запустить в одном терминале main.py, а в другом redis_publisher.py
Чтобы проверить, что все работает корректно, есть ручка "/", к которой можно обращаться, не блокируя прослушивание pubsub потока

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment