Acredito que você já tenha suas respostas nos fóruns de problemas do projeto Fastapi no Github:Issue 452 (fechado). Mas vou recapitular as soluções aqui para referência futura:
Resumindo, você pode usar motor ou mongoengine, Fastapi suporta ambos e você pode reutilizar um objeto de cliente global que é iniciado e finalizado com o processo do seu aplicativo.
Alguns detalhes de contexto para (espero) esclarecer essas tecnologias e seus relacionamentos:
O driver oficial do MongoDB para Python é o pymongo. Sob os capôs, tanto o MongoEngine quanto o Motor usam o Pymongo. O Pymongo implementa um cliente direto para MongoDB (daemons) e oferece uma API Python para fazer solicitações.
Se você quisesse, você poderia usar o pymongo com Fastapi diretamente. (No lado SQL das coisas, isso seria equivalente a usar psycopg2 no Flask diretamente sem passar por algo como SQLAlchemy.)
MongoEngine é um ODM (Mapeador Objeto-Documento). Ele oferece uma API orientada a objetos Python que você pode usar em seu aplicativo para trabalhar com mais conforto e, quando se trata das solicitações reais do banco de dados, o MongoEngine usará pymongo.
Motor é um wrapper para pymongo que o torna não bloqueante (permitindo async/await). Ele usa um loop de eventos, seja por meio de Tornado ou por meio de assíncrono. Se você estiver usando o Fastapi com o uvicorn, o uvicorn implementará a funcionalidade assíncrona com o uvloop. Em suma, usando o Motor com FastAPI, o async deve "simplesmente funcionar". Infelizmente, Motor não implementa um ODM. Nesse sentido, é mais semelhante ao pymongo.
O Fastapi lida com as solicitações dos clientes (usando Starlette), mas permite que você implemente sua própria conexão com o MongoDB. Portanto, você não está restrito a nenhuma escolha específica, mas está principalmente por conta própria (à la Flask).
Você pode usar os ganchos de inicialização/desligamento do seu aplicativo FastAPI para iniciar/parar seu cliente Motor/MongoEngine. Você não precisa se preocupar com o fato de seu objeto cliente não persistir devido a problemas de multiprocesso, pois o Fastapi é single-thread.
@app.on_event("startup")
async def create_db_client():
# start client here and reuse in future requests
@app.on_event("shutdown")
async def shutdown_db_client():
# stop your client here
Um exemplo de implementação de motor com Fastapi pode ser encontrado aqui.