Created
January 6, 2021 13:47
-
-
Save asterios-pantousas/ea7456babec44a88d386bd7038926a2b to your computer and use it in GitHub Desktop.
Created on Skills Network Labs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<a href=\"https://cognitiveclass.ai/\">\n", | |
" <img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/Ad/CCLog.png\" width=\"200\" align=\"center\">\n", | |
"</a>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h1> HTTP and Requests</h1>\n", | |
"\n", | |
"Estimated time needed: **15** minutes\n", | |
"\n", | |
"## Objectives\n", | |
"\n", | |
"After completing this lab you will be able to:\n", | |
"\n", | |
"- Understand HTTP \n", | |
"- Handle the HTTP Requests\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h2>Table of Contents</h2>\n", | |
"\n", | |
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n", | |
" <ul>\n", | |
" <li>\n", | |
" <a href=\"#index\">Overview of HTTP </a>\n", | |
" <ul>\n", | |
" <li><a href=\"#HTTP\">Uniform Resource Locator:URL</a></li>\n", | |
" <li><a href=\"slice\">Request</a></li>\n", | |
" <li><a href=\"stride\">Response</a></li>\n", | |
" </ul>\n", | |
" </li>\n", | |
" <li>\n", | |
" <a href=\"#RP\">Requests in Python </a>\n", | |
" <ul>\n", | |
" <li><a href=\"#get\">Get Request with URL Parameters</a></li>\n", | |
" <li><a href=\"#post\">Post Requests </a></li>\n", | |
"\n", | |
"</ul>\n", | |
" \n", | |
"</div>\n", | |
"\n", | |
"<hr>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h2 id=\"\">Overview of HTTP </h2>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"When you, the **client**, use a web page your browser sends an **HTTP** request to the **server** where the page is hosted. The server tries to find the desired **resource** by default \"<code>index.html</code>\". If your request is successful, the server will send the object to the client in an **HTTP response**; this includes information like the type of the **resource**, the length of the **resource**, and other information. \n", | |
"\n", | |
"<p>\n", | |
"The figure below represents the process; the circle on the left represents the client, the circle on the right represents the Web server. The table under the Web server represents a list of resources stored in the web server. In this case an <code>HTML</code> file, <code>png</code> image, and <code>txt</code> file .\n", | |
"</p>\n", | |
"<p>\n", | |
"The <b>HTTP</b> protocol allows you to send and receive information through the web including webpages, images, and other web resources. In this lab, we will provide an overview of the Requests library for interacting with the <code>HTTP </code> protocol. \n", | |
"</p\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n", | |
" <img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/images/reqest_basics.png\" width=\"750\" align=\"center\">\n", | |
" \n", | |
"</div>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h2 id=\"URL\">Uniform Resource Locator:URL</h2>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Uniform resource locator (URL) is the most popular way to find resources on the web. We can break the URL into three parts. \n", | |
"\n", | |
"<ul>\n", | |
" <li><b>scheme</b> this is this protocol, for this lab it will always be <code>http://</code> </li>\n", | |
" <li><b> Internet address or Base URL </b> this will be used to find the location here are some examples: <code>www.ibm.com</code> and <code> www.gitlab.com </code> </li>\n", | |
" <li><b>route</b> location on the web server for example: <code>/images/IDSNlogo.png</code> </li>\n", | |
"</ul>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"You may also here the term uniform resource identifier (URI), URL are actually a subset of URIs. Another popular term is endpoint, this is the URL of an operation provided by a Web server.\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h2 id=\"RE\">Request </h2>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The process can be broken into the <b>request</b> and <b>response </b> process. The request using the get method is partially illustrated below. In the start line we have the <code>GET</code> method, this is an <code>HTTP</code> method. Also the location of the resource <code>/index.html</code> and the <code>HTTP</code> version .The Request header passes additional information with an <code>HTTP</code> request:\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n", | |
" <img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/images/reqest_messege.png\" width=\"400\" align=\"center\">\n", | |
"</div>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"When an <code>HTTP</code> request is made, an <code>HTTP</code> method is sent, this tells the server what action to perform. A list of several <code>HTTP</code> methods is shown below. We will go over more examples later.\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n", | |
" <img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/images/http_methods.png\" width=\"400\" align=\"center\">\n", | |
"</div>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h2 id=\"RES\">Response</h2>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The figure below represents the response; the response start line contains the version number <code>HTTP/1.0</code>, a status code (200) meaning success, followed by a descriptive phrase (OK). The response header contains useful information. Finally, we have the response body containing the requested file an <code> HTML </code> document. It should be noted that some request have headers.\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n", | |
" <img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/images/response_message.png\" width=\"400\" align=\"center\">\n", | |
"</div>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Some status code examples are shown in the table below, the prefix indicates the class; these are shown in yellow, with actual status codes shown in white. Check out the following <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\">link </a> for more descriptions.\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n", | |
" <img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/images/status_code.png\" width=\"300\" align=\"center\">\n", | |
"</div>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h2 id=\"RP\">Requests in Python</h2>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Requests is a python Library that allows you to send <code>HTTP/1.1</code> requests easily. We can import the library as follows:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import requests" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We will also use the following libraries \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import os \n", | |
"from PIL import Image\n", | |
"from IPython.display import IFrame" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
" You can make a <code>GET</code> request via the method <code>get</code> to [www.ibm.com](http://www.ibm.com?cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ): \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"url='https://www.ibm.com/'\n", | |
"r=requests.get(url)\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We have the response object <code>r</code> , this has information about the request, like the status of the request. We can view the status code using the attribute <code>status_code </code>\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"200" | |
] | |
}, | |
"execution_count": 4, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"r.status_code" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"You can view the request headers:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"{'User-Agent': 'python-requests/2.25.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Cookie': '_abck=80BDEB7A380A785EE92F1C9AFC688A3C~-1~YAAQlPNUuHVhPtZ2AQAAb37N1wVVljI2vgP/EFa2RO0eQqp86dpIC4vcm0ZOhOob6zlfLW0m7FgRfr9HqfKXvGDUypbNrBAwYkApy1+GbC0l/yZLZxmhDl2IO8FSHN6rtr8XxP2ZuEumi1u7ezl0oTPtWdZpEkecNKSQdaztG9sbvzPyyxzUgtoTsIVWkAzoOHWOzz9DpKFizYZeXy3oS91p94No2cR6Pc/GGHwGGhDVqRQ4nWrJN5l7xhLNQhd2baDQmTbI5N6M5B4gHG+T5bkdS2vV2KaQG35tnE8mMNbYnt+KFtv5~-1~-1~-1; bm_sz=B5FD1467C4864E4F749A7A0A2F859DFA~YAAQlPNUuHRhPtZ2AQAAb37N1wr3T+AodEW9DeXFHgijAEgeWtfpyIJpFrn2gTkxu7CwDaNZJ3DIcdp2jpdxjOGXRd0iUeEG1fI2sI+Oar/Kwq6bBbTQG/nQZB43G/w1Dux73L27aYEf377qpZkVqE9SPb2NUuZF+KjquSHrRWh8+DMNWZR99qCEcbDR'}\n" | |
] | |
} | |
], | |
"source": [ | |
"print(r.request.headers)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"You can view the request body, in the following line, as there is no body for a get request we get a <code>None </code>:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"request body: None\n" | |
] | |
} | |
], | |
"source": [ | |
"print(\"request body:\", r.request.body)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
" You can view the <code>HTTP</code> response header using the attribute <code>headers</code>. This returns a python dictionary of <code>HTTP</code> response headers. \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"{'Server': 'Apache', 'x-drupal-dynamic-cache': 'UNCACHEABLE', 'Link': '<https://www.ibm.com/ca-en>; rel=\"canonical\", <https://www.ibm.com/ca-en>; rel=\"revision\", <https://www.ibm.com/ca-en>; rel=\"revision\", <//1.cms.s81c.com>; rel=preconnect; crossorigin, <//1.cms.s81c.com>; rel=dns-prefetch', 'x-ua-compatible': 'IE=edge', 'Content-Language': 'en-ca', 'x-generator': 'Drupal 8 (https://www.drupal.org)', 'x-dns-prefetch-control': 'on', 'x-drupal-cache': 'MISS', 'Last-Modified': 'Wed, 06 Jan 2021 08:30:14 GMT', 'ETag': '\"1609921814\"', 'Content-Type': 'text/html; charset=UTF-8', 'x-acquia-host': 'www.ibm.com', 'x-acquia-path': '/ca-en', 'x-acquia-site': '', 'x-acquia-purge-tags': '', 'x-varnish': '28312630 16452445', 'x-cache-hits': '10', 'x-age': '0', 'Accept-Ranges': 'bytes', 'Content-Encoding': 'gzip', 'Cache-Control': 'public, max-age=300', 'Expires': 'Wed, 06 Jan 2021 13:10:37 GMT', 'X-Akamai-Transformed': '9 10582 0 pmb=mTOE,1', 'Date': 'Wed, 06 Jan 2021 13:05:37 GMT', 'Content-Length': '10696', 'Connection': 'keep-alive', 'Vary': 'Accept-Encoding', 'x-content-type-options': 'nosniff', 'X-XSS-Protection': '1; mode=block', 'Content-Security-Policy': 'upgrade-insecure-requests', 'Strict-Transport-Security': 'max-age=31536000', 'x-ibm-trace': 'www-dipatcher: dynamic rule'}\n" | |
] | |
} | |
], | |
"source": [ | |
"header=r.headers\n", | |
"print(r.headers)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can obtain the date the request was sent using the key <code>Data</code>\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'Wed, 06 Jan 2021 13:05:37 GMT'" | |
] | |
}, | |
"execution_count": 8, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"header['Date']" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<code>Content-Type</code> indicates the type of data:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'text/html; charset=UTF-8'" | |
] | |
}, | |
"execution_count": 9, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"header['Content-Type']" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"You can also check the <code>encoding</code>:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'UTF-8'" | |
] | |
}, | |
"execution_count": 10, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
" r.encoding" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"As the <code>Content-Type</code> is <code>text/html</code> we can use the attribute <code>text</code> to display the <code>HTML</code> in the body. We can review the first 100 characters:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'<!DOCTYPE html>\\n<html lang=\"en-ca\" dir=\"ltr\">\\n <head>\\n <meta charset=\"utf-8\" />\\n<script>digitalD'" | |
] | |
}, | |
"execution_count": 11, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"r.text[0:100]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"You can load other types of data for non-text requests like images, consider the URL of the following image:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Use single quotation marks for defining string\n", | |
"url='https://gitlab.com/ibm/skills-network/courses/placeholder101/-/raw/master/labs/module%201/images/IDSNlogo.png'" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can make a get request:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"r=requests.get(url)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can look at the response header:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"{'Date': 'Wed, 06 Jan 2021 13:05:42 GMT', 'Content-Type': 'image/png', 'Content-Length': '21590', 'Connection': 'keep-alive', 'Set-Cookie': '__cfduid=dcec250413cd25b7a121f72988d12dd981609938342; expires=Fri, 05-Feb-21 13:05:42 GMT; path=/; domain=.gitlab.com; HttpOnly; SameSite=Lax; Secure', 'Cache-Control': 'max-age=60, public', 'Content-Disposition': 'inline', 'Etag': 'W/\"c26d88d0ca290ba368620273781ea37c\"', 'X-Content-Type-Options': 'nosniff', 'X-Download-Options': 'noopen', 'X-Frame-Options': 'DENY', 'X-Gitlab-Feature-Category': 'source_code_management', 'X-Permitted-Cross-Domain-Policies': 'none', 'X-Request-Id': 'lz7Q5SN21r2', 'X-Runtime': '0.062591', 'X-Ua-Compatible': 'IE=edge', 'X-Xss-Protection': '1; mode=block', 'Strict-Transport-Security': 'max-age=31536000', 'Referrer-Policy': 'strict-origin-when-cross-origin', 'GitLab-LB': 'fe-08-lb-gprd', 'GitLab-SV': 'web-14-sv-gprd', 'CF-Cache-Status': 'REVALIDATED', 'Accept-Ranges': 'bytes', 'cf-request-id': '077966aa5f0000cab8d3331000000001', 'Expect-CT': 'max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"', 'Vary': 'Accept-Encoding', 'Server': 'cloudflare', 'CF-RAY': '60d5a6f098c8cab8-YYZ'}\n" | |
] | |
} | |
], | |
"source": [ | |
"print(r.headers)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can we can see the <code>'Content-Type'</code>\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'image/png'" | |
] | |
}, | |
"execution_count": 15, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"r.headers['Content-Type']" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"An image is a response object that contains the image as a <a href=\"https://docs.python.org/3/glossary.html#term-bytes-like-object\">bytes-like object</a>. As a result, we must save it using a file object. First, we specify the file path and\n", | |
"name \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'/resources/labs/PY0101EN/image.png'" | |
] | |
}, | |
"execution_count": 16, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"path=os.path.join(os.getcwd(),'image.png')\n", | |
"path" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We save the file, in order to access the body of the response we use the attribute <code>content</code> then save it using the <code>open</code> function and write <code>method</code>: \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"with open(path,'wb') as f:\n", | |
" f.write(r.content)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can view the image:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<PIL.PngImagePlugin.PngImageFile image mode=P size=800x800 at 0x7F50B0A1FF28>" | |
] | |
}, | |
"execution_count": 18, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"Image.open(path) " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h3>Question 1: write <a href=\"https://www.gnu.org/software/wget/\"><code> wget </code></a></h3>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"In the previous section, we used the <code>wget</code> function to retrieve content from the web server as shown below. Write the python code to perform the same task. The code should be the same as the one used to download the image, but the file name should be <code>'example.txt'</code>. \n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<code>!wget -O /resources/data/Example1.txt [https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/labs/example1.txt](https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/labs/example1.txt?cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ)</code>\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 19, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"url ='https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/labs/example1.txt'\n", | |
"r=requests.get(url)\n", | |
"path=os.path.join(os.getcwd(),'example1.txt')\n", | |
"with open(path,'wb') as f:\n", | |
" f.write(r.content)\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<details><summary>Click here for the solution</summary>\n", | |
"\n", | |
"```python\n", | |
"url='https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/labs/example1.txt'\n", | |
"path=os.path.join(os.getcwd(),'example1.txt')\n", | |
"r=requests.get(url)\n", | |
"with open(path,'wb') as f:\n", | |
" f.write(r.content)\n", | |
"\n", | |
"```\n", | |
"\n", | |
"</details>\n", | |
" \n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h2 id=\"URL_P\">Get Request with URL Parameters </h2>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"You can use the <b>GET</b> method to modify the results of your query, for example retrieving data from an API . We send a <b>GET</b> request to the server. Like before we have the <b>Base URL</b>, in the <b>Route</b> we append <code>/get</code> this indicates we would like to preform a <code>GET</code> request, this is demonstrated in the following table:\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n", | |
" <img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/images/base_URL_Route.png\" width=\"400\" align=\"center\">\n", | |
"</div>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The Base URL is for <code>[http://httpbin.org/](http://httpbin.org?cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ&cm_mmc=Email_Newsletter-_-Developer_Ed%2BTech-_-WW_WW-_-SkillsNetwork-Courses-IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork-19487395&cm_mmca1=000026UJ&cm_mmca2=10006555&cm_mmca3=M12345678&cvosrc=email.Newsletter.M12345678&cvo_campaign=000026UJ)</code> is a simple HTTP Request & Response Service. The <code>URL</code> in Python is given by:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 20, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"url_get='http://httpbin.org/get'" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"A <a href=\"https://en.wikipedia.org/wiki/Query_string\">query string</a> is a part of a uniform resource locator (URL), this sends other information to the web server. The start of the query is a <code>?</code>, followed by a series of parameter and value pairs, as shown in the table below. The first parameter name is <code>name</code> and the value is <code>Joseph</code> the second parameter name is <code>ID</code> and the Value is <code>123</code>. Each pair, parameter and value is separated by an equals sign, <code>=</code>.\n", | |
"The series of pairs is separated by the ampersand <code>&</code>.\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n", | |
" <img src=\"https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/PY0101EN/images/query_string.png\" width=\"500\" align=\"center\">\n", | |
"</div>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"To create a Query string, add a dictionary. The keys are the parameter names, and the values are the value of the Query string.\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 21, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"payload={\"name\":\"Joseph\",\"ID\":\"123\"}" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Then passing the dictionary <code>payload</code> to the <code>params</code> parameter of the <code> get()</code> function:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 22, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"r=requests.get(url_get,params=payload)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can print out the <code>URL</code> and see the name and values \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 23, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'http://httpbin.org/get?name=Joseph&ID=123'" | |
] | |
}, | |
"execution_count": 23, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"r.url" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"There is no request body \n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 24, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"request body: None\n" | |
] | |
} | |
], | |
"source": [ | |
"print(\"request body:\", r.request.body)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can print out the status code\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 25, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"200\n" | |
] | |
} | |
], | |
"source": [ | |
"print(r.status_code)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can view the response as text:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 26, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"{\n", | |
" \"args\": {\n", | |
" \"ID\": \"123\", \n", | |
" \"name\": \"Joseph\"\n", | |
" }, \n", | |
" \"headers\": {\n", | |
" \"Accept\": \"*/*\", \n", | |
" \"Accept-Encoding\": \"gzip, deflate\", \n", | |
" \"Host\": \"httpbin.org\", \n", | |
" \"User-Agent\": \"python-requests/2.25.0\", \n", | |
" \"X-Amzn-Trace-Id\": \"Root=1-5ff5bea5-4a8e85f05e73cc9f097cd648\"\n", | |
" }, \n", | |
" \"origin\": \"158.85.91.176\", \n", | |
" \"url\": \"http://httpbin.org/get?name=Joseph&ID=123\"\n", | |
"}\n", | |
"\n" | |
] | |
} | |
], | |
"source": [ | |
"print(r.text)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can look at the <code>'Content-Type'</code>.\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'application/json'" | |
] | |
}, | |
"execution_count": 27, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"r.headers['Content-Type']" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"As the content <code>'Content-Type'</code> is in the <code>JSAON</code> format we can use the method <code>json()</code> , it returns a Python <code>dict</code>:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 28, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'args': {'ID': '123', 'name': 'Joseph'},\n", | |
" 'headers': {'Accept': '*/*',\n", | |
" 'Accept-Encoding': 'gzip, deflate',\n", | |
" 'Host': 'httpbin.org',\n", | |
" 'User-Agent': 'python-requests/2.25.0',\n", | |
" 'X-Amzn-Trace-Id': 'Root=1-5ff5bea5-4a8e85f05e73cc9f097cd648'},\n", | |
" 'origin': '158.85.91.176',\n", | |
" 'url': 'http://httpbin.org/get?name=Joseph&ID=123'}" | |
] | |
}, | |
"execution_count": 28, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"r.json()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"The key <code>args</code> had the name and values:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 29, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"{'ID': '123', 'name': 'Joseph'}" | |
] | |
}, | |
"execution_count": 29, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"r.json()['args']" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<h2 id=\"POST\">Post Requests </h2>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Like a <code>GET</code> request a <code>POST</code> is used to send data to a server, but the <code>POST</code> request sends the data in a request body. In order to send the Post Request in Python in the <code>URL</code> we change the route to <code>POST</code>:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 30, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"url_post='http://httpbin.org/post'" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"This endpont will expect data as a file or as a form, a from is convenient way to configure an HTTP request to send data to a server.\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"To make a <code>POST</code> request we use the <code>post()</code> function, the variable <code>payload</code> is passed to the parameter <code> data </code>:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"r_post=requests.post(url_post,data=payload)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Comparing the URL from the response object of the <code>GET</code> and <code>POST</code> request we see the <code>POST</code> request has no name or value pairs.\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"print(\"POST request URL:\",r_post.url )\n", | |
"print(\"GET request URL:\",r.url)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can compare the <code>POST</code> and <code>GET</code> request body, we see only the <code>POST</code> request has a body:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"print(\"POST request body:\",r_post.request.body)\n", | |
"print(\"GET request body:\",r.request.body)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"We can view the form as well:\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"r_post.json()['form']" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"There is a lot more you can do check out <a href=\"https://requests.readthedocs.io/en/master/\">Requests </a> for more.\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<hr>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Authors\n", | |
"\n", | |
"<p><a href=\"https://www.linkedin.com/in/joseph-s-50398b136/\" target=\"_blank\">Joseph Santarcangelo</a> <br>A Data Scientist at IBM, and holds a PhD in Electrical Engineering. His research focused on using Machine Learning, Signal Processing, and Computer Vision to determine how videos impact human cognition. Joseph has been working for IBM since he completed his PhD.</p>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Other Contributors\n", | |
"\n", | |
"<a href=\"www.linkedin.com/in/jiahui-mavis-zhou-a4537814a\">Mavis Zhou</a>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Change Log\n", | |
"\n", | |
"| Date (YYYY-MM-DD) | Version | Changed By | Change Description |\n", | |
"| ----------------- | ------- | ---------- | ---------------------------- |\n", | |
"| 2020-09-02 | 2.0 | Simran | Template updates to the file |\n", | |
"| | | | |\n", | |
"| | | | |\n", | |
"\n", | |
"## <h3 align=\"center\"> © IBM Corporation 2020. All rights reserved. <h3/>\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python", | |
"language": "python", | |
"name": "conda-env-python-py" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.6.12" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment