python - 如何在辅助线程中运行 aiohttp Web 应用程序
问题描述
以下代码取自aiohttp
文档https://docs.aiohttp.org/en/stable/
确实有效:
from aiohttp import web
async def handle(request):
name = request.match_info.get('name', "Anonymous")
text = "Hello, " + name
return web.Response(text=text)
app = web.Application()
app.add_routes([web.get('/', handle),
web.get('/{name}', handle)])
if __name__ == '__main__':
web.run_app(app)
但是让网络服务器劫持主线程是不可接受的:网络服务器应该在一个单独的非主线程上,并且 从属于主后端应用程序。
我无法确定如何在辅助线程上运行 webapp。这是我尝试过的:
- 无法在
ipython
repl 中运行代码片段:
我试图以这种方式运行它:
#if __name__ == '__main__':
web.run_app(app)
并收到有关的通知no current event loop
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3293, in run_code
async def run_code(self, code_obj, result=None, *, async_=False):
File "<ipython-input-8-344f41746659>", line 13, in <module>
web.run_app(app)
File "/usr/local/lib/python3.8/site-packages/aiohttp/web.py", line 393, in run_app
def run_app(app: Union[Application, Awaitable[Application]], *,
File "/usr/local/Cellar/python@3.8/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/events.py", line 628, in get_event_loop
def get_event_loop(self):
RuntimeError: There is no current event loop in thread 'Thread-11'.
那么..它只能运行在什么main
地方?我在这里遗漏了一些东西..
我尝试在另一个独立脚本中运行,但在从属线程上运行:
def runWebapp():
from aiohttp import web
async def handle(request):
name = request.match_info.get('name', "Anonymous")
text = "Hello, " + name
return web.Response(text=text)
app = web.Application()
app.add_routes([web.get('/', handle),
web.get('/{name}', handle)])
web.run_app(app)
if __name__ == '__main__':
from threading import Thread
t = Thread(target=runWebapp)
t.start()
print('thread started let''s nap..')
import time
time.sleep(50)
但这给出了基本相同的错误:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/Cellar/python@3.8/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/local/Cellar/python@3.8/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/git/bluej/experiments/python/aio_thread.py", line 12, in runWebapp
web.run_app(app)
File "/usr/local/lib/python3.8/site-packages/aiohttp/web.py", line 409, in run_app
loop = asyncio.get_event_loop()
File "/usr/local/Cellar/python@3.8/3.8.1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/events.py", line 639, in get_event_loop
raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.
那么如何让这个 webapp 脱离main
线程并让它与我的应用程序中的其他线程一起玩
解决方案
干得好:
import http.server
import threading
import socketserver
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
def serve_forever():
with socketserver.TCPServer(("", PORT), Handler) as httpd:
httpd.serve_forever()
if __name__ == "__main__":
threading.Thread(target=serve_forever).start()
while 1:
x = input("enter a number")
print("You entered {}".format(x))
注意这是一个巧妙的聚会技巧,但不一定对生产工作有用:http.server 模块的文档在文档页面顶部用炽热的红色字母表示不要在生产中使用它。但是几乎所有的 python webserver 框架都作为 WSGI 服务器运行,并且没有按照您希望它们的方式工作:它们通常期望由 gunicorn 或 apache 之类的其他东西运行。
如果你需要一个 HTTP 服务器来监控一个正在运行的应用程序,我强烈建议你使用 asyncio 来代替,并为所有事情使用 coros,但是如果你真的想要的话,你可以像上面那样滚动你自己的线程场景。您可以看到您仍然可以在无限输入循环中与 shell 交互,同时您还可以 curl localhost:8000 来获取包含目录列表的 HTML 页面。
只需传入您自己创建的非默认处理程序即可执行其他操作,例如以 JSON 格式返回应用程序状态。
推荐阅读
- c# - 如何使用 QuikGraph C# 从顶点列表构造最小生成树?
- python - 我的 LSTM 解决方案给出了预测的平均线,但 val_loss 的损失为 0.1 * e-5
- r - 使用 blogdown 自动化站点构建
- node.js - Websocket和node.js中没有响应
- php - 使用 php curl 对 paypal api 没有响应
- redux - Redux 随机重置 reducer 的状态
- bison - 在 YACC 错误消息中打印多字符标记
- reactjs - Nextjs 和 TypeScript 中的条件渲染不起作用
- sql - 在 PostgreSQL 中使用 WHERE 子句时出现语法错误
- html - 如何删除末尾的可用空间?