+1

PyMOTM: Requests

PyMOTM - Python Module of the Month. Một phiên bản tiếng Việt của PyMOTW (Python Module of the Week) nhằm chia sẻ đến mọi người những module hay ho cho Python! Để mở đầu cho series này, mình xin giới thiệu module Requests nhé 😄!

Requests - HTTP for humans

Mục đích: Làm việc với các HTTP request

Mặc định, Python cũng hỗ trợ chúng ta làm việc với các HTTP request thông qua module urllib2. Nhưng nó khá là lằng nhằng và rắc rối. Chúng ta thử xem qua 2 ví dụ dưới đây để rõ hơn nhé:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import urllib2

gh_url = 'https://api.github.com'

req = urllib2.Request(gh_url)

password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_manager.add_password(None, gh_url, 'user', 'pass')

auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
opener = urllib2.build_opener(auth_manager)

urllib2.install_opener(opener)

handler = urllib2.urlopen(req)

print handler.getcode()
print handler.headers.getheader('content-type')

# ------
# 200
# 'application/json'
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests

r = requests.get('https://api.github.com', auth=('user', 'pass'))

print r.status_code
print r.headers['content-type']

# ------
# 200
# 'application/json'

Ở 02 ví dụ trên đều gọi tới API của Github với thông tin username và password. Và bạn cũng đã thấy, ở ví dụ 2 chúng ta sẽ phải viết code ít hơn, dễ dàng để hiểu và nhớ hơn, đúng không ạ 😄? OK, bây giờ chúng ta sẽ đi vào chi tiết cách cài đặt và những tính năng chính của module Requests nhé 😄!

Cài đặt

Trước tiên, chúng ta có thể kiểm tra xem trên máy của mình đã cài module này chưa hoặc nếu đã cài rồi, chúng ta xem mình đã ở phiên bản mới nhất chưa bằng 1 đoạn code ngắn trên terminal như sau:

python -c "import requests; print(requests.__version__);"

Sau khi thử đoạn code trên, nếu máy bạn đã cài rồi thì nó sẽ xuất hiện phiên bản của module requests. Còn không, bạn sẽ nhận được một lỗi như sau:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named requests

Nếu chưa cài, bạn có thể cài module này bằng 2 cách là thông qua pip hoặc easy_install

# Easy install
easy_install requests
# PIP
pip install requests

Hoặc nếu đã cài rồi mà chưa phải là phiên bản mới nhất (phiên bản 2.9.1), bạn có thể update bằng 2 cách sau, cũng thông qua PIP hoặc easy_install:

# Easy install
easy_install -U requests

# PIP
pip install -U requests

Vậy là đã cài đặt xong, để chắc chắn, bạn hãy chạy lại lệnh phía trên để kiểm tra xem việc cài đặt có thật sự thành công không nhé 😄! Sang phần tiếp theo, mình sẽ giới thiệu về các tính năng được module requests hỗ trợ.

Các tính năng

  • International Domains and URLs
  • Keep-Alive & Connection Pooling
  • Sessions with Cookie Persistence
  • Browser-style SSL Verification
  • Basic/Digest Authentication
  • Elegant Key/Value Cookies
  • Automatic Decompression
  • Automatic Content Decoding
  • Unicode Response Bodies
  • Multipart File Uploads
  • HTTP(S) Proxy Support
  • Connection Timeouts
  • Streaming Downloads
  • .netrc Support
  • Chunked Requests
  • Thread-safety

Requests làm việc tốt với 2 phiên bản của Python là 2.6, 3.5 và PyPy. Tiếp theo, chúng ta sẽ thử làm việc với module này bằng cách tạo một vài request đơn giản nhé 😄

Make your first request

Để thử, bạn có thể tạo 1 file với extension là .py hoặc thực hiện luôn trên terminal với Python interpreter. Mình sẽ chọn cách 2 là dùng Python interpreter cho tiện 😄! Để sử dụng Python interpreter, bạn chỉ cần đơn giản là gõ python (mặc định là sẽ sử dụng Python 2) hoặc python3 (cho phiên bản Python 3) trên terminal là có thể sử dụng. Chúng ta thử một request đơn giản là lấy các events mới nhất trên Github (bao gồm các event như push, merge, create, ... - đối với các public repository):

