将 fastapi 与 plotly.dash 结合并将令牌依赖项添加为 auth 时出现问题

Problem with combining fastapi with plotly.dash and adding token dependency as auth

所以这是一个安装到 fastapi 的示例 dash 应用程序。我正在使用基于官方文档 fastapi-adcanced-wsgi 中的示例的 app.mount。现在我被卡住了,因为我看不到可以安装这个 dash 应用程序并添加 fastapi 依赖项的方法

我想以向 fastapi 路由添加单一依赖项的方式向此 dash 子应用程序添加令牌甚至基本身份验证:

from fastapi import Depends, FastAPI
from fastapi.security import HTTPBasic, HTTPBasicCredentials

app = FastAPI()

security = HTTPBasic()


@app.get("/users/me")
def read_current_user(credentials: HTTPBasicCredentials = Depends(security)):
    return {"username": credentials.username, "password": credentials.password}

FastAPI 示例与工作仪表板应用程序。

from fastapi import FastAPI
from fastapi.middleware.wsgi import WSGIMiddleware
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
from datetime import datetime

# Create the Dash application, make sure to adjust requests_pathname_prefx
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app_dash = dash.Dash(__name__, external_stylesheets=external_stylesheets, requests_pathname_prefix='/dash/')

app_dash.layout = html.Div([
    html.Label('Dropdown'),
    dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value='MTL'
    ),

    html.Label('Multi-Select Dropdown'),
    dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value=['MTL', 'SF'],
        multi=True
    ),

    html.Label('Radio Items'),
    dcc.RadioItems(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value='MTL'
    ),

    html.Label('Checkboxes'),
    dcc.Checklist(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value=['MTL', 'SF']
    ),

    html.Label('Text Input'),
    dcc.Input(value='MTL', type='text'),

    html.Label('Slider'),
    dcc.Slider(
        min=0,
        max=9,
        marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)},
        value=5,
    ),
], style={'columnCount': 2})

# Now create your regular FASTAPI application

app = FastAPI()

@app.get("/hello_fastapi")
def read_main():
    return {"message": "Hello World"}

# Now mount you dash server into main fastapi application
app.mount("/dash", WSGIMiddleware(app_dash.server))

不确定是否可以将依赖项与 WSGI 子应用程序一起使用,您可以考虑使用中间件作为解决方法。像这样:

from fastapi import FastAPI, Request
from fastapi.middleware.wsgi import WSGIMiddleware
from flask import Flask, escape, request
from starlette.responses import JSONResponse

flask_app = Flask(__name__)


@flask_app.route("/")
def flask_main():
    name = request.args.get("name", "World")
    return f"Hello, {escape(name)} from Flask!"


app = FastAPI()


@app.middleware("http")
async def auth_middleware(request: Request, call_next):
    if (request.url.path.startswith("/v1") and
            request.headers.get('X-Token', None) != "expected_token"):
        return JSONResponse(status_code=403)
    response = await call_next(request)
    return response


@app.get("/v2")
def read_main():
    return {"message": "Hello World"}


app.mount("/v1", WSGIMiddleware(flask_app))