作者归档:李辉

代码厨房开源松 x PyCon China 2024

活动已结束,回顾文章见这里:https://codekitchen.community/t/topic/1372


七月我们突破了屏幕的限制,在戴尔五角场办公室举办了第一次线下代码厨房开源松。而这一次开源松 Sprint 6 我打算在 11 月 23 日举办的 PyCon China 2024 大会里办一场开源松。没错,一场面向 Python 爱好者的开源松!

开源松!?

开源松(Song of Open Source)是代码厨房社区自造的词语,可以大概理解为开源黑客松,但是又不必那么 hack。只是一场开源爱好者互相交流和共同参与开源项目的聚会活动。我们希望借助这个活动来鼓励和帮助大家参与开源项目、推动开源项目发展、孵化新的项目 idea。

如果你从来都没有参与过开源项目的话,这次活动也许会是你开源之路的第一步。你会认识其他喜欢编程和开源的朋友,和开源项目维护者们交流,顺便提交第一个开源贡献。

PyCon China 2024 x 代码厨房开源松

开源松活动在大会下午开始,你可以在现场找到开源松会场指引标识,或者到代码厨房社区展台询问。如果打算参加活动,记得在报名大会时勾选相应的选项。会场内会设置三个活动区域:

  • 养成区:给没有参加过开源项目的新手提供科普和指导
  • 发电区:用爱发电的地方
  • 休息区:代码写累了?来和其他开源爱好者聊天吧

顺便也欢迎来代码厨房展台玩。我们为还没开始工作、或者刚刚被裁的朋友准备了「Python 八股文面试题挑战」……通过挑战的话可以体验现场拿 offer 的感觉。

有哪些项目可以参与?

在其他项目报名之前,我们已经准备了两个代码厨房社区项目:

  • FineWeather:一个 Vuejs+Python 实现的网络相册

不管你喜不喜欢拍照,肯定有一堆照片存在某个地方。有没有想过摆脱商业公司的限制,自己部署一个在线相册?放上自己最喜欢的照片,自己的数据自己管理。一起来打造一个完美的开源相册程序吧。

下面是项目作者 Allen 部署的相册实例

新增项目:

  • PDM – Python 包和依赖管理器
  • pyecharts – Python ECharts Plotting Library
  • UtilMeta – Python 渐进式元框架

基于 Flask 实现的 Web API 框架,集成了 marshmallow、webargs 等项目来让 Web API 开发更加简单。我们在计划项目的 3.0 版本,有很多有用的功能可以加入。完成了大半的文档翻译项目也等待一个人来再推进一步。

如果你有自己的 Python 开源项目,欢迎报名参与!作为项目维护者,你需要完成这些事情:

  • 准备三个不同难度等级的任务
  • 在现场介绍项目和任务
  • 指导参与者完成任务
  • 准备小奖品(可选)

报名方式:在代码厨房社区置顶贴留言,或是通过下面的表单报名:

https://jsj.top/f/CscvKZ

你需要准备些什么?

除了了解 Git 基本用法,你还要会一点 Python。有一台充电器还找得到的笔记本电脑。还有一点点的开源热情。

如果你不仅仅想要来做开源项目,那么可以带一点其他的东西来。比如一个关于你自己项目或其他经验的五分钟分享、新项目的 idea……尽管自由发挥。 如果你有其他想法和建议,欢迎留言。

开源松/大会报名

这次开源松将在 PyCon China 2024 内举办,因此报名大会即可参与:

https://hdxu.cn/g77s

一辆自行车多久会被偷

已经很久没有真正锁车了。今天终于决定扔掉车锁,想看看哪天车子会被偷。如果没有人偷,说明我的车子太破,根本就不会被偷,那每天上锁岂不是多余?如果被偷了,那我就买一辆公路车。这样就可以像通勤路上飞过我身边的人那样,撅起高傲的屁股,让齿轮发出好听的声音。

写到这里就去豆瓣翻了下这部《偷自行车的人》。我在若干年前标记时写道:「纯粹的电影。平实、有感染力,这他妈才是现实主义啊。餐厅吃饭那段真让人心酸。」。等车子被偷那天,我计划重新看一遍这部电影,然后回来更新这篇文章。

最近勉强算是把书写完了,可以放下一颗心来。但是又好像没有完全写完,因为还要处理读者试读留下的评论,以及编辑还没发来的审稿建议。接下来有太多新的计划可以展开,不过让心再次悬起来之前,不如多停留一会儿。与此同时,CS2 的游戏时间记录即将突破 300 小时……


