推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
abersheeran
V2EX  ›  Python

快速暴露 Python 函数作为 HTTP 服务

  •  
  •   abersheeran · Feb 18, 2021 · 6149 views
    This topic created in 2085 days ago, the information mentioned may be changed or developed.

    给算法岗擦屁股的人应该明白那种痛苦的感觉。为了解耦不同服务之间的程序,但又能像调用原生函数一样调用远程函数,我在过去写下了 rpc.py。用了一段时间之后,过年守岁的时候闲着没事花了一夜把 coverage 提高到了 100%,修了几个隐藏的小 bug,现在基本稳定。

    当然在造轮子之前我了解和使用过 grpc,怎么说呢……用起来挺蛋疼的。注册很麻烦,调用很麻烦,和其它服务配合起来也很麻烦。于是研究了一下 grpc 的原理,自己写了一个。

    由于是基于 ASGI/WSGI 这两个通用网关协议的,所以 HTTP 部分我就可以偷懒不处理了,用社区发展十几年的成果就行。你想用 HTTP/1.0 、1.1 还是 2.0,或者更激进点直接 3.0,都可以。Python 社区都有现成方案。

    基于这两通用网关协议,还有一个好处就是可以方便的和现有的 Django 、Bottle 、Flask 、Starlette 、FastAPI 、Sanic 、CherryPy 、Responder 、IndexPy……总之你能想到的支持这两个协议中至少一种的任何 Web 框架集成。也就是说,鉴权之类的工作,都可以用现成的。自己独立弄一个是不存在的,如果可以,这辈子我都不想自己造轮子了。

    序列化协议上是天然解耦的,目前只内置了 JSON 、pickle 和 msgpack,如果大家还有什么高性能序列化协议,可以提 PR 或者发个 Discussion 。当然,也可以只在自己代码里用,自己注册一个还是很方便的。

    基于 Type hint,可以自动转换类型,客户端在调用的时候还会主动检查类型。当然你不用 Type hint 也是可以正常用的。基于 Type hint 生成文档,似乎新框架都自带这个了哈哈哈

    https://github.com/abersheeran/rpc.py

    最后,造这个轮子的主要原因就是之前某项目大概有上千个函数需要批量转成可远程调用的接口。历史包袱、历史包袱。

    37 replies  •  2021-02-19 11:32:32 +08:00
    lipcao
    lipcao
    Feb 18, 2021
    1
    过年守岁的时候闲着没事花了一夜把 coverage 提高到了 100% 重点,要考
    yazoox
    yazoox
    Feb 18, 2021
    2
    不明觉厉!
    abersheeran
    abersheeran
    OP
    Feb 18, 2021
    3
    @lipcao 这算啥重点……

    @yazoox 用用就明白了。用法还是很简单的。
    jenlors
    jenlors
    Feb 18, 2021
    4
    楼主 github 头像本人?
    fy1993
    fy1993
    Feb 18, 2021
    5
    楼主 github 头像本人?
    musi
    musi
    Feb 18, 2021
    6
    看了下楼主的博客,这文采做程序员真的屈才了。多写写小说没准已经拍成电视剧了
    LengthMin
    LengthMin
    Feb 18, 2021
    7
    楼主也是 `index.py` 的作者
    madpecker009
    madpecker009
    Feb 18, 2021
    8
    这妹子好看啊
    abersheeran
    abersheeran
    OP
    Feb 18, 2021
    9
    @madpecker009 谢谢。

    @musi 哈哈哈,谢谢你看我的小说。

    @LengthMin 我是个取名废柴,要不是 web.py 被人用了,Index.py 估计会被我改成这个。
    jenlors
    jenlors
    Feb 18, 2021
    10
    看了楼主 blog,不去写小说可惜了。
    abersheeran
    abersheeran
    OP
    Feb 18, 2021
    11
    @long2ice 😀
    z740713651
    z740713651
    Feb 18, 2021
    12
    大佬太牛了 公司业务正好要用到 rpc.py 感谢大佬
    lewinlan
    lewinlan
    Feb 18, 2021 via Android
    13
    grpc 蛋疼是 python 的问题。换其他语言写 grpc 快乐的很
    abersheeran
    abersheeran
    OP
    Feb 18, 2021
    14
    @z740713651 用呗。我们也在用。

    @lewinlan 那就没办法了。
    no1xsyzy
    no1xsyzy
    Feb 18, 2021
    15
    所以说 Client.remote_call 和 RPC.register 有什么形式上的差别吗?
    完全可以用同一个函数去注册不是吗?
    Client 没必要分离吧(
    johnsona
    johnsona
    Feb 18, 2021 via iPhone
    16
    是不是要有负载均衡(乱说的 bushi
    silymore
    silymore
    Feb 18, 2021 via iPhone
    17
    开源工作相关的框架需要公司同意吗
    gscsnm
    gscsnm
    Feb 18, 2021
    18
    喜欢你的博客,请问下博客是自己开发的吗?还是用的什么?
    poplar50
    poplar50
    Feb 18, 2021 via iPhone
    19
    楼主 github 头像本人?
    jaswer
    jaswer
    Feb 18, 2021
    20
    楼主 github 头像本人?
    skies457
    skies457
    Feb 18, 2021
    21
    直接白嫖阿里云的 serverless 函数计算不香吗(狗头
    HashV2
    HashV2
    Feb 18, 2021
    22
    楼主 github 头像本人?
    cornetCat
    cornetCat
    Feb 18, 2021
    23
    楼主不是妹子吧
    看腾讯离职那篇提到有女朋友的
    XingWu
    XingWu
    Feb 18, 2021
    24
    为啥不用 serverless 呢
    abersheeran
    abersheeran
    OP
    Feb 18, 2021
    25
    @no1xsyzy ?如果你客户端代码和服务端代码写在一起了,直接调用不就好了吗
    abersheeran
    abersheeran
    OP
    Feb 18, 2021
    26
    @silymore 这不是我所在公司需要用到的。也不是工作期间开发的。
    abersheeran
    abersheeran
    OP
    Feb 18, 2021
    27
    @skies457
    @XingWu

    虽然我感觉你们完全不知道 rpc.py 和 serverless 的关系,但是恰好说对了它的用途。阿里云的函数计算原生支持 WSGI 接口,所以部署起来简直不要太简单。再配合另一个库 a2wsgi,可以把 ASGI 模式转成 WSGI,异步函数也可以一样一键注册。
    abersheeran
    abersheeran
    OP
    Feb 18, 2021
    28
    @silymore 想了想,所在的公司或许后续要上微服务,所以可能会被用到。但是直到目前为止,它仍然和我目前所在的公司没什么关系。我上班期间为这家公司造的轮子,是仅内部使用的,而且因为特殊的原因,就算开源了也没有通用价值。轮子造了快三个月,所以我才说不想再造轮子了。

    公司正在用的我的开源项目,唯一一个就是 Index\.py 。我入职前基本完工的,公司现在在用。

    详细解释一下免得让大家以为我把公司项目给开源了。
    no1xsyzy
    no1xsyzy
    Feb 18, 2021
    29
    @abersheeran 我的服务端会有一些缓存,而且是再请求上游服务器的,上游服务器效率非常差( ping 超 300ms,更不用说每组有意义的请求通常包含三个来回),但有更新推送,所以可以拿一个中间服务器作为缓存,根据推送重新获取信息。
    abersheeran
    abersheeran
    OP
    Feb 18, 2021 via Android
    30
    @no1xsyzy 原来如此。
    SethShi
    SethShi
    Feb 18, 2021
    31
    楼上怎么关注点不同呀. 老是关注楼主身份. 搞得点进来的人都无法专心看问题啦.
    ----

    话说这样, 和直接暴露一个 path 接口, 然后反射调用然后返回函数返回值有什么区别吗?
    abersheeran
    abersheeran
    OP
    Feb 18, 2021 via Android
    32
    @seth19960929 你的意思是直接用某个 web 框架创建接口?其实没有本质上的差别。只不过需要自己约定一个规则和序列化工具。对于生成器函数需要自己手写一下 SSE (目前为止好像没有几个 Py 框架支持这个)。

    我在写出 rpcpy 之前,都是用的 bottlepy 作为代替。但 web 框架的大部分功能其实是用不上的,所以效率上可能稍差一点。

    用 web 框架手写更自由,也更可控。不过代码量就……
    SethShi
    SethShi
    Feb 18, 2021
    33
    是否支持其他语言客户端? 如果支持, 怎么保证序列化每一种语言的实现. 去用 ProtoBuf ?
    如果只支持 Python 有专门的库把任意 Python 数据类型序列化成字符串. 然后客户端反序列化用就好了.
    todd7zhang
    todd7zhang
    Feb 18, 2021
    34
    2.7 老古董看到 typing 脑壳昏, 是不是应该学一学这个 typing 了
    abersheeran
    abersheeran
    OP
    Feb 18, 2021
    35
    @seth19960929 现在内置的三个序列化器,JSON 、Msgpack 都是跨语言的。JSON 自然不必多说,Msgpack 也有很多语言可以支持。ProtoBuf 考虑过,不过没有好用的库,就作罢了。

    @todd7zhang 没事,不用 typing 也可以正常工作的。只不过有 type hint 的信息,功能更丰富一点罢了。
    NeilWang
    NeilWang
    Feb 19, 2021
    36
    "可以方便的和现有的 Web 框架集成。也就是说,鉴权之类的工作,都可以用现成的"
    楼主,你的意思是说 注册到 rpc.py 的函数,可以转换成 Flask 等 Web 框架的视图函数? Web 框架转 ASGI/WSGI 应用倒是很简单,不过没见过 ASGI/WSGI 应用转 Web 框架视图函数的。不知道我的理解对不对,有相关的例子可以提供吗
    abersheeran
    abersheeran
    OP
    Feb 19, 2021❤️1
    37
    @NeilWang 不能转视图函数。这里我说的是 WSGI/ASGI Application 组合。Flask 我不记得能不能 mount wsgi app,但是 Bottle.mount 可以,所以我猜 Flask 应该也实现了这个功能。具体的你可以去 Flask 社区问问。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2857 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 119ms · UTC 10:55 · PVG 18:55 · LAX 02:55 · JFK 05:55
    ♥ Do have faith in what you're doing.