<pre>
>> import requests
>> r = requests.get('https://api.github.com/events')
>> r.status_code
200
>> r.headers['content-type']
>> 'application/json; charset=utf-8'
</pre>

Vậy là chúng ta đã có một Response object mà Github API trả về là một JSON, bạn có thể lấy và làm việc luôn với JSON object của response như sau (kết quả tùy thuộc vào mỗi người và mỗi khoảng thời gian chúng ta gọi API):

<pre>
>> events = r.json()
>> events[0]['id']
u'3812051780'
>> events[0]['type']
u'PushEvent'
</pre>

Ví dụ trên là GET method, vậy còn các method khác như POST, PUT, DELETE, ... thì sao? Requests hỗ trợ bạn như sau:

<pre>
>> r = requests.post('Request URL', data = {'key': 'value'})
>> r = requests.delete('Request URL')
>> r = requests.put('Request URL')
>> r = requests.options('Request URL')
</pre>

Và requests cũng hỗ trợ bạn có thể viết như sau:

<pre>
>> r = requests.request('Method name', 'Request URL', [Extra options])
</pre>

Passing parameters in URLs

Bạn muốn sử dụng query string trong URL. Bạn có thể làm như sau:

<pre>
>> payload = {'key1': 'value1', 'key2': 'value2', 'keyn': 'valuen'}
>> r = requests.get('Request URL', params=payload)
>> r.url
u'http://domain.gtld/?keyn=valuen&key2=value2&key1=value1'
</pre>

POST a Multipart-Encoded File

  • Binary file
<pre>
>> files = {'file': open('Path to file', 'rb')}
>> r = requests.post('Request URL', files=files)
</pre>
  • String file
<pre>
>> # files = {'file': ('File name', 'File content')}
>> files = {'file': ('lorem.txt', 'lorem ipsum dolor sit amet')}
>> r = requests.post('Request URL', files=files)
</pre>

Response status codes

Bạn muốn kiểm tra status code của một request trước khi thực hiện các nghiệp vụ tiếp theo?

<pre>
>> r = requests.get('Request URL')
>> r.status_code
</pre>

Và module requests cũng hỗ trợ chúng ta một danh sách các status code để bạn có thể kiểm tra.

<pre>
>> r = requests.get('Not found URL')
>> r.status_code == requests.codes.not_found
</pre>

Để xem đầy đủ danh sách các status code của requests, bạn có thể sử dụng một trong hai lệnh sau:

<pre>
>> vars(requests.codes)
>> dir(requests.codes)
</pre>

Response Headers

Chúng ta cũng có thể xem headers mà server trả về cho chúng ta bằng cách sau:

<pre>
>> r.headers
>> r.headers['user-agent']
>> r.headers.get('user-agent')
</pre>

Cá nhân mình khuyên bạn nên sử dụng headers.get('key') để đảm bảo, tránh các exception có thể xảy ra nếu một key mà bạn muốn lấy nó không có trong headers trả về. Vì hàm get() sẽ trả về kiểu dữ liệu là None nếu key đó không tồn tại.

<pre>
>> r = requests.get('https://api.github.com/events')
>> print r.headers['user-agent']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/namnv609/Desktop/abc/local/lib/python2.7/site-packages/requests-2.9.1-py2.7.egg/requests/structures.py", line 54, in __getitem__
    return self._store[key.lower()][1]
KeyError: 'user-agent'
>> print r.headers.get('user-agent')
None
>> r.headers.get('user-agent') == None
True
</pre>

Trên đây, mình đã giới thiệu sơ qua về module Requests. Đủ để bạn có thể bắt đầu và làm việc ngay với module này. Nếu bạn muốn tìm hiểu kỹ hơn, bạn có thể vào trang chủ của nó tại: http://docs.python-requests.org/en/master/ để đọc thêm về các vấn đề nâng cao như sử dụng Session object, Cookie JAR, SSL Cert Verification, ... nhé 😄! Có dịp mình sẽ viết bài hướng dẫn mọi người sử dụng module requests với cookie trực tiếp từ trình duyệt (Chrome, Firefox, Safari) nhé 😄!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí