【Python】dash-fastapi前后端搭建

概述

项目中需要快速搭建一个前后端系统,涉及到dash-fastapi架构的时候,对该架构的时候进行总结。本文主要总结的是对该架构的基本使用,后续再对该架构的项目源码进行总结分析

此处实现一个小的demo,迷你任务管理器,后端使用FastAPI,前端则使用Dash,数据存储暂时使用列表进行存储,主要功能如下

  • 任务列表展示: 前端页面显示一个简单的任务列表,包含任务标题和状态。
  • 添加任务: 用户可以在前端输入任务标题,点击按钮添加新任务。
  • 刷新任务列表: 点击按钮可以刷新任务列表,从后端获取最新数据。

整体架构理解

代码主体架构

  • 后端
    • main.py (Fast API主文件)
    • requirements.txt(后端依赖)
  • 前端
    • app.py(Dash主文件)
    • api_client.py(前端API客户端)
    • layoputs.py(前端布局)
    • callbacks.py(前端回调函数)
    • requirements.txt(后端依赖)

主要逻辑理解

代码中具体体现

  • 后端
    • main.py:后端,也就类似于厨房。专门负责接收顾客的订单,然后准备食物(构建响应)并告知服务器食物准备后
    • tasks_db = []:通过列表内存列表,类似于厨师的菜单列表。其记录了餐厅可以提供的菜品,也就是后端可以完成的任务
    • @app.get :厨师提供给服务员今日菜单,服务员发送get请求的时候,就可以知道后端提供什么服务(从tasks_db中获取)
    • @app.post:创创建任务,类似于服务员将菜单传给厨房;后面的逻辑就是请求响应的基本逻辑
    • Task(使用Pydantic模型):菜单上的菜品叙述,规定了每个任务包含哪些信息,提供任务名以及状态是否完成
  • 前端
    • layouts.py:餐厅的菜单,定义了顾客可以看到什么,也就是前端显示的页面
      • dcc.Input:点餐单的填写区域,顾客要吃什么
      • dbc.Button:提交按钮,这里可以对应设计供,例如提交点餐单或者是刷新菜单信息
      • html.Div:上菜的盘子,厨房准备后的食物会放进这个盘子里展示给顾客
    •  callbacks.py:服务员接收到顾客的指令应该如何行动
    • api_client.py:点餐系统,帮助前端与后端沟通,服务员与厨师之间的沟通                                                                                                                                                                   

具体实现

该实例主要用于理解该结构的运行

代码

后端:主要提供两个方法,获取所有任务列表和创建新任务

# backend/main.pyfrom fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Listapp = FastAPI()# 模拟内存数据库 (使用 Python 列表)
tasks_db = []
# 用于生成唯一的用户ID
task_id_counter = 1class Task(BaseModel):id: inttitle: strstatus: str = "待完成"  # 默认状态class TaskCreate(BaseModel):title: strclass TaskResponse(BaseModel):tasks: List[Task]@app.get("/api/tasks", response_model=TaskResponse)
async def get_tasks():"""获取所有任务列表"""return TaskResponse(tasks=tasks_db)@app.post("/api/tasks", response_model=Task)
async def create_task(task_create: TaskCreate):"""创建新任务"""global task_id_counternew_task = Task(id=task_id_counter, title=task_create.title)tasks_db.append(new_task)task_id_counter += 1return new_taskif __name__ == "__main__":import uvicornuvicorn.run(app, host="0.0.0.0", port=8000, reload=True)

后端依赖:requirements.txt

fastapi
uvicorn
pydantic

前端代码:api_client.py(向服务端发起请求)

import requestsAPI_BASE_URL = "http://localhost:8000/api"  # 后端 API 基础 URLdef get_task_list():"""获取任务列表"""url = f"{API_BASE_URL}/tasks"response = requests.get(url)response.raise_for_status()  # 检查请求是否成功 (状态码 2xx)return response.json()def create_new_task(title):"""创建新任务"""url = f"{API_BASE_URL}/tasks"headers = {'Content-Type': 'application/json'}data = {'title': title}response = requests.post(url, headers=headers, json=data)response.raise_for_status()return response.json()

前端回调:callbacks.py,当顾客触碰哪些按钮后与后端交互然后返回的逻辑实现

