FastAPI使用异步Redis

  1. 安装依赖
bash 复制代码
pip install fastapi redis uvicorn
  1. 主要代码
python 复制代码
#!/usr/bin/env python
import os
import sys
from contextlib import AbstractAsyncContextManager, asynccontextmanager
from datetime import timedelta
from pathlib import Path

from fastapi import FastAPI, Request
from pydantic import BaseModel
from redis import asyncio as aioredis


class RegisterRedis(AbstractAsyncContextManager):
    def __init__(self, app: FastAPI, *args, **kw) -> None:
        app.state.redis = self._redis = aioredis.Redis(*args, **kw)

    async def __aenter__(self) -> "RegisterRedis":
        await self._redis.ping()
        return self

    async def __aexit__(self, *args, **kw):
        await self._redis.aclose()

    @staticmethod
    def get_client(request: Request) -> aioredis.Redis:
        return request.app.state.redis


@asynccontextmanager
async def lifespan(app: FastAPI):
    async with RegisterRedis(app):
        yield


app = FastAPI(lifespan=lifespan)


@app.get("/")
async def get_all_redis_keys(request: Request) -> list[str]:
    redis = RegisterRedis.get_client(request)
    return await redis.keys()


class Item(BaseModel):
    key: str
    value: str | int | float | bytes
    expire: int | timedelta | None = None


@app.post("/")
async def set_key_value(request: Request, item: Item) -> dict[str, str]:
    redis = RegisterRedis.get_client(request)
    await redis.set(item.key, item.value, item.expire or None)
    value = await redis.get(item.key)
    return {item.key: value.decode()}


def runserver() -> None:
    """This is for debug mode to start server. For prod, use supervisor+gunicorn instead."""
    import uvicorn  # type:ignore

    root_app = Path(__file__).stem + ":app"
    auto_reload = "PYCHARM_HOSTED" not in os.environ
    host = "0.0.0.0"
    port = 8000
    if sys.argv[1:]:
        port = int(sys.argv[1])
    if sys.platform == "darwin" or sys.platform.lower().startswith("win"):
        tool = "open" if Path("/usr/bin/open").exists() else "explorer"
        os.system(f"{tool} http://127.0.0.1:{port}")  # Auto open browser
    uvicorn.run(root_app, host=host, port=port, reload=auto_reload)


if __name__ == "__main__":
    runserver()
相关推荐
renhongxia130 分钟前
世界模型,是“空中楼阁”还是AGI的“最后一块拼图”?
运维·服务器·数据库·人工智能·算法·agi
程序员无隅39 分钟前
Coding Agent 为什么压缩上下文后还能继续工作?上下文模块设计拆解
java·开发语言·数据库
愿做无知一猿1 小时前
Nacos连接MySQL异常?DataGrip竟成救星
数据库·mysql
G.O.G.O.G1 小时前
LeetCode SQL 从入门到精通(MySQL)06(上)
数据库·sql·mysql·leetcode
研究员子楚2 小时前
GEO行业发展标准体系白皮书V2.0-第10卷 · 全球篇:跨国标准协同与全球品牌语义治理框架
数据库·人工智能·microsoft·架构·geo
Omics Pro2 小时前
深度学习多组学互作:组内+组间
数据库·人工智能·深度学习·mysql·搜索引擎·自然语言处理
残*影4 小时前
如何优雅地保存MySQL数据变更历史?
数据库·mysql
tellmewhoisi4 小时前
多版本共用redis的token有效期校验(过期重新登录)
java·redis·缓存
乐观的Terry4 小时前
3、数据库设计与领域实体
java·数据库·spring boot·spring cloud·ai编程
舞影天上4 小时前
RuoYi-Vue-Plus Docker 部署踩坑:MySQL 中文双重编码的根因与修复
数据库