Issue
Im trying to make a Pyqt5 app with aiohttp request, and asyncio tasks. Im using quamash package too and it requires Python 3.7 so i installed this version.(it didn't work on Python 3.10) The main reason i use asyncio and quamash is because i want to do requests and without freezing the GUI of the app.
I get this error when i click the Start button and close the app:
Task exception was never retrieved
future: <Task finished coro=<App.rotator() done, defined at C:\Users\Zsolt\Documents\python-example\stack_exmaple.py:37> exception=RuntimeError('no running event loop')>
Traceback (most recent call last):
File "C:\Users\Zsolt\Documents\python-example\stack_exmaple.py", line 41, in rotator
response = await get()
File "C:\Users\Zsolt\Documents\python-example\stack_exmaple.py", line 51, in get
async with session.get(pokemon_url) as resp:
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\aiohttp\client.py", line 1138, in __aenter__
self._resp = await self._coro
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\aiohttp\client.py", line 533, in _request
async with ceil_timeout(real_timeout.connect):
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\aiohttp\helpers.py", line 734, in ceil_timeout
return async_timeout.timeout(None)
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\async_timeout\__init__.py", line 30, in timeout
loop = _get_running_loop()
File "C:\Users\Zsolt\AppData\Local\Programs\Python\Python37\lib\site-packages\async_timeout\__init__.py", line 236, in _get_running_loop
return asyncio.get_running_loop()
RuntimeError: no running event loop
Here is the full code:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QKeySequence, QPalette, QColor
from PyQt5.QtCore import Qt
from PyQt5 import QtGui, QtCore
import asyncio
import aiohttp
import quamash
import os.path
import json
import sys
class App(QWidget):
run = 0
response = ''
def __init__(self, loop):
super().__init__()
btn = QPushButton('Start', self)
btn.resize(btn.sizeHint())
btn.clicked.connect(self.start)
self.setGeometry(200, 200, 700, 400)
self.display = QLabel(self)
self.display.resize(200, 500)
self.display.move(1, 50)
self.count = 0
self.show()
self.loop = loop
self.tasks = []
self.tasks.append(loop.create_task(self.rotator()))
async def rotator(self):
while await asyncio.sleep(0, True):
if (self.run == 1):
self.count += 1
response = await get()
self.display.setText(str(response))
def start (self):
self.run = 1
async def get():
async with aiohttp.ClientSession() as session:
pokemon_url = 'https://pokeapi.co/api/v2/pokemon/151'
async with session.get(pokemon_url) as resp:
pokemon = await resp.json()
print(pokemon)
return pokemon
app = QApplication(sys.argv)
app.setApplicationName("Sample ;)")
loop = quamash.QEventLoop(app)
asyncio.set_event_loop(loop)
with loop:
window = App(loop)
window.show()
loop.run_forever()
If i comment out the response = await get()
it works, it counts the self.count += 1 and it shows the variable on self.display.setText(str(self.count))
. But i need to get it to work with the aiohttp request so it should print out the response from the request.
Solution
TLDR; replace quamash with qasync
In asyncio, a task always exists when async code is executed. Like in a multithreaded program at least the main thread is present. If quamash doesn't follow the rule -- it is not aiohttp problem.
quamash is not maintained anymore, the latest release was made 3.5 years ago. The maintained successor is qasync which has no this bug and works with the latest aiohttp perfectly fine.
Answered By - Andrew Svetlov
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.