from dash import Output, Input, State
from .app import app  # 导入 Dash app 实例
from frontend import api_client  # 导入 API 客户端
import dash_html_components as html
import  dash@app.callback(Output("task-list-output", "children"),[Input("refresh-tasks-button", "n_clicks"),Input("add-task-button", "n_clicks")],[State("new-task-title", "value")]
)
def update_task_list(refresh_clicks, add_clicks, new_task_title):"""更新任务列表显示"""triggered_id = [p['prop_id'] for p in dash.callback_context.triggered][0]if "add-task-button" in triggered_id:if new_task_title:api_client.create_new_task(new_task_title) # 调用 API 创建新任务tasks_data = api_client.get_task_list() # 调用 API 获取任务列表task_items = []if tasks_data and tasks_data.get('tasks'): # 检查 tasks_data 和 tasks 键是否存在for task in tasks_data['tasks']:task_items.append(html.Li(f"{task['title']} - 状态: {task['status']} (ID: {task['id']})"))else:task_items.append(html.Li("暂无任务"))return html.Ul(task_items)

 前端页面布局layouts.py

import dash_html_components as html
import dash_core_components as dcc
import dash_bootstrap_components as dbclayout = dbc.Container([html.H1("迷你任务管理器"),dbc.Row([dbc.Col([html.Div("任务标题:"),dcc.Input(id="new-task-title", type="text", placeholder="请输入任务标题"),dbc.Button("添加任务", id="add-task-button", n_clicks=0, className="mt-2"),]),]),html.Hr(className="mt-3"),html.H4("任务列表"),dbc.Button("刷新任务列表", id="refresh-tasks-button", n_clicks=0, className="mb-2"),html.Div(id="task-list-output"), # 用于显示任务列表
])

前端依赖

dash
dash-bootstrap-components
requests

pydantic补充

