diff --git a/lecture_material/12-web-2/solution.ipynb b/lecture_material/12-web-2/solution.ipynb index 8ca8f48e0f8f5355d68688b96cee04d9d971f3a6..09d1c355c187545ba1a0c5b06e3660a03ee6ad82 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 941b19fc9c2ddfc54dab1be622b4d569df488780..d1548ec03d68ea21d417ef8306da0f10723d9711 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 d4f758903bd9b3a00b41d99dcea8cfd891f7333f..ec598f08c3fe62a07c5cdee2ad2a1736f7c52998 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 94e927319c02f15ed50e125e8594176908a5a980..bfc95224ea2b577ea028d4ebcedc07b0447a4dc6 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 d4f758903bd9b3a00b41d99dcea8cfd891f7333f..f5aa17fd5d0cd408c751903d856c4d68c0a0e347 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 94e927319c02f15ed50e125e8594176908a5a980..5888343253a34486caa1072a13cb39b5420374db 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 6e99ca0bb92dfdc953e2c46044c7cccb428d2be6..bbab49462681da91fc9e53665ea44baec975ae85 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 3253c47e0ff0cc475aad13824173eae72f15663c..66e3bf3f739d206c7d6fcf2829e23cde328904a7 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 66eb333ebc29ffa3abb4c68889f42bf4ff6fdc30..2b3de5197342306f6dd41de9e263f3c04eda3713 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 b939f286a1a9b862032e26473fda0c45983193ea..25b352fdad794caff61e5bc608d4acf66db55fde 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 66eb333ebc29ffa3abb4c68889f42bf4ff6fdc30..e47bb0ec191d1033aa9471496a51c9c5f6781dd8 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 b939f286a1a9b862032e26473fda0c45983193ea..25b352fdad794caff61e5bc608d4acf66db55fde 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("/")