IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    在py3里同步/异步混合使用 httpx 调用

    est发表于 2023-07-05 17:39:54
    love 0

    比如开发需求是请求一个 http API,得到数据,解析一下返回,那么一般的做法是封装一个方法,比如

    import httpx
    
    
    def get_sth(p1, default=MY_VAL):
        # network
        r = httpx.get(API_URL, params={'t1': p1})
        # parsing
        res = r.json().get('my_key') or MY_VAL
    

    但是如果想在 async/await 里用这段代码,就得改成

    import httpx
    
    
    async def get_sth(p1, default=MY_VAL):
        # network
        with http.AsyncClient() as client:
            r = await client.get(API_URL, params={'t1': p1})
        # parsing
        res = r.json().get('my_key') or MY_VAL
    

    注意其中 def get_sth() 也必须改成 async def get_sth 。这就是所谓 async/await 传染性

    这个时候,如果你想把这块代码抽象出来,让同步/异步的库都能调用,我在最近重构里找到一个最佳实践:

    import httpx
    
    
    def get_sth(p1, default=MY_VAL):
        r = httpx.Request('GET', API_URL, params={'t1': p1})
        r.parse = lambda x: (x.get('my_key') or MY_VAL)
    
    # 同步调用:
    with httpx.Client() as client:
        r = client.send(get_sth())
    r.request.parse(r.json())
    
    # 异步调用:
    async with httpx.AsyncClient() as client:
        r = await client.send(get_sth())
    r.request.parse(r.json())
    

    思路是 逻辑和 transport解耦,也是某种意义上的 Sans-IO 了吧?



沪ICP备19023445号-2号
友情链接