Diagram as Code -- 用 Python 画框架图

最近注意到一个很有意思的项目 Diagrams, 用 Python 代码来绘制架构或流程图, 以前基本用 Gliffy 来画。继一系列 X as X, 如 PaaS, SaaS, IaaS, CaC(Configuration as Code), IaC(Infrastructure as Code) 等,Diagrams 喊出了 Diagram as Code 的口号。其实,在这之前, Markdown 就做了许多 Diagram as Code 的事情,也许更准确说是 Diagram as Document。

熟练的程序员大概不喜欢用可视化设计器来生成 GUI 代码,那会让代码变得极不简洁,而是直接写,眼中看到的是代码,头脑中即时产生映像。

Diagrams 就是这样一款写 Python 代码产生架构或流程图的库,它绘制的架构图支持主要的云服务提供商,如

  1. 知名的(本人认为的): AWS, Azure, GCP, IBM, DigitalOcean, AlibabaCloud, OCI(Oracle Cloud Infrastructure, 不是 Open Container Initiative), OpenStack
  2. 刚了解到的: Google 的 Firebase, Elastic(ElasticSearch 出品方也有自己的平台), Outscale
  3. 以及应用平台 K8S, Saas 和 OnPrem 中的元素
  4. 通用元素,编程语言及流程图,还能定制自己的节点图

阅读全文 >>

学习 Airflow 第一篇章

Airflow 起初是由 Airbnb 开发的, 用于调度和监控工作流的平台,后来开源了, 并于 2019 年 1 月成为了 Apache 的顶级项目。它是用 Python 编写的,管理的工作流是有向无环图(DAG - Directed Acyclic Graph), 这能满足绝大多数情况下的需求。

顺带插一句,Airflow 用了与 Google Photos 极其相似的 Logo,不知算不算侵权。

说到工作调度,头脑中很快会掠过 Cron, 计划任务, Quartz, Spring Schedule, 和 Control-M。除了商业的 Control-M 有调度和监控工作流的功能外,其他的基本只用来调度任务,监控全靠自己的日志。

还有一个类似的工具是由易观贡献给 Apache 的 DolphinScheduler, 它处理的也是 DAG 工作流,用 Java 实现的,所以体量大,硬件要求会高些。它的工作流的创建是通过 Web UI 可视化界面完成的,对程序员来说不那么友好。奇怪的是, 作为 Apache 旗下的项目,项目首页面是中文的,启动后控制台默认界面也是中文的。

而 Airflow 功能就厉害了, 它可动态管理工作流,易于扩展,可集群化进行伸缩,更有一个漂亮的 UI 用于实时监控任务。基于以上特性 Airflow 是很适于执行数据的 ETL(Extract, Transform, Load) 操作的。

这么好的开源产品, 免不了又被 AWS 盯上了, 以 Amazon Managed Workflows for Apache Airflow(MWAA) 服务进行出售,费用还真不菲。AWS 创造性的以 vCPU 数量,DAG 数量限制进行分层次进行收费,远比自己启动一两个 EC2 实例部署 Airflow 贵的多。但 MWAA 有个方便的特性就是 DAG 文件可以放到 S3 中自动部署,相信自己部署的 Airflow 也能进行扩展而从 S3 加载 DAG。 阅读全文 >>

Python 3.10 关键新特性

Python 3.10 于 2021-10-04 发布,至今已大半年,目前 AWS 的 Lambda 尚未直接支持,但用 Docker 镜像的方式使用 AWS Lambda 是可以使用 Python 3.10。Python 一年一发布的节奏比 Java LTS 还紧密。下一个版本 Python 3.11 预计在 2022-10-03 发布。在学习 Python 3.10 之前先回顾一下 Python 3.7, 3.8, 3.9 的特性(不想关心之前版本的变迁可直接跳跃到下方的 Python 3.10 新特性去)

Python 3.7 所带来的新特性

  1. breakpoint()
  2. 数据类(@dataclass)
  3. 类型提示强化和延迟注解求值
  4. 时间精度的提高
  5. 保证字典的顺序
  6. async 和 await 成为关键字
  7. asyncio.run() 简化事件循环
  8. 上下文变量(ContextVar) - 可实现 ThreadLocal 和 SLF4J 的 MDC 功能

阅读全文 >>

Python 中泛型的实现

在学习 Python 3.10 新特性时,其中有个类型别名(TypeAlias), 所举的例子是

StrCache = 'Cache[str]' # a type alias
LOG_PREFIX = 'LOG[DEBUG]' # a module constant

可写成

StrCache: TypeAlias = 'Cache[str]' # a type alias
LOG_PREFIX = 'LOG[DEBUG]' # a module constant

这让 StrCache 更像是一个类型别名,而不是一个看起来明显就是 Cache[str] 的字符串变量(实际上它确实是)。

