当前位置: 首页 > news >正文

【Flask】Explore-Flask:早期 Flask 生态的实用指南

开源项目:explore-flask/README.rst at master · rpicard/explore-flask (github.com)

一、Coding conventions

Summary

  • Try to follow the coding style conventions laid out in PEP 8.

  • Try to document your app with docstrings as defined in PEP 257.

def launch_rocket():"""Main launch sequence director.Locks seatbelts, initiates radio and fires engines."""# [...]
  • Use relative imports to import your app’s internal modules.

# myapp/views.py# An absolute import gives us the User model
from myapp.models import User# A relative import does the same thing
from .models import User

✅ 至今仍然适用的原则

1. 遵循 PEP 8 代码风格
  • 为什么有效
    PEP 8 仍是 Python 官方推荐的代码风格标准,确保代码一致性和可读性。

    • 例如:缩进用 4 空格、变量名用 snake_case、类名用 CamelCase

  • 现代工具支持

    • 自动格式化工具(如 blackautopep8)可强制遵循 PEP 8。

    • IDE(如 VS Code、PyCharm)内置 PEP 8 检查。

  • 注意
    PEP 8 是指南而非铁律,部分规则可灵活调整(如行长度默认 88/79 字符,但 black 强制 88)。

2. 使用 PEP 257 文档字符串(Docstrings)
  • 为什么有效

    • 文档字符串是 Python 生态的通用约定,IDE 和工具(如 Sphinx、pydoc)依赖它生成文档。

    • 类型注解(Type Hints)的普及(PEP 484)并未取代文档字符串,而是互补。

  • 推荐格式

    • Google 风格(简洁)或 NumPy 风格(详细),而非严格的 PEP 257 原始格式。

def calculate(a: int, b: int) -> int:"""Compute the sum of two integers.Args:a: First integer.b: Second integer.Returns:Sum of a and b."""return a + b
3. 相对导入(Relative Imports)的合理使用
  • 适用场景

    • 在 包内部模块互相引用 时,相对导入(from . import module)仍是最清晰的方式。

    • 避免硬编码包名,提高可移植性(如重构时包名变更不影响导入)。

  • 现代补充

    • 结合 __init__.py 和 pyproject.toml 定义包结构(PEP 621)。


⚠️ 需要调整或谨慎使用的原则

1. 相对导入的潜在问题
  • 问题场景

    • 在脚本直接运行(python script.py)时,相对导入可能失败(因 __package__ 未定义)。

    • 复杂的项目结构(如嵌套包)可能导致导入混乱。

  • 现代建议

    • 优先使用 绝对导入from mypackage import module)除非明确需要相对导入。

    • 将可执行脚本放在包外,或通过 python -m mypackage.module 运行。

2. PEP 8 的局部调整
  • 灵活性增强

    • 行长度black 等工具默认允许 88 字符(原 PEP 8 建议 79)。

    • 类型注解:PEP 8 已更新允许更灵活的类型注解换行(PEP 484+)。

  • 例外情况

    • 某些 API 设计(如 Django 的 models.ForeignKey)可能不符合 PEP 8 命名,但遵循框架惯例更重要。

3. 文档字符串的过度工程化
  • 旧问题
    PEP 257 的原始规范(如单行文档字符串的格式)可能过于严格。

  • 现代实践

    • 更注重 实用性(如 Google/NumPy 风格),而非机械遵循 PEP 257。

    • 工具(如 pydocstyle)可配置检查规则。


🔧 2023 年推荐的最佳实践

原则现代调整建议
PEP 8 风格用 black 自动格式化,局部例外可通过 # fmt: off 忽略。
文档字符串结合类型注解 + Google/NumPy 风格,用 mkdocs 或 Sphinx 生成文档。
相对导入仅在包内部使用;脚本和顶层模块用绝对导入。

总结:如何应用这些原则 today?

  1. 坚持核心规范

    • PEP 8 和文档字符串仍是 Python 开发的基石,但可通过工具自动化。

  2. 灵活调整细节

    • 行长度、导入方式等根据项目和团队需求调整。

  3. 结合现代工具链

    • 格式化:black + isort

    • 文档:mkdocs-material + pydocstyle

    • 导入:优先绝对导入,包内用相对导入。

这些原则的核心理念(可读性、一致性、可维护性)始终重要,但实现方式更智能高效了。

二、Environment

Summary

  • Use virtualenv to keep your application’s dependencies together.

  • Use virtualenvwrapper to keep your virtual environments together.

  • Keep track of dependencies with one or more text files.

  • Use a version control system. I recommend Git.

  • Use .gitignore to keep clutter and secrets out of version control.

  • Debug mode can give you information about problems in development.

  • The Flask-DebugToolbar extension will give you even more of that information.

✅ 至今仍然适用的原则

1. 使用虚拟环境隔离依赖(virtualenv)
  • 为什么有效
    Python 项目依赖冲突问题依然存在(尤其是不同项目需要同一库的不同版本时)。虚拟环境仍是官方推荐的依赖隔离方案。

  • 现代改进
    Python 3.3+ 内置了 venv 模块(python -m venv venv),但 virtualenv 仍更灵活(如支持旧版 Python)。

2. 使用版本控制系统(Git)
  • 为什么有效
    Git 已成为行业标准(尤其是配合 GitHub/GitLab),代码版本管理、协作、回滚等需求不变。

  • 现代补充
    可结合 pre-commit 等工具自动化代码检查。

3. 用 .gitignore 排除无关文件
  • 为什么有效
    避免提交编译文件(如 .pyc)、敏感信息(如 .env)、IDE 配置等仍是基本规范。

  • 现代扩展
    现在更推荐使用 环境变量(如 python-dotenv)或 专用配置管理工具(如 Vault)管理密钥,而非手动忽略文件。

4. 记录依赖清单(requirements.txt)
  • 为什么有效
    明确依赖是项目可复现的基础。

  • 现代改进

    • 推荐使用 pip-tools 或 poetry 管理依赖(自动处理子依赖版本冲突)。

    • 区分开发/生产依赖(如 requirements-dev.txt)。

5. 调试模式与工具(Flask-DebugToolbar)
  • 为什么有效
    Debug 模式和 DebugToolbar 仍是快速定位问题的有效工具。

  • 注意点
    需确保仅限开发环境使用(生产环境禁用!)。


⚠️ 需要调整或过时的原则

1. virtualenvwrapper 的必要性降低
  • 原因

    • 现代工具(如 poetrypipenv)已内置虚拟环境管理功能。

    • IDE(如 VS Code、PyCharm)直接支持虚拟环境切换,减少手动操作需求。

  • 建议
    新项目可优先尝试 poetry(依赖管理 + 虚拟环境一体化)。

