繁体   English   中英

设置 `aiohttp.ClientSession` 默认参数

[英]Setting `aiohttp.ClientSession` default params

我正在从requests迁移到aiohttp ,并且我以前使用过requests.Session.params为会话发出的每个请求设置默认查询参数。

我如何正确实现与aiohttp.ClientSession的等效?

我试过了:

  • 子类化aiohttp.ClientSession以覆盖_request方法。 这会引发DepcrecationWarning: Inheritance from ClientSession is discouraged ,不过。
  • 子类化aiohttp.ClientResponse以覆盖__init__方法,并更新那里的params ,然后将子类传递给aiohttp.ClientSession 这是行不通的,因为我需要在会话的基础上定义(并且是可变的)自定义参数。

编辑:我希望我的代码看起来如何的示例,以供澄清:

from aiohttp import ClientSession

session = ClientSession()
# Do something fancy here, or in the initialization of `ClientSession`, so that
# `default_params` is set as the default parameters for each request
default_params = dict(some_parameter="a value")

async with session.get("http://httpbin.org/get") as resp:
    j = await resp.json()
assert j["args"] == default_params

# Do something fancy here, where we change the default parameters
default_params.update(some_parameter="another value")

async with session.get("http://httpbin.org/get") as resp:
    j = await resp.json()
assert j["args"] == default_params

自定义请求标头
如果您需要向请求添加 HTTP 标头,请将它们以字典形式传递给 headers 参数。

它在文档http://docs.aiohttp.org/en/stable/client_advanced.html#custom-request-headers 中

url = 'http://example.com/image'
payload = b'GIF89a\x01\x00\x01\x00\x00\xff\x00,\x00\x00'
          b'\x00\x00\x01\x00\x01\x00\x00\x02\x00;'
headers = {'content-type': 'image/gif'}

await session.post(url,
                   data=payload,
                   headers=headers)

要添加默认和稍后的自定义参数,您可以这样做而无需进行任何子类化( 基于文档的这一部分

import asyncio
from aiohttp import ClientSession

async def fetch(url, params, loop):
    async with ClientSession() as session:
        async with session.get(url, params=params) as response:
            print(response.request_info)
            print(str(response.url))
            print(response.status)
            args = await response.json()
            resp_text = await response.text()
            print('args:', args['args'])
            print(resp_text)

def main(url, params):
    loop = asyncio.get_event_loop()
    return loop.run_until_complete(fetch(url, params, loop))

if __name__ == '__main__':
    url = 'http://httpbin.org/get'
    default_params = {'param1': 1, 'param2': 2}
    main(url, default_params)
    new_params = {'some_parameter': 'a value', 'other_parameter': 'another value'}
    default_params.update(new_params)
    main(url, default_params)

结果:

RequestInfo(url=URL('http://httpbin.org/get?param1=1&param2=2'), method='GET', headers=<CIMultiDict('Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'Python/3.5 aiohttp/3.4.4')>, real_url=URL('http://httpbin.org/get?param1=1&param2=2'))
  http://httpbin.org/get?param1=1&param2=2
  200
  args: {'param1': '1', 'param2': '2'}
  {
    "args": {
      "param1": "1", 
      "param2": "2"
    }, 
    "headers": {
      "Accept": "*/*", 
      "Accept-Encoding": "gzip, deflate", 
      "Connection": "close", 
      "Host": "httpbin.org", 
      "User-Agent": "Python/3.5 aiohttp/3.4.4"
    }, 
    "origin": "10.10.10.10", 
    "url": "http://httpbin.org/get?param1=1&param2=2"
  }

  RequestInfo(url=URL('http://httpbin.org/get?param1=1&param2=2&some_parameter=a+value&other_parameter=another+value'), method='GET', headers=<CIMultiDict('Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'Python/3.5 aiohttp/3.4.4')>, real_url=URL('http://httpbin.org/get?param1=1&param2=2&some_parameter=a+value&other_parameter=another+value'))
  http://httpbin.org/get?param1=1&param2=2&some_parameter=a+value&other_parameter=another+value
  200
  args: {'other_parameter': 'another value', 'param1': '1', 'param2': '2', 'some_parameter': 'a value'}
  {
    "args": {
      "other_parameter": "another value", 
      "param1": "1", 
      "param2": "2", 
      "some_parameter": "a value"
    }, 
    "headers": {
      "Accept": "*/*", 
      "Accept-Encoding": "gzip, deflate", 
      "Connection": "close", 
      "Host": "httpbin.org", 
      "User-Agent": "Python/3.5 aiohttp/3.4.4"
    }, 
    "origin": "10.10.10.10", 
    "url": "http://httpbin.org/get?param1=1&param2=2&some_parameter=a+value&other_parameter=another+value"
  }

ClientSession接受request_class作为其参数之一。 它应该是aiohttp.client_reqrep.ClientRequest一个实例。 您可以从中继承并设置默认值,但这不是很动态。 另一种选择是创建一个包装函数,该函数返回ClientRequest并在那里添加默认值的逻辑。 因为ClientSession只是调用req = self._request_class( 这里

示例 Python 3.8

import asyncio
import aiohttp 
import aiohttp.client_reqrep

def wrap(default_params):
    def request_class(*args, **kwargs):
        """
        Merge defaults and pass them along to the ClientRequest class
        """
        kwargs["params"] = {**default_params, **params} \
            if (params := kwargs.get("params")) else default_params
        return aiohttp.client_reqrep.ClientRequest(*args, **kwargs)
    return request_class

async def run():
    default_params = dict(some_parameter="a value")
    async with aiohttp.ClientSession(request_class=wrap(default_params)) as session:
        async with session.get("http://httpbin.org/get") as resp:
            j = await resp.json()
            print(j)            
        assert j["args"] == default_params

        # Do something fancy here, where we change the default parameters
        default_params.update(some_parameter="another value")

        async with session.get("http://httpbin.org/get") as resp:
            j = await resp.json()
            print(j)            
        assert j["args"] == default_params

        async with session.get("http://httpbin.org/get",
                               params={"foo": "bar"}) as resp:
            j = await resp.json()
            print(j)
        assert j["args"] == {**{"foo": "bar"}, **default_params}

        async with session.get("http://httpbin.org/get",
                               params={"some_parameter": "foo"}) as resp:
            j = await resp.json()
            print(j)
        assert j["args"] == {"some_parameter": "foo"}

# run
asyncio.run(run())        

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM