requests 发送文件模块

# -*- coding: utf-8 -*-
# !/usr/bin/env python
# Software: PyCharm
# __author__ == "YU HAIPENG"
# fileName: request发送文件.py
# Month: 七月
# time: 2021/7/30 11:31
""" Write an introduction to the module here """
import binascii
import os
from io import BytesIO

import requests
import six

logger = None


def get_log():
    global logger
    if logger is None:
        import logging
        logging.basicConfig(
            format='PROCESS ID:%(process)d: %(asctime)s-%(name)s-%(levelname)s '
                   '-[line:%(lineno)d]: %(message)s', level=logging.INFO)
        logger = logging.getLogger('req')
        return logger


def __send(url, data=None, json=None, headers=None, params=None, **kwargs):
    session = kwargs.pop("session", requests)
    try:
        response = session.post(
            url=url,
            params=params,
            json=json or {},
            data=data or {},
            headers=headers or {"Content-Type": "application/json"},
            timeout=int(kwargs.pop("timeout", 20)),
            **kwargs
        )
    except Exception as e:
        import traceback
        get_log()
        logger.info(traceback.format_exc())
        return
    return response


def send_file(url, files, *args, **kwargs):

    content_type, body, content_length = encode_multipart_form_data(kwargs.pop("data", None), files=files)
    headers = kwargs.pop("headers", dict())
    headers["Content-Type"] = content_type
    headers["Content-Length"] = content_length
    return __send(
        url=url,
        headers=headers,
        data=body,
        *args, **kwargs
    )


def encode_multipart_form_data(data=None, files=None):
    """
    data is a sequence of {name:value} elements for regular form fields.
    files is a sequence of {filename:value} elements for data to be
    uploaded as files.
    Return (content_type, body) ready for httplib.HTTP instance
    files
        todo example one:
            多个文件
                [
                    远程接收名字          文件名      文件内容
                    {remote_accpt_name: {file_name: content}},
                    {remote_accpt_name2: {file_name2: content2}},
                ]
            单个文件
                远程接收名字          文件名      文件内容
                {remote_accpt_name: {file_name: content}}
         todo example two:
             多个文件
                [
                    远程接收名字          路径
                    {remote_accpt_name: file_path},
                    {remote_accpt_name2: file_path2},
                ]
            单个文件
                远程接收名字          路径
                {remote_accpt_name: file_path }
    data 数据
    """
    data = data or dict()
    files = [] if not files else [files] if isinstance(files, dict) else files

    with BytesIO() as body:
        boundary = choose_boundary()
        for key, value in data.items():
            body.write(f'--{boundary}\r\n'.encode(encoding="utf-8"))
            body.write(f'Content-Disposition:form-data;name="{key}"\r\n\r\n'.encode(encoding="utf-8"))
            if isinstance(value, int):
                value = str(value)
            body.write(f'{value}\r\n'.encode(encoding="utf-8"))

        for file in files:
            for remote_name, value in file.items():
                body.write(f'--{boundary}\r\n'.encode(encoding="utf-8"))
                if isinstance(value, str):
                    if not os.path.isfile(value):
                        raise FileNotFoundError("文件不存在")
                    file_name = os.path.basename(value)
                    with open(value, 'rb') as fd:
                        content = fd.read()
                elif isinstance(value, dict):
                    for file_name, content in value.items():
                        break
                else:
                    raise ValueError("文件格式不支持")
                body.write(f'Content-Disposition: form-data; '
                           f'name="{remote_name}"; '
                           f'filename="{file_name}"'
                           f';filelength="{len(content)}"'
                           f'\r\n\r\n'.encode('utf8'))
                body.write(content)
                body.write(b"\r\n")
        body.write(f'--{boundary}--\r\n'.encode("utf-8"))
        content_type = 'multipart/form-data;boundary=%s' % boundary
        getvalue = body.getvalue()
    content_length = str(len(getvalue))
    return content_type, getvalue, content_length


def choose_boundary():
    """
    Our embarrassingly-simple replacement for mimetools.choose_boundary.
    """
    boundary = binascii.hexlify(os.urandom(16))
    if six.PY3:
        boundary = boundary.decode('ascii')
    return boundary

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值