2. 纯手动维护依赖文件(pip freeze)
  • 问题
    pip freeze 会导出所有依赖(包括间接依赖),导致文件臃肿且难以维护。

  • 替代方案

    • 使用 poetry 的 pyproject.toml 或 pipenv 的 Pipfile 显式声明依赖。

    • 仅锁定版本时生成 requirements.txt(如部署用)。

3. Flask-DebugToolbar 的局限性
  • 现代挑战

    • 对异步框架(如 FastAPI)支持有限。

    • 前端复杂应用可能需要更专业的调试工具(如浏览器 DevTools + 后端日志聚合)。

  • 替代方案
    结合 loggingSentry(错误追踪)、Postman(API 调试)等。


🔧 2023 年推荐的工具链升级

传统方式现代替代方案优势
virtualenv + pippoetry / pdm依赖解析、虚拟环境管理一体化
requirements.txtpyproject.toml (PEP 621)标准化依赖声明,支持元数据
Flask-DebugToolbarpdbpp + logging + Sentry更灵活的调试和错误监控

总结:如何应用这些原则 today?

  1. 仍要坚持

    • 隔离环境、版本控制、依赖记录、调试安全。

  2. 需要更新

    • 用 poetry 替代 virtualenvwrapper + 手动 pip

    • 敏感信息改用环境变量或专用服务管理。

  3. 扩展实践

    • 容器化(Docker)进一步隔离环境。

    • CI/CD 自动化测试和部署。

这些原则的核心思想(隔离性、可复现性、安全性)依然重要,只是工具更高效了。

三、Organizing your project

Summary

  • Using a single module for your application is good for quick projects.

  • Using a package for your application is good for projects with views, models, forms and other components.

config.py
requirements.txt
run.py
instance/config.py
yourapp/__init__.pyviews.pymodels.pyforms.pystatic/templates/
  • Blueprints are a great way to organize projects with several distinct components.

✅ 至今仍然适用的原则

1. 单模块适合小型项目
  • 适用场景

    • 快速原型、微服务或简单 API(如一个 app.py 包含路由和逻辑)。

    • 仍常见于教程、实验性代码或小型工具开发。

  • 现代补充

    • 即使单文件,也应遵循模块化设计(如分离路由、业务逻辑)。

    • 可搭配 Flask 2.0 的 async 支持提升简单应用的性能。

2. 包结构适合复杂项目
  • 为什么有效

    • 分层架构(如 models/views/services/)仍是中大型项目的标准实践。

    • 支持更好的可测试性和可维护性。

  • 现代改进

    • 结合 工厂模式(Factory Pattern)创建应用实例(通过 create_app() 函数)。

    • 使用 Flask-SQLAlchemy 或 Flask-Pydantic 等扩展规范组件交互。

3. 蓝图(Blueprints)组织多组件
  • 核心优势

    • 模块化路由:将不同功能(如用户认证、API 版本)拆分为独立蓝图。

    • 资源隔离:每个蓝图可拥有自己的模板、静态文件。

  • 现代实践

    • 在微服务架构中,蓝图仍用于单体应用内的功能分区。

    • 结合 Flask-RESTX 或 Flask-Smorest 构建结构化 API。


⚠️ 需要调整或谨慎使用的原则

1. 单模块的局限性
  • 问题场景

    • 随着项目增长,单文件难以维护(路由、模型、逻辑混杂)。

    • 缺乏明确的依赖管理,易导致代码臃肿。

  • 替代方案

    • 即使小型项目,也建议拆分为 app.py + extensions.py + config.py 等。

2. 纯包结构的冗余性
  • 旧问题
    传统包结构(如 myapp/__init__.py + myapp/views.py)可能导致过度分层。

  • 现代优化

    • 按功能垂直拆分(如 auth/blog/ 子包),而非按技术分层(models/views/)。

    • 使用 Dependency Injection 替代隐式导入(减少循环依赖)。

3. 蓝图的替代方案
  • 新兴趋势

    • FastAPI 的 APIRouter:类似蓝图但更轻量,适合纯 API 项目。

    • 微服务拆分:若组件独立性极强,可直接拆分为独立服务(而非蓝图)。

  • 注意
    蓝图仍适用于 Flask 单体应用,但需避免过度设计(如嵌套蓝图)。


🔧 2023 年推荐的项目组织方式

中型项目(包 + 蓝图)
myapp/
├── __init__.py     # create_app() 工厂函数
├── auth/           # 认证蓝图
│   ├── routes.py
│   └── models.py
├── blog/           # 博客蓝图
│   ├── routes.py
│   └── templates/
├── extensions.py   # 数据库、缓存等扩展
└── config.py

大型项目(按功能垂直拆分)

myapp/
├── core/           # 核心逻辑
├── api/            # API 蓝图(可进一步拆分为 v1/, v2/)
├── cli/            # 命令行工具
├── tests/          # 按功能匹配的测试结构
└── config/├── dev.py└── prod.py

总结:如何应用这些原则 today?

  1. 坚持核心思想

    • 简单项目用单文件,复杂项目用包+蓝图。

    • 模块化设计始终重要。

  2. 现代调整

    • 优先按功能(而非技术)划分代码。

    • 结合工厂模式和依赖注入提升灵活性。

  3. 评估替代方案

    • 纯 API 项目可考虑 FastAPI;

    • 超大型应用直接拆微服务。

Flask 的这些原则仍具指导意义,但需根据项目规模和团队需求灵活调整。

四、configuration

Summary

  • A simple app may only need one configuration file: config.py.

DEBUG = True # Turns on debugging features in Flask
BCRYPT_LOG_ROUNDS = 12 # Configuration for the Flask-Bcrypt extension
MAIL_FROM_EMAIL = "robert@example.com" # For use in application emails
# app.py or app/__init__.py
from flask import Flaskapp = Flask(__name__)
app.config.from_object('config')# Now we can access the configuration variables via app.config["VAR_NAME"].
  • Instance folders can help us hide secret configuration values.

config.py
requirements.txt
run.py
instance/config.py
yourapp/__init__.pymodels.pyviews.pytemplates/static/
# app.py or app/__init__.pyapp = Flask(__name__, instance_relative_config=True)
app.config.from_object('config')
app.config.from_pyfile('config.py')
  • Instance folders can be used to alter an application’s configuration for a specific environment.

  • We should use environment variables and app.config.from_envvar() for more complicated environment-based configurations.

1. 简单应用只需一个 config.py

✅ 仍有优势,但需谨慎使用

  • 适用场景

    • 快速原型开发、小型项目、个人工具。

    • 无需多环境部署或敏感信息的场景。

  • 优势

    • 简单直接,适合低复杂度项目。

  • 过时点

    • 硬编码敏感信息:现代开发中,直接写密码/API 密钥到文件是严重的安全反模式。

    • 环境适应性差:无法轻松切换开发/生产配置。