11/4 更新:被偷了。心情很复杂。错愕、后知后觉的侥幸突然中断、失去的难过混在一起,远没有想象得那么轻松。只是因为早上红绿灯晚了几秒,把车子停在了另一个不常去的地铁入口,晚上回来车子就不见了。事实证明,在上海杨浦,一辆没上锁的六成新自行车被偷需要七天。

夏天不是读书天

#清空草稿箱计划# 原文创建于 2023 年 6 月 24 日。

回上海的这一天上午,我需要去附近的乡里走一趟。

桃市附近多了一家养蜂场,叫小武养蜂场。风景区附近的围墙上有一些新的标语。下一句是“仰望星空展未来”,上一句你肯定猜不出来——“一心一意跟党走”。电信营业厅戴着口罩咳嗽的店员,提醒我新冠还没有过去。天气很晒,但风很凉爽,耳机里是 Vampire Weekend 的那张《Father of the Bride》,一张专辑刚好够打一个来回。在这样的街上,太阳浇灭了所有购物的冲动。更何况这里没有城市里的那些陷阱——没有音乐,没有香氛,没有创意十足的广告,没有精致完美的女人在墙上直勾勾地想把你看穿。只有奄奄一息的老年人和中年人在发烫的遮阳棚下玩手机和打盹。我还是想买一些东西,只想买一些必需品。去两元超市给小巴买了一个橡胶球,两块钱。不过每次送给它的球都玩不了几天——要么被它咬烂,要么被邻居家的狗偷走。然后去隔壁的超市买了一瓶矿泉水,也是两块钱。

从上海回家是在父亲节前一天,我在火车上看完了安妮·埃尔诺的《一个男人的位置》。听了《昨日之海》的某期播客后买了这本书和《一个女人的故事》。某一天我把《位置》读了个开头,然后放在我的床边。一放就是许多天过去。这种情况多了,床头柜变成书柜,堆栈变成积木。果然旅途才是最适合阅读的环境,单程就可以读一本书。

这本书的阅读体验像是某个人的博客,一个为爸爸写的博客。很多人小学的时候都会写一篇《我的爸爸》这样的作文。成年之后,直至爸爸去世,却很少有人再写一篇《我的爸爸》。我突然想到,世界上某个人也许会在爸爸的葬礼上读他写的第一篇《我的爸爸》:我的爸爸不抽烟,也不喝酒。他戴墨镜的样子很酷。他告诉我酷有很多种,外表酷只是其中一种,做事情认真也是一种酷,帮忙别人也是一种……

读的过程中,我不断想起从小到大我熟悉的那些“大人”。想起每一次的婚礼和葬礼,那些家族里的男人们。想起他们在这个世界上的位置,以及他们为了把下一代推离到更远的位置的努力。他们从没有想过有另一条路可走,总是像个硬汉。他们快乐吗?他们的孩子快乐吗?也许从没有人问过他们。祝他们夏天快乐。

干杯

最近花了很多时间在准备一个年会节目。整个过程记录到了下面的短片:

https://www.bilibili.com/video/BV1Re411E7uX

整体的设计是这样的:节目一开始会放这个短片,当画面放到走向年会会场的时候,我们就真的入场。入场后画面会是滚动的歌词(上面的视频里已经被替换为实际的演出画面)。滚动的时长就是演唱的时长(三分钟),唱完刚好会出现演职员表。

blank

整体基本按照计划执行,唯一的遗憾是前面的部分因为网速原因有些卡顿,卡点全都没对上。除此之外还有很多乌龙:话筒放错了位置,导致我要仰头唱,Qingfeng 要低头唱。上场前被谁碰了一下变调夹,导致六弦有点松。演出上午我还在弹错和唱错,反而正式演出却没出问题。再往前一天,还在纠结吉他收音和话筒支架问题。再往前半个月,因为高音唱不上去、吉他和弦切换不熟练焦虑,嗓子疼了好几天。虽然问题很多,最后呈现的效果还不错。

短片里很多穿帮镜头也没有时间打磨,比如上场前和演出时的衣服不是同一件。因为大家都在上班,经常随便抓一个没开会的同事帮我拍视频,大都只拍了一两条就用了。本来还计划了一些长镜头和分镜画面。因为时间有限,没法一一实现。

很开心的一段经历!剪短片、排练、演出都很快乐。关掉会场的灯,大家一起看我做的视频的感觉,让我想起来大学那次做的幻灯片。也许我应该去逐梦演艺圈 :P

最后贴上同事 Steve Wang 年会后写的诗(词)作结:

御街行

岁末寒风冬日暮,春将至,来时路。
久别年会今时归,料定狂欢无度。
铃鼓轻拍,沙锤细响,吉他低吟谱。
深度影视当乱舞,几月天?六点五。
彩排剪辑需几步,八仙各显其术。
用心数只,人生几处,今宵惟一赋。

 

