标签归档:Flask

Flask 已死,FastAPI 永生

好险,刚刚要写一个新项目,执行了 pip install flask。等得无聊所以打开了知乎,突然看到首页推荐的这篇《Flask 已死,FastAPI 是未来》。看到一半吓得我赶紧按下 Ctrl-C,然后重新执行了 pip install fastapi。好快!不愧是 FastAPI,连安装都这么快。

Flask!Flask!你怎么了?Flask~Flask~你不能死呀!我跟你相依为命、同甘共苦了这么多年,何况我的书还没有写完,想不到今天白发人送黑发人……

咳咳,说回正题,2021 年我写过一篇《请不要把 Flask 和 FastAPI 放到一起比较》。不是同一个等级的框架拿到一起比较没有意义。这篇《Flask 已死,FastAPI 是未来》从一开始的标题就是错的。

除了比较上的问题,上一篇文章里最后提的问题现在有答案了吗?

各种对比文章贴出来的 hello world benchmark 对于开发生产应用来说有多大的意义?这里的 benchmark 背后有没有任何的 hacky?异步是否等同于高性能还是要看情况?框架本身的性能在一个请求处理流程中占多大的影响?asyncio 的生态怎么样?

同时我也指出了一些 FastAPI 的问题——现在 FastAPI 营销至上的项目运作方式改变了吗?

从长远看这些大都是一些临时问题,而且 FastAPI 作者已经开始全职开发开源项目,这些问题在未来应该都会慢慢得到改善。指出这些是希望更多的人可以客观看待 FastAPI,吹捧并不能让一个东西变得更好,参与开发、介绍用法和回答社区提问是比盲目吹捧更有意义的事情。我当然期待 FastAPI 能够越来越好,也期待看到有更多优秀的 Python 框架出现,但我不喜欢过度炒作、盲目的吹捧和错误的对比。

如果一个人即没有深入了解 Flask,也对 FastAPI 的整体状况一知半解,然后突然跳出来写了一篇《Flask 已死,FastAPI 是未来》,他的目的是什么?炒作啊,朋友。标题党也就罢了,到处都是逻辑漏洞和事实错误这也行?

精彩片段赏析

前两天在 Twitter 上对这篇文章发了一点想法。大概是我的语言能力退化,导致很多人没看懂我的反讽和调侃……所以还是好好说话,摘评几条原文的内容:

其实我这篇文章,也可以叫做「Django和Flask之死」,但是在框架应用场景角度来说Flask和FastAPI对比更合适,而Django直接和FastAPI相比有一些差别。在一些商业场景(例如CMS)Django依然是首选,而Flask(甚至FastAPI)看起来更像个「玩具」,所以Django短时间不会被取代(Flask这些年不是也是没取代的了嘛)。
Django REST Framework(DRF)
Django主旨是为了在后端生成 HTML,而不是创建现代前端(如 React、Vue.js )或与其通信的其他系统使用的 API。所以FastAPI其实和Django REST Framework直接对标,它们主要场景都是构建 Web API,但是名字上也可以看出来,DRF还是依托于Django框架,所以缺点一样。

既然作者能看出来 Django 和 FastAPI 有差别,也了解「FastAPI其实和Django REST Framework直接对标」,那么就看不出来 Flask 和 FastAPI 在框架应用场景角度有差别?所以为什么不用 APIFlask 这种和 FastAPI 对标的框架,而是挑了 Flask?

Flask本来的优点是灵活性和极简主义,但这意味着很多很多组件需要自己造,这个要不然需要公司够大专门有开发者开发和维护,要不然得个人能力极强,否则插件很难达到生产级别,这就造成Flask的第三方插件质量层次不齐,且无法保证长期维护。就像我上面说的那些库,现在来看,其中已经很多不再维护了。

这点蛮中肯,Flask 扩展的质量和维护状态确实参差不齐,这也是为什么我要发起濒危 Flask 扩展拯救计划并创建这个 Flask 扩展状态监控项目。那请问 FastAPI 呢?首先 FastAPI 是否有这么多「FastAPI 扩展」可用?其次 FastAPI 的第三方插件就不会出现这些问题?说到底这是所有开源项目和社区生态都会遇到的问题。

所以即便是今天,你想用Flask构建一个API服务,还是要东拼西凑各个组件,其中某些组件有些没及时更新的地方要自己动手解决,这对于老手来说还好,对于新人来说很痛苦,尤其是你想要应用现在最新的实践方案和理念,只能望而兴叹。

首先作者了解 Flask 和 FastAPI 相比,后者的主要场景是「主要场景都是构建 Web API」,接着又说 Flask 生态构建 API 需要东拼西凑。听起来不太对劲?

另外 Flask 生态中类似 FastAPI 这种提供 API 整体解决方案的框架都被作者忽略了?随便列几个:

东拼西凑就一定是缺点?不熟悉这些工具的人选择打包方案,熟悉的人选择自己组装,这有什么问题吗?

