2017-08-07 27 views
0

我正在嘗試編寫一個不和諧的機器人程序,它使用我從http休息調用中獲取的數據更新用戶。如何在asycio後臺線程中使用aiohttp

由於discord.py使用asyncio,我想我會嘗試按照這種方法。

async def my_background_task(): 

    print("starting BG task") 
    await client.wait_until_ready() 
    while not client.is_closed: 
     requests.get(getMyUrl()).json()["dict_element"] 
     #do more stuff 

client.loop.create_task(my_background_task()) 
client.run("api key goes here") 

它使用同步「請求」庫足夠簡單。但是,我可以運行這個過程幾個小時,直到它崩潰。我假設因爲'請求'未能完成無限循環。

async def fetch(session, url): 
    async with session.get(url) as resp: 
     print(resp.status) 
     return await resp 

async def fetch_url(loop, url): 
    async with aiohttp.ClientSession(loop=loop) as session: 
     await fetch(session, url) 

async def my_method(url): 

    loop = asyncio.get_event_loop() 
    return loop.run_until_complete(fetch_url(loop,url)) 

async def my_background_task(): 

    print("starting BG task") 
    await client.wait_until_ready() 
    while not client.is_closed: 
     await my_method.("www.theinternet.com/restcall").json()["dict_element"] 
     #do more stuff 

所以我現在嘗試用aiohttp工作,但碰上這種循環中異步循環的問題。

我還沒有找到如何解決這個問題的正確解釋。我對Python和異步函數很陌生。

回答

0

我通過讓另一個後臺任務將http響應作爲全局變量並自行更新來解決此問題。

我不確定這是我應該這樣做的方式,但這就是讓我走出泡菜的原因。

1

沒有從aiohttp版本中得到的錯誤,很難猜測。但是一見鍾情,我要說的是:

  • 無需顯式傳遞事件循環ClientSession,它會自動選擇當前事件循環,所以你應該叫​​
  • fetch功能不應該await respresp那裏不是一個協程。你可能想return await resp.json()(並刪除my_background_task額外.json()
  • my_method,你已經在協程運行,由async def所示。所以要調用另一個協程,你應該是await -ing它,而不是創建一個新的事件循環,並在新的循環中運行它。
  • my_background_task中,您正在等待一些毫無意義的事情:檢查運算符的優先級await,您在協程上調用.__getitem__,然後等待__getitem__的結果,這與您想要的結果相反。
  • 仍然在該行上,響應關閉後,您無法嘗試讀取響應的json主體(只要您退出async with,即fetch方法完成,響應即會關閉)。
  • 最後,您不應該在每個循環都重新創建ClientSession。這存在,以便它可以請求之間共享,所以你應該my_background_task一次創建它,使用它

-

async def fetch(session, url): 
    async with session.get(url) as resp: 
     print(resp.status) 
     return await resp.json() 

async def my_background_task() 
    print("starting BG task") 
    await client.wait_until_ready() 
    async with aiohttp.ClientSession() as session: 
     while not client.is_closed: 
      data = await fetch(session, "www.theinternet.com/restcall") 
      element = data["dict_element"] 
相關問題