分享下自己的开源项目 Pywss - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
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
CzaOrz
V2EX    Python

分享下自己的开源项目 Pywss

  •  
  •   CzaOrz
    czasg 2024-01-18 17:47:15 +08:00 3081 次点击
    这是一个创建于 634 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Pywss

    Pywss (发音 /piwaz/,类似 p~whys )是一个轻量级的 Python Web 框架,它基于 Python3.6+ 特性构建。

    与 Flask 、Django 等主流框架不同的是,Pywss 的底层并没有实现 WSGI 接口协议。 其编程风格也更类似于 Gin 、Iris 等框架,因此对于熟悉这些框架的开发者来说,Pywss 是一个非常值得探索的项目。

    其关键特性有:

    • 简单:拒绝海量参数,减少心智负担。了解上下文 pywss.Context 即刻启程。
    • 快速:引入线程池机制,减少并发场景下线程创建/销毁开销。
    • 优雅:ctx.next 真的太优雅了。如果你也和我一样喜欢,那我觉得这件事情,泰裤辣!!
    • 标准化:集成了部分 OpenAPI ( Swagger )能力,方便开发者快速生成 API 文档并进行调试。
    • 支持 WebSocket:开箱即用的 WebSocket 能力。
    • 接口测试:开箱即用的 API 测试模块,不启动服务也能测试接口功能辣!

    Demo

    import pywss import time import random def logHandler(ctx: pywss.Context): startTime = time.time() ctx.next() cost = time.time() - startTime print(f"{ctx.method} - {ctx.route} - cost: {cost: .2f}") def helloHandler(ctx: pywss.Context): ctx.write({"hello": "world"}) app = pywss.App() app.post("/hello", logHandler, helloHandler) app.run() 

    最后

    有想学习底层 socket 编程 / web 框架开发 的同学,可以关注学习学习,源码也算是简单易懂~

    作者已经在公司内部多个项目正式应用 Pywss ,所以不用担心没人帮你踩坑~

    最后求 star~

    6 条回复    2024-01-19 17:30:29 +08:00
    nicoljiang
        1
    nicoljiang  
    PRO
       2024-01-18 18:05:01 +08:00   1
    赞一下。
    abersheeran
        2
    abersheeran  
       2024-01-19 09:59:27 +08:00
    确实有自己的风格,不过我挺好奇的,下面这么写不是更 pythonic ,心智负担更小吗?用一个 ctx 进行 write 和 set_status 感觉比较难定位最终到底用的是哪个 response 。

    def home():
    return "<html></html>"

    def api(p: Annotated[str, uery(...)]) -> Annotated[Any, JSONResponse[200, {}, ResponseModel]]:
    return {"key": "value"}
    CzaOrz
        3
    CzaOrz  
    OP
       2024-01-19 14:29:36 +08:00
    @abersheeran
    不管是通过 return 返回数据,还是通过 write 指定响应数据,我感觉都很不错。我列举一个爬虫场景:

    ```python
    def spiderHandler(ctx: pywss.Context):
    # 参数校验
    try:
    req = SpiderRequest(**ctx.json())
    except UrlInvalidSchemaErr as e:
    loggus.error(f"url 参数异常: {e}")
    ctx.write(HttpResponse(code=99999, message=f"{e}").dict())
    return
    except Exception as e:
    loggus.error(f"请求参数异常: {e}")
    ctx.write(HttpResponse(code=99999, message="请求参数异常").dict())
    return
    # 爬虫服务
    try:
    data = spiderService.get(req)
    ctx.write(HttpResponse(code=0, message="ok", data=data).dict())
    except Exception as e:
    loggus.error(f"爬虫服务异常: {e}")
    ctx.write(HttpResponse(code=99999, message=f"爬虫服务异常").dict())
    ```

    在这个例子中,不管是 retrun 还是 ctx.write 应该都能写的很漂亮。

    我文档中所说的心智负担,主要是很多框架参数、模块,多到记不住,,有时太久不用,想实现一个简单的功能,可能还得对着文档调试半天。。
    CzaOrz
        4
    CzaOrz  
    OP
       2024-01-19 14:30:47 +08:00
    回复不支持 markdown 嘛~
    ```
    ==
    ```
    abersheeran
        5
    abersheeran  
       2024-01-19 15:22:20 +08:00   1
    @CzaOrz #3 一个小建议,用 h11 去处理 http 协议,这玩意有很多边缘情况,靠你一个人穷举是不现实的。

    像 Starlette 、baize ,这种都只有很少的参数和模块。flask 、django 它们参数和模块多,主要原因就是它们是社区维护,喜欢加一些极少用到、而且很容易让用户自己实现的功能,我严重怀疑是有些人为了刷 PR 。
    CzaOrz
        6
    CzaOrz  
    OP
       2024-01-19 17:30:29 +08:00
    @abersheeran 这个项目也算是我个人学习的阶段性产物,帮助我进一步学习了解 socket 、http 、websocket 、openapi ,包括一些架构上的思考等。确实很多标准都没有支持,或许将来遇到了就顺手 fix 了~
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5592 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 08:08 PVG 16:08 LAX 01:08 JFK 04:08
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86