Bottle 框架快速上手:Python 轻量级 WSGI 微框架从安装到路由实战

原创2026-09-24 23:32:15260 阅读
文章标签:后端Web框架

Bottle 框架快速上手:Python 轻量级 WSGI 微框架从安装到路由实战

Bottle 是一个以单一 bottle.py 文件分发、除 Python 标准库外零依赖的轻量级 WSGI 微框架,本指南以其官方文档 docs/index.rst 为骨架,结合当前仓库源码带你掌握路由映射、模板渲染、内置服务器启动、安装部署方式以及文档体系导航,读完即可用几行代码跑起一个可访问的 Web 应用。

框架概览:为什么选择 Bottle

Bottle 定位是 "fast, simple and lightweight",它把 Web 开发中最常用的能力压缩进一个单文件模块 bottle.py(约 4500 行)中,核心特性集中在四个方面:

  • 路由(Routing):将 HTTP 请求映射到 Python 函数,支持整洁的动态 URL(如 /hello/<name>),由 bottle.py 中的 Router 类 实现,底层将路由规则编译为正则表达式进行匹配。
  • 模板(Templates):自带快速且 Pythonic 的内置模板引擎(SimpleTemplate,详见 docs/stpl.rst),同时支持 Mako、Jinja2、Cheetah 等第三方模板引擎。
  • 工具(Utilities):提供对表单数据、文件上传、Cookie、请求头等 HTTP 特性的便捷访问,全部封装在 BaseRequest 类 中。
  • 服务器(Server):内置 HTTP 开发服务器,并提供面向 gunicorn、paste、cheroot 等众多 WSGI 服务器的现成适配器,详见 docs/deployment.rst。

由于整个框架就是一个模块文件,你可以直接把它拷贝进项目目录使用,也可以作为标准 WSGI 应用挂载到任何 WSGI 兼容的环境中。

一分钟上手:"Hello World" 示例

官方文档给出的入门示例展示了 Bottle 的三个核心 API——route 装饰器、template 函数和 run 启动器:

from bottle import route, run, template

@route('/hello/<name>')
def index(name):
    return template('<b>Hello {{name}}</b>!', name=name)

run(host='localhost', port=8080)

把这段代码保存为脚本运行,或直接粘贴进 Python 交互式控制台,然后访问 http://localhost:8080/hello/world 即可看到渲染结果。

它的工作原理值得拆解:

  1. @route('/hello/<name>') 把 /hello/<name> 这个 URL 路径绑定到 index 函数,<name> 是通配符,URL 中对应片段会作为关键字参数 name 传入函数。
  2. template(...) 调用内置模板引擎,将 {{name}} 占位符替换为传入的值并渲染出 HTML。
  3. run(host='localhost', port=8080) 启动内置开发服务器,阻塞运行直到按 Ctrl-C 停止。

