From df5877233cc57005e3003c19c0dbf89aafc53804 Mon Sep 17 00:00:00 2001
From: gsingh58 <gurmail-singh@wisc.edu>
Date: Thu, 7 Mar 2024 07:02:16 -0600
Subject: [PATCH] lec12 & 13 updated

---
 lecture_material/12-web-2/solution.ipynb      | 23 +++++++++++++++--
 lecture_material/12-web-2/solution.py         |  2 +-
 .../12-web-2/template_lec_001.ipynb           | 21 +++++++++++++++-
 lecture_material/12-web-2/template_lec_001.py |  5 ++--
 .../12-web-2/template_lec_002.ipynb           | 23 +++++++++++++++--
 lecture_material/12-web-2/template_lec_002.py |  4 +--
 lecture_material/13-web-3/solution.ipynb      | 24 ++++++++++--------
 lecture_material/13-web-3/solution.py         |  2 +-
 .../13-web-3/template_lec_001.ipynb           | 25 ++++++++++++-------
 lecture_material/13-web-3/template_lec_001.py |  3 ---
 .../13-web-3/template_lec_002.ipynb           | 23 ++++++++++++++++-
 lecture_material/13-web-3/template_lec_002.py |  3 ---
 12 files changed, 118 insertions(+), 40 deletions(-)

diff --git a/lecture_material/12-web-2/solution.ipynb b/lecture_material/12-web-2/solution.ipynb
index 8ca8f48..09d1c35 100644
--- a/lecture_material/12-web-2/solution.ipynb
+++ b/lecture_material/12-web-2/solution.ipynb
@@ -27,11 +27,30 @@
    "source": [
     "### Rate-limited webpage parsing\n",
     "\n",
+    "\n",
     "- `requests` module:\n",
     "    - `resp = requests.get(<URL>)` method: enables us to send HTTP GET request\n",
     "    - `resp.status_code`: status code of the response\n",
     "    - `resp.text`: `str` text content of the response\n",
-    "    - `resp.headers`: `dict` content of response headers"
+    "    - `resp.headers`: `dict` content of response headers\n",
+    "    \n",
+    "- `@` operator is called a \"decorator\"\n",
+    "- `flask.Response`: enables us to create a response object instance\n",
+    "    - Arguments: `str` representing reponse, `headers` dict representing metadata, `status` representing status code.\n",
+    "    - ex: \n",
+    "    ```python\n",
+    "    flask.Response(\"<b>go away</b>\",\n",
+    "                              status=429,\n",
+    "                              headers={\"Retry-After\": \"3\"})\n",
+    "    ```\n",
+    "    \n",
+    "    ```python\n",
+    "    flask.Response(\"\"\"User-Agent: *\n",
+    "    Disallow: /never\n",
+    "    \"\"\", headers={\"Content-Type\": \"text/plain\"})\n",
+    "    ```\n",
+    "\n",
+    "- `flask.request.remote_addr`: enables us to take action based on the IP address from which we receive the request"
    ]
   },
   {
@@ -73,7 +92,7 @@
     "        resp.raise_for_status() # raise exception if not 200\n",
     "        return resp\n",
     "    \n",
-    "friendly_get(base_url + \"/slow\").text"
+    "friendly_get(base_url + \"slow\").text"
    ]
   }
  ],
diff --git a/lecture_material/12-web-2/solution.py b/lecture_material/12-web-2/solution.py
index 941b19f..d1548ec 100644
--- a/lecture_material/12-web-2/solution.py
+++ b/lecture_material/12-web-2/solution.py
@@ -1,6 +1,6 @@
 import flask # requires installation if not already installed - pip3 install flask
 import time
-import json
+# import json
 
 app = flask.Flask("my application") # name of the web application can be anything
 
