{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# FastAPI 子应用\n", "\n", "参考:[sub-applications](https://fastapi.tiangolo.com/zh/advanced/sub-applications/)\n", "\n", "如果你需要有两个独立的 FastAPI 应用程序,它们有自己独立的 OpenAPI 和自己的文档 UI,你可以分别拥有主应用程序和“挂载”的一个或多个子应用程序。\n", "\n", "## 挂载 FastAPI 应用程序\n", "\n", "“挂载”意味着在特定路径中添加完全“独立”的应用程序,然后处理该路径下的所有内容,并在该子应用程序中声明路径操作。\n", "\n", "### 顶层 FastAPI 应用程序\n", "\n", "首先,创建主要的顶层 FastAPI 应用程序及其路径操作:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from fastapi import FastAPI\n", "\n", "app = FastAPI()\n", "\n", "\n", "@app.get(\"/app\")\n", "def read_main():\n", " return {\"message\": \"Hello World from main app\"}" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### 子应用\n", "\n", "然后,创建子应用程序及其路径操作。\n", "\n", "这里的子应用程序只是另一个标准的 FastAPI 应用程序,但它将被“挂载”:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "subapi = FastAPI()\n", "\n", "\n", "@subapi.get(\"/sub\")\n", "def read_sub():\n", " return {\"message\": \"Hello World from sub API\"}" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### 挂载子应用程序\n", "\n", "在顶层应用程序 `app` 中,挂载子应用程序 `subapi`。\n", "\n", "在这种情况下,它将被挂载在 `/subapi` 路径下:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "app.mount(\"/subapi\", subapi)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## 挂载其他 WSGI 组件\n", "\n", "可以使用 `WSGIMiddleware` 来包装你的 WSGI 应用,如:Flask,Django 等。\n", "\n", "使用中间件包装 WSGI 应用(例如 Flask),之后将其挂载到某一个路径下:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from fastapi import FastAPI\n", "from fastapi.middleware.wsgi import WSGIMiddleware\n", "from flask import Flask, escape, request\n", "\n", "flask_app = Flask(__name__)\n", "\n", "\n", "@flask_app.route(\"/\")\n", "def flask_main():\n", " name = request.args.get(\"name\", \"World\")\n", " return f\"Hello, {escape(name)} from Flask!\"\n", "\n", "\n", "app = FastAPI()\n", "\n", "\n", "@app.get(\"/v2\")\n", "def read_main():\n", " return {\"message\": \"Hello World\"}\n", "\n", "\n", "app.mount(\"/v1\", WSGIMiddleware(flask_app))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "现在,所有定义在 `/v1/` 路径下的请求将会被 Flask 应用处理。其余的请求则会被 FastAPI 处理。\n", "```" ] } ], "metadata": { "kernelspec": { "display_name": "py310", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "7e468feb35f514aafce3cc952fb1f3b43bab876fc14f6450ea05924ae7e4a934" } } }, "nbformat": 4, "nbformat_minor": 2 }