-
Notifications
You must be signed in to change notification settings - Fork 1
/
dh_requests.html
148 lines (136 loc) · 12.8 KB
/
dh_requests.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<!DOCTYPE html>
<html lang="vi">
<head>
<title>Tin tức Python PyMI.vn</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="utf-8" />
<link href="https://n.pymi.vn/feeds/all.atom.xml" type="application/atom+xml" rel="alternate" title="Tin tức Python PyMI.vn Full Atom Feed" />
<!-- twitter card metadata -->
<meta name="twitter:site" content="">
<meta name="twitter:title" content="[Deep Reading] Chọc sâu vào thư viện dùng phổ biến nhất của Python: lib requests">
<meta name="twitter:description" content="Đọc code Python requests cùng PyMivn">
<!-- OG Tags -->
<meta property="og:url" content="./dh_requests.html"/>
<meta property="og:title" content="[Deep Reading] Chọc sâu vào thư viện dùng phổ biến nhất của Python: lib requests | Tin tức Python PyMI.vn" />
<meta property="og:description" content="Đọc code Python requests cùng PyMivn" />
<!-- favicon -->
<!-- moment.js for date formatting -->
<script src="./theme/js/moment.js"></script>
<!-- css -->
<link rel="stylesheet" type="text/css" href="./theme/css/main.css" />
<script>
/*! grunt-grunticon Stylesheet Loader - v2.1.2 | https://github.com/filamentgroup/grunticon | (c) 2015 Scott Jehl, Filament Group, Inc. | MIT license. */
(function(e){function t(t,n,r,o){"use strict";function a(){for(var e,n=0;u.length>n;n++)u[n].href&&u[n].href.indexOf(t)>-1&&(e=!0);e?i.media=r||"all":setTimeout(a)}var i=e.document.createElement("link"),l=n||e.document.getElementsByTagName("script")[0],u=e.document.styleSheets;return i.rel="stylesheet",i.href=t,i.media="only x",i.onload=o||null,l.parentNode.insertBefore(i,l),a(),i}var n=function(r,o){"use strict";if(r&&3===r.length){var a=e.navigator,i=e.Image,l=!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect||!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")||e.opera&&-1===a.userAgent.indexOf("Chrome")||-1!==a.userAgent.indexOf("Series40")),u=new i;u.onerror=function(){n.method="png",n.href=r[2],t(r[2])},u.onload=function(){var e=1===u.width&&1===u.height,a=r[e&&l?0:e?1:2];n.method=e&&l?"svg":e?"datapng":"png",n.href=a,t(a,null,null,o)},u.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==",document.documentElement.className+=" grunticon"}};n.loadCSS=t,e.grunticon=n})(this);(function(e,t){"use strict";var n=t.document,r="grunticon:",o=function(e){if(n.attachEvent?"complete"===n.readyState:"loading"!==n.readyState)e();else{var t=!1;n.addEventListener("readystatechange",function(){t||(t=!0,e())},!1)}},a=function(e){return t.document.querySelector('link[href$="'+e+'"]')},c=function(e){var t,n,o,a,c,i,u={};if(t=e.sheet,!t)return u;n=t.cssRules?t.cssRules:t.rules;for(var l=0;n.length>l;l++)o=n[l].cssText,a=r+n[l].selectorText,c=o.split(");")[0].match(/US\-ASCII\,([^"']+)/),c&&c[1]&&(i=decodeURIComponent(c[1]),u[a]=i);return u},i=function(e){var t,o,a;o="data-grunticon-embed";for(var c in e)if(a=c.slice(r.length),t=n.querySelectorAll(a+"["+o+"]"),t.length)for(var i=0;t.length>i;i++)t[i].innerHTML=e[c],t[i].style.backgroundImage="none",t[i].removeAttribute(o);return t},u=function(t){"svg"===e.method&&o(function(){i(c(a(e.href))),"function"==typeof t&&t()})};e.embedIcons=i,e.getCSS=a,e.getIcons=c,e.ready=o,e.svgLoadedCallback=u,e.embedSVG=u})(grunticon,this);
grunticon(["./theme/css/icons.data.svg.css", "./theme/css/icons.data.png.css", "./theme/css/icons.fallback.css"]);
</script>
<noscript><link href="./theme/css/icons.fallback.css" rel="stylesheet"></noscript>
<!-- menu toggle javascript -->
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", initMenu);
function initMenu(){
var menu = document.getElementById("menu");
var menulink = document.getElementById("menu-link");
menulink.addEventListener("click", function toggleMenu(){
window.event.preventDefault();
menulink.classList.toggle('active');
menu.classList.toggle('active');
});
};
</script>
<meta name="description" content="Đọc code Python requests cùng PyMivn" />
<meta name="tags" content="deep reading" />
<meta name="tags" content="requests" />
<meta name="tags" content="code" />
</head>
<body>
<div role="banner" id="masthead">
<header>
<h1><a href="/">Pymiers's Blog</a></h1>
<a href="#menu" id="menu-link">more stuff</a>
<nav id="menu">
<ul>
<li><a href="./category/features.html">features</a></li>
<li class="active"><a href="./category/news.html">news</a></li>
<li><a href="./category/pymivn.html">pymi.vn</a></li>
</ul>
</nav>
</header>
</div>
<div class="page" role="main">
<div class="article" role="article">
<article>
<footer>
<a name="top"></a>
<p>
<time datetime=" 2022-07-29 00:00:00+07:00">
<script>document.write(moment('2022-07-29 00:00:00+07:00').format('LL'));</script>
</time>
</p>
</footer>
<header>
<h2>
[Deep Reading] Chọc sâu vào thư viện dùng phổ biến nhất của Python: lib requests
</h2>
<center>
<h4>
by Pymier0
</h4>
</center>
</header>
<div class="content">
<p><img alt="img" src="https://images.unsplash.com/photo-1470509037663-253afd7f0f51?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwyMzI1MzN8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NTkxMDIxMDM&ixlib=rb-1.2.1&q=80&w=600"></p>
<p>Nếu 10 năm trước, khi nói bạn “học sâu”, người ta nghĩ tới việc tìm hiểu thật kỹ, chọc sâu vào qua nhiều tầng lớp để nắm thật chắc kiến thức, thì sau 10 năm marketing, Deep Learning - một nhánh của <span class="caps">AI</span>, được dịch sang tiếng Việt với tên “học sâu”, đã chiếm mất nghĩa của từ học sâu ban đầu.</p>
<p>Vậy nên chúng tôi gọi là deep reading, nghe cho nó đỡ lẫn.</p>
<p>Loạt bài viết deep reading đi sâu vào các dòng code của các thư viện Python, xem chúng được viết thế nào, bí hiểm ra sao. Và lên thớt đầu tiên chính là thư viện được download nhiều số 1 của Python: requests.</p>
<h2><a href="https://github.com/psf/requests/tree/v2.28.1/requests">Cấu trúc thư mục</a></h2>
<p>Code thư viện nằm gọn trong 1 thư mục tên “requests”, cùng level nó có 1 thư mục tên “tests”. Trong requests, chỉ có 18 files py và không có thư mục con nào:</p>
<div class="highlight"><pre><span></span><code>ls requests/
adapters.py auth.py compat.py exceptions.py hooks.py _internal_utils.py packages.py status_codes.py utils.py
api.py certs.py cookies.py help.py __init__.py models.py sessions.py structures.py __version__.py
</code></pre></div>
<h3><a href="https://github.com/psf/requests/blob/v2.28.1/setup.py#L61-L65">Dependencies</a></h3>
<p>requests phụ thuộc trực tiếp vào 4 thư viện, đáng kể nhất là urllib3.</p>
<div class="highlight"><pre><span></span><code><span class="n">requires</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">"charset_normalizer>=2,<3"</span><span class="p">,</span>
<span class="s2">"idna>=2.5,<4"</span><span class="p">,</span>
<span class="s2">"urllib3>=1.21.1,<1.27"</span><span class="p">,</span>
<span class="s2">"certifi>=2017.4.17"</span><span class="p">,</span>
<span class="p">]</span>
</code></pre></div>
<h3><a href="https://github.com/psf/requests/blob/v2.28.1/requests/__init__.py"><code>__init__.py</code></a></h3>
<p>File đầu tiên nên đọc là <code>__init__.py</code> nó chứa những gì ta có thể truy cập khi gõ <code>requests.</code>, ví dụ như <code>requests.get</code>. File này chỉ import các function, class từ các file khác vào.</p>
<h3><a href="https://github.com/psf/requests/blob/v2.28.1/requests/api.py"><code>api.py</code></a></h3>
<p>Các function tiện lợi requests.get requests.post … đều nằm trong api.py. File này chứa các function ứng với các <span class="caps">HTTP</span> verb/method, và chỉ có vậy. Code cũng rất đơn giản:</p>
<div class="highlight"><pre><span></span><code><span class="k">def</span> <span class="nf">request</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="k">with</span> <span class="n">sessions</span><span class="o">.</span><span class="n">Session</span><span class="p">()</span> <span class="k">as</span> <span class="n">session</span><span class="p">:</span>
<span class="k">return</span> <span class="n">session</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="n">method</span><span class="o">=</span><span class="n">method</span><span class="p">,</span> <span class="n">url</span><span class="o">=</span><span class="n">url</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">"""... đã bỏ comment cho ngắn"""</span>
<span class="k">return</span> <span class="n">request</span><span class="p">(</span><span class="s2">"get"</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">params</span><span class="o">=</span><span class="n">params</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</code></pre></div>
<p><code>get</code> thực chất chỉ gọi <code>request</code>, function <code>request</code> tạo một Session và dùng nó để kết nối <span class="caps">HTTP</span> qua <code>session.request</code>.</p>
<h3><a href="https://github.com/psf/requests/blob/v2.28.1/requests/sessions.py#L355">sessions.py</a> - chứa class Session, trái tim của requests</h3>
<p>Một Session sẽ chứa đủ thông tin cần thiết như url, headers, auth, proxy, … rồi thực hiện gọi tới <span class="caps">HTTP</span> adapter để thực hiện kết nối.</p>
<h3><a href="https://github.com/psf/requests/blob/v2.28.1/requests/adapters.py#L101">adapters.py</a> - nơi kết nối thực sự xảy ra</h3>
<p>Dù là thực hiện kết nối <span class="caps">HTTP</span> thì trên Python cũng có rất nhiều thư viện, từ thư viện có sẵn của Python stdlib cho tới thư viện bên ngoài và dùng mặc định cho requests: urllib3. Function <a href="https://github.com/psf/requests/blob/v2.28.1/requests/adapters.py#L436"><code>send</code></a> trong adapters thực hiện kết nối với “Request” được chuẩn bị, và trả về Response. Code của send dài 150 dòng, không có gì quá phức tạp.</p>
<p>Còn gì không? còn nhiều và bạn có thể tự khám phá, nhưng từng ấy cũng đủ vừa sâu để hiểu rõ hơn về requests, hơn hàng ngàn lập trình viên ngoài kia rồi.</p>
<p>Happy deeeeeep reading.</p>
<p>Hết.</p>
<p>Đăng ký ngay tại <a href="https://pymi.vn">PyMI.vn</a> để học Python tại Hà Nội <span class="caps">TP</span> <span class="caps">HCM</span> (Sài Gòn),
trở thành lập trình viên #python chuyên nghiệp ngay sau khóa học.</p>
</div>
<div class="back-to-top">
<a href="#top">back to top</a>
</div>
</article>
</div>
<!-- end article -->
<footer>
<div class="icons">
<a href="https://github.com/pymivn" target="_blank"><div class="icon-github icon"></div></a>
</div>
<p>© <script>document.write(moment().format('YYYY'));</script> Pymiers</p>
</footer>
</div>
</body>
</html>