| OLD | NEW |
| (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. | |
| OLD | NEW |