Skip to content

Instantly share code, notes, and snippets.

@oC-n
Created June 29, 2021 17:36
Show Gist options
  • Save oC-n/fd3cfeef8debf9f281531c4974c96ff3 to your computer and use it in GitHub Desktop.
Save oC-n/fd3cfeef8debf9f281531c4974c96ff3 to your computer and use it in GitHub Desktop.
Python for Data Science, AI & Development - Week 5 - Hands-on Lab: Access REST APIs & Request HTTP
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a href=\"https://cognitiveclass.ai/?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\">\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 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://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/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 hear 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://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/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://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/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 requests have headers.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-info\" style=\"margin-top: 20px\">\n",
" <img src=\"https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/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?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\">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://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/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": 3,
"metadata": {},
"outputs": [],
"source": [
"import os \n",
"from PIL import Image\n",
"from IPython.display import IFrame\n",
"\n",
"# It would be useful to know what these are, rather than just importing without knowing why."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can make a <code>GET</code> request via the method <code>get</code> to www.ibm.com:\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"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": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"200"
]
},
"execution_count": 5,
"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": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'User-Agent': 'python-requests/2.25.1', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Cookie': 'bm_sz=E703E147B7C202126536343E24FE560E~YAAQo50ZuHcA31J6AQAAFbahWAwHxxwyp3IF6x8s835DT2naMSo/BJiGZ/r6qW7V+btEmD7g7DTnmx0iAfWlPjJeRpwlWH6WHc4NAvgEaxacTftKY4eMnCC3pyUEaA2sgr8dOyTJvT+UkNrzB2Q6kFm1ADD1XXhfrqDyR6UPgXI8Jvb0SA6egJ1bFngm; _abck=24B59B7C260845A73BD3921B0B7C0574~-1~YAAQo50ZuHgA31J6AQAAFbahWAZIP7ab3WqzJ/+ZAFPb3tAKPAVt/06qF2DlX1Ui136owojyQGFR9I9Lir5fi+PKReJpjbbUp6Fl7lHaaKtl+pE4Iyn2AK6845HY8FptZB1Y8Aiekgz17mmG4iTV8jYpCw5cLNWv3xMvmeEwZpZnNO8jB5bRjXbgfKnVMhQ9sH5u8Kyf9/y9v0/+arowCGpMCU9IbpWiR2+SCEf6uU2DgjGH7tzEnpFaEALD314yJj3B8lMgHfOHa7E+kP7V/ZazGmigro1hybtWZQYYTFMsWBjupVCYKlNAHeRIKoKYXe4wBZMyfIWDX9rhiAbyHoKz9NCi/um7zVFmM7KV4kYQo7kJfc8=~-1~-1~-1'}\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": 7,
"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": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'Cache-Control': 'max-age=301', 'Expires': 'Mon, 28 Jun 2021 12:52:39 GMT', 'Last-Modified': 'Fri, 25 Jun 2021 18:05:17 GMT', 'ETag': '\"17dd2-5c59afb733963\"', 'Accept-Ranges': 'bytes', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'X-Akamai-Transformed': '9 18051 0 pmb=mTOE,1', 'Date': 'Tue, 29 Jun 2021 16:37:10 GMT', 'Content-Length': '18129', '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'}\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>Date</code>\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Tue, 29 Jun 2021 16:37:10 GMT'"
]
},
"execution_count": 9,
"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": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'text/html'"
]
},
"execution_count": 10,
"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": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'ISO-8859-1'"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
" r.encoding\n",
" \n",
"# Wouldn't it be helpful to know what any of this means, why one would do it, rather than just that \"you can\"?"
]
},
{
"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": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'<!DOCTYPE html><html lang=\"en-US\"><head><meta name=\"viewport\" content=\"width=device-width\"/><meta ch'"
]
},
"execution_count": 12,
"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": 19,
"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'\n",
"\n",
"# Actually, it makes no difference whether single or double quotes are used."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can make a get request:\n"
]
},
{
"cell_type": "code",
"execution_count": 20,
"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": 21,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'Date': 'Tue, 29 Jun 2021 16:42:37 GMT', 'Content-Type': 'image/png', 'Content-Length': '21590', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=60, public', 'Content-Disposition': 'inline', 'Etag': 'W/\"c26d88d0ca290ba368620273781ea37c\"', 'Permissions-Policy': 'interest-cohort=()', 'Vary': 'Accept, Accept-Encoding', 'X-Content-Type-Options': 'nosniff', 'X-Download-Options': 'noopen', 'X-Frame-Options': 'DENY', 'X-Permitted-Cross-Domain-Policies': 'none', 'X-Request-Id': '01F9C1YG0FYK1SN04JGGC5SW2J', 'X-Runtime': '0.062287', '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-07-lb-gprd', 'GitLab-SV': 'web-22-sv-gprd', 'CF-Cache-Status': 'HIT', 'Age': '60', 'Accept-Ranges': 'bytes', 'cf-request-id': '0afa3fcb5300005dda5e3e6000000001', 'Expect-CT': 'max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"', 'Server': 'cloudflare', 'CF-RAY': '66709bf21bc75dda-IAD'}\n"
]
}
],
"source": [
"print(r.headers)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see the <code>'Content-Type'</code>\n"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'image/png'"
]
},
"execution_count": 22,
"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?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01#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": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'/resources/labs/image.png'"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"path=os.path.join(os.getcwd(),'image.png')\n",
"path\n",
"\n",
"# Presume os has something to do with operating system commands?\n",
"# getcwd presumably returns \"current working directory\".\n",
"# Join concatenates the directory and the name, to make a string representing the whole 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": 25,
"metadata": {},
"outputs": [],
"source": [
"with open(path,'wb') as f:\n",
" f.write(r.content)\n",
" \n",
"# 'wb' to write as bytes rather than characters."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can view the image:\n"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<PIL.PngImagePlugin.PngImageFile image mode=P size=800x800 at 0x7FB8926DFBE0>"
]
},
"execution_count": 26,
"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/?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\"><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>'Example1.txt'</code>.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<code>!wget -O /resources/data/Example1.txt https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/data/Example1.txt</code>\n"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"url = 'https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/data/Example1.txt'\n",
"r = requests.get(url)\n",
"path = os.path.join(os.getcwd(),'example1.txt')\n",
"# path = '/resources/data/Example1.txt' ; seems we're not to replicate the wget statement exactly.\n",
"with open(path, 'wb') as eg:\n",
" eg.write(r.content)\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<details><summary>Click here for the solution</summary>\n",
"\n",
"```python\n",
"url='https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/data/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"
]
},
{
"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://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/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/</code> is a simple HTTP Request & Response Service. The <code>URL</code> in Python is given by:\n"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [],
"source": [
"url_get='http://httpbin.org/get'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A <a href=\"https://en.wikipedia.org/wiki/Query_string?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\">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://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-PY0101EN-SkillsNetwork/labs/Module%205/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": 32,
"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": 33,
"metadata": {},
"outputs": [],
"source": [
"r=requests.get(url_get,params=payload)\n",
"# Is the difference between this and the above uses of the get function that here we're getting data, rather than a file?"
]
},
{
"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": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'http://httpbin.org/get?name=Joseph&ID=123'"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r.url"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There is no request body\n"
]
},
{
"cell_type": "code",
"execution_count": 35,
"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": 36,
"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": 37,
"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.1\", \n",
" \"X-Amzn-Trace-Id\": \"Root=1-60db51ee-0610225e2394b3504dd15eb5\"\n",
" }, \n",
" \"origin\": \"52.116.125.104\", \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": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'application/json'"
]
},
"execution_count": 38,
"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>JSON</code> format we can use the method <code>json()</code>, it returns a Python <code>dict</code>:\n"
]
},
{
"cell_type": "code",
"execution_count": 39,
"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.1',\n",
" 'X-Amzn-Trace-Id': 'Root=1-60db51ee-0610225e2394b3504dd15eb5'},\n",
" 'origin': '52.116.125.104',\n",
" 'url': 'http://httpbin.org/get?name=Joseph&ID=123'}"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r.json()\n",
"# Quite a gap in the course that JSON still hasn't been explained."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The key <code>args</code> has the name and values:\n"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'ID': '123', 'name': 'Joseph'}"
]
},
"execution_count": 40,
"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": 41,
"metadata": {},
"outputs": [],
"source": [
"url_post='http://httpbin.org/post'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This endpoint will expect data as a file or as a form. A form 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": 42,
"metadata": {},
"outputs": [],
"source": [
"r_post=requests.post(url_post,data=payload)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# But what the hell does post do? What does sending data to the server do? To what does this data have to conform?\n",
"# What's an example situation?\n",
"\n",
"# \"POST is used to send data to a server to create/update a resource.\" https://www.w3schools.com/tags/ref_httpmethods.asp"
]
},
{
"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": 43,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"POST request URL: http://httpbin.org/post\n",
"GET request URL: http://httpbin.org/get?name=Joseph&ID=123\n"
]
}
],
"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": 44,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"POST request body: name=Joseph&ID=123\n",
"GET request body: None\n"
]
}
],
"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": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'ID': '123', 'name': 'Joseph'}"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r_post.json()['form']"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'args': {},\n",
" 'data': '',\n",
" 'files': {},\n",
" 'form': {'ID': '123', 'name': 'Joseph'},\n",
" 'headers': {'Accept': '*/*',\n",
" 'Accept-Encoding': 'gzip, deflate',\n",
" 'Content-Length': '18',\n",
" 'Content-Type': 'application/x-www-form-urlencoded',\n",
" 'Host': 'httpbin.org',\n",
" 'User-Agent': 'python-requests/2.25.1',\n",
" 'X-Amzn-Trace-Id': 'Root=1-60db53bc-1dc56ac04a46aa0b66659a99'},\n",
" 'json': None,\n",
" 'origin': '52.116.125.104',\n",
" 'url': 'http://httpbin.org/post'}"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r_post.json()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There is a lot more you can do. Check out <a href=\"https://requests.readthedocs.io/en/master/?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\">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/?utm_medium=Exinfluencer&utm_source=Exinfluencer&utm_content=000026UJ&utm_term=10006555&utm_id=NA-SkillsNetwork-Channel-SkillsNetworkCoursesIBMDeveloperSkillsNetworkPY0101ENSkillsNetwork19487395-2021-01-01\" 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",
"|2021-12-20 | 2.1 | Malika | Updated the links |\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"
]
}
],
"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.13"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment