如何将关键字参数添加到通过 ThreadPoolExecuter 和 run_in_executor 调用的方法?

Mil*_*ani 3 python python-3.x python-requests python-asyncio

我正在尝试在 的帮助下同时发送 POST 请求concurrent.futures。由于某种原因,我无法设置自定义标头。我想设置

  1. Authorization
  2. Content-type

这是我到目前为止所取得的进展。

import asyncio
import concurrent.futures
import requests
from urllib.parse import urlencode, quote_plus


params = urlencode({'a': 'b', 'c': 'd', 'e': 'f'})
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "*/*","Authorization": "Bearer kdjalskdjalskd"}

async def main():

    with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:

        loop = asyncio.get_event_loop()
        futures = [
            loop.run_in_executor(
                executor, 
                requests.post,
                'https://fac03c95.ngrok.io',params, headers)
            for i in range(20)
        ]
        for response in await asyncio.gather(*futures):
            print(response.text)
            pass

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,标头似乎没有显示在请求中。有人可以帮我从这里出去吗?

提前致谢 :)

Olv*_*ght 5

免责声明:这是所讨论的特定问题的解决方案。提高所提供代码的质量不是此答案的目的。

让我们检查loop.run_in_executor()和的文档requests.post()

run_in_executor()将提供的参数传递给函数。现在让我们看一下您的代码:

loop.run_in_executor(executor, requests.post, 'https://fac03c95.ngrok.io', params, headers)
Run Code Online (Sandbox Code Playgroud)

因此,函数将被这样调用:

requests.post('https://fac03c95.ngrok.io', params, headers)
Run Code Online (Sandbox Code Playgroud)

让我们将提供的参数的值与其关键字合并:

  • 网址- https://fac03c95.ngrok.io;
  • 数据-{'a': 'b', 'c': 'd', 'e': 'f'}
  • json-{"Content-type": "application/x-www-form-urlencoded", ...}

要添加自定义标头,您应该传递关键字参数headers=。不幸的是,run_in_executor()它不转发关键字参数,因此您必须使用某种代理函数。以下是一些变体:

  1. 功能

    def proxy_post(url, data, headers):
        return requests.post(url, data=data, headers=headers)
    
    ...
    
    loop.run_in_executor(executor, proxy_post, 'https://fac03c95.ngrok.io', params, headers)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 拉姆达

    loop.run_in_executor(executor, lambda: requests.post('https://fac03c95.ngrok.io', data=params, headers=headers))
    
    Run Code Online (Sandbox Code Playgroud)
  3. functools.partial()

    import functools
    
    ...
    
    loop.run_in_executor(executor, functools.partial(requests.post, 'https://fac03c95.ngrok.io', data=params, headers=headers))
    
    Run Code Online (Sandbox Code Playgroud)