Flask 已死,FastAPI 永生

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

blank

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

blank

咳咳,说回正题,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

蚊子偷看我写书

家里太舒服,所以决定去图书馆写书。起得太晚,到达已经是十一点半。写了半小时,午饭时间到。想找到特定颜色的共享单车,结果一直找到吃饭的地方。

午饭后脑袋昏沉,睡了一觉,压得手臂发麻。醒过来两眼失神,无法聚焦。感觉越来越热。不知道为什么 VPN 节点全部失联,换了备用服务器,然而命令行还是无法连接 GitHub。打开几个网页,但是早已没有兴致解决这类问题。政府可真是神通广大,随随便便就浪费掉我三十分钟。感觉越来越热,决定打包离开。

图书馆有两个天井,四个位置都有人。徘徊了两圈,终于等到一个空位。今天风很凉爽,一年里少有的好天气。树叶在旁边沙沙地响。下午四点零八分,开始写书。四点十分,发现一只蚊子在附近转来转去,好像要偷看我的书稿——我那写了两年还是一团浆糊的书稿。经过一阵周旋,四点十一分,蚊子终于被我杀死了。

如果没有工作的话,我可以一天一天地在城市里游荡。从一个座位到另一个座位,从一栋建筑到另一栋建筑。直到把想做的事情做完,直到我对这个地方感到厌倦。如果没有鬼魂,这个世界就太没意思了。如果没有自由的人,那这个城市还有什么希望?

P.S. 距离我信誓旦旦宣称的交稿时间已经过去 5 天,距离跟编辑承诺的交稿时间还剩 25 天,距离合同上的交稿日期还剩两个月满一周年。

代码厨房社区欢迎你

代码厨房是一个面向编程和开源爱好者的社区。社区的主体是坐落在 codekitchen.community 的论坛。这个论坛的前身是创建于 2019 年 1 月 11 日的 HelloFlask 论坛(HelloFlask discuss!),因为论坛服务器一直在海外颠沛流离,所以访问起来并不是很顺利。最近把论坛以及 628 位 HelloFlask 原住民一起搬家到了香港,改头换面变成代码厨房社区。

「代码厨房」最早是我创建的公众号的名字。同一时间注册了 daimachufang.com,想要在这个网站上放些什么已经不得而知。后来公众号一再改名,代码厨房已经不见。再一次想起来是在去年 10 月, 29 日心血来潮去参加中国开源年会的开源集市。作为现场唯一一个个人展位,我带去了两个项目。一个是方学园,另一个便是代码厨房俱乐部

blank

出发前一天为代码厨房俱乐部更新了 daimachufang.com,也就是下面的样子:

blank

俱乐部现场成立,现场报名。报名单上收集了十个人,最后筛选到五个。算上我自己,六个人在一年内完成了四次聚会。大家互相带来很多新想法和思考,也玩得很开心,但逐渐有点忘记最初想要做什么。于是,在 2023 年的 10 月 22 号,最后一次聚会,大家回到了报名的地方——微软 Reactor。我在那里重新介绍了代码厨房社区的构想

代码厨房的核心构想是「一个让人快乐和放松的编程社区」,主要的板块是:

blank

不论你是当下、曾经还是未来的编程爱好者,都可以加入我们。代码厨房欢迎你!

APIFlask 2.0 版本发布

一边上班一边赶工做开源项目真是太累了。更不用说还要一边焦虑写书的进度。不过这次 2.0 版本基本把想做的功能都完成了,剩下两个大的功能(为蓝本拆分单独的 OpenAPI Spec、解耦 marshmallow)实在是没精力加进来了,只好放到 2.1。

APIFlask 2.0 版本的 codename 是 Gongqing(年初我从五角场搬到了共青森林公园旁边。没错,1.0 版本是 Wujiaochang)。

回到正题,这次最主要的一个变动(breaking change)是把所有 input 装饰器的参数改成了关键字参数。

@app.post('/pets')
@app.input(PetQuery, location='query')
@app.input(PetIn)  # equals to app.input(PetIn, location='json')
def create_pet(query_data, json_data):
    pass

关键字参数的名字默认是 {location}_data,通过 arg_name 参数可以自定义。这个改动让我删掉了很多 hack Flask 的代码。推动这个功能在上游 webargs 实现,所以不用加代码在自己这里。再加上一些改动已经在 Flask 实现了,又删掉一些。非常轻松。理想情况是,文档越来越多,代码越来越少。

如果你感兴趣的话,下面是 2.0 版本的详细内容:

 

