用纯 Python 构建 Web 应用

本教程将带你从零开始,构建一个交互式的待办事项清单。

fasthtml 的核心哲学是“回归初心,大道至简”。在当今复杂的前后端分离技术栈中 ,它提供了一条返璞归真的路径,旨在让你能用纯粹的 Python 构建从简单到复杂的全栈 Web 应用,彻底告别“前端/后端分离”带来的割裂感。

第一步:环境准备与项目初始化

首先,我们需要安装 fasthtml。它基于 Starlette 和 Uvicorn,性能卓越。

打开你的终端(CMDPowerShellTerminal)并运行以下命令:

pip install python-fasthtml

安装完成后,创建一个名为 todo_app.py 的文件,准备编写代码。

第二步:Python代码

# -*- coding: utf-8 -*-# ==============================================================================
# 1. 导入与初始化 (Imports & Initialization)
# ==============================================================================
# 从 fasthtml.common 导入所有核心组件。
# fasthtml 巧妙地借助 fastcore.xml 库,将所有标准HTML标签(如Div, P, Form)都变成了Python中的类。
# 这让你可以在纯 Python 代码中直接构建 HTML 结构,无需使用模板语言。
from fasthtml.common import *# AttrDict 允许我们用 `todo.task` 这样的属性访问方式替代 `todo['task']`,让代码更优雅。
from fastcore.utils import *# `fast_app()` 会创建应用实例和路由装饰器。
# app 是一个基于 Starlette 的高性能 ASGI 应用实例。
# rt 是路由对象,用于将 URL 路径(如'/')与处理函数关联起来。
app, rt = fast_app()# ==============================================================================
# 2. 数据存储 (Data Store)
# ==============================================================================
# 使用带唯一ID的列表来存储数据。
# 原始代码使用 list.index(),当任务重名时会导致错误。唯一ID是更健壮的实践。
todos = []
next_id = 0# ==============================================================================
# 3. 组件化渲染 (Componentized Rendering)
# ==============================================================================
# 将UI元素封装成函数是 fasthtml 的核心优势之一,这极大地促进了代码的复用和组件化。
# 这个函数就是一个可复用的 “ToDo Item” 组件。
def render_todo(todo: AttrDict):"""根据传入的 todo 对象,生成对应的 HTML 列表项 <li>。"""return Li(Div(# --- HTMX 驱动的动态交互 ---# HTMX 是 fasthtml 实现动态交互的秘密武器。# 它让任何HTML元素都能向服务器发请求,并用返回的HTML片段更新页面局部,无需刷新。Input(type="checkbox",checked=todo.done,# hx-post: 点击时,向指定URL发送POST请求。hx_post=f"/toggle/{todo.id}",# hx-target: 指定服务器返回的HTML应该更新哪个元素(使用CSS选择器)。# 'closest li' 表示“找到最近的父级<li>元素”。hx_target="closest li",# hx-swap: 指定如何更新目标元素。# 'outerHTML' 表示用返回的内容完整替换整个目标元素(包括<li>标签自身)。hx_swap="outerHTML",cls="mr-2"),Span(todo.task, cls=("line-through text-gray-500" if todo.done else "")),Button("❌",# hx-delete: 点击时发送 DELETE 请求。hx_delete=f"/delete/{todo.id}",hx_target="closest li",# hx-swap='delete': 一个特殊值,它会直接将目标元素从页面移除。hx_swap="delete",cls="text-red-500 ml-auto"),cls="flex items-center py-2 border-b"))# ==============================================================================
# 4. 页面路由 (Page Routes)
# ==============================================================================
@rt('/')
def get():"""定义根路由('/')的处理器,返回构成整个页面的Python对象。"""return Html(Head(Title('FastHTML ToDo App'),# 引入 Tailwind CSS。fasthtml 可以轻松集成任何CSS框架,如 DaisyUI。Script(src="https://cdn.tailwindcss.com"),# 引入 HTMX 库本身。这是实现所有 "hx-*" 魔法的基础。Script(src="https://unpkg.com/htmx.org@1.9.12"),),Body(Div(H1("我的 FastHTML 待办事项", cls="text-2xl font-bold mb-4 text-center"),Form(Input(type="text", name="task", placeholder="输入新任务...", required=True, cls="border p-2 mr-2 flex-grow"),Button("添加任务", type="submit", cls="bg-blue-500 text-white p-2 rounded hover:bg-blue-600"),# 提交表单时,向 /add URL 发送 POST 请求。hx_post="/add",# 返回的HTML片段将被插入到 id="todo-list" 的元素中。hx_target="#todo-list",# 'beforeend' 表示在目标元素的末尾追加内容。hx_swap="beforeend",# 请求成功后清空输入框,提升用户体验。hx_on="htmx:afterRequest: this.reset()",cls="flex mb-8"),# 初始加载时,渲染所有已存在的待办事项。# 这里的列表推导式完美体现了逻辑与视图的统一。Ul([render_todo(t) for t in todos], id="todo-list"),cls="container mx-auto p-8 max-w-lg bg-white rounded-lg shadow-lg mt-10"),cls="bg-gray-100"))# ==============================================================================
# 5. API 路由 (API Routes for HTMX)
# 这些路由只返回 HTML 片段,供 HTMX 进行局部更新。
# ==============================================================================
@rt('/add')
def post(task: str):"""处理添加任务的请求。FastHTML 会自动将表单字段'task'映射到函数参数。"""global next_idnew_todo = AttrDict(id=next_id, task=task, done=False)todos.append(new_todo)next_id += 1# 仅返回新任务的HTML片段,HTMX会将其追加到列表中。return render_todo(new_todo)@rt('/toggle/{id:int}')
def post(id: int):"""根据ID切换任务的完成状态。"""todo = next((t for t in todos if t.id == id), None)if todo:todo.done = not todo.done# 返回更新后的任务HTML,HTMX会用它替换掉旧的列表项。return render_todo(todo)return ""@rt('/delete/{id:int}')
def delete(id: int):"""根据ID删除任务。"""todo_to_delete = next((t for t in todos if t.id == id), None)if todo_to_delete:todos.remove(todo_to_delete)# 对于 hx-swap="delete",只需返回一个HTTP 200 OK的空响应即可。return ""# ==============================================================================
# 6. 启动服务 (Run the Server)
# ==============================================================================
if __name__ == "__main__":# 启动 Uvicorn 服务器来运行我们的 ASGI 应用。serve()

第三步:运行你的应用

  1. 保存好 todo_app.py 文件。
  2. 在终端中,确保你位于该文件所在的目录。
  3. 执行命令:
    python todo_app.py
    
  4. 你会看到服务器启动的提示。
  5. 在浏览器中打开 http://localhost:5001 (或其他端口),你将看到你的应用界面。

第四步:为什么选择 fasthtml

fasthtml 的优势非常明确:

  • 纯粹的 Python:为 Python 开发者,尤其是后端和数据科学家,提供了一条无需深入学习前端框架(如 React, Vue)就能构建全功能 Web 应用的捷径。
  • 简化但强大:它将 htmx 的强大功能无缝集成到 Python 中,通过简单的函数调用实现复杂的动态交互,极大地降低了全栈开发的门槛。
  • 性能优异:基于 Starlette 和 Uvicorn,具备处理生产环境需求的异步和高性能特性。
  • 快速原型验证:对于需要快速将 AI 模型等想法转化为可交互原型的场景,fasthtml 是比 Streamlit 或 Gradio 更灵活、更接近生产形态的选择。

第五步:下一步探索与部署上线

ToDo 应用现在已经在本地运行了。接下来,你可以尝试:

  1. 功能扩展:添加“编辑”功能,这会涉及到 hx-get(获取编辑表单)和 hx-put(提交更新)。
  2. 异步任务:尝试集成一个外部 API。或者像 AI 图片生成示例一样 ,处理耗时任务,并使用 hx-trigger='every 1s' 进行轮询。
  3. 实时通信:对于需要多人协作的应用,可以研究 fasthtml 对 WebSocket 的一流支持。

部署你的应用

fasthtml 应用是标准的 ASGI 应用,可以部署到任何支持 Python 的平台

  • Railway:通过 Git 自动化部署,非常适合小型项目。
  • Replit:一个在线 IDE,可以在浏览器中一键开发和部署,适合学习和实验。
  • HuggingFace Spaces:如果你在构建 AI 应用或模型 Demo,这是理想选择,它提供了优化的环境和免费计算资源。
  • 其他:你也可以使用 Vercel、PythonAnywhere 或任何云服务器(VPS)进行传统部署。

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

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

相关文章

开源 Arkts 鸿蒙应用 开发(九)通讯--tcp客户端

文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发&#xff0c;公司安排开发app&#xff0c;临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 Arkts …

Go的defer和recover

在 Go 语言中&#xff0c;defer 和 recover 是两个紧密相关的关键字&#xff0c;主要用于错误处理和资源清理。它们通常一起使用&#xff0c;特别是在处理panic&#xff08;运行时崩溃&#xff09;时&#xff0c;确保程序不会直接崩溃&#xff0c;而是能够优雅地恢复并继续执行…

Spring Boot 配置文件常用配置属性详解(application.properties / application.yml)

前言 Spring Boot 的一大优势就是通过简单的配置文件即可快速定制应用行为&#xff0c;而无需编写大量 XML 配置或 Java 代码。Spring Boot 使用 application.properties 或 application.yml 作为核心配置文件&#xff0c;支持丰富的配置属性。 本文将详细介绍 Spring Boot 常用…

uni-appDay02

1.首页-通用轮播组件 轮播图组件需要再首页和分类页使用&#xff0c;封装成通用组件 准备组件自动导入组件 <script setup lang"ts"> import XtxSwiper from /components/XtxSwiper.vue import CustomNavbar from ./components/CustomNavbar.vue </scrip…

FastAPI入门:请求体、查询参数和字符串校验、路径参数和数值校验

请求体 FastAPI 使用请求体从客户端&#xff08;例如浏览器&#xff09;向 API 发送数据。请求体是客户端发送给 API 的数据。响应体是 API 发送给客户端的数据。 使用 Pydantic 模型声明请求体&#xff0c;能充分利用它的功能和优点 from fastapi import FastAPI from pydanti…

Docker的docker-compose类比Spring的ApplicationContext

总一句话是&#xff1a;Docker Compose&#xff1a;集中化管理多个容器及其依赖的资源环境&#xff1b;ApplicationContext&#xff1a;集中化管理 多个Bean 及其运行所需的资源和依赖关系。 1. 整体概念 Docker Compose&#xff1a;用于定义和运行多容器 Docker 应用程序&…

Reason-before-Retrieve(CVPR 2025)

研究方向&#xff1a;Image Captioning论文全名&#xff1a;《Reason-before-Retrieve: One-Stage Reflective Chain-of-Thoughts for Training-Free Zero-Shot Composed Image Retrieval》1. 论文介绍组合图像检索&#xff08;CIR&#xff09;旨在检索与参考图像密切相似的目标…

Idefics2:构建视觉-语言模型时,什么是重要的

温馨提示&#xff1a; 本篇文章已同步至"AI专题精讲" Idefics2&#xff1a;构建视觉-语言模型时&#xff0c;什么是重要的 摘要 随着large language models和vision transformers的进步&#xff0c;视觉-语言模型&#xff08;VLMs&#xff09;受到了越来越多的关注…

再谈fpga开发(fpga调试方法)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】我们之前在学校学习c、c的时候&#xff0c;其实学校漏掉了很重要的一个教学环节&#xff0c;那就是调试、测试。很多时候我们代码写出来了&#xff…

C语言中的数据结构--栈和队列(1)

前言本届开始我们将对数据结构中栈的内容进行讲解,那么废话不多说,我们正式进入今天的学习栈栈是一种很特殊的线性表&#xff0c;它只能在固定的一端进行插入和删除操作&#xff0c;进行数据的插入和删除的一端叫做栈顶&#xff0c;另外一端叫做栈底&#xff0c;栈中的元素遵守…

字符串是数据结构还是数据类型?

比较纠结的一个问题&#xff0c;以下是在网上查到后总结的&#xff0c;不知道对不对&#xff0c;欢迎讨论。这是个触及计算机科学核心概念的精妙问题&#xff01;字符串既可以被视为一种数据类型&#xff0c;也可以被视为一种数据结构&#xff0c;这取决于你观察的视角和讨论的…

Cline与Cursor深度实战指南:AI编程助手的革命性应用

引言 在AI编程工具快速发展的今天&#xff0c;Cline和Cursor作为两款备受瞩目的AI编程助手&#xff0c;正在重新定义开发者的工作方式。作为一名深度使用这两款工具的开发者&#xff0c;我在过去一年的实践中积累了丰富的经验和独到的见解。本文将从技术角度深入分析Cline和Cur…

根本是什么

根本是什么 根本没有了&#xff0c;枝叶还在么&#xff1f; 没有了内涵&#xff0c;外延还有么&#xff1f; 丢弃了根本&#xff0c;再嗨也是无意义&#xff0c;无根据空虚之乐罢了。 人之所行所言所思所想所念皆欲念、历程感怀&#xff0c;情思。所谓得失过往&#xff0c;时空…

springboot基于Java的人力资源管理系统设计与实现

管理员&#xff1a;登录&#xff0c;个人中心&#xff0c;部门管理&#xff0c;员工管理&#xff0c;培训信息管理&#xff0c;员工奖励管理&#xff0c;员工惩罚管理员工考核管理&#xff0c;调薪信息管理&#xff0c;员工调动管理&#xff0c;员工工资管理员工&#xff1a;注…

金字塔降低采样

文章目录image_scale.hppimage_scale.cppmainimage_scale.hpp #ifndef IMAGE_SCALE_HPP #define IMAGE_SCALE_HPP#include <vector> #include <cstdint> #include <utility> // for std::pair #include <algorithm> #include <string> enum cl…

Filament引擎(四)——光照渲染Froxelizer实现分析

Froxelizer主要是用于filament光照效果的实现&#xff0c;生成光照渲染时所需的必要信息&#xff0c;帮助渲染过程中明确哪些区域受哪些光源所影响&#xff0c;是Filament中保证光照效果渲染效率的核心所在。这部分的源码&#xff0c;可以结合filament官方文档中Light Path部分…

2025 环法对决,VELO Angel Glide 坐垫轻装上阵

2025环法第16赛段的风秃山之巅&#xff0c;当最后一缕夕阳沉入云层&#xff0c;山风裹挟着砾石的气息掠过赛道&#xff0c;一场足以载入史册的激战正酣。帕雷-潘特的肌肉在汗水里贲张&#xff0c;链条与齿轮的咬合声混着粗重喘息&#xff0c;在171.5公里赛程的最后3公里陡坡上&…

Linux程序->进度条

进度条最终效果&#xff1a; 目录 进度条最终效果&#xff1a; 一&#xff1a;两个须知 1&#xff1a;缓冲区 ①&#xff1a;C语言自带缓冲区 ②&#xff1a;缓冲区的刷新策略 2&#xff1a;回车和换行的区别 二&#xff1a;倒计时程序 三&#xff1a;入门板进度条的实…

Python爬虫实战:研究tldextract库相关技术构建新闻网站域名分析爬虫系统

1. 引言 网络爬虫作为一种自动获取互联网信息的技术,在数据挖掘、信息检索、舆情分析等领域有着广泛的应用。Python 因其丰富的库和简洁的语法,成为了开发爬虫的首选语言。tldextract 是 Python 中一个强大的域名解析库,能够准确地从 URL 中提取顶级域名、二级域名等关键信…

【算法-华为机试-火星基地改造】

基地改造题目描述目标输入输出代码实现题目描述 在2XXX年&#xff0c;人们发现了一块火星地区&#xff0c;这里看起来很适合建设新家园。但问题是&#xff0c;我们不能一次性将这片地区的空气变得适合人类居住&#xff0c;得分步骤来。 把这片火星地区想象成一个巨大的棋盘。棋…