I am trying to understand what is the right way to use aiohttp with Sanic.
From aiohttp documentation, I find the following:
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.
And when I go to Sanic documentation I find an example like this:
This is an example:
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)
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?
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?
2
Answers
That is essentially what I am doing.
I created a module (
interactions.py
) that has, for example a function like this:Then I just
await
on that:I am not sure why that is not the “right way”. The session (at least for my needs) can be closed as soon as my request is done.
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.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.Breakdown of the code:
aiohttp.ClientSession
, passing as argument the loop thatSanic
apps create at the start, avoiding this pitfall in the process.app
.