改进建议
即使小型项目,也应避免硬编码敏感信息,至少用 .env 文件 + python-dotenv


2. 使用 Instance Folders 隐藏敏感配置

⚠️ 部分过时,仍有特定用途

  • 适用场景

    • 传统 Flask 项目(非云原生部署)。

    • 需要本地开发与生产配置分离的简单场景。

  • 优势

    • 避免敏感配置提交到版本控制(如 instance/config.py 在 .gitignore 中)。

  • 过时点

    • 云原生兼容性差:现代部署(Docker/K8s)更依赖环境变量或 Secrets 管理。

    • 不够动态:需手动维护不同环境的实例文件夹,不符合自动化流程。

改进建议
云原生项目中,优先使用环境变量或 Secrets 管理工具(如 Vault、K8s Secrets)。


3. 使用环境变量 + app.config.from_envvar()

✅ 仍是黄金标准

  • 适用场景

    • 任何需要多环境(开发/测试/生产)支持的项目。

    • 云原生、容器化(Docker/K8s)或 Serverless 部署。

  • 优势

    • 安全性:敏感信息通过运行时注入,不暴露在代码中。

    • 灵活性:无需修改代码即可切换环境配置。

    • 符合 12-Factor App:被现代 DevOps 工具链(CI/CD)原生支持。

  • 注意事项

    • 需配合工具(如 python-dotenv)简化本地开发。

现代扩展
使用更高级的配置库(如 dynaconfpydantic-settings)支持多格式(YAML/JSON)和类型校验。


4. 混合配置策略的演进

✅ 推荐实践:分层配置
现代项目通常结合以下方式:

  1. 默认配置config.py 或 settings.toml(非敏感值)。

  2. 环境覆盖:通过环境变量或 .env 文件(开发环境)。

  3. 生产机密:通过云平台 Secrets 管理(如 AWS Secrets Manager)。

优势

  • 兼顾开发便利性与生产安全性。

  • 避免“过时”方案的硬编码问题。


总结:哪些原则已过时?

原则是否过时原因替代方案
单一 config.py部分过时硬编码不安全默认配置 + 环境变量覆盖
Instance Folders基本过时云原生兼容性差环境变量/Secrets
环境变量仍是主流符合现代实践无,可扩展工具链

现代最佳实践建议

  1. 简单项目.env + python-dotenv + config.py(仅非敏感配置)。

  2. 复杂项目:环境变量 + dynaconf/pydantic-settings + 云 Secrets 管理。

  3. 彻底弃用:硬编码敏感信息、依赖实例文件夹切换环境。

云原生时代,环境变量和集中式 Secrets 管理已成为事实标准,而传统方法仅适用于遗留项目或极简场景。

五、Advanced patterns for views and routing

Summary

  • The @login_required decorator from Flask-Login helps you limit views to authenticated users.

# app.pyfrom flask import render_template
from flask_login import login_required, current_user@app.route('/')
def index():return render_template("index.html")@app.route('/dashboard')
@login_required
def account():return render_template("account.html")
  • The Flask-Cache extension gives you a bunch of decorators to implement various methods of caching.

# app.pyfrom flask_cache import Cache
from flask import Flaskapp = Flask()# We'd normally include configuration settings in this call
cache = Cache(app)@app.route('/')
@cache.cached(timeout=60)
def index():[...] # Make a few database calls to get the information we needreturn render_template('index.html',latest_posts=latest_posts,recent_users=recent_users,recent_photos=recent_photos)
  • We can develop custom view decorators to help us organize our code and stick to DRY (Don’t Repeat Yourself) coding principles.

# myapp/util.pyfrom functools import wraps
from datetime import datetimefrom flask import flash, redirect, url_forfrom flask_login import current_userdef check_expired(func):@wraps(func)def decorated_function(*args, **kwargs):if datetime.utcnow() > current_user.account_expires:flash("Your account has expired. Update your billing info.")return redirect(url_for('account_billing'))return func(*args, **kwargs)return decorated_function
  • Custom URL converters can be a great way to implement creative features involving URL’s.

1. @login_required 装饰器(Flask-Login)

✅ 仍在广泛使用

  • 现状

    • Flask-Login 仍是 Flask 生态中最主流的身份验证库,@login_required 是限制未登录访问的标准方式

    • 配合现代前端(如 JWT、OAuth2)时,可能改用权限校验中间件(如 Flask-JWT-Extended),但传统 Session 登录场景仍依赖此装饰器。

  • 优势

    • 简单直观,适合服务端渲染(SSR)或混合应用。

  • 注意点

    • 若项目完全基于 API(如 React/Vue 前端),可能改用 JWT 的 @jwt_required(但逻辑类似)。


2. Flask-Cache 的缓存装饰器

⚠️ 已过时,被替代

  • 现状

    • Flask-Cache 官方已停止维护,其继任者是 Flask-Caching(支持更现代的缓存后端,如 Redis、Memcached)。

    • 装饰器(如 @cache.cached())仍在使用,但底层实现更高效。

  • 现代替代方案

    • 使用 Flask-Caching + Redis 实现分布式缓存。

    • 对于 API 项目,可能直接用 CDN 缓存 或 HTTP 缓存头(如 Cache-Control)。

关键变化
缓存逻辑从“代码装饰器”扩展到“基础设施层”(如 Redis、Nginx)。


3. 自定义视图装饰器(DRY 原则)

✅ 仍是核心实践

  • 现状

    • 自定义装饰器(如 @check_permissions@log_requests)仍是 Flask 中复用逻辑的推荐方式

    • 在微服务或复杂项目中,可能结合 中间件(Middleware) 或 蓝图(Blueprint)钩子 实现类似功能。

  • 优势

    • 保持代码简洁,符合 DRY 原则(例如统一处理权限、日志、限流)。

  • 注意点

    • 过度使用装饰器可能导致代码可读性下降(需权衡)。


4. 自定义 URL 转换器