这个时候Flask并不想接受改变,社区迟迟的不加入aio的支持,另外Flask原作者也去写rust了,把项目交给了2个维护者(现在只剩一个人了)。

到这里文章就开始有些不对劲了,喜剧/戏剧效果逐渐增加……Flask 开始被拟人化了。Flask 是谁?是谁要求改变?Flask 说了啥表示不想改变?

Flask 作者把项目交给了 2 个维护者?现在只剩一个人了?!Flask 真的好惨……可是这些事情都是什么时候发生的?虽然我最近两年开始工作已经没怎么给 Flask 提交代码,不知道哪天被踢出群聊。但是至少我从 18 年到现在一直是 Flask 的维护者,这些事情我怎么一点都不知道?

在Flask的那个时代,代码执行是单线程、同步的,这意味着要依次处理请求,前一个请求完成前,其他请求消耗在等待 I/O 操作上。而asyncio是最好的解决方案,它让I/O成为异步操作,无需等待任务完成即可获取任务结果并继续处理其他任务请求。

好奇 Flask 的那个时代是哪个时代呀?听起来像是妈妈在讲小时候的故事呢。Flask 2.0 已经添加了有限的 async 支持Quart (Flask 的 ASGI 实现)已经合并到 pallets 组织,作者正在推动 ASGI 支持的 Flask。这些都是这个时代的 Flask 在发生的事情哦。

而FastAPI天生支持并发和异步代码,代码写对了就可以在效率上达到极致,所以它被认为是目前最快的Python框架,效率和NodeJS或Go接近。当速度和性能至关重要时,FastAPI 是最佳选择。

嗯,这个我无从反驳。你说快就是快,宇宙最快 Web 框架。

另外由于集成了Pydantic,所以非常容易在项目中添加ORM(如SQLAlchemy),从请求中获得的对象可以直接传递到数据库,因为已经做过数据验证。反之亦然,可以将从数据库获取的对象直接返回。
相对的,Flask这方面的缺失的。

完蛋,Pydantic 对 Flask 发起了单方面安装制裁。当你在 Flask 项目里试图引入 Pydantic 的时候,就会出现安装错误“Warnning: Pydantic is strictly forbidden to installed into a Flask project. Your behavior has been reported to PAFAFC (Pydantic and FastAPI and friends Committee).”

再补充一点。FastAPI无论看项目名字还是介绍都能感觉出来它是用于构建API服务的,事实上FastAPI自己的核心代码也确实是这样的,可以说它不是一个传统的、完全自己实现的框架,它更像是一个集各家之长的框架,从一个空壳开始,把需要的、适合的组件组装起来。例如它没有模版引擎,如果你确实需要用它实现一个web应用要渲染模版,你可以再组合你想要的选择,当然还可以用Starlette内置的Jinja2(是的,也是Flask内置的)

作者对于 Flask 和 FastAPI 两者定位不同的认识真是越来越清晰了呢。不过「组合我想要的选择」不就变成前面说的 Flask 那样东拼西凑了嘛,不好。还有就是 FastAPI 为啥要在介绍模板引擎的文档里让我安装 Jinja2 呢?看来「相对的,FastAPI这方面是缺失的」。

上面提的是FastAPI的优势,但是也不能说明Flask已死,我为什么会这么觉得呢? 主要还是看开发者和用户的人气。

重头戏来了,下面终于到了对于「Flask 之死」的凄惨景观的详细描写(注:这几点后来作者看到了我在 Twitter 上发的东西又自己做了补充和修改。这里我引用的是原文)。

1. 社区活跃度。例如项目的Issue和Pull Request数量,Flask都是个位数,和FastAPI相比根本不是一个水平。这其实侧面证明项目不再活跃,因为如果活跃的话,老的用户会有更多需求,它们不来说明已经离开,而新的用户意味着有各种问题,文档即便足够全,其实我们要知道还是会有很多用户来提问和贡献代码的,没有就说明用得少。

如果你经常参与开源项目或是自己开发了开源项目,通常会了解到,一个流行的项目想要把所有的 issue 和 pull request 都处理掉是很难的事情。而 Flask 能做到这一点反而是维护团队的努力尽责和项目本身足够成熟的体现:

blank

以及对 issue 和 pull request 快速响应的体现:

blank

如果你想知道有多少人在用 Flask 和 FastAPI,有两个参考数据,一个是 GitHub 上开源项目的用户数量统计。这些可以在两个项目的 GitHub 主页直接看到。

FastAPI

blank

Flask

blank

另一个数据是 PyPI 下载量,这个可以在 PyPI Download Stats 上看到。

FastAPI

blank

Flask

blank

另一方面,不同的项目对 issue 的使用策略是不同的。有的使用自己的 issue tracker,有些鼓励用户来提问。Issue 和 pull requests 不仅不能用来表示项目活跃度,过多的数量反而能说明一个项目的维护状况堪忧。堆积的 PR 对于用户和开发者来说都是灾难。以 FastAPI 为例,你看看现在的 PR 列表里都是什么?项目不如改名叫「FastAPI 文档大全」好了。你觉得这样会让提交代码贡献,修复 bug 的人有很好的体验?

