如何在Sanic中使用aiohttp ClientSession? [英] How to use an aiohttp ClientSession with Sanic?

查看:581
本文介绍了如何在Sanic中使用aiohttp ClientSession?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解在Sanic中使用aiohttp的正确方法。

I am trying to understand what is the right way to use aiohttp with Sanic.

来自aiohttp 文档,我发现以下内容:

From aiohttp documentation, I find the following:


不要为每个请求创建会话 >。每个应用程序很可能需要一个会话来执行所有请求。
更复杂的情况可能需要每个站点进行一次会话,例如一个用于Github,另一个用于Facebook API。无论如何,为每个请求建立会话是一个非常糟糕的主意。
会话内部包含一个连接池。连接重用和保持活动状态(默认情况下都处于启用状态)可能会提高整体性能。

Don’t create a session per request. Most likely you need a session per application which performs all requests altogether. More complex cases may require a session per site, e.g. one for Github and another one for Facebook APIs. Anyway making a session for every request is a very bad idea. A session contains a connection pool inside. Connection reuse and keep-alive (both are on by default) may speed up total performance.

当我去看Sanic文档时,找到这样的示例:

And when I go to Sanic documentation I find an example like this:

这是一个示例:

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会话的正确方法...

Which is not the right way to manage an aiohttp session...

那么正确的方法是什么?

我应该在应用程序并将会话注入到所有层中的所有方法?

So what is the right way?
Should I init a session in the app and inject the session to all the methods in all layers?

我发现的唯一问题是,但这无济于事,因为我需要创建自己的类来使用该会话,而不是sanic。

还找到了,它说您不应该在事件循环之外创建会话。

The only issue I found is this but this doesn't help because I need to make my own classes to use the session, and not sanic.
Also found this in Sanic documentation, which says you shouldn't create a session outside of an eventloop.

我有点困惑:(
正确的做法是什么?

I am a little confused :( What is the right way to go?

推荐答案

为了使用单个 aiohttp.ClientSession 我们只需要实例化一次会话,并在其余应用程序中使用该特定实例。

In order to use a single aiohttp.ClientSession we need to instantiate the session only once and use that specific instance in the rest of the application.

要实现此目的我们可以使用 before_server_start 监听器,这将允许我们在应用程序提供第一个字节之前创建实例。

To achieve this we can use a before_server_start listener which will allow us to create the instance before the app serves the first byte.

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 应用程序在开始时创建的循环作为参数传递,避免此过程中的陷阱

  • 我们将该会话存储在Sanic app

  • 最后,我们正在使用此会话发出请求。

  • We are creating an aiohttp.ClientSession, passing as argument the loop that Sanic apps create at the start, avoiding this pitfall in the process.
  • We store that session in the Sanic app.
  • Finally, we are using this session to make our requests.

这篇关于如何在Sanic中使用aiohttp ClientSession?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