本文不在 TypeAlias 本身,而是从 Cache[str] 能看出 Python 似乎也能支持像 Java 那样的泛型, 就像 Python 内置支持的 List[str] 或 list[str] 那样。

那么来看 Python 怎么去实现一个只能放入字符串的  Cache[str] Cache, 而不能放入别的类型。 阅读全文 >>

Python 函数重载实现

Python 不支持函数重载,在同一个模块中声明同名方法不会报错,只会不停的覆盖,无论参数个数是否不同,最终只会保留最后一个函数

输出 阅读全文 >>

Python 3.9 新特性回顾

Python 3.10 虽已于 2021/10/04 发布,但目前主要使用的 Python 版本仍然是 3.9。之前有两篇介绍了 Python 3.7 和 3.8 带来的新特性

  1. Python 3.7 所带来的新特性
  2. 体验一下 Python 3.8 带来的主要新特性

于此,再补充一下 Python 3.7 和 3.8 各自的发布日期是 2018/06/27 和 2019/10/14。Python 3.9 是在 2020/10/05 发布,由此看出 Python 是每年一发布。

每个版本的主要新特性就是它们的亮点,不关注新特性也就不能很好的掌握这种语言,除非是直接使用汇编或字节码指令,他们的变迁比较缓慢。

对于以 Python 3.9 为现阶段基准版本使用来说,更有必要了解一下 Python 3.9 的新特性,不然别人一见代码就仿佛是以二战时的打法应对现代战争。

Python 3.9 主要有哪些新特征呢?总结起来就是

字典的更新/合并, 字符串新增删除前/后缀的方法,datetime 支持时区了, Executor.shutdown() 可取消未执行的任务,类型提示可直接用 list[str], dict[str, int] 这样表示泛型 阅读全文 >>

流畅的 Python 读书笔记(四)

Python 的函数是一等对象

因为它符合编程语言理论家对 "一等对象 -- first-class object" 的定义

  1. 运行时创建
  2. 可赋值给变量或数据结构的属性
  3. 能作为函数参数
  4. 能被函数返回 

依据这种定义,还有我们最为熟悉的 JavaScript 的函数也是一等对象,Java 的函数都是依附于类或对象存在的,不是一等对象。

Python 的文档字符串(docstring) 是放在模块,函数,类中的第一个纯字符串。可用单个引号(单引号或双引),通常因为有大段的文字会用三引号的字符串,比如

def foo():
    '''doing nathing'''
    pass

代码中用 foo.__doc__ 能查看到到 docstring,或用 help(foo), doc(foo) 都能输出包含 docstring 的信息 阅读全文 >>

流畅的 Python 读书笔记(三)

书中的数据结构还差文本和字节序列那一章未阅读完。Python 的 str 是 unicode 类型,编码在应用方面基本上就是 .decode(), .encode() 方法的调用,默认编解码时用 UTF-8 就行,差不多就不用太深入了。

Python 的 bytes 和 bytearray 中的元素都是介于 0 ~ 255(含) 之间的整数,即一个字节,bytes 的切片是 bytes, bytearray 的切片还是 bytearray。bytes 和 bytearray 的输出(__repl__) 

  1. 可打印的 ASCII 码以 ASCII 字符贵
  2. 特殊字转义,如 \r, \n, \r, 和 \\
  3. 其他字符以十六进制转义输出,如 \xc3

像 endswith, replace, strip, translate, upper 等函数可以直接用来处理 bytes,如 阅读全文 >>

流畅的 Python 读书笔记(二)

继续啃这本略微有些旧的书,《Fluent Python》第二版出版在即,预计今年四月份,它将会讲解到更新版本 Python 的特性,书中有提到 Python 3.10。第一版读下来也不会是浪费时间的。

还是数据结构,现在来到字典,dict 是 Python 语言的基石,在它内部也被广泛应用,比如 type(globals()) 是个  dict, globals() 的内容有我们能调用的全局函数。如果在编程中不想创建新对象的话,dict 几乎能表述需要的数据结构。

dict 就是一个 hash 表,它是 collections.abc 下 Mapping 和 MutableMapping 的子类。和其他语言中的字典一样,dict 的 key 必须实现了 __hash__()__qe__() 方法,否则不能作为 key,比如 list 是不能作 key 的。两个key 的 hash() 相等的话,那么  key1 == key2, 反之不一定。所以当 __eq__ 依赖于可变状态就不要去实现 __hash__ 方法. 阅读全文 >>

配置 AWS Lambda Python Logging

通常在 Python 应用中简单的配置使用内置的 logging 是这样的

假如文件名为 test.py, 用 python test.py 执行后输出

2022-01-25 21:02:47,231 - INFO - test(<module>:6) - hello world

在 Lambda 中的现象

可是这同样的代码放到 AWS Lambda Python 代码中却不灵验了,logging.info() 将得不到任何输出。 阅读全文 >>