Асинхронный питон с угрем - PullRequest
0 голосов
/ 03 июня 2019

Я создаю настольное приложение с использованием eel . Однако у меня возникла проблема с одновременным запуском функций.

Идея угря заключается в том, что он позволяет электрону общаться с Python через JS. Итак, я создал кнопку в пользовательском интерфейсе eel, которая запускает часть моей программы (несколько асинхронных сеансов aiohttp). Функция, которая их выполняет, определяется как асинхронная, т.е. async def main():. И все функции, выполняемые main(), также являются асинхронными. Вот общий план программы:

import eel
import asyncio
from aiohttp import ClientSession

options = {
    'mode': 'custom',
    'args': ['node_modules/electron/dist/electron.exe', '.'],
}


@eel.expose
async def start_program():  # this is run when the user clicks the run button
    await main()


@eel.expose
async def test_print():  # this is run when the user clicks the test button
    print("test")


async def main():
    tasks = []
    loop = asyncio.get_event_loop()
    for i in range(instances):
        task = asyncio.ensure_future(launch(url))
        tasks.append(task)
    loop.run_until_complete(asyncio.wait(tasks))


async def launch(url):
    done = False
    async with ClientSession() as session:
        while not done:
            async with session.get(url, timeout=40) as initial:
                html_text = await initial.text()
                if x in html_text:
                    done = True
        await session.close()



if __name__ == "__main__":
    eel.init('web')
    eel.start('html/index.html', options=options)

А потом в моем JavaScript у меня есть:

async function start_program_js() { // this is run when the user clicks the run button
    await eel.start_program()();
}

async function test_print_js() { // this is run when the user clicks the test button
    await eel.test_print()();
}

Итак, желаемым выводом является то, что после того, как я уже нажал кнопку «Выполнить», если я затем нажму кнопку «Проверить», будет напечатано «Проверка». Однако на данный момент ни один из них не работает. Я мог бы заставить работать работать, изменив async def main(): на def main():, async def start_program(): на def start_program(): и async def test_print(): на def test_print():. Затем в JS я изменил его на

function start_program_js() { // this is run when the user clicks the run button
    eel.start_program();
}

function test_print_js() { // this is run when the user clicks the test button
    eel.test_print();
}

Тем не менее, теперь моя проблема в том, что кнопка «тест» ничего не сделает, если я уже нажал «запустить». Он работает сам по себе, но не при запуске «run».

Я думал, что асинхронный подход, который я подробно описал вначале, сработает, но использование этого и нажатие кнопки «выполнить» вызвало эту ошибку:

Traceback (most recent call last):
  File "src\gevent\greenlet.py", line 766, in gevent._greenlet.Greenlet.run
  File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\site-packages\eel\__init__.py", line 209, in _process_message
    'value': return_val    }))
  File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\json\__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\json\encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type coroutine is not JSON serializable
2019-06-03T13:00:59Z <Greenlet at 0x4f4b4b0: _process_message({'call': 6.074835210306471, 'name': 'start_program', 'ar, <geventwebsocket.websocket.WebSocket object at 0x0)> failed with TypeError

C:\Users\x\AppData\Local\Programs\Python\Python37-32\lib\site-packages\gevent\libuv\loop.py:193: RuntimeWarning: coroutine 'start_program' was never awaited
  super(loop, self)._run_callbacks()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

Кто-нибудь знает, как я могу решить эту проблему?

Спасибо.

РЕДАКТИРОВАТЬ: я только что заметил, что в readme есть асинхронный раздел. Я пытался повторить это, но я не могу заставить его работать. Я пытался

@eel.expose
def start_program():  # this is run when the user clicks the run button
    eel.spawn(main)


@eel.expose
def test_print():  # this is run when the user clicks the test button
    eel.spawn(test_print_x)


def test_print_x():
    print("test")

Тем не менее, у меня та же проблема, что и раньше, т. Е. Не работает функция кнопки «тест».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...