diff --git a/lecture_material/12-web-2/template_lec_001.ipynb b/lecture_material/12-web-2/template_lec_001.ipynb
index d4f7589..ec598f0 100644
--- a/lecture_material/12-web-2/template_lec_001.ipynb
+++ b/lecture_material/12-web-2/template_lec_001.ipynb
@@ -26,11 +26,30 @@
    "source": [
     "### Rate-limited webpage parsing\n",
     "\n",
+    "\n",
     "- `requests` module:\n",
     "    - `resp = requests.get(<URL>)` method: enables us to send HTTP GET request\n",
     "    - `resp.status_code`: status code of the response\n",
     "    - `resp.text`: `str` text content of the response\n",
-    "    - `resp.headers`: `dict` content of response headers"
+    "    - `resp.headers`: `dict` content of response headers\n",
+    "    \n",
+    "- `@` operator is called a \"decorator\"\n",
+    "- `flask.Response`: enables us to create a response object instance\n",
+    "    - Arguments: `str` representing reponse, `headers` dict representing metadata, `status` representing status code.\n",
+    "    - ex: \n",
+    "    ```python\n",
+    "    flask.Response(\"<b>go away</b>\",\n",
+    "                              status=429,\n",
+    "                              headers={\"Retry-After\": \"3\"})\n",
+    "    ```\n",
+    "    \n",
+    "    ```python\n",
+    "    flask.Response(\"\"\"User-Agent: *\n",
+    "    Disallow: /never\n",
+    "    \"\"\", headers={\"Content-Type\": \"text/plain\"})\n",
+    "    ```\n",
+    "\n",
+    "- `flask.request.remote_addr`: enables us to take action based on the IP address from which we receive the request"
    ]
   },
   {
diff --git a/lecture_material/12-web-2/template_lec_001.py b/lecture_material/12-web-2/template_lec_001.py
index 94e9273..bfc9522 100644
--- a/lecture_material/12-web-2/template_lec_001.py
+++ b/lecture_material/12-web-2/template_lec_001.py
@@ -1,6 +1,6 @@
 import flask # requires installation if not already installed - pip3 install flask
 import time
-import json
+
 
 app = flask.Flask("my application") # name of the web application can be anything
 
@@ -18,8 +18,7 @@ last_visit = 0 # TODO: dict of visit times, for each IP
 # TODO: create a dynamic page ha.html
 # DYNAMIC
 
-# STATIC
-# @ operator is called a "decorator"
+
 # STATIC
 # @ operator is called a "decorator"
 @app.route("/")
diff --git a/lecture_material/12-web-2/template_lec_002.ipynb b/lecture_material/12-web-2/template_lec_002.ipynb
index d4f7589..f5aa17f 100644
--- a/lecture_material/12-web-2/template_lec_002.ipynb
+++ b/lecture_material/12-web-2/template_lec_002.ipynb
@@ -26,11 +26,30 @@
    "source": [
     "### Rate-limited webpage parsing\n",
     "\n",
+    "\n",
     "- `requests` module:\n",
     "    - `resp = requests.get(<URL>)` method: enables us to send HTTP GET request\n",
     "    - `resp.status_code`: status code of the response\n",
     "    - `resp.text`: `str` text content of the response\n",
-    "    - `resp.headers`: `dict` content of response headers"
+    "    - `resp.headers`: `dict` content of response headers\n",
+    "    \n",
+    "- `@` operator is called a \"decorator\"\n",
+    "- `flask.Response`: enables us to create a response object instance\n",
+    "    - Arguments: `str` representing reponse, `headers` dict representing metadata, `status` representing status code.\n",
+    "    - ex: \n",
+    "    ```python\n",
+    "    flask.Response(\"<b>go away</b>\",\n",
+    "                              status=429,\n",
+    "                              headers={\"Retry-After\": \"3\"})\n",
+    "    ```\n",
+    "    \n",
+    "    ```python\n",
+    "    flask.Response(\"\"\"User-Agent: *\n",
+    "    Disallow: /never\n",
+    "    \"\"\", headers={\"Content-Type\": \"text/plain\"})\n",
+    "    ```\n",
+    "\n",
+    "- `flask.request.remote_addr`: enables us to take action based on the IP address from which we receive the request"
    ]
   },
   {
@@ -56,7 +75,7 @@
     "        resp.raise_for_status() # raise exception if not 200\n",
     "        return resp\n",
     "    \n",
-    "friendly_get(base_url + \"/slow\").text"
+    "friendly_get(base_url + \"slow\").text"
    ]
   }
  ],
diff --git a/lecture_material/12-web-2/template_lec_002.py b/lecture_material/12-web-2/template_lec_002.py
index 94e9273..5888343 100644
--- a/lecture_material/12-web-2/template_lec_002.py
+++ b/lecture_material/12-web-2/template_lec_002.py
@@ -1,6 +1,5 @@
 import flask # requires installation if not already installed - pip3 install flask
 import time
