【python】requests多项目请求封装

0.背景

背景:成熟的项目体系或架构中,一定是多个项目或模块在线上同时运行
缘由:解决公司实际业务接口自动化测试中跨项目请求联调

1.封装

"""
@Author: yl
@File: new_request.py
@Time: 2023/02/13 20:05:14
"""
import ujson
import logging
import requests
import warnings
import threading
from setting import app_cof
from requests import Response
from typing import Any, Literal, TypeVar

T = TypeVar("T")
requests.packages.urllib3.disable_warnings()
warnings.filterwarnings('ignore')


def dictToUriStr(content: dict):
    """字典转为uri格式的字符串"""
    if not content:
        return ""
    res: str = "?"
    keys: list = list(content.keys())
    for index, item in enumerate(content):
        res += (item + "=")
        res += str(content.get(item))
        if index < len(keys) - 1:
            res += "&"
    return res


# noinspection DuplicatedCode
class RequestHandle:
    """requests请求封装"""
    _instance: dict = {}
    lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if cls._instance :
            return cls._instance
        with cls.lock:
            if not cls.__instance:
                cls.__instance = super().__new__(cls)
        return cls.__instance

    def visited(self, method: str, url: str, **kwargs) -> Response:
        return requests.request(method=method.upper(), url=url, **kwargs)

    def currency(
        self,
        _module: str,
        method: Literal["get", "post", "put", "patch", "delete"],
        point: str,
        content_type: str = "application/json;charset=UTF-8",
        resful: bool = True,
        **kwargs
    ) -> T | Response:
        """
        Args:
            _module(str): request module
            method (str): request method
            point (str): request url
            content_type (str): request headers content type, default: json
            resful (bool): whether to serialize output
        """
        headers: dict = {
            "Content-Type": content_type,
            "Connection": "Keep-Alive",
            "Accept-Encoding": "gzip"
        }
        match _module:
            case "first":
                headers["access-token"] = self.db.get("FirstToken")
                _url: str = app_cof.FirstUrl + point
            case "second":
                headers["access-token"] = self.db.get("SecondToken")
                _url: str = app_cof.SecondUrl + point
            case "third":
                headers["access-token"] = self.db.get("ThirdToken")
                _url: str = app_cof.ThirdUrl + point
            case "fourth":
                headers["access-token"] = self.db.get("FourthToken")
                _url: str = app_cof.FourthUrl + point
            case "fifth":
                headers["access-token"] = self.db.get("FifthToken")
                _url: str = app_cof.FifthUrl + point
            case _:
                raise Exception("request module to be implemented!")
        params: dict = kwargs.get("params", {})

        # output request method and uri information
        logging.info("{}, {}".format(method, point + dictToUriStr(params)))

        res: Response = self.visited(method, _url, headers=headers, **kwargs)
        assert res.status_code in (200, 201, 204)
        if resful:
            return ujson.loads(str(res.content, encoding="utf-8"))
        return res
 
    def first_request_json(
        self,
        method: str,
        point: str,
        resful: bool = False,
        **kwargs
    ) -> Any | Response:
        """First App Request, Type: json"""
        return self.currency(
            _module="first",
            method=method,
            point=point,
            resful=resful,
            **kwargs
        )

    def first_request_xml(
        self,
        method: str,
        point: str,
        content_type: str = "text/xml;charset=utf-8",
        resful: bool = False,
        **kwargs
    ) -> Any | Response:
        """First App Request, Type: xml"""
        return self.currency(
            _module="first",
            method=method,
            point=point,
            content_type=content_type,
            resful=resful,
            **kwargs
        )

    def second_request_json(
        self,
        method: str,
        point: str,
        resful: bool = True,
        **kwargs
    ) -> Any | Response:
        """Second App Request, Type: json"""
        return self.currency(
            _module="second",
            method=method,
            point=point,
            resful=resful,
            **kwargs
        )
    ...


reh: RequestHandle = RequestHandle()

2.使用

"""
@Author: yl
@File: new_request.py
@Time: 2023/02/13 20:15:28
"""
import allure
from utils.new_request import reh


@allure.story("查询用户")
def getUserList(user_id: str, **kwargs) -> Any | Response:
    """
    :param user_id: 用户id
    """
    point: str = f"/api/user/list"
    params: dict = {
        "keyword": kwargs.get("keyword", ""),
        "page": kwargs.get("page", 0),
        "size": kwargs.get("size", 10),
        "sort": kwargs.get("keyword", "id,desc")
    }
    content: Response = reh.first_request_json('get', point, params=params)
    return content


@allure.story("新增用户")
def postUserAdd(mobile: str, pwd: str, role: str = "stu", **kwargs) -> Any | Response:
    """
    :param mobile: 手机号
    :param pwd: 密码
    :param role: 角色, 默认: 学生
    """
    point: str = f"/api/user/save"
    params: dict = {
        "role": role
    }
    payload: dict = {
    	"mobile": mobile,
    	"pwd": pwd
    }
    content: Response = reh.first_request_json('post', point, params=params, json=payload)
    return content
  1. from setting import app_cof: 项目配置项
  2. self.db.get(“xxx”): 登陆后将token存储在db中获取
  3. 每个项目的请求,如first_request_json, second_request_json… 均可以实现定制化请求;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值