Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: recipe_engine/third_party/requests/docs/user/quickstart.rst

Issue 2164713003: Vendor requests. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/recipes-py@master
Patch Set: Fix deps.pyl Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 .. _quickstart:
2
3 Quickstart
4 ==========
5
6 .. module:: requests.models
7
8 Eager to get started? This page gives a good introduction in how to get started
9 with Requests.
10
11 First, make sure that:
12
13 * Requests is :ref:`installed <install>`
14 * Requests is :ref:`up-to-date <updates>`
15
16
17 Let's get started with some simple examples.
18
19
20 Make a Request
21 --------------
22
23 Making a request with Requests is very simple.
24
25 Begin by importing the Requests module::
26
27 >>> import requests
28
29 Now, let's try to get a webpage. For this example, let's get GitHub's public
30 timeline ::
31
32 >>> r = requests.get('https://api.github.com/events')
33
34 Now, we have a :class:`Response <requests.Response>` object called ``r``. We can
35 get all the information we need from this object.
36
37 Requests' simple API means that all forms of HTTP request are as obvious. For
38 example, this is how you make an HTTP POST request::
39
40 >>> r = requests.post('http://httpbin.org/post', data = {'key':'value'})
41
42 Nice, right? What about the other HTTP request types: PUT, DELETE, HEAD and
43 OPTIONS? These are all just as simple::
44
45 >>> r = requests.put('http://httpbin.org/put', data = {'key':'value'})
46 >>> r = requests.delete('http://httpbin.org/delete')
47 >>> r = requests.head('http://httpbin.org/get')
48 >>> r = requests.options('http://httpbin.org/get')
49
50 That's all well and good, but it's also only the start of what Requests can
51 do.
52
53
54 Passing Parameters In URLs
55 --------------------------
56
57 You often want to send some sort of data in the URL's query string. If
58 you were constructing the URL by hand, this data would be given as key/value
59 pairs in the URL after a question mark, e.g. ``httpbin.org/get?key=val``.
60 Requests allows you to provide these arguments as a dictionary, using the
61 ``params`` keyword argument. As an example, if you wanted to pass
62 ``key1=value1`` and ``key2=value2`` to ``httpbin.org/get``, you would use the
63 following code::
64
65 >>> payload = {'key1': 'value1', 'key2': 'value2'}
66 >>> r = requests.get('http://httpbin.org/get', params=payload)
67
68 You can see that the URL has been correctly encoded by printing the URL::
69
70 >>> print(r.url)
71 http://httpbin.org/get?key2=value2&key1=value1
72
73 Note that any dictionary key whose value is ``None`` will not be added to the
74 URL's query string.
75
76 You can also pass a list of items as a value::
77
78 >>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
79
80 >>> r = requests.get('http://httpbin.org/get', params=payload)
81 >>> print(r.url)
82 http://httpbin.org/get?key1=value1&key2=value2&key2=value3
83
84 Response Content
85 ----------------
86
87 We can read the content of the server's response. Consider the GitHub timeline
88 again::
89
90 >>> import requests
91
92 >>> r = requests.get('https://api.github.com/events')
93 >>> r.text
94 u'[{"repository":{"open_issues":0,"url":"https://github.com/...
95
96 Requests will automatically decode content from the server. Most unicode
97 charsets are seamlessly decoded.
98
99 When you make a request, Requests makes educated guesses about the encoding of
100 the response based on the HTTP headers. The text encoding guessed by Requests
101 is used when you access ``r.text``. You can find out what encoding Requests is
102 using, and change it, using the ``r.encoding`` property::
103
104 >>> r.encoding
105 'utf-8'
106 >>> r.encoding = 'ISO-8859-1'
107
108 If you change the encoding, Requests will use the new value of ``r.encoding``
109 whenever you call ``r.text``. You might want to do this in any situation where
110 you can apply special logic to work out what the encoding of the content will
111 be. For example, HTTP and XML have the ability to specify their encoding in
112 their body. In situations like this, you should use ``r.content`` to find the
113 encoding, and then set ``r.encoding``. This will let you use ``r.text`` with
114 the correct encoding.
115
116 Requests will also use custom encodings in the event that you need them. If
117 you have created your own encoding and registered it with the ``codecs``
118 module, you can simply use the codec name as the value of ``r.encoding`` and
119 Requests will handle the decoding for you.
120
121 Binary Response Content
122 -----------------------
123
124 You can also access the response body as bytes, for non-text requests::
125
126 >>> r.content
127 b'[{"repository":{"open_issues":0,"url":"https://github.com/...
128
129 The ``gzip`` and ``deflate`` transfer-encodings are automatically decoded for yo u.
130
131 For example, to create an image from binary data returned by a request, you can
132 use the following code::
133
134 >>> from PIL import Image
135 >>> from StringIO import StringIO
136
137 >>> i = Image.open(StringIO(r.content))
138
139
140 JSON Response Content
141 ---------------------
142
143 There's also a builtin JSON decoder, in case you're dealing with JSON data::
144
145 >>> import requests
146
147 >>> r = requests.get('https://api.github.com/events')
148 >>> r.json()
149 [{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...
150
151 In case the JSON decoding fails, ``r.json`` raises an exception. For example, if
152 the response gets a 204 (No Content), or if the response contains invalid JSON,
153 attempting ``r.json`` raises ``ValueError: No JSON object could be decoded``.
154
155 It should be noted that the success of the call to ``r.json`` does **not**
156 indicate the success of the response. Some servers may return a JSON object in a
157 failed response (e.g. error details with HTTP 500). Such JSON will be decoded
158 and returned. To check that a request is successful, use
159 ``r.raise_for_status()`` or check ``r.status_code`` is what you expect.
160
161
162 Raw Response Content
163 --------------------
164
165 In the rare case that you'd like to get the raw socket response from the
166 server, you can access ``r.raw``. If you want to do this, make sure you set
167 ``stream=True`` in your initial request. Once you do, you can do this::
168
169 >>> r = requests.get('https://api.github.com/events', stream=True)
170
171 >>> r.raw
172 <requests.packages.urllib3.response.HTTPResponse object at 0x101194810>
173
174 >>> r.raw.read(10)
175 '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
176
177 In general, however, you should use a pattern like this to save what is being
178 streamed to a file::
179
180 with open(filename, 'wb') as fd:
181 for chunk in r.iter_content(chunk_size):
182 fd.write(chunk)
183
184 Using ``Response.iter_content`` will handle a lot of what you would otherwise
185 have to handle when using ``Response.raw`` directly. When streaming a
186 download, the above is the preferred and recommended way to retrieve the
187 content.
188
189
190 Custom Headers
191 --------------
192
193 If you'd like to add HTTP headers to a request, simply pass in a ``dict`` to the
194 ``headers`` parameter.
195
196 For example, we didn't specify our user-agent in the previous example::
197
198 >>> url = 'https://api.github.com/some/endpoint'
199 >>> headers = {'user-agent': 'my-app/0.0.1'}
200
201 >>> r = requests.get(url, headers=headers)
202
203 Note: Custom headers are given less precedence than more specific sources of inf ormation. For instance:
204
205 * Authorization headers set with `headers=` will be overridden if credentials
206 are specified in ``.netrc``, which in turn will be overridden by the ``auth=` `
207 parameter.
208 * Authorization headers will be removed if you get redirected off-host.
209 * Proxy-Authorization headers will be overridden by proxy credentials provided i n the URL.
210 * Content-Length headers will be overridden when we can determine the length of the content.
211
212 Furthermore, Requests does not change its behavior at all based on which custom headers are specified. The headers are simply passed on into the final request.
213
214
215 More complicated POST requests
216 ------------------------------
217
218 Typically, you want to send some form-encoded data — much like an HTML form.
219 To do this, simply pass a dictionary to the ``data`` argument. Your
220 dictionary of data will automatically be form-encoded when the request is made::
221
222 >>> payload = {'key1': 'value1', 'key2': 'value2'}
223
224 >>> r = requests.post("http://httpbin.org/post", data=payload)
225 >>> print(r.text)
226 {
227 ...
228 "form": {
229 "key2": "value2",
230 "key1": "value1"
231 },
232 ...
233 }
234
235 There are many times that you want to send data that is not form-encoded. If
236 you pass in a ``string`` instead of a ``dict``, that data will be posted directl y.
237
238 For example, the GitHub API v3 accepts JSON-Encoded POST/PATCH data::
239
240 >>> import json
241
242 >>> url = 'https://api.github.com/some/endpoint'
243 >>> payload = {'some': 'data'}
244
245 >>> r = requests.post(url, data=json.dumps(payload))
246
247 Instead of encoding the ``dict`` yourself, you can also pass it directly using
248 the ``json`` parameter (added in version 2.4.2) and it will be encoded automatic ally::
249
250 >>> url = 'https://api.github.com/some/endpoint'
251 >>> payload = {'some': 'data'}
252
253 >>> r = requests.post(url, json=payload)
254
255
256 POST a Multipart-Encoded File
257 -----------------------------
258
259 Requests makes it simple to upload Multipart-encoded files::
260
261 >>> url = 'http://httpbin.org/post'
262 >>> files = {'file': open('report.xls', 'rb')}
263
264 >>> r = requests.post(url, files=files)
265 >>> r.text
266 {
267 ...
268 "files": {
269 "file": "<censored...binary...data>"
270 },
271 ...
272 }
273
274 You can set the filename, content_type and headers explicitly::
275
276 >>> url = 'http://httpbin.org/post'
277 >>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/v nd.ms-excel', {'Expires': '0'})}
278
279 >>> r = requests.post(url, files=files)
280 >>> r.text
281 {
282 ...
283 "files": {
284 "file": "<censored...binary...data>"
285 },
286 ...
287 }
288
289 If you want, you can send strings to be received as files::
290
291 >>> url = 'http://httpbin.org/post'
292 >>> files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\ n')}
293
294 >>> r = requests.post(url, files=files)
295 >>> r.text
296 {
297 ...
298 "files": {
299 "file": "some,data,to,send\\nanother,row,to,send\\n"
300 },
301 ...
302 }
303
304 In the event you are posting a very large file as a ``multipart/form-data``
305 request, you may want to stream the request. By default, ``requests`` does not
306 support this, but there is a separate package which does -
307 ``requests-toolbelt``. You should read `the toolbelt's documentation
308 <https://toolbelt.readthedocs.io>`_ for more details about how to use it.
309
310 For sending multiple files in one request refer to the :ref:`advanced <advanced> `
311 section.
312
313 .. warning:: It is strongly recommended that you open files in `binary mode`_.
314 This is because Requests may attempt to provide the
315 ``Content-Length`` header for you, and if it does this value will
316 be set to the number of *bytes* in the file. Errors may occur if
317 you open the file in *text mode*.
318
319 .. _binary mode: https://docs.python.org/2/tutorial/inputoutput.html#reading-and -writing-files
320
321
322 Response Status Codes
323 ---------------------
324
325 We can check the response status code::
326
327 >>> r = requests.get('http://httpbin.org/get')
328 >>> r.status_code
329 200
330
331 Requests also comes with a built-in status code lookup object for easy
332 reference::
333
334 >>> r.status_code == requests.codes.ok
335 True
336
337 If we made a bad request (a 4XX client error or 5XX server error response), we
338 can raise it with
339 :meth:`Response.raise_for_status() <requests.Response.raise_for_status>`::
340
341 >>> bad_r = requests.get('http://httpbin.org/status/404')
342 >>> bad_r.status_code
343 404
344
345 >>> bad_r.raise_for_status()
346 Traceback (most recent call last):
347 File "requests/models.py", line 832, in raise_for_status
348 raise http_error
349 requests.exceptions.HTTPError: 404 Client Error
350
351 But, since our ``status_code`` for ``r`` was ``200``, when we call
352 ``raise_for_status()`` we get::
353
354 >>> r.raise_for_status()
355 None
356
357 All is well.
358
359
360 Response Headers
361 ----------------
362
363 We can view the server's response headers using a Python dictionary::
364
365 >>> r.headers
366 {
367 'content-encoding': 'gzip',
368 'transfer-encoding': 'chunked',
369 'connection': 'close',
370 'server': 'nginx/1.0.4',
371 'x-runtime': '148ms',
372 'etag': '"e1ca502697e5c9317743dc078f67693f"',
373 'content-type': 'application/json'
374 }
375
376 The dictionary is special, though: it's made just for HTTP headers. According to
377 `RFC 7230 <http://tools.ietf.org/html/rfc7230#section-3.2>`_, HTTP Header names
378 are case-insensitive.
379
380 So, we can access the headers using any capitalization we want::
381
382 >>> r.headers['Content-Type']
383 'application/json'
384
385 >>> r.headers.get('content-type')
386 'application/json'
387
388 It is also special in that the server could have sent the same header multiple
389 times with different values, but requests combines them so they can be
390 represented in the dictionary within a single mapping, as per
391 `RFC 7230 <http://tools.ietf.org/html/rfc7230#section-3.2>`_:
392
393 A recipient MAY combine multiple header fields with the same field name
394 into one "field-name: field-value" pair, without changing the semantics
395 of the message, by appending each subsequent field value to the combined
396 field value in order, separated by a comma.
397
398 Cookies
399 -------
400
401 If a response contains some Cookies, you can quickly access them::
402
403 >>> url = 'http://example.com/some/cookie/setting/url'
404 >>> r = requests.get(url)
405
406 >>> r.cookies['example_cookie_name']
407 'example_cookie_value'
408
409 To send your own cookies to the server, you can use the ``cookies``
410 parameter::
411
412 >>> url = 'http://httpbin.org/cookies'
413 >>> cookies = dict(cookies_are='working')
414
415 >>> r = requests.get(url, cookies=cookies)
416 >>> r.text
417 '{"cookies": {"cookies_are": "working"}}'
418
419
420 Redirection and History
421 -----------------------
422
423 By default Requests will perform location redirection for all verbs except
424 HEAD.
425
426 We can use the ``history`` property of the Response object to track redirection.
427
428 The :meth:`Response.history <requests.Response.history>` list contains the
429 :class:`Response <requests.Response>` objects that were created in order to
430 complete the request. The list is sorted from the oldest to the most recent
431 response.
432
433 For example, GitHub redirects all HTTP requests to HTTPS::
434
435 >>> r = requests.get('http://github.com')
436
437 >>> r.url
438 'https://github.com/'
439
440 >>> r.status_code
441 200
442
443 >>> r.history
444 [<Response [301]>]
445
446
447 If you're using GET, OPTIONS, POST, PUT, PATCH or DELETE, you can disable
448 redirection handling with the ``allow_redirects`` parameter::
449
450 >>> r = requests.get('http://github.com', allow_redirects=False)
451
452 >>> r.status_code
453 301
454
455 >>> r.history
456 []
457
458 If you're using HEAD, you can enable redirection as well::
459
460 >>> r = requests.head('http://github.com', allow_redirects=True)
461
462 >>> r.url
463 'https://github.com/'
464
465 >>> r.history
466 [<Response [301]>]
467
468
469 Timeouts
470 --------
471
472 You can tell Requests to stop waiting for a response after a given number of
473 seconds with the ``timeout`` parameter::
474
475 >>> requests.get('http://github.com', timeout=0.001)
476 Traceback (most recent call last):
477 File "<stdin>", line 1, in <module>
478 requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)
479
480
481 .. admonition:: Note
482
483 ``timeout`` is not a time limit on the entire response download;
484 rather, an exception is raised if the server has not issued a
485 response for ``timeout`` seconds (more precisely, if no bytes have been
486 received on the underlying socket for ``timeout`` seconds).
487
488
489 Errors and Exceptions
490 ---------------------
491
492 In the event of a network problem (e.g. DNS failure, refused connection, etc),
493 Requests will raise a :class:`~requests.exceptions.ConnectionError` exception.
494
495 In the rare event of an invalid HTTP response, Requests will raise an
496 :class:`~requests.exceptions.HTTPError` exception.
497
498 If a request times out, a :class:`~requests.exceptions.Timeout` exception is
499 raised.
500
501 If a request exceeds the configured number of maximum redirections, a
502 :class:`~requests.exceptions.TooManyRedirects` exception is raised.
503
504 All exceptions that Requests explicitly raises inherit from
505 :class:`requests.exceptions.RequestException`.
506
507 -----------------------
508
509 Ready for more? Check out the :ref:`advanced <advanced>` section.
OLDNEW
« no previous file with comments | « recipe_engine/third_party/requests/docs/user/intro.rst ('k') | recipe_engine/third_party/requests/ext/requests-logo.ai » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698