requests 封装, http

封装

点击查看代码
import functools
import traceback

from django_redis import get_redis_connection
from requests.adapters import HTTPAdapter

import requests
import logging

redis_obj = get_redis_connection()


def http_base(func):
    @functools.wraps(func)
    def decorator(*args, **kwargs):
        timeout = kwargs.get("timeout")
        exception_info = kwargs.pop("exception_info", None)  # 异常时需要打印的信息
        exception_info = f"【{exception_info}】" if exception_info else ""
        retry = kwargs.pop("retry", 0)
        _session = requests.Session()
        _session.mount("http://", HTTPAdapter(max_retries=retry))
        _session.mount("https://", HTTPAdapter(max_retries=retry))
        try:
            kwargs["session"] = _session
            response = func(*args, **kwargs)
            if response.status_code != 200:
                logger.error(f"{exception_info},外部接口调用状态错误:{args, kwargs}\n,错误码:{response.status_code}")
                return False, dict()
            else:
                return True, response.json()
        except requests.exceptions.ReadTimeout:
            _timeout = timeout * retry if retry else timeout
            logger.error(f"{exception_info},外部接口调用超时:{args, kwargs}\n请求时长:{_timeout}S")
            return False, dict()
        except Exception as e:
            logger.error(f"{exception_info},外部接口调用异常:{args, kwargs}\n{traceback.format_exc()}")
            return False, dict()

    return decorator


@http_base
def http_post(*args, **kwargs) -> (bool, dict):
    """用于外部post请求,封装相关异常处理
    :param kwargs:
        session: request对象(http_base装饰器返回)
        exception_info:异常提示
        retry:超时重试次数
    :return data: 字典,具体有业务决定
    """
    _session = kwargs.pop("session")
    return _session.post(*args, **kwargs)


@http_base
def http_get(*args, **kwargs) -> (bool, dict):
    """用于外部get请求,封装相关异常处理
    :param kwargs:
        session: request对象(http_base装饰器返回)
        exception_info:异常提示
        retry:超时重试次数
    :return data: 字典,具体有业务决定
    """
    _session = kwargs.pop("session")
    return _session.get(*args, **kwargs)

使用

点击查看代码
	url = ''
	json_data = {
	}
	headers = {
	"token": ''
	}
	ok, data = http_post(url=url, timeout=TIMEOUT, json=json_data, headers=headers,
	exception_info=f"分流推送异常")
	return data

异常

如果在使用的时候遇到"UNSAFE_LEGACY_RENEGOTIATION_DISABLED"异常,这是因为ssl加密不支持了,需要跟换加密方式,解决方案如需下:

import ssl
import urllib3
from requests.adapters import HTTPAdapter

class CustomHttpAdapter (requests.adapters.HTTPAdapter):
    '''Transport adapter" that allows us to use custom ssl_context.'''

    def __init__(self, ssl_context=None, **kwargs):
        self.ssl_context = ssl_context
        super().__init__(**kwargs)

    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = urllib3.poolmanager.PoolManager(
            num_pools=connections, maxsize=maxsize,
            block=block, ssl_context=self.ssl_context)

# 把http_base函数用下边的替换:
def http_base(func):
    @functools.wraps(func)
    def decorator(*args, **kwargs):
        timeout = kwargs.get("timeout")
        exception_info = kwargs.pop("exception_info", None)  # 异常时需要打印的信息
        exception_info = f"【{exception_info}】" if exception_info else ""
        retry = kwargs.pop("retry", 0)
        ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
        ctx.options |= 0x4
        _session = requests.Session()
        _session.mount("http://", CustomHttpAdapter(ctx, max_retries=retry))
        _session.mount("https://", CustomHttpAdapter(ctx, max_retries=retry))
        try:
            kwargs["session"] = _session
            response = func(*args, **kwargs)
            if response.status_code != 200:
                logger.error(f"{exception_info},外部接口调用状态错误:{args, kwargs}\n,错误码:{response.status_code}")
                return False, dict()
            else:
                return True, response.json()
        except requests.exceptions.ReadTimeout:
            _timeout = timeout * retry if retry else timeout
            logger.error(f"{exception_info},外部接口调用超时:{args, kwargs}\n请求时长:{_timeout}S")
            return False, dict()
        except Exception as e:
            logger.error(f"{exception_info},外部接口调用异常:{args, kwargs}\n{traceback.format_exc()}")
            return False, dict()

    return decorator

上边最主要的是改了一下内容:
image

posted @ 2022-03-24 11:02  一枚码农  阅读(62)  评论(0编辑  收藏  举报