✅ 仍有用,但需求减少

  • 现状

    • Flask 内置的 URL 转换器(如 intstring)已覆盖大部分场景,自定义转换器(如 @app.url_value_preprocessor需求减少

    • 现代 RESTful API 更依赖 标准化的 URL 设计(如 /users/<uuid:user_id>),而非复杂自定义规则。

  • 适用场景

    • 需要特殊路由逻辑(如动态子域名、Slug 校验)时仍有用武之地。

替代趋势
复杂路由逻辑可能移交到 API Gateway(如 Kong、Traefik)或前端路由(React/Vue Router)。


总结:哪些原则已过时?

原则是否过时原因现代替代方案
@login_required仍主流无更优替代兼容 JWT 时需调整
Flask-Cache 装饰器已过时项目废弃Flask-Caching + Redis
自定义装饰器仍推荐DRY 原则核心可结合中间件
自定义 URL 转换器边缘化需求减少标准化路由或 API Gateway

现代 Flask 开发建议

  1. 身份验证

    • 传统 SSR:Flask-Login + @login_required

    • 纯 API:Flask-JWT-Extended + @jwt_required

  2. 缓存

    • 使用 Flask-Caching + Redis,而非旧版 Flask-Cache

  3. 代码复用

    • 优先用装饰器,复杂场景可搭配 蓝图的 before_request 或 中间件

  4. 路由设计

    • 遵循 RESTful 规范,非必要不自定义 URL 转换器。

Flask 的轻量级哲学使其核心原则(如装饰器)依然有效,但工具链(如缓存、身份验证)需跟随生态演进。

六、Blueprints

Summary

  • A blueprint is a collection of views, templates, static files and other extensions that can be applied to an application.

  • Blueprints are a great way to organize your application.

  • In a divisional structure, each blueprint is a collection of views, templates and static files which constitute a particular section of your application.

facebook/__init__.pytemplates/layout.htmlhome/layout.htmlindex.htmlabout.htmlsignup.htmllogin.htmldashboard/layout.htmlnews_feed.htmlwelcome.htmlfind_friends.htmlprofile/layout.htmltimeline.htmlabout.htmlphotos.htmlfriends.htmledit.htmlsettings/layout.htmlprivacy.htmlsecurity.htmlgeneral.htmlviews/__init__.pyhome.pydashboard.pyprofile.pysettings.pystatic/style.csslogo.pngmodels.py
  • In a functional structure, each blueprint is just a collection of views. The templates are all kept together, as are the static files.

  • To use a blueprint, you define it then register it on the application by calling Flask.register_blueprint()..

# facebook/__init__.pyfrom flask import Flask
from .views.profile import profileapp = Flask(__name__)
app.register_blueprint(profile)
  • You can define a dynamic URL prefix that will be applied to all routes in a blueprint.

# facebook/views/profile.pyfrom flask import Blueprint, render_templateprofile = Blueprint('profile', __name__, url_prefix='/<user_url_slug>')# [...]
# facebook/__init__.pyfrom flask import Flask
from .views.profile import profileapp = Flask(__name__)
app.register_blueprint(profile, url_prefix='/<user_url_slug>')
  • You can also define a dynamic subdomain for all routes in a blueprint.

  • Refactoring a growing application to use blueprints can be done in five relatively small steps.

1. 蓝图(Blueprint)作为应用组件集合

✅ 仍是核心模式

  • 现状

    • 蓝图仍然是 Flask 中模块化组织代码的标准方式,包含视图、模板、静态文件等。

    • 在微服务架构中,大型应用可能拆分为多个独立服务,但单体应用内仍依赖蓝图分模块。

  • 优势

    • 解耦功能模块(如 auth_bpadmin_bp),支持多人协作开发。

  • 现代调整

    • 结合 工厂模式(Application Factory) 动态注册蓝图,更适合测试和扩展。


2. 组织方式:功能型(Functional) vs 分区型(Divisional)

⚠️ 分区型(Divisional)更主流,功能型(Functional)边缘化

  • 分区型(Divisional)

    • 仍广泛使用:每个蓝图是一个完整功能模块(如 users_bp 包含视图、模板、静态文件)。

    • 适合大多数项目,符合“高内聚低耦合”原则。

  • 功能型(Functional)

    • 基本过时:将模板/静态文件全局集中管理,视图按逻辑拆分(如 auth_views_bpprofile_views_bp)。

    • 缺点:模板和静态文件难以维护,不符合组件化趋势。

现代实践
优先用分区型,甚至进一步拆分为 独立 Python 包(如 flask-admin 的插件化设计)。


3. 动态 URL 前缀/子域名

✅ 仍在使用,但需求减少

  • 动态 URL 前缀url_prefix):

    • 常用:如 API 版本控制(/api/v1/)或多租户路径隔离(/tenant/<id>/)。

  • 动态子域名subdomain):

    • 边缘化:现代架构中,子域名路由通常由 反向代理(Nginx) 或 API Gateway(如 Kong)处理,而非应用层。

适用场景
简单项目可直接用 Flask 子域名功能,复杂场景移交基础设施层。


4. 重构为蓝图的步骤

✅ 仍是标准流程

  • 现状

    • 将大型应用拆分为蓝图的步骤(如逐步迁移视图、模板)未过时,但现代项目更倾向于 从一开始设计蓝图

  • 现代改进

    • 结合 模块化工厂模式create_app())动态注册蓝图,支持环境差异化配置。


