我正在尝试了解将Sanio与aiohttp一起使用的正确方法。
从aiohttp documentation,我发现以下内容:
当我去Sanic文档时,我会找到一个这样的例子:
这是一个例子:
from sanic import Sanic
from sanic.response import json
import asyncio
import aiohttp
app = Sanic(__name__)
sem = None
@app.route("/")
async def test(request):
"""
Download and serve example JSON
"""
url = "https://api.github.com/repos/channelcat/sanic"
async with aiohttp.ClientSession() as session:
async with sem, session.get(url) as response:
return await response.json()
app.run(host="0.0.0.0", port=8000, workers=2)
这不是管理aiohttp session 的正确方法...
那么正确的方法是什么?
我应该在应用程序中启动 session 并将 session 注入(inject)到所有层中的所有方法吗?
我发现的唯一问题是this,但这无济于事,因为我需要创建自己的类来使用该 session ,而不是sanic。
还可以在Sanic文档中找到this,它说您不应该在eventloop之外创建 session 。
我有点困惑 :(
正确的方法是什么?
最佳答案
为了使用单个aiohttp.ClientSession
,我们只需要实例化一次 session ,并在应用程序的其余部分中使用该特定实例。
为此,我们可以使用 before_server_start
listener,它允许我们在应用程序提供第一个字节之前创建实例。
from sanic import Sanic
from sanic.response import json
import aiohttp
app = Sanic(__name__)
@app.listener('before_server_start')
def init(app, loop):
app.aiohttp_session = aiohttp.ClientSession(loop=loop)
@app.listener('after_server_stop')
def finish(app, loop):
loop.run_until_complete(app.aiohttp_session.close())
loop.close()
@app.route("/")
async def test(request):
"""
Download and serve example JSON
"""
url = "https://api.github.com/repos/channelcat/sanic"
async with app.aiohttp_session.get(url) as response:
return await response.json()
app.run(host="0.0.0.0", port=8000, workers=2)
代码分类:
aiohttp.ClientSession
,将Sanic
应用程序在开始时创建的循环作为参数传递,从而避免了this pitfall的过程。 app
中。