Detailed description of the application programming interface of the Python programming concept

Source: Internet
Author: User
Tags auth data structures error code exception handling in python


When writing a software package (library), a well-designed API is as important as the functionality of the package (if, of course, you want to be used by others), what is the standard of a good API? In this article, I will compare the differences between the Requests library and the Urllib library (which belongs to the Python Standard library) in some typical HTTP usage scenarios, and publish some of the author's views, and discuss why the Requests library becomes the actual standard library in the Python user base 。

In the next discussion we will use Python 3.5 and Requests 2.10.0.

This article was adapted from my speech at the local Python party last week. The reader can find the slides of the speech here.

Requests and Urllib

Use Case 1: send a GET request

Import Urllib.request
Urllib.request.urlopen (' http://python.org/')
Import requests
Requests.get (' http://python.org/')
<response [200]>
Explicit (API endpoint) superior to obscure

Requests libraries send requests for more concise purposes (and therefore clearer)
The Urllib library sends a GET request without omitting the data parameter, which is more obscure
The function name of the Requests library clearly explains the purpose of the function
Useful Object Notation

As the reader observes, the Requests library returns a string containing the request status code (which is implemented through the __REPR () __ method)
The Urllib library returns only the default (Fuzzy) object representation
Code fragment

requests/api.py:

Def request (method, URL, **kwargs):
With sessions. Session () as session:
Return Session.request (Method=method, Url=url, **kwargs)

def get (URL, Params=none, **kwargs):
Kwargs.setdefault (' allow_redirects ', True)
Return request (' Get ', url, params=params, **kwargs)

def post (URL, Data=none, Json=none, **kwargs):
Return request (' post ', URL, Data=data, Json=json, **kwargs)
All HTTP actions have a similar process before they are sent, so a request () function is implemented as the main process control function.
All HTTP actions have a corresponding "auxiliary function", and then call the request () function in the helper function, which makes our function calls more explicit.
Use Case 2: Get the request status code

Import Urllib.request
r = Urllib.request.urlopen (' http://python.org/')
R.getcode ()
200
Import requests
r = Requests.get (' http://python.org/')
R.status_code
200
No need for getters and setters.

Getting the attributes of an object by reading the property, rather than by invoking the method, can make the code clearer.
If the reader is exposed to other object-oriented languages (such as Java), you may be able to modify the object's properties by setting getters and setters. This is not necessary in Python, and readers can accomplish this only by using @property adorners.
Code fragment

http/client.py:

Class HttpResponse (IO. Bufferediobase):

# ...

def getcode (self):
Return Self.status
Urllib Library (or HTTP) returns the properties of a class with an "getter" method
Use Case 3: Encode, send, and decode POST requests

Import Urllib.parse
Import Urllib.request
Import JSON

url = ' Http://www.httpbin.org/post '
Values = {' name ': ' Michael Foord '}

data = Urllib.parse.urlencode (values). Encode ()
Response = Urllib.request.urlopen (URL, data)
BODY = Response.read (). Decode ()
Json.loads (body)
Import requests

url = ' Http://www.httpbin.org/post '
data = {' name ': ' Michael Foord '}

Response = Requests.post (URL, data=data)
Response.json ()
Common features to be easy to use

The Requests library provides a preset way to encode data and parse JSON responses, but readers need to implement these methods themselves when using the Urllib library.
When designing APIs, readers need to think: what is the main purpose of the package? What interfaces can be added that can be more easily met for these purposes?
Similarly, the Requests library provides an elegant way to send JSON data:

Import requests

url = ' Http://www.httpbin.org/post '
data = {' name ': ' Michael Foord '}

Response = Requests.post (URL, json=data)
Response.json ()
Use case 4: send a validated request

The following code completes a long-term authentication for HTTP requests and sends a request:

Import Urllib.request

Gh_url = ' Https://api.github.com/user '

Password_mgr = Urllib.request.HTTPPasswordMgrWithDefaultRealm ()
Password_mgr.add_password (None, Gh_url, ' user ', ' pswd ')
Handler = Urllib.request.HTTPBasicAuthHandler (password_mgr)

Opener = Urllib.request.build_opener (handler)
Opener.open (Gh_url)
Import requests

Session = requests. Session ()
Session.auth = (' user ', ' pswd ')
Session.get (' Https://api.github.com/user ')
But what if we just need to complete one HTTP request? Do you need so much code? Using the Requests library requires only the following code to complete:

Import requests