5. 蓝图的注册方式(register_blueprint

✅ 语法未变,但注册时机演进

  • 传统方式

    • 直接在模块层调用 app.register_blueprint()

  • 现代方式

    • 在 应用工厂 中注册,或通过 插件系统(如 flask-sqlalchemy 的 init_app() 模式)延迟绑定。


总结:哪些原则已过时?

原则是否过时原因现代替代方案
蓝图作为模块化单元仍主流无可替代
功能型(Functional)结构已过时维护性差分区型(Divisional)
动态子域名边缘化由基础设施处理Nginx/API Gateway
直接全局注册蓝图不推荐缺乏灵活性应用工厂模式

现代 Flask 蓝图最佳实践

  1. 设计阶段

    • 按 业务边界 划分蓝图(如 auth_bporder_bp),每个蓝图包含自己的视图、模板、静态文件。

  2. 代码结构

    /app
    ├── /auth               # 蓝图模块
    │   ├── __init__.py     # 创建蓝图对象
    │   ├── routes.py       # 视图
    │   ├── templates/      # 蓝图专属模板
    │   └── static/         # 蓝图专属静态文件
    ├── /orders
    │   └── ...             # 同上
    └── create_app.py       # 应用工厂
  3. 注册时机

  • 在 create_app() 中动态注册蓝图,支持测试和配置隔离:

def create_app(config):app = Flask(__name__)app.register_blueprint(auth_bp)app.register_blueprint(orders_bp, url_prefix='/orders')return app
  1. 进阶场景

    • 将蓝图发布为 独立 PyPI 包(如 flask-admin),通过 pip 安装复用。


何时不需要蓝图?

  • 极简应用:单文件 Flask 应用(如原型开发)。

  • 微服务架构:功能已拆分为独立服务,单体内部无需再分蓝图。

Flask 蓝图的核心思想(模块化)并未过时,但实现细节需结合现代架构(如工厂模式、基础设施分层)优化。

七、Templates

Summary

  • Use Jinja for templating.

  • Jinja has two kinds of delimeters: {% ... %} and {{ ... }}. The first one is used to execute statements such as for-loops or assign values, the latter prints the result of the contained expression to the template.

{# _myapp/templates/layout.html_ #}<!DOCTYPE html>
<html lang="en"><head><title>{% block title %}{% endblock %}</title></head><body>{% block body %}<h1>This heading is defined in the parent.</h1>{% endblock %}</body>
</html>
  • Templates should go in myapp/templates/ — i.e. a directory inside of the application package.

  • I recommend that the structure of the templates/ directory mirror the URL structure of the app.

  • You should have a top-level layout.html in myapp/templates as well as one for each section of the site. The latter extend the former.

templates/layout.htmlindex.htmlabout.htmlprofile/layout.htmlindex.htmlphotos.htmladmin/layout.htmlindex.htmlanalytics.html
  • Macros are like functions made-up of template code.

{# myapp/templates/layout.html #}{% from "macros.html" import nav_link with context %}
<!DOCTYPE html>
<html lang="en"><head>{% block head %}<title>My application</title>{% endblock %}</head><body><ul class="nav-list">{{ nav_link('home', 'Home') }}{{ nav_link('about', 'About') }}{{ nav_link('contact', 'Get in touch') }}</ul>{% block body %}{% endblock %}</body>
</html>
  • Filters are functions made-up of Python code and used in templates.

1. 使用 Jinja2 作为模板引擎

✅ 仍是 Flask 的黄金标准

  • 现状

    • Jinja2 仍是 Flask 默认且官方推荐的模板引擎,与 Flask 深度集成。

    • 现代前端框架(如 React/Vue)的兴起减少了服务端渲染(SSR)的使用,但 Jinja2 在 SSR 场景中不可替代

  • 优势

    • 语法简洁,支持模板继承、宏等高级功能。

    • 适合内容型网站(如博客、CMS)或需要 SEO 的页面。

  • 注意点

    • 纯 API 项目可能完全不需要 Jinja2。


2. Jinja2 分隔符 {% ... %} 和 {{ ... }}

✅ 语法未变,仍是核心

  • 现代调整

    • 新增 {% ... %} 的扩展用法(如 {% set x = namespace() %}),但基础逻辑不变。

    • 前端开发者可能更熟悉 JSX/Vue 的 {{ }},但 Jinja2 的语义保持一致。


3. 模板目录应位于 myapp/templates/

⚠️ 仍适用,但灵活性增加

  • 传统实践

    • Flask 默认从 templates/ 加载模板,符合“约定优于配置”原则。

  • 现代演进

    • 可通过 template_folder 参数自定义路径(如 Flask(__name__, template_folder="../frontend/templates"))。

    • 大型项目可能将模板拆分为 独立包(如共享模板库)。

建议:除非有特殊需求,否则仍推荐默认目录结构。


4. 模板目录结构应镜像 URL 结构

❌ 已过时(仅适用于简单项目)

  • 过时原因

    • 现代项目更倾向于 按功能模块组织模板(如 templates/auth/login.html),而非严格匹配 URL(如 /auth/login)。

    • RESTful API 和前端框架的普及使得 URL 结构与模板解耦。

  • 例外

    • 内容型网站(如新闻分类)可能仍保留部分镜像结构。


5. 顶层 layout.html + 区块模板继承

✅ 仍是最佳实践

  • 现状

    • 基模板(layout.html)定义通用结构(如导航栏、页脚),子模板通过 {% extends %} 和 {% block %} 覆盖特定区块。

    • 与前端框架的“组件化”思想一致(如 Vue 的 <slot>)。

  • 优势

    • 避免重复代码,符合 DRY 原则。


6. 宏(Macros)作为模板函数

✅ 仍有用,但使用减少

  • 现状

    • 宏适合复用模板片段(如渲染表单字段),但在以下场景中被替代:

      • 前端框架(如 React/Vue)通过组件化实现更强大的复用。

      • 复杂逻辑更适合移回后端(通过 API 返回结构化数据)。

  • 适用场景

    • 服务端渲染中需要重复使用的 UI 元素(如分页控件)。


7. 过滤器(Filters)

✅ 仍有用,但需谨慎使用

  • 现状

    • 内置过滤器(如 |safe|capitalize)仍常用。

    • 自定义过滤器适合简单文本处理(如日期格式化),但复杂逻辑应优先在 后端处理 或通过 前端工具库(如 day.js)。

  • 风险

    • 过度使用过滤器会导致模板臃肿,违背“逻辑与表现分离”原则。


总结:哪些原则已过时?

原则是否过时原因现代替代方案
使用 Jinja2仍主流无更优替代纯 API 项目可省略
分隔符语法未变语法稳定
默认 templates/ 目录仍适用约定优于配置支持自定义路径
模板镜像 URL 结构已过时灵活性差按功能模块组织
模板继承(layout.html仍最佳实践DRY 原则类似前端组件化
宏(Macros)边缘化前端框架替代Vue/React 组件
过滤器(Filters)有限使用逻辑应后移后端处理或前端工具库

现代 Jinja2 模板开发建议

  1. 组织方式

    • 按功能模块划分模板目录(如 templates/auth/templates/blog/),而非机械匹配 URL。

  2. 逻辑分离

    • 复杂计算通过 视图函数 预处理,模板仅负责渲染。

  3. 组件化

    • 使用 {% include %} 或宏封装可复用 UI 片段(如按钮、卡片)。

  4. 安全性

    • 始终用 |safe 标记可信的 HTML 内容,避免 XSS。

  5. 结合现代工具

    • 开发阶段启用 TEMPLATES_AUTO_RELOAD=True 自动刷新模板。

何时不用 Jinja2?

  • 纯 API 项目(无服务端渲染)。

  • 前后端完全分离(前端使用 React/Vue)。

Jinja2 的核心功能(模板继承、变量渲染)依然不可替代,但需根据项目架构调整使用方式。

八、Static files

Summary

  • Static files go in the static/ directory.

myapp/__init__.pystatic/templates/views/models.py
run.py
  • Separate third-party libraries from your own static files.

static/css/lib/bootstrap.cssstyle.csshome.cssadmin.cssjs/lib/jquery.jshome.jsadmin.jsimg/logo.svgfavicon.ico
  • Specify the location of your favicon in your templates.

  • Use Flask-Assets to insert static files in your templates.

# myapp/util/assets.pyfrom flask_assets import Bundle, Environment
from .. import appbundles = {'home_js': Bundle('js/lib/jquery-1.10.2.js','js/home.js',output='gen/home.js'),'home_css': Bundle('css/lib/reset.css','css/common.css','css/home.css',output='gen/home.css'),'admin_js': Bundle('js/lib/jquery-1.10.2.js','js/lib/Chart.js','js/admin.js',output='gen/admin.js'),'admin_css': Bundle('css/lib/reset.css','css/common.css','css/admin.css',output='gen/admin.css')
}assets = Environment(app)assets.register(bundles)
  • Flask-Assets can compile, combine and compress your static files.

仍然适用的原则 ✅

  1. Static files go in the static/ directory

    • Flask 仍然默认使用 static/ 目录存放静态文件,这是官方推荐的做法

  2. Separate third-party libraries from your own static files

    • 仍然建议将第三方库(如 jQuery、Bootstrap)和自己的静态文件分开管理

  3. Specify the location of your favicon in your templates

    • 仍然需要在模板中正确指定 favicon 路径

部分过时/有更好替代方案的原则 ⚠️

  1. Use Flask-Assets to insert static files in your templates

    • 仍然可用但不是主流选择,现代前端工作流更倾向于使用:

      • Webpack/Vite 等现代打包工具

      • Flask 原生 url_for('static', ...) 方式

      • CDN 直接引入前端库

  2. Flask-Assets can compile, combine and compress your static files

    • 功能仍然存在但不再是首选方案,现代替代方案包括:

      • 使用 npm/yarn/pnpm + Webpack/Vite/Rollup

      • 使用 Flask-Minify 等专门压缩扩展

      • 云服务(如 AWS CloudFront)自动压缩

现代补充建议 ✨

  • 考虑使用 flask-static-compress 或 flask-minify 进行压缩

  • 对于复杂项目,建议采用前后端分离架构

  • 静态文件建议通过 CDN 分发

  • 现代前端框架(React/Vue)通常有自己的静态文件处理方式

Flask-Assets 虽然仍能工作,但在 2023 年后的新项目中已经很少被用作主要解决方案,除非是在维护传统项目。

九、Storing data

Summary

  • Use SQLAlchemy to work with relational databases.

# ourapp/__init__.pyfrom flask import Flask
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__, instance_relative_config=True)app.config.from_object('config')
app.config.from_pyfile('config.py')db = SQLAlchemy(app)
# ourapp/models.pyfrom . import dbclass Engine(db.Model):# Columnsid = db.Column(db.Integer, primary_key=True, autoincrement=True)title = db.Column(db.String(128))thrust = db.Column(db.Integer, default=0)
  • Use Flask-SQLAlchemy to work with SQLAlchemy.

  • Alembic helps you migrate your data between schema changes.

ourapp/alembic.inialembic/env.pyREADMEscript.py.makoversions/3512b954651e_add_account.py2b1ae634e5cd_add_order_id.py3adcc9a56557_rename_username_field.pymyapp/__init__.pyviews.pymodels.pytemplates/run.pyconfig.pyrequirements.txt
  • You can use NoSQL databases with Flask, but the methods and tools vary between engines.

  • Back up your data!

仍然适用的原则 ✅

  1. Use SQLAlchemy to work with relational databases

    • SQLAlchemy 仍然是 Python 生态中最主流、最强大的 ORM,Flask 项目中的首选方案

    • 核心功能(ORM/SQL Expression)设计经受了时间考验

  2. Use Flask-SQLAlchemy to work with SQLAlchemy

    • Flask-SQLAlchemy 仍然是官方推荐的集成方案(最新版本 3.1.x)

    • 提供了 db.session 管理和 Flask 集成等便利功能

  3. Alembic helps you migrate your data between schema changes

    • Alembic 仍然是 SQLAlchemy 生态的标准迁移工具

    • 现代改进:支持异步(Alembic 1.11+)、更好的 DDL 事务控制

  4. Back up your data!

    • 永恒真理,现在更多通过云数据库的自动备份功能实现(如 AWS RDS 快照)


需要更新的原则 ⚠️

  1. You can use NoSQL databases with Flask, but the methods and tools vary between engines

    • 仍然正确,但现代变化:

      • MongoDB:推荐官方驱动 PyMongo(Flask-PyMongo 已不维护)

      • Redis:直接使用 redis-py,部分场景可用 Flask-Caching

      • 新兴数据库:如 ClickHouse 有专用 Python 驱动

    • 趋势:NoSQL 不再强调 "Flask 扩展",而是直接使用各数据库的官方 SDK


现代补充建议 ✨

  1. 异步支持

    • SQLAlchemy 2.0+ 全面支持 async(需配合 asyncpg/aiomysql

    • Flask 本身不支持异步,但可通过 Quart(Flask 异步克隆)实现

  2. 替代方案

    • 简单项目可考虑 PeeWee 或 SQLModel(SQLAlchemy + Pydantic)

    • Django 开发者可能更喜欢 Flask-Marshmallow 序列化

  3. 云原生趋势

    • 无服务器场景考虑 Serverless 数据库(如 PlanetScale、Neon)

    • 分布式 SQL(如 CockroachDB)有完善 SQLAlchemy 支持

  4. 开发体验

    • 使用 Flask-Migrate 简化 Alembic 操作(flask db migrate

    • 推荐 SQLAlchemy 2.0 声明式表配置(更简洁的语法)

  5. 安全建议

    • 一定要启用 SQLAlchemy 的 echo=False 生产环境

    • 使用 scoped_session 避免多线程问题


过时/不推荐的做法 🚫

  • 避免旧版 SQLAlchemy 1.3 的写法(如 query.get() 已弃用)

  • 不再推荐使用 Flask-MongoEngine 等封装过度的 NoSQL 扩展

  • 避免手动拼接 SQL(SQLAlchemy Core 已能处理绝大多数场景)

现代 Flask 项目数据库选择建议:PostgreSQL + SQLAlchemy 2.0 + Alembic 仍是黄金组合。

十、Handling forms

Summary

  • Forms can be scary from a security perspective.

# ourapp/forms.pyfrom flask_wtf import Form
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Emailclass EmailPasswordForm(Form):email = StringField('Email', validators=[DataRequired(), Email()])password = PasswordField('Password', validators=[DataRequired()])
  • WTForms (and Flask-WTF) make it easy to define, secure and render your forms.

  • Use the CSRF protection provided by Flask-WTF to secure your forms.

{# ourapp/templates/login.html #}{% extends "layout.html" %}
<html><head><title>Login Page</title></head><body><form action="{{ url_for('login') }}" method="post"><input type="text" name="email" /><input type="password" name="password" />{{ form.csrf_token }}</form></body>
</html>
  • You can use Flask-WTF to protect AJAX calls against CSRF attacks too.

  • Define custom form validators to keep validation logic out of your views.

  • Use the WTForms field rendering to render your form’s HTML so you don’t have to update it every time you make some changes to the form definition.

仍然适用的原则 ✅

  1. Forms can be scary from a security perspective

    • 表单安全仍是重中之重(CSRF/XSS/SQL 注入等风险依然存在)

  2. Use the CSRF protection provided by Flask-WTF to secure your forms

    • Flask-WTF 的 CSRF 保护仍是标准方案(最新版本 1.2.x)

    • 现代补充:REST API 推荐改用 JWT/OAuth2 + SameSite cookies

  3. Define custom form validators to keep validation logic out of your views

    • 验证逻辑与视图分离仍是最佳实践

    • 现代扩展:可结合 Pydantic 进行更复杂的验证


需要更新的原则 ⚠️

  1. WTForms (and Flask-WTF) make it easy to define, secure and render your forms

    • 仍然可用但不再是唯一选择,现代替代方案:

      • 前端框架(React/Vue)直接处理表单 + Flask 仅作 API 验证

      • 使用 Pydantic 进行数据验证(尤其适合 API 项目)

      • 简单场景可用 flask.request.get_json() 直接处理

  2. You can use Flask-WTF to protect AJAX calls against CSRF attacks too

    • 仍然有效但现代方案更倾向于:

      • 对 API 使用 JWT + CORS 限制

      • 启用 SameSite=Strict cookie 策略

      • 框架内置 CSRF(如 Next.js/Angular 自带防护)

  3. Use the WTForms field rendering to render your form’s HTML

    • 服务器端渲染表单逐渐减少,现代趋势:

      • 前端动态渲染(React/Vue/Svelte 表单组件库)

      • 仅用 WTForms 做验证,前端单独实现 UI

      • HTMX 等新技术实现渐进式增强


现代补充建议 ✨

  1. 混合验证架构

    # 结合 Pydantic 和 WTForms 的优点
    from pydantic import BaseModel
    from flask_wtf import FlaskFormclass APIModel(BaseModel):  # API 请求验证name: strage: intclass WebForm(FlaskForm):  # 传统网页表单name = StringField(validators=[DataRequired()])

  2. 安全增强

    • 始终启用 WTF_CSRF_ENABLED = True(默认已开启)

    • 对敏感操作添加二次验证(如 CAPTCHA)

  3. 现代替代工具

    • 前端表单:Formik(React)、VeeValidate(Vue)

    • 验证库:Pydantic、marshmallow

    • 安全:Flask-Talisman(强制 HTTPS/HSTS)

  4. 性能优化

    • 对静态表单考虑缓存渲染结果

    • 使用 flask-caching 缓存验证规则

过时/不推荐的做法 🚫

  • 避免完全依赖 WTForms 渲染前端(难以适应现代 UI 需求)

  • 不要手动拼接 HTML 表单(易导致 XSS 漏洞)

  • 避免在 AJAX 中直接提交 application/x-www-form-urlencoded(推荐 JSON)


当前推荐方案

场景推荐工具
传统多页应用Flask-WTF + WTForms
SPA 前后端分离Pydantic + 前端表单库
混合应用(HTMX)WTForms 验证 + 部分渲染

关键结论:WTForms 仍然安全可靠,但现代项目更倾向于将表单逻辑交给前端,后端专注数据验证。对于新项目,建议优先考虑 Pydantic + 前端框架的组合。

十一、Patterns for handling users

Summary

  • Use the itsdangerous package to create and validate tokens sent to an email address.

# ourapp/util/security.pyfrom itsdangerous import URLSafeTimedSerializerfrom .. import appts = URLSafeTimedSerializer(app.config["SECRET_KEY"])
# ourapp/views.pyfrom flask import redirect, render_template, url_forfrom . import app, db
from .forms import EmailPasswordForm
from .util import ts, send_email@app.route('/accounts/create', methods=["GET", "POST"])
def create_account():form = EmailPasswordForm()if form.validate_on_submit():user = User(email = form.email.data,password = form.password.data)db.session.add(user)db.session.commit()# Now we'll send the email confirmation linksubject = "Confirm your email"token = ts.dumps(self.email, salt='email-confirm-key')confirm_url = url_for('confirm_email',token=token,_external=True)html = render_template('email/activate.html',confirm_url=confirm_url)# We'll assume that send_email has been defined in myapp/util.pysend_email(user.email, subject, html)return redirect(url_for("index"))return render_template("accounts/create.html", form=form)
{# ourapp/templates/email/activate.html #}Your account was successfully created. Please click the link below<br>
to confirm your email address and activate your account:<p>
<a href="{{ confirm_url }}">{{ confirm_url }}</a>
</p><p>
--<br>
Questions? Comments? Email hello@myapp.com.
</p>
  • You can use these tokens to validate emails when a user creates an account, changes their email or forgets their password.

# ourapp/views.py@app.route('/confirm/<token>')
def confirm_email(token):try:email = ts.loads(token, salt="email-confirm-key", max_age=86400)except:abort(404)user = User.query.filter_by(email=email).first_or_404()user.email_confirmed = Truedb.session.add(user)db.session.commit()return redirect(url_for('signin'))
  • Authenticate users using the Flask-Login extension to avoid dealing with a bunch of session management stuff yourself.

  • Always think about how a malicious user could abuse your app to do things that you didn’t intend.

仍然适用的原则 ✅

  1. Authenticate users using Flask-Login

    • Flask-Login(最新版本 0.6.x)仍是管理用户会话的事实标准

    • 核心功能稳定:@login_requiredcurrent_userremember_me 等

    • 现代补充:支持自定义用户加载器(包括异步场景)

  2. Always think about security

    • "考虑恶意用户行为"是永恒原则,现代威胁模型新增:

      • API 滥用(暴力破解/爬虫)→ 需增加速率限制(Flask-Limiter)

      • 密码 spraying 攻击→ 强制 MFA(如 Flask-Dance 支持 OAuth)

      • 供应链攻击→ 依赖项扫描(pip-audit)


需要更新的原则 ⚠️

  1. Use itsdangerous for email tokens

    • 仍然可用但不再是首选方案,现代替代方案:

      • 专用令牌库:PyJWT(RFC 7519 标准 JWT)

      • 安全增强:使用 cryptography 直接生成加密令牌

      • 云服务:AWS Cognito/Auth0 等托管服务

    • 仅推荐 itsdangerous 用于简单场景(如开发环境)


现代补充建议 ✨

认证架构升级
# 现代认证组合示例(2024)
from flask_jwt_extended import JWTManager  # REST API
from flask_principal import Principal  # 权限管理
from authlib.integrations.flask_client import OAuth  # 第三方登录jwt = JWTManager(app)  # 替代部分 itsdangerous 场景
oauth = OAuth(app)
关键实践
  1. 密码重置/邮件验证

    • 改用 时间受限的 JWTflask-jwt-extended

    • 必须使用 一次性令牌(即使 itsdangerous 也需自行实现)

  2. 会话管理

    • 启用 SESSION_PROTECTION = "strong"(Flask-Login)

    • 生产环境必须使用 Secure/HttpOnly cookies

  3. 现代威胁防护

    # 安全头设置(Flask-Talisman)
    talisman = Talisman(app,content_security_policy=...,force_https=True
    )

  4. 审计工具

    • 使用 bandit 扫描安全漏洞

    • 依赖项检查:safety check 或 GitHub Dependabot

过时/不推荐的做法 🚫

  • 避免直接使用 itsdangerous 处理敏感操作(如密码重置)

  • 不要自行实现加密算法(应使用 passlib 或 bcrypt

  • 避免将 Flask-Login 用于纯 API 项目(应改用 JWT)


2024 年推荐方案

场景工具选择
传统网页应用Flask-Login + Flask-WTF CSRF
REST APIflask-jwt-extended + OAuth2
邮件验证/密码重置PyJWT(而非 itsdangerous)
第三方登录Authlib/OAuthLib

核心建议

  1. 新项目优先考虑 JWT + OAuth 2.0 生态

  2. 维护旧项目时可继续使用 itsdangerous,但需增加速率限制

  3. 必须实施 密码哈希(argon2id/bcrypt) + HTTPS 强制跳转

十二、Deployment

Summary

  • Three good choices for hosting Flask apps are AWS EC2, Heroku and Digital Ocean.

  • The basic deployment stack for a Flask application consists of the app, an application runner like Gunicorn and a reverse proxy like Nginx.

(ourapp)$ gunicorn rocket:app
2014-03-19 16:28:54 [62924] [INFO] Starting gunicorn 18.0
2014-03-19 16:28:54 [62924] [INFO] Listening at: http://127.0.0.1:8000 (62924)
2014-03-19 16:28:54 [62924] [INFO] Using worker: sync
2014-03-19 16:28:54 [62927] [INFO] Booting worker with pid: 62927
(ourapp)$ gunicorn rocket:app -p rocket.pid -D
(ourapp)$ cat rocket.pid
63101
(ourapp)$ kill -HUP `cat rocket.pid`
(ourapp)$ kill `cat rocket.pid`
  • Gunicorn should sit behind Nginx and listen on 127.0.0.1 (internal requests) not 0.0.0.0 (external requests).

  • Use Werkzeug’s ProxyFix to handle the appropriate proxy headers in your Flask application.

仍然适用的原则 ✅

  1. 基础部署架构(App → Gunicorn → Nginx)

    • 传统虚拟机部署仍保持此结构,但现代方案更倾向于容器化

    • 新增要求:Nginx 现在需强制配置 HTTP/2 和 TLS 1.3

  2. Gunicorn 监听本地端口

    • 安全规范仍然要求:生产环境必须绑定 127.0.0.1 而非 0.0.0.0

    • 现代补充:Kubernetes 环境下改为通过 Service 暴露

  3. Werkzeug 的 ProxyFix

    • 仍然需要处理反向代理头,但现代方案:

      from werkzeug.middleware.proxy_fix import ProxyFix
      app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1)
    • 新增要求:必须显式配置 x_for/x_proto 数量(防伪造)

需要更新的原则 ⚠️

  1. 三大托管服务推荐(EC2/Heroku/Digital Ocean)

    • Heroku:已不再提供免费层(2022年11月取消),性价比下降

    • Digital Ocean:现更推荐其 App Platform(托管容器服务)

    • AWS EC2:仍是主流但非最优选择,现代替代方案:

      • 容器服务:AWS ECS/EKS、Google Cloud Run

      • Serverless:AWS Lambda(Zappa框架)、Vercel

      • 边缘部署:Fly.io、Cloudflare Workers


现代补充建议 ✨

部署架构演进

关键实践升级
  1. 运行时选择

    • 同步应用:仍可用 Gunicorn + gevent

    • 异步应用:改用 Uvicorn(ASGI 服务器,支持 HTTP/2)

  2. 安全强化

    # Nginx 现代配置片段
    location / {proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_set_header X-Forwarded-Proto $scheme;# 必须设置严格 CSPadd_header Content-Security-Policy "default-src 'self'";
    }

  3. 基础设施即代码

    • 使用 Terraform/Pulumi 管理云资源

    • 部署工具:GitHub Actions > Fabric/Capistrano

  4. 性能优化

    • 静态文件移交 CDN(Cloudflare/R2)

    • 启用 Brotli 压缩替代 gzip

过时/不推荐的做法 🚫

  • 避免直接部署裸机/虚拟机(除非有特殊需求)

  • 不要使用 flask run 生产环境(仍常见于教程但极不安全)

  • 避免手动配置服务器(应使用 Docker + CI/CD 自动化)


2024 年推荐方案

场景推荐方案优势
快速原型Fly.io/Render5分钟部署,免费额度
传统应用Docker + EC2平衡控制力与成本
高流量服务Kubernetes + GCP自动伸缩
ServerlessAWS Lambda + API Gateway按需计费

重要趋势

  1. 容器化已成默认选择(即使小型项目)

  2. Serverless 方案成熟(Cold Start 问题显著改善)

  3. 边缘计算兴起(如 Cloudflare Workers 支持 Python)

建议新项目优先考虑:Docker → 托管容器服务(如 Fly.io) 的路径,既保持开发一致性,又降低运维复杂度。

相关文章:

  • 多模态大语言模型arxiv论文略读(三十三)
  • 【产品经理思维】
  • 多级缓存架构,让系统更快的跑起来!
  • 特伦斯智慧钢琴评测:如何用科技重塑钢琴学习新体验
  • Cribl 利用表向event 中插入相应的字段-example-01
  • C++入门语法
  • FreeRTOS中的优先级翻转问题及其解决方案:互斥信号量详解
  • 第十四届蓝桥杯 2023 C/C++组 平方差
  • 设计模式 建造者模式
  • Pycharm(九)函数的闭包、装饰器
  • compat-openssl10和libnsl下载安装
  • Java高效合并Excel报表实战:GcExcel让数据处理更简单
  • 靠华为脱胎换骨,但赛力斯仍需要Plan B
  • MySQL访问权限授权问题
  • 二分查找、分块查找、冒泡排序、选择排序、插入排序、快速排序
  • SPL 量化 序言
  • 【FFmpeg从入门到精通】第四章-FFmpeg转码
  • 性能比拼: Nginx vs Caddy
  • 乾元通渠道商中标舟山市自然灾害应急能力提升工程基层防灾项目
  • VTK知识学习(53)- 交互与Widget(四)
  • 人民日报聚焦外贸“重镇”福建晋江:多元化布局扩大“朋友圈”
  • 美国土安全部长餐厅遇窃,重要证件被盗走
  • 艺术开卷|近现代中国古代书画东渡日本的历史图景
  • 海拔四百公里的救赎
  • 上海崇明“人鸟争食”何解?检察机关推动各方寻找最优解
  • 新城市志|全球供应链动荡加剧,中国稳外贸有信心有底气