【发布时间】:2021-01-28 03:06:53
【问题描述】:
我也可以将 MongoDB 与 FastAPI 一起使用
- 使用全局
client: motor.motor_asyncio.AsyncIOMotorClient对象,否则 - 通过在
startup事件期间为每个 this SO answer 创建一个,它指的是 this "Real World Example"。
但是,我也想使用fastapi-users,因为它可以很好地与开箱即用的 MongoDB 配合使用。缺点是它似乎只适用于处理我的数据库客户端连接(即全局)的第一种方法。原因是为了配置 fastapi-users,我必须有一个活动的 MongoDB 客户端连接,这样我才能创建 db 对象,如下所示,我需要 db 然后创建 MongoDBUserDatabase 对象fastapi-users 要求:
# main.py
app = FastAPI()
# Create global MongoDB connection
DATABASE_URL = "mongodb://user:paspsword@localhost/auth_db"
client = motor.motor_asyncio.AsyncIOMotorClient(DATABASE_URL, uuidRepresentation="standard")
db = client["my_db"]
# Set up fastapi_users
user_db = MongoDBUserDatabase(UserDB, db["users"])
cookie_authentication = CookieAuthentication(secret='lame secret' , lifetime_seconds=3600, name='cookiemonster')
fastapi_users = FastAPIUsers(
user_db,
[cookie_authentication],
User,
UserCreate,
UserUpdate,
UserDB,
)
在代码中的那一点之后,我可以导入 fastapi_users 路由器。但是,如果我想将我的项目分解为我自己的 FastAPI 路由器,我会感到很沮丧,因为:
- 如果我将
client创建移动到另一个模块以导入到我的app和我的路由器中,那么我在不同的事件循环中有不同的客户端并得到像RuntimeError: Task <Task pending name='Task-4' coro=<RequestResponseCycle.run_asgi() running at /usr/local/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py:389> cb=[set.discard()]> got Future <Future pending cb=[_chain_future.<locals>._call_check_cancel() at /usr/local/lib/python3.8/asyncio/futures.py:360]> attached to a different loop这样的错误(在 this SO question 中提到) - 如果我使用“真实世界示例”的解决方案,那么在我的代码示例中我会卡在哪里构建我的
fastapi_users对象:我无法在main.py中执行此操作,因为没有db对象。
我考虑将MongoDBUserDatabase 对象作为startup 事件代码的一部分(即在真实世界示例中的async def connect_to_mongo() 内),但我也无法让它工作,因为我做不到看看如何让它发挥作用。
我该怎么做
- 以一种可以在我的主要
app和几个routers之间共享的方式创建一个全局 MongoDB 客户端和 FastAPI-User 对象,而不会出现“附加到不同的循环”错误,或者 - 创建精美的包装类和函数以使用
startup触发器设置 FastAPI 用户?
【问题讨论】:
标签: mongodb fastapi tornado-motor