从源码看,run 函数的完整签名(bottle.py#L3800)默认使用 wsgiref 服务器适配器、绑定 127.0.0.1:8080,开发期无需任何额外配置即可运行。

安装与获取:三种方式对比

官方文档明确说明 Bottle 除 Python 标准库外没有硬性依赖(模板或服务器适配器类需要对应模块时才需要额外安装)。

方式一:pip 安装稳定版(推荐)

pip install bottle

方式二:直接下载单文件

把 bottle.py 下载到项目目录即可使用,无需安装:

wget https://bottlepy.org/bottle.py

方式三:配合虚拟环境使用

更推荐为每个项目创建独立虚拟环境再安装:

python3 -m venv venv          # 创建虚拟环境
source venv/bin/activate      # 切换默认 Python 到虚拟环境
pip install -U bottle         # 在虚拟环境中安装 bottle

此外,Bottle 既是模块也是命令行程序。通过 pip 安装后,路径上会出现 bottle 命令,可用于启动应用(详见 docs/tutorial.rst):

bottle --help
python3 -m bottle --help
./path/to/bottle.py --help

示例(使用 --debug 与 --reload 启动模块 mymodule):

bottle --debug --reload mymodule

输出类似:

Bottle v0.13-dev server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

注意:0.13 版本起,可执行脚本从 bottle.py 更名为 bottle,旧名称已弃用,以避免循环导入问题。

Python 版本支持矩阵("Dead Snakes" 策略)

Bottle 0.12 及之前版本支持了极为宽泛的 Python 版本(其中一些早已停止维护超过十年)。自 0.13 起,项目只保证与仍在官方维护周期内的 Python 版本保持向后兼容;旧版本 Python 可能仍能运行,但不再经过兼容性测试。

官方文档中的支持矩阵如下:

Bottle 版本 Python 2 Python 3
0.12 2.5 - 2.7 3.2 - 3.12
0.13 2.7 >=3.8
0.14(规划中) 已放弃 >=3.9

文档脚注进一步说明:Bottle 通常仍能在刚停止维护的 Python 3.x 版本上运行,项目不会刻意破坏兼容性,但也不再针对这些版本进行测试,使用时需自行承担风险。如果你的生产环境必须依赖较老的 "dead snakes" Python,建议停留在 Bottle 0.12(长期支持版);否则应定期升级以获取新功能与改进。

四大核心能力详解

结合文档路标与源码,下面深入每一项核心能力。

1. 路由:从静态路径到动态 URL

路由是 Bottle 最重要的概念。route 装饰器将 URL 路径与回调函数绑定,一个回调可以绑定多个路由,动态路由中的通配符会以关键字参数形式传入函数:

@route('/')
@route('/hello/<name>')
def greet(name='Stranger'):
    return template('Hello {{name}}, how are you?', name=name)

通配符语法为 <name>,默认匹配到下一个斜杠为止;通过过滤器可约束和转换匹配内容(详见 docs/routing.rst)。内置过滤器对应源码 Router.filters 中的实现:

过滤器 匹配规则 说明
:int 有符号数字,转换为 int 对应正则 -?\d+
:float 小数,转换为 float 对应正则 -?[\d.]+
:path 非贪婪匹配任意字符(含 /) 可匹配多段路径,对应正则 .+?
:re 在配置字段中指定自定义正则 匹配值不经过类型转换

实战示例:

@route('/object/<id:int>')
def callback(id):
    assert isinstance(id, int)

@route('/show/<name:re:[a-z]+>')
def callback(name):
    assert name.isalpha()

@route('/static/<path:path>')
def callback(path):
    return static_file(path, ...)

2. HTTP 方法与头部处理

所有未指定方法的路由默认只匹配 GET 请求。处理 POST、PUT、DELETE、PATCH 时,可在 route 装饰器中传 method 参数,或直接使用 get、post、put、delete、patch 五个快捷装饰器(见 bottle.py#L898-L916)。

表单登录示例:

from bottle import get, post, request

@get('/login')  # 显示表单
def login():
    return '''
        <form action="/login" method="POST">
            Username: <input name="username" type="text" />
            Password: <input name="password" type="password" />
            <input value="Login" type="submit" />
        </form>
    '''

@post('/login')  # 处理提交
def do_login():
    username = request.forms.username
    password = request.forms.password
    if check_login(username, password):
        return "<p>Your login information was correct.</p>"
    else:
        return "<p>Login failed.</p>"

此外有两个特殊方法值得注意:

  • HEAD:自动回退到对应的 GET 路由并截断响应体,用于获取资源的元信息,无需手动声明 HEAD 路由。
  • ANY:非标准方法,作为低优先级兜底——ANY 路由会匹配任意 HTTP 方法,但仅当没有更具体的匹配路由时生效,非常适合代理路由(proxy-route)场景。

从源码看,Bottle 实例本身就是一个可调用的 WSGI 应用(__call__ 委托给 wsgi 方法,见 bottle.py#L1091-L1093),_handle 负责执行路由匹配与回调调用。

3. 模板:内置引擎与第三方支持

Bottle 自带 SimpleTemplate 引擎,支持 {{...}} 变量插值、% 行内 Python 代码等语法,详细教程见 docs/stpl.rst。同时通过适配器支持 Mako、Jinja2 和 Cheetah 模板,模板引擎的插件化加载实现在 TemplatePlugin 类。

4. 服务器:内置开发服务器与生产部署适配

开发期用 run() 即可;生产部署时 Bottle 提供大量 WSGI 服务器适配器(gunicorn、paste、cheroot、bjoern、flup 等),配置方式见 docs/deployment.rst。run 的关键参数(源码签名见 bottle.py#L3800-L3809):

参数 默认值 说明
host 127.0.0.1 绑定地址;传 0.0.0.0 监听所有网络接口
port 8080 端口;低于 1024 需要 root 权限
server wsgiref 服务器适配器名称或 ServerAdapter 子类
reloader False 是否启用自动重载
interval 1 自动重载检查间隔(秒)
quiet False 是否抑制输出
debug None 调试模式开关

文档导航:官方文档体系与进阶路线

官方文档索引把全部文档按五个主题组织,每篇对应一个进阶方向。以下均为当前仓库 docs/ 目录下的真实文件,可作为持续学习的地图:

入门篇(Getting Started)

进阶主题(Advanced Topics)

插件(Plugins)

补充与开发

其中,路由、配置、模板引擎与部署四篇是进阶到生产级应用必读的核心材料。

从源码看框架核心实现

为进一步印证文档描述,当前仓库的 bottle.py 提供了全部实现证据:

  • 请求处理链路:Bottle.wsgi()(bottle.py#L1059)是 WSGI 入口,内部先调用 _handle(environ) 完成路由匹配与回调执行,再通过 _cast(bottle.py#L984)对回调返回值进行类型归一化,最后调用 WSGI 的 start_response 输出。catchall 配置为 True 时,未捕获异常会转为 500 错误页而不会击垮 WSGI 服务器。
  • 动态路由编译:Router.add()(bottle.py#L329)把通配符规则编译成带命名分组((?P<name>...))的正则表达式;静态路由单独存入 self.static 字典优先匹配,动态路由存入 self.dyna_routes。CPython 正则单次最多支持 99 个分组,源码中 _MAX_GROUPS_PER_PATTERN = 99(bottle.py#L278)对此做了显式限制。
  • 核心插件机制:每个 Bottle 实例在初始化时自动安装 JSONPlugin 与 TemplatePlugin(bottle.py#L630-L631)——这正是"返回字典自动转为 JSON 响应""模板自动渲染"两个开箱即用行为的来源。
  • Hook 机制:支持 before_request、after_request、app_reset、config 四类钩子(bottle.py#L636),其中 after_request 按逆序执行,便于在响应阶段做统一加工。

许可与使用须知

Bottle 的代码与文档以 MIT 许可证发布,许可证全文见仓库根目录 LICENSE。但有一个重要例外:Bottle 的 Logo 不受该许可证覆盖——Logo 仅允许用于指向 Bottle 主页的链接,或与未修改的库直接相关的情境;其他情况使用前需先征求许可。

结语

从本文可以看出,Bottle 的价值在于"小而不薄":单文件、零依赖让上手成本几乎为零,而路由过滤器、内置模板引擎、插件机制、WSGI 兼容性等设计又保证了它足以支撑真实项目。建议按本文的文档地图,结合 bottle.py 源码逐篇深入,尤其是 docs/tutorial.rst 的完整教程与 docs/routing.rst 的动态路由进阶,即可从"能跑通"走向"用得精"。

登录后查看全文
bottle