0

我做错了什么?有解决办法吗?我是异步编程的新手;这很令人困惑。

# myFile.py
import httpx
async def ping_api():
    async with httpx.AsyncClient() as client:
        sleep(1)
        print('right after with')
        sleep(1)
        print('before await')
        sleep(1)
        response = await client.get(url, params=params)
        sleep(1)
        print('after await')
        sleep(1)
        data = response.json() # what's wrong here?
        sleep(1)
        print('after json')
        sleep(1)

    return data



# myFastAPI.py
from myFile import ping_api
@app...
async def main():
    data = await ping_api()

 

结果错误:

before await
after await
C:\Users\foo\grok\site-packages\httpx\_client.py:1772: UserWarning: Unclosed <authlib.integrations.httpx_client.oauth2_client.AsyncOAuth2Client object at 0x0000021F318EC5E0>. See https://www.python-httpx.org/async/#opening-and-closing-clients for details.
warnings.warn(
after json

上下文管理器不应该自动关闭连接吗?这是图书馆中的错误还是我遗漏了什么?这个 response.json() 是原因还是其他地方的问题,但此时恰好“打印”?

https://github.com/encode/httpx/issues/1332

4

1 回答 1

0

找到原因:问题实际上是我使用了另一个库(tda-api)。在这里找到答案;“不要尝试在每个令牌文件中使用多个客户端对象,因为这可能会导致底层 OAuth2 会话管理出现问题”。我的错误是导致在与我没有明显关系的函数调用中“打印”错误(例如 datetime.combine()、response.json())。我没有在函数内调用客户端对象的创建,而是在外部创建它并将客户端对象作为参数参数传递给我的各种 async def 函数。

sync def 函数中不会发生该错误,因为它在返回之前的任何时候都不会将线程让给事件循环。这意味着没有同时调用的并发客户端对象。因此,在同步情况下不会违反 1:1 的客户端对象:令牌文件比率,并且在函数内创建客户端对象不是问题。

于 2021-07-12T03:20:48.557 回答