"""
简单事例
"""# from pydantic import BaseModel
#
# class User(BaseModel):
#     id: int
#     name: str
#     email: str
#     is_active: bool = True  # 默认值
#
# # 示例数据
# user_data = {
#     'id': 1,
#     'name': 'Alice',
#     'email': 'alice@example.com',
# }
#
# # 使用 Pydantic 模型进行数据验证和解析
# user = User(**user_data)
# print(user)"""
复杂事例的封装
"""
from pydantic import BaseModel
from typing import Listclass Address(BaseModel):street: strcity: strzip_code: strclass User(BaseModel):id: intname: straddress: Address  # 嵌套模型# 创建嵌套数据
user_data = {'id': 1,'name': 'John','address': {'street': '123 Main St','city': 'New York','zip_code': '10001',}
}user = User(**user_data)
print(user)

前端回调逻辑

@app.callback(Output("task-list-output", "children"),[Input("refresh-tasks-button", "n_clicks"),Input("add-task-button", "n_clicks")],[State("new-task-title", "value")]
)
def update_task_list(refresh_clicks, add_clicks, new_task_title):"""更新任务列表显示"""triggered_id = [p['prop_id'] for p in dash.callback_context.triggered][0]if "add-task-button" in triggered_id:if new_task_title:api_client.create_new_task(new_task_title) # 调用 API 创建新任务tasks_data = api_client.get_task_list() # 调用 API 获取任务列表task_items = []if tasks_data and tasks_data.get('tasks'): # 检查 tasks_data 和 tasks 键是否存在for task in tasks_data['tasks']:task_items.append(html.Li(f"{task['title']} - 状态: {task['status']} (ID: {task['id']})"))else:task_items.append(html.Li("暂无任务"))return html.Ul(task_items)

回调函数callbacks理解

Dash框架中回调函数是实现交互的关键,其一可以连接前端的UI组件交互和侯丹数据的处理逻辑(调用API或者更新图表操作),从而实现动态更新前端UI,而不需要更新整个页面

Output("task-list-output", "children") (输出)

该处定义了回调函数的输出,其指定了当回调函数执行完毕后,哪个前端组件的哪个属性会被更新

html.Div(id="task-list-output") #  <---  这里定义了 id="task-list-output" 的 Div 组件

这个回调函数执行完成后,将会更新 id"task-list-output"Div 组件的 children 属性。 换句话说,回调函数的返回值将会被设置为这个 Div 组件的内容,从而更新任务列表的显示

换句话说,output就是上菜的盘子,盘子里面的内容就是children属性

[Input("refresh-tasks-button", "n_clicks"), Input("add-task-button", "n_clicks")] (输入 - 触发器)

指定了当前前端组件的哪些属性发生变化的时候,会触发这个回调函数执行

dbc.Button("刷新任务列表", id="refresh-tasks-button", ...) # <--- 这里定义了 id="refresh-tasks-button" 的按钮

类似于顾客点击菜价查询,服务员就会去问一下菜价,当顾客点击提交餐单的时候,服务员就会立马去厨房下单

[State("new-task-title", "value")] (状态)

指定哪些前端组件的哪些属性的当前值需要传递给回调函数,但是State组件属性的变化不会触发回调函数执行

可以理解State就是顾客在菜单上书写的菜名

update_task_list 回调函数被触发执行时 (因为 "刷新任务列表" 按钮或 "添加任务" 按钮被点击了),Dash 框架会将 id"new-task-title" 的输入框组件的 value 属性的 "当前值" 作为参数传递给 update_task_list 函数。 注意,输入框内容的变化 不会 直接触发回调函数,只有当 Input 指定的组件属性变化时才会触发

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/897856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA中链接使用mysql数据库

一、连接mysql 1. 打开idea&#xff0c;在右上角侧边栏有数据库database插件&#xff0c;打开侧边栏点击加号->数据源&#xff0c;可以看到支持很多数据库&#xff0c;选择mysql。 2. 首次使用需要下载驱动程序&#xff0c;不然连接数据库会报错。找到mysql&#xff0c;点击…

程序编译生成的文件

目录 .i 文件 .s 文件 .o文件 总结 在 C 编程中&#xff0c;.i、.s和 .o 文件是编译过程中生成的不同阶段的文件&#xff0c;它们代表不同的含义&#xff1a; .i 文件 全称 &#xff1a;预处理后的文件&#xff08;Intermediate File&#xff09;。 含义&#xff1a;.i文件…

[S32K]SPI

SpiShiftClockidleLevel: CLK空闲时电平(CPOL)&#xff1b; SpiDataShifrEdge:数据移位边沿(CPHA)&#xff1b; SpiDataWidth: SpiTransferStart: MSB(高位起始)&#xff0c;LSB(低位起始)&#xff1b;&#xff1b; SpiHwUnit: 这是一个具体的硬件&#xff1f; SpiDataShiftE…

系统思考:客户价值

“真正的市场竞争&#xff0c;不是比谁更能制造产品&#xff0c;而是比谁更能创造价值。” ——杰夫贝索斯 在组织辅导中&#xff0c;我经常问团队一个问题&#xff1a;“我们的客户是谁&#xff1f;”大多数人的第一反应是——“支付费用的就是客户。” 这在过去的市场扩张阶…

ArcGIS Pro 车牌分区数据处理与地图制作全攻略

在大数据时代&#xff0c;地理信息系统&#xff08;GIS&#xff09;技术在各个领域都有着广泛的应用&#xff0c;而 ArcGIS Pro 作为一款功能强大的 GIS 软件&#xff0c;为数据处理和地图制作提供了丰富的工具和便捷的操作流程。 车牌数据作为一种重要的地理空间数据&#xf…

OpenCV图像加权函数:addWeighted

1 addWeighted函数 在OpenCV 里&#xff0c;addWeighted 函数的作用是对两个图像进行加权求和&#xff0c;常用于图像融合、图像过渡等场景。函数如下&#xff1a; cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])2 参数解释 src1&#xff1a;第一个输入图…

Tcp网络通信的基本流程梳理

先来一张经典的流程图 接下介绍一下大概流程&#xff0c;各个函数的参数大家自己去了解加深一下印象 服务端流程 1.创建套接字&#xff1a;使用 socket 函数创建一个套接字&#xff0c;这个套接字后续会被用于监听客户端的连接请求。 需要注意的是&#xff0c;服务端一般有俩…

mysql学习-删除数据(drop、truncate、delete)

1、概述 drop、truncate、delete都可以删除mysql中的数据&#xff0c;但它们的作用范围和操作方式有很大的不同。 2、详细区别 2.1、drop 特点&#xff1a; 1、速度快 2、会删除表数据&#xff0c;还会删除表结构&#xff0c;包括与该表相关的所有数据&#xff0c;索引&…

编程自学指南:java程序设计开发,网络编程基础,TCP编程,UDP编程,HTTP客户端开发

编程自学指南&#xff1a;java程序设计开发&#xff0c;网络编程基础 学习目标&#xff1a; 理解网络协议&#xff08;TCP/IP、UDP&#xff09;的核心概念 掌握Socket编程实现客户端与服务端通信 能够通过多线程处理并发网络请求 开发简单的网络应用&#xff08;如聊天程序…

leecode797.所有可能的路径

深度优先搜索 class Solution { private:vector<vector<int>> result;vector<int> temp;void allPathsSourceTarget(vector<vector<int>> &graph,int v){if(vgraph.size()-1)result.push_back(temp);else{for(auto& adjVertex:graph[v]…

第八节:红黑树(初阶)

【本节要点】 红黑树概念红黑树性质红黑树结点定义红黑树结构红黑树插入操作的分析 一、红黑树的概念与性质 1.1 红黑树的概念 红黑树 &#xff0c;是一种 二叉搜索树 &#xff0c;但 在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是 Red和 Black 。 通过对 任何…

微信小程序threejs三维开发

微信小程序threejs开发 import * as THREE from three; const { performance, document, window, HTMLCanvasElement, requestAnimationFrame, cancelAnimationFrame, core, Event, Event0 } THREE .DHTML import Stats from three/examples/jsm/libs/stats.module.js; im…

jupyter无法转换为PDF,HTMLnbconvert failed: Pandoc wasn‘t found.

无法转为PDF 手动下载工具 https://github.com/jgm/pandoc/releases/tag/3.6.3 似乎跟我想的不大一样&#xff0c;还有新的报错 https://nbconvert.readthedocs.io/en/latest/install.html#installing-tex 不知道下的啥玩意儿 sudo apt-get install texlive-xetex texlive-fon…

关于PLC、电缆线材及气缸选型的详细教程

以下是关于PLC、电缆线材及气缸选型的详细教程&#xff0c;整合了多个专业来源的核心要点&#xff1a; 一、PLC选型要点 生产厂家选择 日系PLC&#xff08;如三菱FX系列、欧姆龙CP1系列&#xff09;适合独立设备或简单控制系统&#xff0c;性价比高。欧美系PLC&#xff08;如西…

使用 Excel 实现绩效看板的自动化

引言 在日常工作中&#xff0c;团队的绩效监控和管理是确保项目顺利进行的重要环节。然而&#xff0c;面临着以下问题&#xff1a; ​数据分散&#xff1a;系统中的数据难以汇总&#xff0c;缺乏一个宏观的团队执行情况视图。​看板缺失&#xff1a;系统本身可能无法提供合适…

02 windows qt配置ffmpeg开发环境搭建

版本说明 首先我使用ffmpeg版本是4.2.1 QT使用版本5.14.2 我选择是c编译 在02Day.pro⾥⾯添加ffmpeg头⽂件和库⽂件路径 win32 { INCLUDEPATH $$PWD/ffmpeg-4.2.1-win32-dev/include LIBS $$PWD/ffmpeg-4.2.1-win32-dev/lib/avformat.lib \$$PWD/ffmpeg-4.2.1-win32-dev/l…

Dask:Python高效并行计算利器

Dask&#xff1a;Python高效并行计算利器 Dask是一个开源的Python并行计算库&#xff0c;旨在扩展Python常用工具&#xff08;如NumPy、Pandas、Scikit-learn等&#xff09;的功能&#xff0c;使其能够处理更大规模的数据集和更复杂的计算任务。它通过动态任务调度和分布式计算…

掌握市场先机:9款销售渠道管理工具深度测评

本文主要介绍了以下9款销售渠道管理工具&#xff1a;1.纷享销客&#xff1b; 2.销帮帮&#xff1b; 3.小满CRM&#xff1b; 4.有赞&#xff1b; 5.Oracle NetSuite&#xff1b; 6.Salesforce Sales Cloud&#xff1b; 7.Cin7&#xff1b; 8.Pipedrive&#xff1b; 9.BigCommerc…

C语言基础知识04

指针 指针概念 指针保存地址&#xff0c;地址是字节的编号 指针类型和保存的地址类型要一直 使用时注意&#xff0c;把地址转换为&变量的格式来看 int a[3]; a转为&a[0] 指针的大小 64bit 固定8字节&#xff0c; 32bit 固定4字节 指针…

计算矩阵边缘元素之和(信息学奥赛一本通-1121)

【题目描述】 输入一个整数矩阵&#xff0c;计算位于矩阵边缘的元素之和。所谓矩阵边缘的元素&#xff0c;就是第一行和最后一行的元素以及第一列和最后一列的元素。 【输入】 第一行分别为矩阵的行数m和列数n&#xff08;m<100&#xff0c;n<100&#xff09;&#xff0c…