Janz Blog

Janz Blog

aiohttp session的使用

41
2023-10-31

Session

官网介绍的时候推荐采用同一个session做请求,可以自带很多的优势,比如keeplive,cookie等。
具体的可以看官网的内容:Advanced Client Usage — aiohttp 3.8.4 documentation

官网给出的session示例

官网示例地址:The aiohttp Request Lifecycle — aiohttp 3.8.4 documentation
对于session只有一点需要注意,那就是需要close,可以手动关闭,也可以利用上下文管理的with

第一种

import aiohttp
import asyncio

async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get('http://python.org') as response:
            html = await response.text()
            print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

第二种

第一种情况可以看到,对于单一的请求是可以的,但是对于多个请求未免有些烦琐,我们看官网给的第二种方式。

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'http://python.org')
        print(html)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

我们可以在main函数中利用创建一个session来完成多次请求。
但是我们发现如果把session和我们的类相结合,上面的两种方式就都不是很友好,看github的issue作者是建议用构造函数来完成。

和项目相结合的方式

from aiohttp import ClientResponse, ClientTimeout
from aiohttp_retry import RetryClient, ClientSession

class Request:
    def __init__(self, *args, **kwargs):
        self.client_session = ClientSession(trust_env=False)
        self.retry_client = RetryClient(client_session=self.client_session)
        self.request = self.retry_client.request(*args, **kwargs)

    async def __aenter__(self) -> ClientResponse:
        return await self.request

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.client_session.close()
        await self.retry_client.close()


def request(method, url, params=None, headers=None, data=None, json=None):
    if headers is None:
        headers = {}
    if params is None:
        params = {}
    if json is not None:
        return Request(method, url, params=params, headers=headers, ssl=False, json=json,
                       timeout=ClientTimeout(total=100))
    else:
        return Request(method, url, params=params, headers=headers, data=data, ssl=False,
                       timeout=ClientTimeout(total=100))

新建一个Request的类,实现__aenter____aexit__两个方法,实例化类时新建一个session,请求完毕后关闭。

Enjoy!

aiohttp是一个非常好玩的库,可以做client,也可以做server,对于个人项目来说非常的舒服,可以一把梭了。