blank

FastAPI 有不少 issue 在建议作者创建开发团队,摆脱当前这种低效的维护模式。类似的抱怨有很多,我不想去翻历史,这里仅以置顶 issue 里的一则回复举例:

blank

评论中提到的是这个 PR。一个 bug 在 2022 年就有人试图修复,但是到现在都没有被处理。而且报告相关 bug 的 issue 已经被转换成讨论。最后一条是用户在建议把这个讨论转换回 issue:

blank

没错,FastAPI 本来有几百个 issue(好活跃,对吧),某个时间点被批量转换为讨论,谁知道里面有多少是没有被处理的 bug report。谁知道这 646 个 PR 里有多少是需要被优先处理的 PR。我在 2020 年也提议把文档翻译放到单独的仓库,后来这个 issue 也被转成讨论了。到现在贡献者依然被这个问题困扰

blank

2. 讨论度。也就是博客文章,Stackoverflow等网站咨询和讨论的热度,其实可以感受到,已经没什么人写Flask相关的内容了。

作者写文章是可以随口就来的?博客文章不好统计,那么以 Stack Overflow 来看。抛开问题总数量,因为两个项目创建时间不同。但就提问频率,以上次发推文和现在两次截图的数据来看,和 Flask 相关的问题都创建的更频繁。

FastAPI

blank

Flask

blank

3. 开发迭代的频率。翻一下commits,可以看到Flask只有一个维护者会偶尔修修bug,没有什么大的功能特性开发。

开发迭代的频率和活跃度也是作者强行建立的联系,不过结合 FastAPI 的运作方式,两位作者倒也是「双向奔赴」了。「偶尔修修bug,没有什么大的功能特性开发」有什么问题吗?这就是维护者应该做的事情,大的功能特性又不是每天都有。而且作者是不是没有看 FastAPI 的 commits 历史?你肯定猜不到三千多个 commits 里有一千多是 bot 在更新 changelog。再猜猜 FastAPI 最新一个 release 都有哪些新功能?11 个改动里有 5 个是在更新 README 上的赞助商列表哦:

blank

4. 灵魂人物的影响力。Flask的灵魂人物,也就是项目的发起人其实早就不再参与项目了,搜一下项目贡献记录可以看到Armin Ronacher上次参与开发已经是6年前了。

这条实在不知道说什么好。我创建了项目我就得绑死在项目上直到生命最后一刻是吗?引用一下我在 Twitter 上的回复:

开源项目一定不要创建 GitHub org,项目再流行也要放在自己的账号下。不要成立什么开发团队,PR 要自己慢慢 review,用户抱怨多了,你自然知道哪个 PR 比较重要。还有就是用自己的账号或头像来设置 bot,这样即使你哪天兴趣转移了,用户会以为你一直在参与。斯人已去,灵魂犹在。

我真的佩服 FastAPI 作者这一招用自己的账号来作为 bot,用户以为你在活跃,而这个 PR 哪天能够被 merge 还要多烧几炷香:

blank

一边说自己忙得不行,一边又坚持把项目放在自己个人账号下,坚持自己 review PR。这就是灵魂人物?

后记

终于写完了。没想到只是偶然在一台没有屏蔽推荐首页的电脑上打开了知乎,最后要浪费这么多时间和精力。我想肯定会有人看了开头就急着评论,说「FastAPI 如何好用」或是「Flask 如何不好用」甚至是「Python 不如 XXX」。这些都是离题的讨论,我不完全否认这些观点,也并没有谈及这些。这篇文章只有两个目的:

  • 强调不应该把两者放到一起比较
  • 指出那篇「引战文」中的错误观点和事实偏差,顺便指出一些 FastAPI 的问题

对于程序员来说,你可以使用任何框架,你也可以使用任何编程语言。程序员不就是要随时接受改变,随时学习新的东西吗?没人要你一辈子只能用 Flask 或是 Python。另一方面,即使别人都用 FastAPI 了,我用 Flask 又会怎么样?工具而已,只是按照需要做出适当或喜欢的选择。但是你起码要看一看文章再发表评论,而且也不用看到什么观点就相信什么观点(尤其是没有论据、结论先行的文章)。

同时建议 FastAPI 推介者保留一点体面。新事物的建立不一定要踩在已有事物的坟墓上。挑起对立只会导致 Python 社区的混乱。最后再引述我在上一篇文章的想法作结:

从长远看这些大都是一些临时问题,而且 FastAPI 作者已经开始全职开发开源项目,这些问题在未来应该都会慢慢得到改善。指出这些是希望更多的人可以客观看待 FastAPI,吹捧并不能让一个东西变得更好,参与开发、介绍用法和回答社区提问是比盲目吹捧更有意义的事情。我当然期待 FastAPI 能够越来越好,也期待看到有更多优秀的 Python 框架出现,但我不喜欢过度炒作、盲目的吹捧和错误的对比。


