全新 Python Web 框架 - Air,第一个专为 AI 辅助开发而设计的 Web 框架

大家好,我是java1234_小锋老师。

你有没有过这种体验:跟 AI 说「帮我做一个带联系表单的小网站」,它给你甩过来一整套 React、一堆 npm 依赖、再加一段你看了两遍还是不想审的配置。表单本身只要十分钟,配套工程却能拖你一下午。

Air 想改的,就是这件事。

它是 Two Scoops of Django 作者 Audrey 和 Daniel Roy Greenfeld 做的新框架,口号很直白:第一个专门让 AI 来写的 Web 框架。底层还是你熟悉的 FastAPI、Pydantic、HTMX,人写也舒服,AI 写更不容易跑偏。

在这里插入图片描述

Air 到底是什么

一句话:Air 是盖在 FastAPI 上面的一层,专门把「写网页」这件事变简单。

以前用 FastAPI,接口很爽,一到 HTML 就得自己拼 HTMLResponse、Jinja 上下文、模板路径。Air 把这些琐事收掉了。你可以继续写 API,也可以用 Python 类直接拼页面,两种活放在同一个 app 里。

它自己总结的几个卖点,我觉得最实在的是这几条:

  • 没有魔法,air.H1("你好") 看起来是什么,跑起来就是什么
  • 类型和文档写在源码里,编辑器和 AI 不用再去翻外站文档
  • 自带 HTMX,前端 JS 可以压得很薄
  • 表单校验走 Pydantic,和写接口模型是同一套思路
  • MIT 协议,能跑 Python 的地方都能跑,不绑托管平台

目前还在 alpha,接口以后可能会变。用来写小工具、内部后台、AI 一起搭的原型,刚刚好。


为什么说它是给 AI 写的

现在很多框架都说「对 AI 友好」。Air 的做法更具体:它按「AI 怎么才不容易写错」来设计 API。

官方自己也讲过一个对比。你让 AI 做一个联系表单,常见结果是 React + 打包配置 + 水合逻辑,审代码比写需求还累。Air 追求的是:一个文件进去,一个文件出来,生成的少,你要看的也少。

在这里插入图片描述

它为 AI 准备了几件很务实的东西:

  1. 源码即文档。函数参数、用法示例都写在包里面,Cursor、Copilot 这类工具读安装好的包就能懂,不用再联网翻文档。
  2. 类型完整。格式化、检查、类型校验都能跑通。AI 写错了,编辑器当场就能拦住。
  3. 提供 llms.txt。给大模型准备了专用说明,完整版在 llms-full.txt
  4. 尽量少文件。代码越少,生成出来「能跑」的概率越高。

整个协作大概是这样:

不能

你用一句话描述需求

AI 读 Air 源码和 llms.txt

生成少量 Python 代码

类型检查和编辑器补全

能不能跑

浏览器里看页面

改几行再跑

你只审关键逻辑

说白了,不是让 AI 替代你,而是让它少猜、少编、少堆配置。


五分钟跑起来

先说环境:Air 目前需要 Python 3.13 及以上。用 uv 最省事:

uv venv
source .venv/bin/activate   # Windows 用 .venv\Scripts\activate
uv add air

想顺便把 FastAPI 那套开发工具带上,可以装:

uv add "air[standard]"

然后新建一个 main.py

import air

app = air.Air()


@app.page
def index():
    return air.Html(air.H1("Hello, Air", style="color: #2563eb;"))

终端里执行:

air run

打开 http://127.0.0.1:8000,标题就出来了。

@app.page 是个小糖:函数名会变成路径。index 对应 /dashboard 对应 /dashboardshow_item 会变成 /show-item。路径要自己定,或者带 {user_id} 这种参数时,再用 @app.get("/...")


两种写页面的方式

这是我觉得 Air 最对味的一点:你可以从 Python 开始,也可以从 HTML 开始,两条路最后都能跑成同一个网站。

在这里插入图片描述

方式一:用 Air Tags,把 HTML 写成 Python

Air Tags 就是一组带类型的 Python 类, nested 起来就是 DOM。编辑器能补全属性,类型检查能看嵌套对不对:

import air

app = air.Air()


@app.page
def index():
    return air.Html(
        air.Head(air.Title("今日待办")),
        air.Body(
            air.H1("今日待办"),
            air.Ul(
                air.Li("写完 Air 的试用笔记"),
                air.Li("把联系表单接到接口上"),
                air.Li("晚上早点睡"),
            ),
        ),
    )

air.H1("text") 渲染出来就是 <h1>text</h1>。没有隐藏步骤,AI 也不用猜「这个宏最后会展开成什么」。