-import json
 
 app = flask.Flask("my application") # name of the web application can be anything
 
@@ -18,8 +17,7 @@ last_visit = 0 # TODO: dict of visit times, for each IP
 # TODO: create a dynamic page ha.html
 # DYNAMIC
 
-# STATIC
-# @ operator is called a "decorator"
+
 # STATIC
 # @ operator is called a "decorator"
 @app.route("/")
diff --git a/lecture_material/13-web-3/solution.ipynb b/lecture_material/13-web-3/solution.ipynb
index 6e99ca0..bbab494 100644
--- a/lecture_material/13-web-3/solution.ipynb
+++ b/lecture_material/13-web-3/solution.ipynb
@@ -22,16 +22,18 @@
   },
   {
    "cell_type": "markdown",
-   "id": "527600aa",
+   "id": "725234ef-a02b-47da-bfec-aaa16e852a58",
    "metadata": {},
    "source": [
-    "### Rate-limited webpage parsing\n",
-    "\n",
-    "- `requests` module:\n",
-    "    - `resp = requests.get(<URL>)` method: enables us to send HTTP GET request\n",
-    "    - `resp.status_code`: status code of the response\n",
-    "    - `resp.text`: `str` text content of the response\n",
-    "    - `resp.headers`: `dict` content of response headers"
+    "- `flask.request.args`: enables us to get the arguments passed as part of the URL\n",
+    "    - How do we pass arguments?\n",
+    "        - at the end of the URL, add a \"?\"\n",
+    "        - then separate argument-value pair by \"=\"\n",
+    "        - use \"&\" as delimiter between two argument-value pairs\n",
+    "    - examples: \n",
+    "        - http://34.123.132.20:5000/add?x=10&y=20\n",
+    "        - http://34.123.132.20:5000/survey?major=CS\n",
+    "        - http://34.123.132.20:5000/survey?major=Mechanical_Engineering"
    ]
   },
   {
@@ -87,7 +89,7 @@
     {
      "data": {
       "text/plain": [
-       "True"
+       "False"
       ]
      },
      "execution_count": 4,
@@ -96,7 +98,7 @@
     }
    ],
    "source": [
-    "rp.can_fetch(\"cs320bot\", base_url + \"/never\")"
+    "rp.can_fetch(\"cs320bot\", base_url + \"never\")"
    ]
   },
   {
@@ -130,7 +132,7 @@
     "        resp.raise_for_status() # raise exception if not 200\n",
     "        return resp\n",
     "    \n",
-    "friendly_get(base_url + \"/slow\").text"
+    "friendly_get(base_url + \"slow\").text"
    ]
   }
  ],
diff --git a/lecture_material/13-web-3/solution.py b/lecture_material/13-web-3/solution.py
index 3253c47..66e3bf3 100644
--- a/lecture_material/13-web-3/solution.py
+++ b/lecture_material/13-web-3/solution.py
@@ -1,6 +1,6 @@
 import flask # requires installation if not already installed - pip3 install flask
 import time
-import json
+# import json
 
 app = flask.Flask("my application") # name of the web application can be anything
 
diff --git a/lecture_material/13-web-3/template_lec_001.ipynb b/lecture_material/13-web-3/template_lec_001.ipynb
index 66eb333..2b3de51 100644
--- a/lecture_material/13-web-3/template_lec_001.ipynb
+++ b/lecture_material/13-web-3/template_lec_001.ipynb
@@ -21,16 +21,18 @@
   },
   {
    "cell_type": "markdown",
-   "id": "527600aa",
+   "id": "a5f26f67-000a-4d68-8033-3e46023b8196",
    "metadata": {},
    "source": [
-    "### Rate-limited webpage parsing\n",
-    "\n",
-    "- `requests` module:\n",
-    "    - `resp = requests.get(<URL>)` method: enables us to send HTTP GET request\n",
-    "    - `resp.status_code`: status code of the response\n",
-    "    - `resp.text`: `str` text content of the response\n",
-    "    - `resp.headers`: `dict` content of response headers"
+    "- `flask.request.args`: enables us to get the arguments passed as part of the URL\n",
+    "    - How do we pass arguments?\n",
+    "        - at the end of the URL, add a \"?\"\n",
+    "        - then separate argument-value pair by \"=\"\n",
+    "        - use \"&\" as delimiter between two argument-value pairs\n",
+    "    - examples: \n",
+    "        - http://34.123.132.20:5000/add?x=10&y=20\n",
+    "        - http://34.123.132.20:5000/survey?major=CS\n",
+    "        - http://34.123.132.20:5000/survey?major=Mechanical_Engineering"
    ]
   },
   {
@@ -79,10 +81,15 @@
     "def friendly_get(url):\n",
     "    while True:\n",
     "        resp = requests.get(url)\n",
+    "        if resp.status_code == 429:\n",
+    "            seconds = int(resp.headers.get(\"Retry-After\", 1))\n",
+    "            print(f\"sleep {seconds}\")\n",
+    "            time.sleep(seconds)\n",
+    "            continue\n",
     "        resp.raise_for_status() # raise exception if not 200\n",
     "        return resp\n",
     "    \n",
-    "friendly_get(base_url + \"/slow\").text"
+    "friendly_get(base_url + \"slow\").text"
    ]
   }
  ],