相关链接

PyCon China 2023:濒危 Flask 扩展拯救计划

月初参加了 PyCon China 2023, 做了一个关于 Flask 扩展生态的演讲。不太算是技术分享,讲故事为主。主要的契机是最近尝试把几个失去维护的 Flask 扩展通过各种方式「救」了回来,所以借此机会分享一下经验,也号召大家多多参与开源项目。

演讲介绍

看着一个又一个 Flask 扩展失去维护,不再兼容新版本的 Python 和 Flask,我们能做些什么?在这个演讲里,我会介绍最近我和一些被遗弃的 Flask 扩展打交道的经历,包括如何更新一个古老的 Python 开源项目,以及正在实施中的一个拯救计划。如果你来自其他开源社区,那么这里介绍的经验或许也会帮到你。

录像和幻灯片

P.S. bilibili 认定金正恩的照片是违禁图片,留半秒都不行,最后只好贴了一只马在上面。浪费二十分钟。

照片

blank blank

戴尔 EMC Python/Go 职位内推

内推的最新状态见 greyli.com/dell-jobs。如果你在戴尔招聘网站上发现了其他方向/城市的意向职位,也可以联系我内推。


最近公司又开放了几个新的 Python/Go 职位空缺,如果感兴趣的话,一起来做同事吧。

职位要求:

  • 计算机相关学士学位或 1~2 年软件开发经验(另外还有对应 3~5 年以及 10 年以上经验的职位)
  • 熟悉 Python/Go/Java(任一,最好是 Python/Go 方向)
  • 熟悉 Linux 和 Git 的使用
  • 熟悉 Flask 或其他 Web 框架
  • 有 REST API 开发或微服务相关经验
  • 了解容器和容器编排系统(Docker、Kubernetes、Rancher 等)

加分项:

  • 了解 Angular/React/Vuejs(任一)
  • 了解 MySQL、PostgreSQL 或其他 DBMS
  • 了解或使用过 Jenkins
  • 参与过开源项目
  • 有网络、安全、虚拟化、云平台相关经验

工作地点在上海/成都/台北。工作时间正常,不加班,不打卡,周末双休(965)。混合办公,每周可以最多五天居家办公(不限定时间,在正常工作和沟通的前提下,可以自己安排)。

联系方式:

《Flask 入门教程》第三版发布

最近手里堆积的事情越来越多,两本书的进度被日常工作挤压,于是非常想有一些小小的进展来缓解焦虑。刚好有读者来反馈《Flask 入门教程》不兼容最新版本 Flask 的问题,所以就花了一天时间来更新这个教程。

发布上个版本已经是 2019 年的事情了,这次针对 Flask 最新的 2.1.3 版本做了改写,同时不再兼容 Python 2.7 版本。优化了前面几章的一些内容,后面的章节需要改动的地方不多,就没有认真去更新。另外还顺便用 MkDocs 和 Netlify 把教程重新部署到了 tutorial.helloflask.com 上,后续会废弃掉 GitBook。

过去三年里,这本电子书大概给我带来了五百块的收入(主页上有一个自愿点击的「付费支持¥10」的按钮)。虽然不多,但是时不时收到到账提醒和鼓励的话还是很开心的。感谢每一位付款的读者!

blank

当然,给我带来更大成就感的是看到读者分享他/她通过阅读这个教程写的程序,这是一种给别人带来成就感的成就感——元成就感。

如果你在 macOS 上无法访问 Flask 程序

如果你用 macOS 开发 Flask 时无法正常访问程序,或是使用 ngrok 等内网穿透工具时映射的公网地址无法访问,大概率是因为 macOS 新版本(Monterey)的变动导致。你会在页面上看到类似下面的错误信息:

Access to 127.0.0.1 was denied.

You don't have authorization to view this page.

HTTP ERROR 403

或是在执行 flask run 命令时看到类似下面的报错:

OSError: [Errno 48] Address already in use

首先确认你的 macOS 版本是不是 Monterey(左上角 Apple 图标 – About This Mac)或是之后的版本,如果不是那么问题应该和本文无关。

简单来说,新版本的 macOS 上 localhost 5000 端口被一个叫 AirPlay Receiver 的服务占用了。而 Flask 内置服务器默认就运行在 5000 端口,所以会造成端口冲突。当你通过将 host 设为 0.0.0.0 指定 Flask 的内置服务器对外可见,或是使用内网穿透工具时,会发现程序无法访问(有时未设置对外可见也会遇到这个问题)。

最简单的解决方法是关掉这个服务:

  • 系统设置(System Preferences) > 分享(Sharing) > AirPlay Receiver > 取消勾选

或是更改 Flask 开发服务器默认的端口(比如改成 8000)。在执行 flask run 命令时使用 -p/–port 选项可以自定义端口:

$ flask run -p 8000  # 或 flask run --port 8000

或是在执行 flask run 之前通过环境变量 FLASK_RUN_PORT 设置:

