我知道可以在 FastAPI 之上安装 Flask 实例。这意味着所有发送到根 URL 的请求都由 FastAPI 处理,并且只有发送到指定 Flask URL 的请求才会转发给它。 是否有可能以相反的方式做到这一点?我有一个用 Flask 构建的网站,我想向其中添加一个 API 以从另一个应用程序管理数据库。 FastAPI 具有自动文档和验证功能,使生活变得更加轻松。我想这样安装它的原因
如果没有,我可以用 uvicorn 单独托管它,并将所有以 /api/ 开头的 URL 转发给它,并以某种方式返回它通过 Flask 返回的任何内容吗?
我在这里混合使用而不是单独运行它们的原因是我无法从 Flask 应用程序外部访问数据库。
我已经使用两个单独的 Flask 应用程序完成了此操作(请参阅此处)。
它可以与 FastAPI 实例一起使用。
FastAPI 实现了 ASGI,而 Flask 实现了 WSGI。 fastapi 文档中的 example 使用
WSGIMiddleware
包装 Flask 应用程序实例,以符合 ASGI 标准。
当你想做相反的事情时,你必须转换 fastapi。幸运的是,有一个可用的库可以完全执行此操作,称为 a2wsgi。
这是一个帮助您入门的最小示例:
from fastapi import FastAPI
from flask import Flask
from werkzeug.middleware.dispatcher import DispatcherMiddleware
from a2wsgi import ASGIMiddleware
flask_app = Flask(__name__)
@flask_app.route("/")
def flask_main():
return f"Hello World from Flask"
fast_app = FastAPI()
@fast_app.get("/")
def read_main():
return {"message": "Hello World from fastapi"}
dispatcher = DispatcherMiddleware(flask_app, {
'/flask': flask_app,
'/fast': ASGIMiddleware(fast_app),
})
app = Flask(__name__)
app.wsgi_app = dispatcher
然后您可以使用
flask run
或例如运行应用程序gunicorn
经过一番修改,我找到了解决方案。
我现在将 Flask 和 FastAPI 作为两个独立的应用程序运行。我添加了一条到 Flask 的路由,使其充当 FastAPI 应用程序的代理:
API_URL = "http://127.0.0.1:8000/"
@views.route("/api/<path:rest>")
def api_redirect(rest):
return requests.get(f"{API_URL}{rest}").content
然后我使用
uvicorn main:app --root-path api/
运行 FastAPI,以便前端知道在哪里可以找到 openapi.json
文件。
我通过添加以下代码解决了访问数据库时遇到的问题(由于不在会话中)。
engine = create_engine(DB_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
models.db.metadata.create_all(bind=engine)
app = FastAPI()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/all-items", response_model=List[schemas.Item], tags=["items"])
def all_items(db: Session = Depends(get_db)):
return db.query(models.Item).all()
这将为每个 API 调用创建一个新会话,然后在调用完成后将其关闭。