方式二:继续用 Jinja 模板

设计师给了 HTML,或者你就想先写页面再接线,用 Jinja 也完全没问题:

import air

app = air.Air()
jinja = air.JinjaRenderer(directory="templates")


@app.page
def index(request: air.Request):
    return jinja(request, name="index.html")

templates/index.html 里放普通 HTML 就行。两种写法可以混在同一个项目里,甚至同一个视图里。官方的态度很务实:能用 Python 就用 Python,遇到模板更合适就用模板,不必站队。


表单:Pydantic 直接管校验

做一个留言表单,大概是这样:

from pydantic import EmailStr

import air

app = air.Air()


class ContactModel(air.AirModel):
    name: str
    email: EmailStr
    message: str


class ContactForm(air.AirForm):
    model = ContactModel


@app.page
def index():
    return air.Html(
        air.Head(air.Title("留言板")),
        air.Body(
            air.H1("给我留言"),
            air.Form(
                air.Input(name="name", placeholder="你的名字"),
                air.Input(name="email", type_="email", placeholder="邮箱"),
                air.Textarea(name="message", placeholder="想说的话"),
                air.Button("发送", type_="submit"),
                method="post",
                action="/contact",
            ),
        ),
    )


@app.post("/contact")
async def contact(request: air.Request):
    form = await ContactForm.from_request(request)
    if form.is_valid:
        data = form.data
        return air.Html(
            air.H1("收到了"),
            air.P(f"{data.name},我们会发信到 {data.email}。"),
        )

    return air.Html(
        air.H1("请检查一下表单"),
        air.Form(
            form.render(),
            air.Button("再试一次", type_="submit"),
            method="post",
            action="/contact",
        ),
    )

校验失败时,form.render() 会把错误信息和用户已经填过的内容带回去。你熟悉 Pydantic,这块几乎不用另学一套。

页面之间的局部刷新,Air 也站 HTMX。一个按钮点下去,只换页面里的一小块,不必上 React。整站 JS 按官方的说法,大约就 HTMX 那 16KB。

数据在页面和接口之间怎么走,可以看成下面这样:

合法

不合法

浏览器提交表单

Air 路由接到 POST

AirForm + Pydantic 校验

数据合不合法

写入数据库或调用业务

返回 Air Tags 或 JSON

带着错误信息重新渲染表单

整页返回,或 HTMX 只换一块


页面和 API 可以放在同一个项目里

Air 底下就是 FastAPI。页面用 Air 写,接口继续用 FastAPI,挂到 /api 即可:

from fastapi import FastAPI

import air

app = air.Air()
api = FastAPI()


@app.page
def index():
    return air.Html(
        air.Head(air.Title("我的小站")),
        air.Body(
            air.H1("我的小站"),
            air.P(air.A("打开 API 文档", href="/api/docs", target="_blank")),
        ),
    )


@api.get("/")
def api_root():
    return {"message": "这接口是 FastAPI 在跑"}


app.mount("/api", api)

以前 FastAPI 那套 response_model、OpenAPI、WebSocket,都能接着用。不是换赛道,是在熟悉的路上把「出网页」补齐了。


现在适不适合上手

适合的情况很清楚:

  • 你已经会一点 FastAPI,想少写模板胶水代码
  • 你经常跟 AI 一起写项目,希望它少引入一堆前端工程
  • 你要的是能跑的页面和表单,而不是先搭 SPA

需要心里有数的地方:

  • 还在 alpha,升级时 API 可能变
  • 要 Python 3.13+
  • 后台管理、国际化、脚手架这些,官方还在做,现在别拿它当 Django 的完整替代

生态上已经有 MCP、llms.txt,组件库方向有基于 Tailwind 的 AirDragon。作者的路线也很明确:核心保持小,新能力往独立包里放,不把底座做成大而全。


写在最后

Air 最打动我的,不是又多了一个 Python Web 框架,而是它把问题问得很准:现在代码经常是人跟 AI 一起写的,框架能不能别再让双方都猜来猜去?

类型写清楚,文档写在源码里,HTML 要么是一眼能看懂的 Python,要么是你本来就会的 Jinja。人读得快,AI 写得稳,审代码也轻松。

想试的话,从官网那 4 行 Hello World 开始就够了。项目在 GitHub 上:feldroy/air(https://github.com/feldroy/air),文档在 docs.airwebframework.org

它未必会取代你手里的 Django 或 FastAPI。但如果你最近总在跟 AI 一起搭小站,它值得你今晚开一个虚拟环境,跑一下 air run

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值