共青森林公园吉祥狗

下雨天和女朋友去共青森林公园散步。因为只有一把伞,所以不得不在中途避了一刻钟雨。我们聊到古代人在这种廊桥避雨,可能一避就是一整天。她说书生一般会在这里邂逅狐妖,然后相谈甚欢。我说然后雨停了就各自走了,再也没有见过。没有烂俗的故事,不给后人拍电影的机会。

雨天的共青森林公园人很少,让人放松。雨稍停的时候,遇到两只非常有戏剧效果的狗。想说服它们放下安逸的生活去逐梦演艺圈或是戏剧圈,它们不为所动。尽管从一路中分到底的毛发可以看出来它们被淋得很惨,但它们说喜欢这样,喜欢这么简单的生活——每天在公园里探险,淋雨,晒太阳,吃游客供奉的食物,汪汪,汪汪……我把放在包里随着我颠沛流离已经变得稀碎的饼干送给了它们。

建议园方让它们俩做「共青森林公园吉祥狗」(当然前提是它们愿意),取代那两只淋多久也不会中分的松鼠。

P.S. 推荐雨天的共青森林公园。记得要穿拖鞋。


blank
blankblankblank

自行车叨位去

最近开始骑车上班了。 单程 20 分钟左右,每周去公司三天的话,一周就可以获得 120 分钟运动时间。在此之前,我会坐九点二十五分出发的那班公交,只需要 15 分钟。不过我经常在九点二十一分才出门。这样下去,迟早有一天会有公交车弃我而去、而我喘着粗气远远目送的画面出现。

在中原城市广场附近,有一个很大的路口,和一个时间超长的红绿灯。我经常在那里等红灯变绿的时候发呆。在路上我会听根据播放历史生成的随机歌单,上一首也许是周杰伦,下一首可能是巴赫。有一次我经过那个路口,耳机里刚好播放到拉赫玛尼诺夫第二钢琴协奏曲的第一小节,突然就很想哭。那个时刻时间变得很缓慢,那个路口也变得更大了,像是一面湖。我漂在上面,风推着我走,周围的人都是我最熟悉的朋友。我们一起在湖面上荡着,吹着凉爽的风,晒着九点多的太阳,又或者是黄昏时柔和的太阳。这一天就到这里多好。

骑车上班的时候,生活又开始流动起来。虽然绕来绕去无论怎么组合,也都只有那么几条路。但是因为背景音乐不同,每天都像是新的电影。到了公司我并不直接进去,而是沿着路继续往前骑,再绕江湾体育场一圈,这一圈让我心情平静。如果不够平静,那就再多一圈。

春天快乐

除了一堆药,医生还开了一个颈托,三百五十块。付款前犹豫了两秒。果然,淘宝只要两百块。回家前路过体育学院旁边的二层破败小楼,看到有小吃摊就拐了进去。躲开一地的猫,发现只有炸香肠和炒饭炒面。虽然炒饭和炒面有一堆排列组合,但我还是走掉了。没有车篮不说,买了去哪里吃呢,回到家估计要冷了。过去之前心里想着的是鸡蛋灌饼和火烧,至少也是手抓饼。

经过大润发,看到高大的樱花树,也可能是山茶树(总之是会开红色花朵的某种树)。想起来再往前是民星公园。没有犹豫,径直转了过去。小小的公园,还算精致。树很多,很密。有些开了花,有些发了新的叶子。这个时节,如果不开花,也不繁茂,春天会责怪你的。七拐八拐转了一圈,除了两三个带着孩子的中年男女,其他都是老年人。穿着精致的、化着浓妆的、悠闲的、昂扬的老年人。尽管在不可避免地走向衰败,但这个公园和春天都是他们的。可是过了几十个春天,不会感到腻烦吗?围着这小小的公园,一圈又一圈,不会感到疲倦吗?也许我不该逆时针走,这样他们就不用被我观察,我也不用生出那么多混乱的念头。

公园中央是一团浑浊的湖,长满了各种水草。没有鸭子。鸭子大概都飞去看海了吧?现在天气这么好,至少也要去共青森林公园里度个假。湖边一圈围栏上挂着三个人——白手套先生在压腿,白口罩小姐在拉伸胳膊,另一个呢,是我,穿着白色的球鞋在写日记。

说到底只是不想回家。期待有另一件计划之外的事情发生。期待迎面突然走来一个人,拉着我的胳膊说,快跟我走,没有时间解释了……什么?合什么 PR!?等到第二个 code owner 看到之后 approve了 CI bot 会自动 merge 的……&%¥%……

好了,该回家了。白手套先生和白口罩小姐,春天快乐!