diff --git a/lecture_material/13-web-3/template_lec_001.py b/lecture_material/13-web-3/template_lec_001.py
index b939f28..25b352f 100644
--- a/lecture_material/13-web-3/template_lec_001.py
+++ b/lecture_material/13-web-3/template_lec_001.py
@@ -1,6 +1,5 @@
 import flask # requires installation if not already installed - pip3 install flask
 import time
-import json
 
 app = flask.Flask("my application") # name of the web application can be anything
 
@@ -29,8 +28,6 @@ last_visit = 0 # TODO: dict of visit times, for each IP
 # TODO: create a dynamic page ha.html
 # DYNAMIC
 
-# STATIC
-# @ operator is called a "decorator"
 # STATIC
 # @ operator is called a "decorator"
 @app.route("/")
diff --git a/lecture_material/13-web-3/template_lec_002.ipynb b/lecture_material/13-web-3/template_lec_002.ipynb
index 66eb333..e47bb0e 100644
--- a/lecture_material/13-web-3/template_lec_002.ipynb
+++ b/lecture_material/13-web-3/template_lec_002.ipynb
@@ -19,6 +19,22 @@
     "import time\n"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "14525019-f30b-40a7-be53-db49868abce6",
+   "metadata": {},
+   "source": [
+    "- `flask.request.args`: enables us to get the arguments passed as part of the URL\n",
+    "    - How do we pass arguments?\n",
+    "        - at the end of the URL, add a \"?\"\n",
+    "        - then separate argument-value pair by \"=\"\n",
+    "        - use \"&\" as delimiter between two argument-value pairs\n",
+    "    - examples: \n",
+    "        - http://34.123.132.20:5000/add?x=10&y=20\n",
+    "        - http://34.123.132.20:5000/survey?major=CS\n",
+    "        - http://34.123.132.20:5000/survey?major=Mechanical_Engineering"
+   ]
+  },
   {
    "cell_type": "markdown",
    "id": "527600aa",
@@ -79,10 +95,15 @@
     "def friendly_get(url):\n",
     "    while True:\n",
     "        resp = requests.get(url)\n",
+    "        if resp.status_code == 429:\n",
+    "            seconds = int(resp.headers.get(\"Retry-After\", 1))\n",
+    "            print(f\"sleep {seconds}\")\n",
+    "            time.sleep(seconds)\n",
+    "            continue\n",
     "        resp.raise_for_status() # raise exception if not 200\n",
     "        return resp\n",
     "    \n",
-    "friendly_get(base_url + \"/slow\").text"
+    "friendly_get(base_url + \"slow\").text"
    ]
   }
  ],
diff --git a/lecture_material/13-web-3/template_lec_002.py b/lecture_material/13-web-3/template_lec_002.py
index b939f28..25b352f 100644
--- a/lecture_material/13-web-3/template_lec_002.py
+++ b/lecture_material/13-web-3/template_lec_002.py
@@ -1,6 +1,5 @@
 import flask # requires installation if not already installed - pip3 install flask
 import time
-import json
 
 app = flask.Flask("my application") # name of the web application can be anything
 
@@ -29,8 +28,6 @@ last_visit = 0 # TODO: dict of visit times, for each IP
 # TODO: create a dynamic page ha.html
 # DYNAMIC
 
-# STATIC
-# @ operator is called a "decorator"
 # STATIC
 # @ operator is called a "decorator"
 @app.route("/")
-- 
GitLab