Python 如何在aiohttp中读取子进程?

Python 如何在aiohttp中读取子进程?,python,subprocess,aiohttp,Python,Subprocess,Aiohttp,我有一个非常简单的服务器,它从子进程读取数据并将数据传递给任何打开的WebSocket。我遇到的问题是,我读取子流程的方法似乎以一种我无法遵循的方式破坏了aiohttp: #!/usr/bin/env python3 import asyncio from aiohttp import web import subprocess async def websocket_handler(request): ws = web.WebSocketResponse() await w

我有一个非常简单的服务器,它从子进程读取数据并将数据传递给任何打开的WebSocket。我遇到的问题是,我读取子流程的方法似乎以一种我无法遵循的方式破坏了aiohttp:

#!/usr/bin/env python3

import asyncio
from aiohttp import web
import subprocess

async def websocket_handler(request):
    ws = web.WebSocketResponse()
    await ws.prepare(request)
    request.app['websockets'].append(ws)
    try:
        async for msg in ws:
            print(msg)
            await asyncio.sleep(1)
    finally:
        request.app['websockets'].remove(ws)
    return ws


async def on_shutdown(app):
    for ws in app['websockets']:
        await ws.close(code=999, message='Server shutdown')
这里是出问题的地方:

async def listen_to_process(app):
    print("listen to process")
    while True:
        print(" looping? ")
        await asyncio.sleep(0.1)
        # the problem seems to be here
        line = await app['process'].stdout.readline()
        # if line:
        #     buffer.append(line)

async def start_background_tasks(app):
    app['process_listener'] = app.loop.create_task(listen_to_process(app))


async def cleanup_background_tasks(app):
    print('cleanup background tasks...')
    app['process_listener'].cancel()
    await app['process_listener']


def init():
    app = web.Application()
    app['websockets'] = []
    app.router.add_get('/updates', websocket_handler)
    cmd = "very long running subprocess"
    app['process'] = subprocess.Popen(cmd.split(" "), stdout=subprocess.PIPE)
    app.on_startup.append(start_background_tasks)
    app.on_cleanup.append(cleanup_background_tasks)
    app.on_shutdown.append(on_shutdown)
    return app


web.run_app(init())
所以,我的问题是:在我的应用程序的后台,如何在循环中读取stdout中的行?感谢您的指点。

请使用:

小巧整洁:使用模块将命令行安全地拆分为参数列表。

请使用:


小型整洁:使用模块将命令行安全地拆分为参数列表。

基本上,
子流程。Popen
不支持异步操作。您不能等待它。我不确定
aiohttp
是否会自动提供一个替代方案,但由于您有问题,我想不会。基本上,
子流程.Popen
不支持异步操作。您不能等待它。我不确定
aiohttp
是否会自动提供替代方案,但由于您有问题,我想不会。
app['process'] = await asyncio.create_subprocess_exec(
                           shlex.split(cmd), stdout=subprocess.PIPE)