Requests.get (' Https://api.github.com/user ', auth= (' user ', ' pswd '))
Contains both simple and advanced usage

The Requests library has both a simple use to send a single request and a complex use to send multiple requests.
Do not allow users to complete simple tasks also need to go through a lengthy process.
Try to use Python's built-in data structure instead of creating new data structures

The Requests library uses Python's built-in data structure, which makes it very easy to use. Users do not need to understand the structure inside the Requests library.
Library code

requests/models.py

def prepare_auth (self, auth, url= "):
"" "Prepares the given HTTP auth data." "

# ...

If Auth:
If Isinstance (auth, tuple) and Len (auth) = 2:
# special-case Basic HTTP Auth
Auth = Httpbasicauth (*auth)
The Requests library converts (user, pass) tuples internally into an authentication class
Use case 5: Handling Errors

From urllib.request import Urlopen
Response = Urlopen (' Http://www.httpbin.org/geta ')
Response.getcode ()
---------------------------------------------------------------------------

Httperror Traceback (most recent call last)

<ipython-input-45-5fba039d189a> in <module> ()
1 from urllib.request import Urlopen
----> 2 response = Urlopen (' Http://www.httpbin.org/geta ')
3 Response.getcode ()


/usr/lib/python3.5/urllib/request.py in Urlopen (URLs, data, timeout, Cafile, Capath, Cadefault, context)
161 Else:
162 opener = _opener
--> 163 return Opener.open (URL, data, timeout)
164
165 def Install_opener (opener):


/usr/lib/python3.5/urllib/request.py in open (self, fullurl, data, timeout)
    470          for processor in Self.process_response.get (protocol, []):
     471             meth = getattr (processor, Meth_name)
--> 472             response = Meth ( Req, response)
    473
    474          Return response


/usr/lib/python3.5/urllib/request.py in Http_response (self, request, response)
    580          if not (<= code < $):
    581              response = Self.parent.error (
--> 582                  ' http ', request , response, Code, MSG, HDRs)
    583
    584          return response


/usr/lib/python3.5/urllib/request.py in error (self, proto, *args)
    508          if Http_err:
    509              args = (dict, ' Default ', ' Http_error_default ') + Orig_args
--> 510 & nbsp;           return Self._call_chain (*args)
     511
    # XXX probably also want an abstract factory this knows when it makes


/usr/lib/python3.5/urllib/request.py in _call_chain (self, chain, kind, Meth_name, *args)
     442         for handler in handlers:
    443 & nbsp;           func = getattr (Handler, meth_name)
--> 444              result = Func (*args)
     445             if not None:
 & nbsp;  446                 return result


/usr/lib/python3.5/urllib/request.py in Http_error_default (self, req, FP, code, MSG, HDRs)
588 class Httpdefaulterrorhandler (Basehandler):
589 def http_error_default (self, req, FP, code, MSG, HDRs):
--> 590 Raise Httperror (Req.full_url, Code, MSG, HDRs, FP)
591
592 class Httpredirecthandler (Basehandler):


Httperror:http Error 404:not FOUND
Import requests
r = Requests.get (' Http://www.httpbin.org/geta ')
R.status_code
404
Let the user choose how to handle the error

Some programmers tend to handle errors in an unusual way, while others tend to handle errors in a way that is checked.
Some scenes are more elegant, while others are the opposite.
It is reasonable to allow the user to choose how to handle the error.
The default return error code can implement the reasonable approach described above, and the default exception handling error is not possible.
Case:

From urllib.request import Urlopen
From Urllib.error import Urlerror, Httperror
Try
Response = Urlopen (' Http://www.httpbin.org/geta ')
Except Httperror as E:
If E.code = 404:
Print (' Page not found ')
Else
Print (' All good ')
Page not found
From requests.exceptions import Httperror
Import requests
r = Requests.get (' Http://www.httpbin.org/posta ')
Try
R.raise_for_status ()
Except Httperror as E:
If E.response.status_code = 404:
Print (' Page not found ')
Page not found
Import requests
r = Requests.get (' Http://www.httpbin.org/geta ')
If R.ok:
Print (' All good ')
elif R.status_code = = Requests.codes.not_found:
Print (' Page not found ')
Page not found
The above is the full contents of this article. In preparing this speech and this article process, the author harvest quite abundant, also hoped that the reader can also have the harvest in the reading process. Readers can advise me by commenting on the comments below the post or on Twitter (@noamelf), and I am very happy to listen to these suggestions

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.