This article was first published on:Walker AI

When we do automated testing, we all want to write code that is as clean as possible, with as little code duplication as possible. Then, we can consider encapsulating the request types of request (e.g., Get, Post, Delect request). This way, we can make requests directly when writing use cases.

1. Source code analysis

Let’s take a look at the source code for Get, Post, Delect, etc., and see what features they have.

(1) Get request source code


	def get(self, url, **kwargs) :
		r"""Sends a GET request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response """
		
		kwargs.setdefault('allow_redirects'.True)
		return self.request('GET', url, **kwargs) 
Copy the code

(2) Post request source code


	def post(self, url, data=None, json=None, **kwargs) :
		r"""Sends a POST request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param data: (optional) Dictionary, list of tuples, bytes, or file-like object to send in the body of the :class:`Request`. :param json: (optional) json to send in the body of the :class:`Request`. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response """
	
		return self.request('POST', url, data=data, json=json, **kwargs)  
Copy the code

(3) Delect request source code


    def delete(self, url, **kwargs) :
        r"""Sends a DELETE request. Returns :class:`Response` object. :param url: URL for the new :class:`Request` object. :param \*\*kwargs: Optional arguments that ``request`` takes. :rtype: requests.Response """
    
        return self.request('DELETE', url, **kwargs)

Copy the code

(4) Analysis results

We find that whether it’s a Get request, a Post request, or a Delect request, they all end up returning a Request function. So, let’s take a look at the source code for the request function.


	def request(self, method, url,
	        params=None, data=None, headers=None, cookies=None, files=None,
	        auth=None, timeout=None, allow_redirects=True, proxies=None,
	        hooks=None, stream=None, verify=None, cert=None, json=None) :
	    """Constructs a :class:`Request <Request>`, prepares it and sends it.
	    Returns :class:`Response <Response>` object.
	
	    :param method: method for the new :class:`Request` object.
	    :param url: URL for the new :class:`Request` object.
	    :param params: (optional) Dictionary or bytes to be sent in the query
	        string for the :class:`Request`.
	    :param data: (optional) Dictionary, list of tuples, bytes, or file-like
	        object to send in the body of the :class:`Request`.
	    :param json: (optional) json to send in the body of the
	        :class:`Request`.
	    :param headers: (optional) Dictionary of HTTP Headers to send with the
	        :class:`Request`.
	    :param cookies: (optional) Dict or CookieJar object to send with the
	        :class:`Request`.
	    :param files: (optional) Dictionary of ``'filename': file-like-objects``
	        for multipart encoding upload.
	    :param auth: (optional) Auth tuple or callable to enable
	        Basic/Digest/Custom HTTP Auth.
	    :param timeout: (optional) How long to wait for the server to send
	        data before giving up, as a float, or a :ref:`(connect timeout,
	        read timeout) <timeouts>` tuple.
	    :type timeout: float or tuple
	    :param allow_redirects: (optional) Set to True by default.
	    :type allow_redirects: bool
	    :param proxies: (optional) Dictionary mapping protocol or protocol and
	        hostname to the URL of the proxy.
	    :param stream: (optional) whether to immediately download the response
	        content. Defaults to ``False``.
	    :param verify: (optional) Either a boolean, in which case it controls whether we verify
	        the server's TLS certificate, or a string, in which case it must be a path
	        to a CA bundle to use. Defaults to ``True``.
	    :param cert: (optional) if String, path to ssl client cert file (.pem).
	        If Tuple, ('cert', 'key') pair.
	    :rtype: requests.Response
	    """
	    # Create the Request.
	    req = Request(
	        method=method.upper(),
	        url=url,
	        headers=headers,
	        files=files,
	        data=data or {},
	        json=json,
	        params=params or {},
	        auth=auth,
	        cookies=cookies,
	        hooks=hooks,
	    )
	    prep = self.prepare_request(req)
	
	    proxies = proxies or {}
	
	    settings = self.merge_environment_settings(
	        prep.url, proxies, stream, verify, cert
	    )
	
	    # Send the request.
	    send_kwargs = {
	        'timeout': timeout,
	        'allow_redirects': allow_redirects,
	    }
	    send_kwargs.update(settings)
	    resp = self.send(prep, **send_kwargs)
	
	    return resp    

Copy the code

As you can see from the request source, it creates a request, puts all the parameters in it, and then calls self.send(), passing the request. Here we will not analyze the back of the send method source, interested students can understand their own.

After analyzing the source code, we found that we do not need to define other methods such as Get and Post in a separate class, and then call Request separately. Instead, we just call Request.

2. requests

Code examples:


	import requests
	
	class RequestMain:
	    def __init__(self) :
	        Session manager requests.session(): maintains sessions and saves parameters across requests.
	        # instantiate session
	        self.session = requests.session()
	
	    def request_main(self, method, url, params=None, data=None, json=None, headers=None, **kwargs) :
	        """ :param method: request method: param URL: request address :param params: dictionary or bytes added as parameters to the URL :param data: Data type parameter, dictionary, byte sequence, or file object, as the content of Request :param JSON: JSON parameter, as the content of Request: Param headers: Request header, dictionary: Param kwargs: If there are additional arguments, pass them in the mutable argument dictionary form :return: """
	
	        Catch the exception
	        try:
	            Encapsulates the request request, including the request method, request address, request parameters, and request information. Verify: True/False; Cert: indicates the local SSL certificate. If SSL authentication is not required, you can remove these two input parameters.
	            re_data = self.session.request(method, url, params=params, data=data, json=json, headers=headers, cert=(client_crt, client_key), verify=False, **kwargs)
	        # Display specific information about exception handling error
	        except Exception as e:
	            # print exception
	            print("Request failed: {0}".format(e))
	        Return the result of the response
	        return re_data


	if __name__ == '__main__':
	    # request address
	    url = 'Requested address'
	    Request parameters
	    payload = {"Request parameters"}
	    # request header
	    header = {"headers"}
	    RequestMain()
	    re = RequestMain()
	    # call request_main and pass the parameter
	    request_data = re.request_main("Request mode", url, json=payload, headers=header)
	    Print the response result
	    print(request_data.text)  
Copy the code

Note: if the interface you set does not require SSL authentication, you can remove the parameters cert and Verify.

3. Summary

This article is just a brief introduction to Python interface automation request encapsulation, there are many optimization areas, I hope to discuss with you.


PS: more dry technology, pay attention to the public, | xingzhe_ai 】, and walker to discuss together!