$ export FLASK_RUN_PORT=8000 # macOS/Linux
> set FLASK_RUN_PORT=8000 # Windows CMD
> $env:FLASK_RUN_PORT=8000 # Powershell

在 Werkzueg 2.1.0(2022/3/28 发布)版本,如果你执行 flask run –host=0.0.0.0 时检测到了端口被占用,会直接显示相关的错误提示:

$ flask run --host=0.0.0.0
Address already in use
Port 5000 is in use by another program. Either identify and stop that program, or start the server with a different port.
On macOS, try disabling the 'AirPlay Receiver' service from System Preferences -> Sharing.

本文源于去年十一月发的一条推文,最近经常碰见有人遇到这个问题,所以转成这篇文章发出来。

画了一幅涂鸦,送给苹果公司:

blank

Flask 工作机会

最近在找工作,发现了一些和 Flask 相关的工作机会。因为目前并没有一个收集 Flask 相关职位的平台,所以就在 GitHub 上创建了一个仓库来分享这些职位,希望可以帮到其他正在找工作的 Flask 用户:

职位以 issue 的形式列出。目前列出来的几个都是和 Flask 关联非常大的职位,这里面有的我投递了申请(比如戴尔),有的收到了拒信(比如育碧),有的收到对方的面试邀请(比如 Dropbase)但并没有通过面试……所以这些职位都在开放中,如果你在找工作的话,尽管投递简历。同时也欢迎在投递之后回来分享面试进度/经历/经验。

如果你所在的公司正在招聘 Flask 相关的职位,或是你在未来发现某个公司发布新的 Flask 相关的职位,欢迎在这个仓库创建 issue 分享。创建 issue 时请遵循下面的格式要求:

  • 在标题注明「公司-职位-城市」,远程工作统一使用「Remote」。
  • 把职位描述里的 requirements 部分贴到 issue 内,并在最后给出职位详情链接。
  • 建议发布和 Flask 技术栈关联比较大的职位,不过 Python 相关的职位也欢迎。

顺便说一句,有很多 Python 相关的工作都会要求掌握某一种 Python Web 框架,类似这样的描述:

  • Good knowledge of web frameworks like Flask, Django, etc.

即使对应职位实际不用 Flask 也不用担心,当你掌握了某一种框架,其他的框架学习起来会非常容易,因为大部分的概念都是相通的。而面试时也会根据你擅长的框架提问,所以尽管申请就好。

祝大家都能找到自己喜欢的工作。

开始写作《Flask Web 开发实战》第二版

Flask Web 开发实战》第二版已经开始写作,计划在今年完成这本书。那本《Python Web API 设计与开发》一直拖着没写完,让我感觉很焦虑。因为拖得太久,HelloFlask 群聊里已经开始谣传我转行送快递了 :D。

所以我想先把《Flask Web 开发实战》新版完成,这样这一年我至少完成了三个年度目标中的一个。「优化」是我擅长和喜欢做的事情,除了要用 Word 写之外,我很乐意给这本书写新版。

内容变动

在各处收集了很多读者反馈和建议,综合我自己的规划,第二版主要有这些大的变动:

  • 不再兼容 Python 2.7,基于 Python 3.x、Flask 2.x。
  • 把大部分知识点集中到第一部分,让第二部分的示例程序内容更精简。
  • 第 1 章使用 pip+venv(+pip-tools) 或 PDM 替代 Pipenv,增加更多对 PyCharm 的介绍。
  • 第 6 章使用 Flask-Mailman 替代 Flask-Mail(同时引入介绍一些新的扩展,比如 Flask-Admin)。
  • 删除第 9、10、11 章(删除后 3 个实战项目),仅保留 Sayhello 和 Bluelog,删减项目的部分功能会合并到这两个项目。
  • 第 10 章删除实战项目,只保留 Web API 开发部分,会新引入 marshmallow 和 APIFlask。
  • 第 12 章添加异步任务相关内容。
  • 第 14 章添加 Docker 相关内容。
  • 删除第 15 章(Flask 扩展开发)。
  • 删掉一些在国内访问有问题的服务介绍,比如 SendGrid(第 6 章)、Heroku(第 14 章)、Twitter 第三方登录(第 11 章)。

大部分内容变动是在做删减,第一版 704 页,第二版内容会删减到 450 页左右。

代码片段

第一部分每一章都有一个示例程序,读者需要切换到每一个子文件夹运行,如果同时自己编写练习代码的话,很容易产生混乱。所以新版的考虑是,第一部分的示例程序不再给出可运行的示例文件(至少不在书里介绍),而是把所有的代码片段放到 HelloFlask 文档,以代码片段的形式组织。读者需要的话可以自己复制代码到本地运行。作为示例,第一章的代码片段可以在这里看到:https://docs.helloflask.com/book/4/snippets/c1/。因为前六章的代码片段变化不大,所以第一版的读者也可以使用这些文档。

