Created
November 20, 2024 21:51
-
-
Save AnnMarieW/cda90db92c56ca90934df4febec6fdd5 to your computer and use it in GitHub Desktop.
FastAPI with Dash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from fastapi import FastAPI, Request | |
from pydantic import BaseModel | |
from typing import List, Dict, Any, Union, Optional | |
from dash import Dash, html, Input, Output, ctx, set_props | |
import dash | |
from flask import Flask, has_request_context | |
import flask | |
from flask.testing import EnvironBuilder | |
from werkzeug.datastructures import Headers | |
from werkzeug.wrappers import Request as WerkzeugRequest | |
import json | |
# Create a Flask server | |
flask_server = Flask(__name__) | |
# Create a FastAPI app | |
app = FastAPI() | |
def print_error(error): | |
print(error) | |
set_props('app_notifications', {'children': 'IT has been notified of the error'}) | |
return dash.no_update | |
# Create a Dash app | |
dash_app = Dash(__name__, server=flask_server, routes_pathname_prefix='/dash/', | |
requests_pathname_prefix='/api/', | |
on_error=print_error) | |
# Define the layout of the Dash app | |
dash_app.layout = html.Div(children=[ | |
html.H1(children='Hello Dash'), | |
html.Div(children='Dash: A web application framework for Python.'), | |
html.Button('Testing', id='test'), | |
html.Div(id='testout') | |
]) | |
class Outputs(BaseModel): | |
id: Union[str, dict] | |
property: str | |
class Inputs(BaseModel): | |
id: Union[str, dict] | |
property: str | |
value: Optional[Any] = None | |
class States(BaseModel): | |
id: Union[str, dict] | |
property: str | |
value: Optional[Any] = None | |
class Payload(BaseModel): | |
output: str | |
outputs: Outputs | |
inputs: List[Inputs] | |
state: Optional[List[States]] = [] | |
changedPropIds: List[Any] | |
parsedChangedPropsIds: List[Any] | |
@app.post('/_dash-update-component') | |
async def execute_callback(payload: Payload, request: Request): | |
# Create a WSGI environment from the FastAPI request | |
headers = [(key, value) for key, value in request.headers.items()] | |
environ_builder = EnvironBuilder( | |
flask_server, | |
method=request.method, | |
path=request.url.path, | |
headers=Headers(headers), | |
data=json.dumps(payload.model_dump()), | |
query_string=request.url.query.encode('utf-8') | |
) | |
flask.request = environ_builder.get_request() | |
response = dash_app.dispatch() | |
return response | |
@dash_app.callback( | |
Output('testout','children'), | |
Input('test','n_clicks') | |
) | |
@app.post('/test-click') | |
def rawr(n): | |
1/0 | |
if has_request_context(): | |
set_props('test', {'children': 'rawr'}) | |
return n | |
return {"status": "ok", "data": n} | |
# Run the app with Uvicorn | |
if __name__ == "__main__": | |
import uvicorn | |
# Run the FastAPI app with Uvicorn | |
uvicorn.run(app, host="0.0.0.0", port=8000) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment