aiohhttp中的会话重用
Session reusing in aiohhttp
我尝试重用 HTTP 会话作为 aiohttp 文档建议
Don’t create a session per request. Most likely you need a session per
application which performs all requests altogether.
但是我在请求库中使用的常用模式不起作用:
def __init__(self):
self.session = aiohttp.ClientSession()
async def get_u(self, id):
async with self.session.get('url') as resp:
json_resp = await resp.json()
return json_resp.get('data', {})
那我试试
await client.get_u(1)
我收到错误
RuntimeError: Timeout context manager should be used inside a task
async_timeout 的任何解决方法都没有帮助。
另一种方法有效:
async def get_u(self, id):
async with aiohttp.ClientSession() as session:
with async_timeout.timeout(3):
async with session.get('url') as resp:
json_resp = await resp.json()
return json_resp.get('data', {})
但似乎是根据请求创建会话。
所以我的问题是:如何正确地重用 aiohttp-session?
UPD:最小的工作示例。具有以下视图的 Sanic 应用程序
import aiohttp
from sanic.views import HTTPMethodView
class Client:
def __init__(self):
self.session = aiohttp.ClientSession()
self.url = 'https://jsonplaceholder.typicode.com/todos/1'
async def get(self):
async with self.session.get(self.url) as resp:
json_resp = await resp.json()
return json_resp
client = Client()
class ExView(HTTPMethodView):
async def get(self, request):
todo = await client.get()
print(todo)
例如,您可以在应用启动时创建 ClientSession
(使用 on_startup
信号 https://docs.aiohttp.org/en/stable/web_advanced.html#signals)。
将它存储到您的应用程序(aiohttp 应用程序具有针对此类问题的 dict 接口 https://aiohttp.readthedocs.io/en/stable/faq.html#id4)并通过请求中的 request.app['YOU_CLIENT_SESSION']
访问您的会话。
我有同样的错误。我的解决方案是在异步函数中初始化客户端。例如:
class SearchClient(object):
def __init__(self, search_url: str, api_key: str):
self.search_url = search_url
self.api_key = api_key
self.session = None
async def _get(self, url, attempt=1):
if self.session is None:
self.session = aiohttp.ClientSession(raise_for_status=True)
headers = {
'Content-Type': 'application/json',
'api-key': self.api_key
}
logger.info("Running Search: {}".format(url))
try:
with timeout(60):
async with self.session.get(url, headers=headers) as response:
results = await response.json()
return results
我尝试重用 HTTP 会话作为 aiohttp 文档建议
Don’t create a session per request. Most likely you need a session per application which performs all requests altogether.
但是我在请求库中使用的常用模式不起作用:
def __init__(self):
self.session = aiohttp.ClientSession()
async def get_u(self, id):
async with self.session.get('url') as resp:
json_resp = await resp.json()
return json_resp.get('data', {})
那我试试
await client.get_u(1)
我收到错误
RuntimeError: Timeout context manager should be used inside a task
async_timeout 的任何解决方法都没有帮助。
另一种方法有效:
async def get_u(self, id):
async with aiohttp.ClientSession() as session:
with async_timeout.timeout(3):
async with session.get('url') as resp:
json_resp = await resp.json()
return json_resp.get('data', {})
但似乎是根据请求创建会话。
所以我的问题是:如何正确地重用 aiohttp-session?
UPD:最小的工作示例。具有以下视图的 Sanic 应用程序
import aiohttp
from sanic.views import HTTPMethodView
class Client:
def __init__(self):
self.session = aiohttp.ClientSession()
self.url = 'https://jsonplaceholder.typicode.com/todos/1'
async def get(self):
async with self.session.get(self.url) as resp:
json_resp = await resp.json()
return json_resp
client = Client()
class ExView(HTTPMethodView):
async def get(self, request):
todo = await client.get()
print(todo)
例如,您可以在应用启动时创建 ClientSession
(使用 on_startup
信号 https://docs.aiohttp.org/en/stable/web_advanced.html#signals)。
将它存储到您的应用程序(aiohttp 应用程序具有针对此类问题的 dict 接口 https://aiohttp.readthedocs.io/en/stable/faq.html#id4)并通过请求中的 request.app['YOU_CLIENT_SESSION']
访问您的会话。
我有同样的错误。我的解决方案是在异步函数中初始化客户端。例如:
class SearchClient(object):
def __init__(self, search_url: str, api_key: str):
self.search_url = search_url
self.api_key = api_key
self.session = None
async def _get(self, url, attempt=1):
if self.session is None:
self.session = aiohttp.ClientSession(raise_for_status=True)
headers = {
'Content-Type': 'application/json',
'api-key': self.api_key
}
logger.info("Running Search: {}".format(url))
try:
with timeout(60):
async with self.session.get(url, headers=headers) as response:
results = await response.json()
return results