P.S. HelloFlask 文档(https://docs.helloflask.com)是我最近刚创建的一个文档集合。所有和书相关的内容都会放到这里,比如勘误、代码片段、衍生文章等。后续也会在这里写一些扩展快速入门介绍、Flask 基础知识等 Flask 相关的东西。

书名

第二版因为有独立的书号,所以可以改书名。责编老师认为原书名就很好,换书名会浪费掉第一本书建立的品牌。我也基本同意这个观点。目前的考虑是主书名不变,出于营销的考虑,副书名或许可以加一个「Python」关键字,比如改成「Python Web 开发入门、进阶与原理解析」。

封面

目前这本书主页上的封面不是正式封面(我用画图软件在初版封面上随手涂了两笔 >_<)。目前的想法是把封面标题颜色换成深红色,然后换一个封面图案,不过暂时还没想好换成什么。

措辞

第一版是用 Word 写的,排版很痛苦,毕竟要在 Word 里面排版代码。第二版也要继续用 Word 写,而且更加痛苦,因为第二版的书稿是编辑老师用工具从 PDF 文件转制成 Word 的,大部分格式都变得很混乱。希望这是我最后一次用 Word 来写技术书。

对于第一版,我交的终稿和最终成书有一些内容的变化,编辑老师会修正错别字和一些病句。但是后面也发现有一些句子修改得并不合理,导致句子原意产生了变化。这次我会在出版前过一遍校正后的书稿,确保不会再出现这样的情况。

另外,编辑老师还会替换一些词汇用法,比如把「我」替换为「笔者」,这个笔者勉强能接受,但是笔者最不能接受的就是要把所有的「点击」改成「单击」。单击一个链接?这太奇怪了。今年和编辑老师再次沟通了这件事,事情终于有了变化,书中的「点击」在这一版不用再死板的按照出版社的规定修改为「单击」。新的读者不会被指导在网页上单击一个链接了。

周边开源项目

我的很多开源项目的开发都是写作驱动的,上一本书驱动我开发了那几个 Flask 示例程序和扩展,这一次同样会有一些开发计划:

  • APIFlask:补齐所有文档,发布 1.0 版本。
  • Bootstrap-Flask:添加 Bootstrap 5 支持。
  • Flask-CKEditor:添加 CKEditor 5 支持,同时集成新版本内置的 Markdown 支持。
  • Flask-WTF:添加多文件上传验证支持。
  • Sayhello:添加分页、多语言、Markdown 支持等功能(总之就是尽可能把删减的示例程序里比较有意思的功能合并到这里)。
  • Bluelog:把 Albumy 的除了图片相关的功能合并过来,会换一个名字(暂定 WeBlog),作为一个社交博客。

如果你对这本书的新版有其他建议和想法,欢迎提出。这两本新书相关的动态会发到 Twitter @helloflask 和我的公众号,欢迎关注。

2021 年 Flask 用户调查报告

七月份创建了一个 Flask 用户调查问卷,到目前为止一共收集到 104 份提交,感谢各位的参与!这篇文章会对问卷收集结果做一个总结,作为一份(非官方的)2021 年(104 位中国)Flask 用户调查报告。

如果你想自己看原始数据,下面是剔除了隐私信息的问卷提交数据文件(CSV 格式):

https://helloflask.com/downloads/flask_report_2021.csv

blank

如果你现在还想参与的话,完全来得及,下面是问卷的地址:

https://jinshuju.net/f/UY6Rd8

你在工作中使用 Flask 吗?

在提交的 104 份问卷里,接近一半的人在工作中使用 Flask,详情如下:

你在工作中使用 Flask 吗?

算上我,还没找到工作的人竟然只有 5 个(《震惊!某份民间调查显示 Flask 用户无业率仅有 4.8 %!》:P)。

Flask 中文文档标语翻译

前段时间发起了 Flask 中文文档翻译,目前正在龟速进行中,欢迎英语比较好的同学参与(翻译或审核已经提交的 PR)。文档首页的 logo 图片里有一句标语——「web development, one drop at a time」,我临时翻译为「Web 开发,一次一滴」。在 GitHub 仓库的讨论里,大家给出了更多更好的备选项。根据这次问卷投票的结果,「Web 开发,起于点滴」排在第一位(由 HelloFlask QQ 群里一位翻译专业的同学翻译),详情如下:

Flask 标语翻译

更保险的选择是「不作翻译」,在投票中排在第二位,最终我会考虑从这两者之间选择。另外,如果翻译的话,如果翻译的话,「Web」会考虑按照英文近年的惯用趋势而使用全小写(你觉得呢?​)。

P.S. 在 GitHub 上的投票结果里,@abersheeran 翻译的「Web 开发,起自微毫」和「任取随用的 Web 框架」票数最高

对 Flask 的新功能请求 & 改进建议

剩下几个问题不方便详细统计和展示,我粗略看了一遍,整理出了关注度最高的几件事。我一一在下面评注了我的想法以及相应的动态。

添加更多 Web API 开发支持

开发接口时自动生成swagger

对 Web API 很友好的支持

加入pydantic用于类型检查

Flask 作为一个通用型框架,不会添加太多关于 Web API 这种细分方向的支持。除了手动集成这些功能/工具,你可以考虑选择基于 Flask 而且集成了这些功能的二次框架,比如 APIFlaskflask-smorestSpectree 等。

添加基于 ASGI 的异步实现

加强对异步的支持

异步支持的不是很成熟

可能是速度吧,据说现在很多新框架都比Flask快,要淘汰Flask云云

Flask 目前的异步支持已经能够满足大部分使用场景。据我所知,基于 ASGI 的异步支持短期内不会实现。

而对于鼓吹性能的文章可以不用太在意:异步和高性能不直接划等号。技术选型不会只考量性能。benchmark 未必客观和能够反映真实情况。如果对异步有强需求,可以考虑用和 Flask 相同 API 的 Quart(一个 Flask 的 ASGI 异步实现),或是换用其他异步框架。

官方维护的扩展列表

一个针对新手的 flask extension 的指南

由Pallets Projects开发团队的成员或者flask官方统一所有第三方插件的开发与发布,目前太乱了,有些都快停更十年了,还占用名字。

各种插件扩展选择太多,但是又质量层次不齐,此外很多个人维护的扩展可能由于开发者精力有限在后期会出现项目生命周期的问题,如:flask_restful,需要官方对常用扩展维护一套比较简洁的扩展。当然这样的话可能又走上了Django的老路,可能作者正在计划的“Flask扩展收容计划”是一个不错的选择,起码可以管理起来。但是脱离原作者维护的项目后期发展如何又成为另一个话题。比如需要对插件进行遴选,另外需要对该计划由官方进行宣传等

这件事我之前有计划在做,前段时间注册了 flaskextensions.org,想用来做一个这样的扩展推荐列表。在 Pallets 会议上沟通之后,决定交给 Pallets 官方来做,所以把域名转给了 Pallets 团队,后续会做一个这样的列表出来:列出来推荐的 Flask 扩展,并给出失去维护扩展的替代品。

另外 Pallets 在 GitHub 创建了一个 pallets-eco 组织,用来收纳失去维护(维护者不想再继续维护)的流行 Flask 扩展,让它们保持健康的维护状态(由社区维护)。目前有两个扩展进入这个组织,分别是 Flask-CachingFlask-OpenID

脚手架工具和大型项目组织

统一并明确开发的工程化流程,包括项目应该新建那些文件夹等。

缺少小白懒人快速一键生成集成框架(webadmin, mysql)

引入蓝图想搞玩大型项目,可大型项目又需要自己组织好项目结构,需要一个对flask很熟悉的人做这事 还不如用django。官方推一个脚手架生成项目模板吧像vue-cli一样 包括是否使用orm等插件,不然还不如django搭建起来快。。

作为一个微框架,Flask 的初衷是不限定项目文件组织形式,所以官方不太可能会出一个脚手架工具或是项目组织指南。在工厂函数和蓝本这两个概念的基础上,你可以自由组织你的项目。另一方面,市面上已经有很多项目模板或是脚手架工具(比如 cookiecutter-flask),也有很多介绍 Flask 项目组织的文章,你可以根据这些工具和文章制定自己的规则,然后为你的组织或团队确定一个项目组织规范或是写一个脚手架工具,或许这才是 Flask 的「正确食用方式」。如果你更需要一个固定的项目组织模式,那么 Django 或许是更好的选择。

我也有计划写一个更简单的脚手架工具(对我来说市面上那些都太复杂,引入了太多扩展和工具),同时给出一份 Flask 项目组织建议,这件事也许会在写《Flask Web 开发实战》第二版的过程里完成。

Bootstrap-Flask 的 Bootstrap 5 支持

Bootstrap-Flask 希望可以早点同步 Bootstrap5 的相关内容。因为Bootswatch的最新版本有我想要使用的组件,但是Bootstrap-Flask只支持到Bootstrap4,所以有些宏无法正常显示,比如render_form等。还有希望Bootstrap-Flask的wiki能够更加的完善和细节,我会持续关注,大佬辛苦

提交的问卷里有一条说到这件事,此前在 TwitterGitHub 上也有人提到,所以也放到一起说一下。我已经在做这件事了,基本的 Bootstrap 5 支持已在 #161 完成,完整的实现会在下个月完成(详见 #162),届时会随 2.0 版本发布。

除了这些,提交的问卷里还有很多其他的建议和问题,我没法一一回应。有时间我会看看问题里提出的问题有哪些我可以试着解决和改善。同时也欢迎你一起尝试解决这些提出的问题,感兴趣的话,去翻翻上面给出的问卷数据吧。

总结

总体来看,Flask 社区在朝着好的方向发展,希望明年这里提到的大多数计划都会有着落。一起加油!

P.S. FlaskCon 2021 会在今年 12 月举办,如果你有 Flask 相关的内容想分享,欢迎报名(英文,预录制演讲)。


相关链接:

欢迎填写 Flask 用户调查问卷

以参加捕蛇者说播客录制 Ep 30 为契机,创建了一个 Flask 用户调查问卷,用来收集 Flask 用户的反馈和建议。尽管这个问卷是由我个人而不是 Flask 官方(Pallets)发起(不过 Flask 官方也在计划着做一个调查问卷),但是我会把收集到的信息反馈到 Flask 开发团队进行讨论。因此,你的建议的确有可能让 Flask 变得更好。

不管你对于 Flask 是有明确的变动建议,还是只是对某个功能不甚满意,都可以把你的想法写下来。谢谢!

问卷地址:https://jinshuju.net/f/UY6Rd8


同时借这个问卷送出四本《Flask Web 开发实战》,填写问卷即可参与。每份问卷会有一个提交序号,中奖序号为 27、36、41、58。预计抽奖会在 7 月 22 号完成,届时抽奖结果会更新到这篇文章。

7 月 21 日更新,抽奖结果已产生:

blank

和捕蛇者说聊聊 Flask 2.0

六月初,应 laike9m 邀请做客捕蛇者说录了一期播客。今天中午发布了上半部分:Ep 30. 和李辉聊聊 Flask 2.0,关于自由职业的下半部分正在剪辑中,预计八月初发布。

这是我第一次录播客。录制那一天,房间里还没有装空调,而开风扇会导致风声录进去,我只能用静静降温法;为了防止录进邻居打骂孩子的声音,我又把门窗闭紧,所以录到临近中午,感觉越来越热。一开始还有点紧张和兴奋,但是我从来没有和别人聊过两小时那么久,录到后面,我就像漏气的气球一样,慢慢瘪了下去。

七月初拿到剪好的第一期,觉得可以再优化一下,所以就自告奋勇再剪一遍。花了接近十个小时,剪掉了很多「呃」、「嗯」、「对」、「然后」、「所以」……在这个过程里也发现不少自己说话上的毛病。

这一期上半部分聊了我从学习 Flask 到成为维护者的经历,这些在 19 年的 COSCUP 演讲简单介绍过。下半部分关于自由职业本来有不少内容想聊,但是因为说太多话有点累,所以有一些漏掉的话题就没有再提出来。录完的这些天有时会突然想到一些很有趣但忘记说的事情,偶尔还会想要不要再约着录一个补丁,也计划着写文章作补充。另外这一期虽然聊到了 FastAPI,但我对它了解并不多,如果有机会的话,以后还想再录一期详细聊聊 FastAPI 和 APIFlask,或是再聊一聊技术写作、翻译和演讲。

最后,如果你用过 Flask,欢迎来填写这个 Flask 用户调查问卷。关于捕蛇者说播客的更多信息,可以访问它的主页Twitter 了解。

下期:和捕蛇者说聊聊自由职业

开始翻译 Flask 文档

我在上周开始策划 Flask 文档翻译的事,制定了大致的翻译流程,创建了翻译协调仓库翻译模板仓库。中文翻译作为这个流程的试水项目,在上周末正式(静悄悄)启动。

blank

启动中文翻译项目的第一步是把 logo 里的标语「web development, one drop at a time」翻译成中文,这让我想起来一个也许冷也许不冷的冷知识。很多人知道 Flask 的名字是对 Bottle 的双关语——另一个容器/另一个 Python Web 框架。那为什么 Python Web 框架爱用容器做名字?其实是因为这些 Python Web 框架都是基于 WSGI 规范实现的,而 WSGI 不知从哪天起流行被读作 Whiskey(威士忌),所以这两个 Python Web 框架才叫做 Bottle 和 Flask,所以才有「Web 开发,一次一滴」。

欢迎在这些 discussions 中分别投票选出最佳翻译词汇、中文 logo 字体和中文标语。

回到正题。如果你对 Flask 足够熟悉,并且擅长翻译,欢迎参与进来!翻译通过 GitHub 进行协作(greyli/flask-docs-zh)。除了翻译文档,我们也需要有丰富翻译经验的朋友来审阅提交的翻译,欢迎在 GitHub 上关注(点 Watch 按钮)这个项目以接收新增翻译提醒。

下面是参与翻译之前要了解的三件事:

  1. 请务必完整阅读 Contributing Guide 了解翻译流程,然后阅读这个 issue 了解翻译要求。
  2. 需要强调的是,完成一章的翻译要提交两个 PR:第一个 PR 在 README 中对应的章节条目后添加自己的用户名以认领章节;第二个 PR 翻译对应的 .po 文件并勾选完成的章节条目。先认领,再翻译,一次只认领一章。
  3. 不要改动任何 ReStructuredText 标记、变量/类/函数/方法名称、URL 等。

如果有其他问题和相关想法,请创建 discussion 发起讨论;如果对翻译流程和项目设置有改进建议,或是发现了翻译错误和笔误,请创建 issue 反馈。

这个项目在后期会转移到 FlaskCWG 组织,并在翻译完成后链接到 Flask 官方文档。