【问题标题】:Python url requests with multithreading具有多线程的 Python url 请求
【发布时间】:2021-09-25 02:36:24
【问题描述】:

我的一个要求是为整个文件夹中的每个视频发送一个上传请求。

如何改成多线程请求?

我的想法是导入线程,目的是上传到aws-s3。

import requests
import base64
import hashlib
import os

tools_dir = os.path.dirname(os.path.realpath(__file__))
project_root = os.path.dirname(tools_dir)
videos_dir = os.path.join(project_root, "output", "videos")

# Basic auth settings
basic_auth_user = "abc123"
basic_auth_password = "abc456"
auth = (basic_auth_user + ":" + basic_auth_password)

# Base64 encode and decode
auth_encode_format = auth.encode("utf-8")
auth_encode_base64 = base64.b64encode(auth_encode_format)
auth_encode_base64_format = auth_encode_base64.decode("utf-8")

str1 = "_"

for file in os.listdir(videos_dir):
    # print(file[0:10:])
    # print(file[:file.index(str1)])
    serial_number = file[:file.index(str1)]
    # print(f'{serial_number}')
    m = hashlib.md5()
    with open(os.path.join(videos_dir, file), 'rb') as f:
        for chunk in iter(lambda: f.read(4096), b""):
            m.update(chunk)
    h = m.hexdigest()
    url = "http://localhost:8000/api/awss3/upload"
    payload = {
    'fileHash': f'{h}',
    'device': {'serialNumber':f'{serial_number}'}
    }
    files = [('file', (f'{file}', open(os.path.join(videos_dir, file), 'rb'), 'application/octet-stream'))]
    headers = {
    'Authorization': f'Basic {auth_encode_base64_format}'
    }
    response = requests.request("POST", url, headers = headers, data = payload, files = files)
    print("\n" + response.text)

【问题讨论】:

    标签: python url request


    【解决方案1】:

    将没有副作用的基于循环的代码(如您在此处的代码)转换为多线程代码的最简单方法是改用基于map 的方法。然后您可以使用线程或process pool,而无需自己手动管理线程。

    这是您目前代码的粗略近似:

    for file_path in big_list_of_files:
        ...
    

    您可以通过将逻辑从循环中拉到函数中作为中间步骤来做到这一点:

    def upload_file(file_path):
        ...
    
    for file_path in big_list_of_files:
        upload_file(file_path)
    

    使切换到基于地图的方法变得容易。上传文件受 IO 限制而不是 CPU 限制,因此您可能希望使用multiprocessing.dummy,它是使用线程而不是进程的multiprocessing 模块的实现。 4 在这种情况下是要使用的线程数:

    from multiprocessing.dummy import Pool
    
    def upload_file(file_path):
        ...
    
    with Pool(4) as thread_pool:
        thread_pool.map(upload_file, big_list_of_files)
    

    如果您要将文件上传到 S3,最好考虑使用 Amazon 的 boto3 库,它可以简化您的代码,并自动执行校验和验证,并对更大的文件使用分段上传。

    【讨论】:

    • 您可能还想考虑使用pathlib 处理文件路径
    猜你喜欢
    • 2014-09-28
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    相关资源
    最近更新 更多