Difference between revisions of "Python-Flask/C2/Request-Response-Cycle-in-a-Flask-Web-App/English"
(Created page with "'''Title of script: The Request-Response Cycle in a Flask web app''' '''Author: Siddhartha Sarkar''' Keywords: Video tutorial, Python Flask, view functions, request objec...") |
(Script synced with video.) |
||
Line 8: | Line 8: | ||
{| class="wikitable" style="border-spacing:0;width:17.489cm;" | {| class="wikitable" style="border-spacing:0;width:17.489cm;" | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
| align=center| '''Visual Cue''' | | align=center| '''Visual Cue''' | ||
| align=center| '''Narration''' | | align=center| '''Narration''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| '''Slide 1: The Request-Response Cycle in a Flask web app''' | || '''Slide 1: The Request-Response Cycle in a Flask web app''' | ||
|| Welcome to the Spoken Tutorial on''' the request-response cycle in a Flask web app.''' | || Welcome to the Spoken Tutorial on''' the request-response cycle in a Flask web app.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| '''Slide 2: Learning Objectives''' | || '''Slide 2: Learning Objectives''' | ||
|| In this tutorial, we will learn | || In this tutorial, we will learn | ||
Line 23: | Line 23: | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| '''Slides 3: System Requirements''' | || '''Slides 3: System Requirements''' | ||
|| To record this tutorial, I’m using | || To record this tutorial, I’m using | ||
Line 30: | Line 30: | ||
* <div style="margin-left:1.27cm;margin-right:0cm;">'''Atom text editor 1.22.1 '''and''' '''</div> | * <div style="margin-left:1.27cm;margin-right:0cm;">'''Atom text editor 1.22.1 '''and''' '''</div> | ||
* <div style="margin-left:1.27cm;margin-right:0cm;">'''Firefox web browser'''</div> | * <div style="margin-left:1.27cm;margin-right:0cm;">'''Firefox web browser'''</div> | ||
+ | |||
+ | |||
+ | |||
You can use any text editor and web browser of your choice. | You can use any text editor and web browser of your choice. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| '''Slide 5:''' | || '''Slide 5:''' | ||
Line 39: | Line 42: | ||
− | || To follow this tutorial, you should have working knowledge of | + | |
− | * <div style="margin-left:1.27cm;margin-right:0cm;">'''Linux commands'''</div> | + | || To follow this tutorial, you should have working knowledge of* <div style="margin-left:1.27cm;margin-right:0cm;">'''Linux commands'''</div> |
+ | |||
* <div style="margin-left:1.27cm;margin-right:0cm;">'''Python programming '''and </div> | * <div style="margin-left:1.27cm;margin-right:0cm;">'''Python programming '''and </div> | ||
* <div style="margin-left:1.27cm;margin-right:0cm;">'''HTML '''syntax</div> | * <div style="margin-left:1.27cm;margin-right:0cm;">'''HTML '''syntax</div> | ||
+ | |||
+ | |||
+ | |||
+ | |||
If not, then please go through the corresponding tutorials on this website. http://spoken-tutorial.org | If not, then please go through the corresponding tutorials on this website. http://spoken-tutorial.org | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| '''Slide 6''': '''The request object''' | || '''Slide 6''': '''The request object''' | ||
|| We already said that the '''Flask app''' instance has to process the received '''request'''. | || We already said that the '''Flask app''' instance has to process the received '''request'''. | ||
Line 51: | Line 59: | ||
For processing, the '''app '''instance needs to have access to certain information. | For processing, the '''app '''instance needs to have access to certain information. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| '''Slide 6''': '''The request object''' | || '''Slide 6''': '''The request object''' | ||
|| A few '''objects '''are provided to the '''view functions,''' where the processing takes place. | || A few '''objects '''are provided to the '''view functions,''' where the processing takes place. | ||
Line 60: | Line 68: | ||
This '''object '''encapsulates the contents of the '''HTTP request '''sent by the '''client'''. | This '''object '''encapsulates the contents of the '''HTTP request '''sent by the '''client'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| '''Slide 7''': '''The request object''' | || '''Slide 7''': '''The request object''' | ||
|| The incoming '''request '''data can be of several forms. For example | || The incoming '''request '''data can be of several forms. For example | ||
Line 69: | Line 77: | ||
We will discuss them in detail in this tutorial. | We will discuss them in detail in this tutorial. | ||
|- | |- | ||
− | | style="background-color:#ffffff;border-top:1pt solid # | + | | style="background-color:#ffffff;border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:1pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.095cm;padding-right:0.191cm;" | Open a Terminal window |
+ | |||
− | | style="background-color:#ffffff;border-top:1pt solid # | + | | style="background-color:#ffffff;border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.095cm;padding-right:0.191cm;" | Let us open the '''Terminal''' by pressing '''Ctrl''', '''Alt''' and '''T''' keys simultaneously on the keyboard. |
− | |- style="background-color:#ffffff;border:0.5pt solid # | + | |- style="background-color:#ffffff;border:0.5pt solid #000000;padding:0.106cm;" |
|| [Terminal] | || [Terminal] | ||
Type cd project_flask & Press Enter | Type cd project_flask & Press Enter | ||
|| Now go to the folder '''project underscore flask''' which we created earlier using '''cd''' '''command.''' | || Now go to the folder '''project underscore flask''' which we created earlier using '''cd''' '''command.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
Line 95: | Line 104: | ||
And press '''Enter'''. | And press '''Enter'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
Highlight (flask_venv) | Highlight (flask_venv) | ||
|| Notice that we are now inside the '''virtual environment flask_venv.''' | || Notice that we are now inside the '''virtual environment flask_venv.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
Line 107: | Line 116: | ||
$ atom hello_flask.py | $ atom hello_flask.py | ||
|| Let’s open the '''hello_flask.py''' file in a text editor, which we created earlier in this series.. | || Let’s open the '''hello_flask.py''' file in a text editor, which we created earlier in this series.. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Text Editor] | || [Text Editor] | ||
+ | |||
Type “'', request''” | Type “'', request''” | ||
+ | |||
+ | |||
|| Let’s look at how the '''request object''' is made available in a '''view function'''. | || Let’s look at how the '''request object''' is made available in a '''view function'''. | ||
Line 119: | Line 131: | ||
In the line '''from flask import Flask, '''we will add '''comma space request''' | In the line '''from flask import Flask, '''we will add '''comma space request''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Text editor] | || [Text editor] | ||
Line 138: | Line 150: | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight | || Highlight | ||
Line 147: | Line 159: | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Press Ctrl+S | || Press Ctrl+S | ||
|| Save the file. | || Save the file. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
Line 161: | Line 173: | ||
|| Let us start the '''server''' to see the changes. | || Let us start the '''server''' to see the changes. | ||
+ | |||
+ | |||
+ | Switch to the terminal. | ||
Line 167: | Line 182: | ||
And press '''Enter'''. | And press '''Enter'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
Line 182: | Line 197: | ||
And press '''Enter'''. | And press '''Enter'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Firefox] | || [Firefox] | ||
Line 190: | Line 205: | ||
And press Enter. | And press Enter. | ||
− | || | + | || Now, open a web browser. |
− | In the '''address bar,''' type [http://127.0.0.1:5000/ http://localhost:5000 | + | In the '''address bar,''' type [http://127.0.0.1:5000/ http://localhost:5000] and press '''Enter'''. |
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight the output | || Highlight the output | ||
|| We got the output as '''Hello World.''' | || We got the output as '''Hello World.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
|| Switch to the '''terminal '''once again. | || Switch to the '''terminal '''once again. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight “Request method is Get” | || Highlight “Request method is Get” | ||
|| Observe that the current '''request method '''is “'''GET'''”. | || Observe that the current '''request method '''is “'''GET'''”. | ||
Line 212: | Line 227: | ||
It specifies the '''parameters''' in the '''URL''' of the '''request '''itself. | It specifies the '''parameters''' in the '''URL''' of the '''request '''itself. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Only narration. | || Only narration. | ||
|| Now let us see how one can send '''data''' to the '''server '''using the '''request object'''. | || Now let us see how one can send '''data''' to the '''server '''using the '''request object'''. | ||
Line 221: | Line 236: | ||
The simplest one is via '''Query Arguments'''. | The simplest one is via '''Query Arguments'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
− | || | + | || [Text Editor] |
− | [Text Editor] | + | |
Type | Type | ||
+ | |||
@app.route('/query') | @app.route('/query') | ||
Line 233: | Line 248: | ||
(Tab)framework = request.args['framework'] | (Tab)framework = request.args['framework'] | ||
− | <nowiki>(Tab)return '''<h1>The framework value is: {}</h1>'''.format(framework) | + | <nowiki>(Tab)return '''<h1>The framework value is: {}</h1>'''.format(framework)</nowiki> |
− | </nowiki> | + | |
|| Let us define a new '''route''' to explain this. | || Let us define a new '''route''' to explain this. | ||
Line 245: | Line 259: | ||
We will call it as '''query'''. | We will call it as '''query'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Press Ctrl+S | || Press Ctrl+S | ||
|| Save the file. | || Save the file. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight | || Highlight | ||
− | <nowiki> | + | |
− | <h1>The framework value is: {}</h1> | + | <nowiki><h1>The framework value is: {}</h1></nowiki> |
− | </nowiki> | + | |
|| Here we have written the '''statement''' inside the '''HTML’s h1 heading tag'''. | || Here we have written the '''statement''' inside the '''HTML’s h1 heading tag'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight '''args''' in | || Highlight '''args''' in | ||
Line 272: | Line 285: | ||
We will use this '''attribute '''to retrieve the '''data '''sent as '''query arguments.''' | We will use this '''attribute '''to retrieve the '''data '''sent as '''query arguments.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
|| Switch to the '''terminal'''. | || Switch to the '''terminal'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Press Ctrl+C | || Press Ctrl+C | ||
|| Press '''Ctrl''' and '''C''' keys to stop the '''server'''. | || Press '''Ctrl''' and '''C''' keys to stop the '''server'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Type | || Type | ||
Line 287: | Line 300: | ||
And press '''Enter'''. | And press '''Enter'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Firefox] | || [Firefox] | ||
|| Switch to the '''web browser. ''' | || Switch to the '''web browser. ''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Type | || Type | ||
Line 299: | Line 312: | ||
and press '''Enter'''. | and press '''Enter'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight the error | || Highlight the error | ||
|| We get a “'''Bad request'''” error. | || We get a “'''Bad request'''” error. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
|| Switch back to the '''terminal'''. | || Switch back to the '''terminal'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight | || Highlight | ||
"GET /query HTTP/1.1" 400 - | "GET /query HTTP/1.1" 400 - | ||
+ | |||
Line 319: | Line 333: | ||
'''400 code''' indicates that the '''server''' could not understand the '''request''' due to invalid '''syntax'''. | '''400 code''' indicates that the '''server''' could not understand the '''request''' due to invalid '''syntax'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Only narration. | || Only narration. | ||
|| So now we have to find out where this '''syntax''' issue has occurred. | || So now we have to find out where this '''syntax''' issue has occurred. | ||
Line 328: | Line 342: | ||
This is called '''debugging'''. | This is called '''debugging'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Text Editor] | || [Text Editor] | ||
+ | |||
Press Ctrl+C | Press Ctrl+C | ||
|| For this, we have to start the '''server''' in the '''debug mode'''. | || For this, we have to start the '''server''' in the '''debug mode'''. | ||
+ | |||
Before that, we need to stop the current '''server''' by pressing '''Ctrl''' and '''C '''keys together. | Before that, we need to stop the current '''server''' by pressing '''Ctrl''' and '''C '''keys together. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
Line 343: | Line 359: | ||
$ export FLASK_ENV=development | $ export FLASK_ENV=development | ||
|| Then type '''export <space>FLASK <underscore> ENV <equal to> development''' | || Then type '''export <space>FLASK <underscore> ENV <equal to> development''' | ||
+ | |||
and press '''Enter'''. | and press '''Enter'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
Type | Type | ||
+ | |||
$ python3 -m flask run | $ python3 -m flask run | ||
Line 357: | Line 375: | ||
And press '''Enter'''. | And press '''Enter'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
Line 365: | Line 383: | ||
− | |- style=" | + | |
+ | |- style="border:1pt solid #000000;padding:0.176cm;" | ||
|| [Firefox] | || [Firefox] | ||
Line 374: | Line 393: | ||
Since the '''debug mode''' is active, we have received a '''traceback''' of errors. | Since the '''debug mode''' is active, we have received a '''traceback''' of errors. | ||
− | |||
This means that we get the line numbers where the errors have occurred in different files. | This means that we get the line numbers where the errors have occurred in different files. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight the different error lines in the traceback of errors. | || Highlight the different error lines in the traceback of errors. | ||
− | |||
|| The '''traceback''' includes the errors from the corresponding '''flask''' files as well. | || The '''traceback''' includes the errors from the corresponding '''flask''' files as well. | ||
− | |||
This is because an error in one file causes errors in other files as well. | This is because an error in one file causes errors in other files as well. | ||
− | |||
This is termed as the '''cascading''' '''effect'''. | This is termed as the '''cascading''' '''effect'''. | ||
− | |||
We have to look for the error in a file that we have written. | We have to look for the error in a file that we have written. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight | || Highlight | ||
Line 398: | Line 412: | ||
framework = request.args['framework'] | framework = request.args['framework'] | ||
|| Scroll down and search for the error in the file '''hello_flask.py''' | || Scroll down and search for the error in the file '''hello_flask.py''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight | || Highlight | ||
− | |||
BadRequestKeyError | BadRequestKeyError | ||
− | + | || We have a '''BadRequestKeyError'''. | |
− | || We have a '''BadRequestKeyError''' | + | |
− | + | ||
That means that the '''key “framework”''' for the '''dictionary request.args''' does not exist. | That means that the '''key “framework”''' for the '''dictionary request.args''' does not exist. | ||
− | |||
To rectify this, we have to modify that line. | To rectify this, we have to modify that line. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Text editor] | || [Text editor] | ||
− | |||
Type | Type | ||
− | |||
framework = request.args.get('framework') | framework = request.args.get('framework') | ||
|| Switch to the '''editor'''. | || Switch to the '''editor'''. | ||
+ | Now change the '''line '''as shown. | ||
− | |||
− | + | |- style="border:1pt solid #000000;padding:0.176cm;" | |
− | |- style=" | + | |
|| Press Ctrl+S | || Press Ctrl+S | ||
|| Save the file. | || Save the file. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Text Editor] | || [Text Editor] | ||
− | |||
Highlight | Highlight | ||
− | |||
framework = request.args.get('framework') | framework = request.args.get('framework') | ||
|| Now even if the '''key''' is not found, '''python''' will handle this properly. | || Now even if the '''key''' is not found, '''python''' will handle this properly. | ||
+ | |||
That means, instead of causing a '''400 error''', it will return '''None'''. | That means, instead of causing a '''400 error''', it will return '''None'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
|| Switch to the '''terminal.''' | || Switch to the '''terminal.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Press Ctrl+C | || Press Ctrl+C | ||
|| Once again stop the '''server''' by pressing '''Ctrl''' and '''C''' keys together. | || Once again stop the '''server''' by pressing '''Ctrl''' and '''C''' keys together. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Type python3 -m flask run | || Type python3 -m flask run | ||
|| Then run the '''server''' again. | || Then run the '''server''' again. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Firefox] | || [Firefox] | ||
|| Go back to the '''browser''' and refresh the page. | || Go back to the '''browser''' and refresh the page. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Click on the refresh button. | || Click on the refresh button. | ||
− | || Now we have the output | + | || Now we have the output as expected. |
The '''framework value''' is '''None'''. | The '''framework value''' is '''None'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| | || | ||
|| Next, we will send some value for the '''framework '''via the '''URL'''. | || Next, we will send some value for the '''framework '''via the '''URL'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Firefox] | || [Firefox] | ||
Line 468: | Line 474: | ||
Click on the address bar | Click on the address bar | ||
|| '''args''' gets the part of the '''URL '''after the question mark in the form of a '''python dictionary'''. | || '''args''' gets the part of the '''URL '''after the question mark in the form of a '''python dictionary'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Firefox] | || [Firefox] | ||
Line 476: | Line 482: | ||
− | '''Question mark framework <equal to> | + | '''Question mark framework <equal to> my_flask''' |
And press '''Enter.''' | And press '''Enter.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight: | || Highlight: | ||
− | The framework value is: my_flask | + | <nowiki>The framework value is: my_flask</nowiki> |
|| So now we have the '''framework attribute''' of the '''dictionary''' set to '''my_flask'''. | || So now we have the '''framework attribute''' of the '''dictionary''' set to '''my_flask'''. | ||
We got the result as expected. | We got the result as expected. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| '''Slide 8''': '''form attribute''' | || '''Slide 8''': '''form attribute''' | ||
|| The '''request object''' has one more important '''attribute''' called '''‘form’'''. | || The '''request object''' has one more important '''attribute''' called '''‘form’'''. | ||
Line 500: | Line 506: | ||
Let us look at an example. | Let us look at an example. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Text Editor] | || [Text Editor] | ||
Type | Type | ||
+ | |||
@app.route('/form', methods=['GET', 'POST']) | @app.route('/form', methods=['GET', 'POST']) | ||
+ | |||
+ | |||
|| We will see how '''form data''' can be sent and received using the '''request object.''' | || We will see how '''form data''' can be sent and received using the '''request object.''' | ||
+ | |||
Let us define a new '''route''' called '''form'''. | Let us define a new '''route''' called '''form'''. | ||
+ | |||
We allow both '''GET''' and '''POST''' as possible '''request''' '''methods'''. | We allow both '''GET''' and '''POST''' as possible '''request''' '''methods'''. | ||
− | + | ||
− | |- style=" | + | Type the code as shown here. |
+ | |- style="border:1pt solid #000000;padding:0.176cm;" | ||
|| [Text Editor] | || [Text Editor] | ||
Type | Type | ||
+ | |||
def my_form(): | def my_form(): | ||
Line 528: | Line 541: | ||
lastname = request.form.get('lastname') | lastname = request.form.get('lastname') | ||
− | || | + | || Inside the '''form route''', define a '''view function''' '''my_form'''() |
− | |||
− | |- style=" | + | |
+ | |||
+ | |- style="border:1pt solid #000000;padding:0.176cm;" | ||
|| Highlight: | || Highlight: | ||
Line 543: | Line 557: | ||
lastname = request.form.get('lastname') | lastname = request.form.get('lastname') | ||
|| | || | ||
+ | |||
This '''block''' will get executed, if the '''request''' is via '''POST method.''' | This '''block''' will get executed, if the '''request''' is via '''POST method.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| '''Slide 9''': '''POST method''' | || '''Slide 9''': '''POST method''' | ||
|| In '''POST request method''' | || In '''POST request method''' | ||
− | |||
* <div style="margin-left:1.27cm;margin-right:0cm;">the '''client''' will send '''data''' to the '''server''' using the '''form'''.</div> | * <div style="margin-left:1.27cm;margin-right:0cm;">the '''client''' will send '''data''' to the '''server''' using the '''form'''.</div> | ||
* <div style="margin-left:1.27cm;margin-right:0cm;">This is to update the '''server''' with some information</div> | * <div style="margin-left:1.27cm;margin-right:0cm;">This is to update the '''server''' with some information</div> | ||
− | + | |- style="border:1pt solid #000000;padding:0.176cm;" | |
− | |- style=" | + | |
|| '''Slide 9''': '''POST method''' | || '''Slide 9''': '''POST method''' | ||
− | || * <div style="margin-left:1.27cm;margin-right:0cm;">For example - you enter your '''username''' and '''password''' while logging in to a website.</div> | + | || |
+ | * <div style="margin-left:1.27cm;margin-right:0cm;">For example - you enter your '''username''' and '''password''' while logging in to a website.</div> | ||
* <div style="margin-left:1.27cm;margin-right:0cm;">In contrast, '''GET request method '''is used to get or read some '''data '''from the '''server'''.</div> | * <div style="margin-left:1.27cm;margin-right:0cm;">In contrast, '''GET request method '''is used to get or read some '''data '''from the '''server'''.</div> | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Only narration | || Only narration | ||
Line 569: | Line 583: | ||
We will obtain the entered values from the '''request object''' using the '''form''' '''attribute'''. | We will obtain the entered values from the '''request object''' using the '''form''' '''attribute'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
− | + | ||
− | + | ||
− | + | ||
|| Type | || Type | ||
− | <nowiki>html_string1 = '''<h1>The firstname value is: {}</h1> </nowiki> | + | <nowiki>html_string1 = '''<h1>The firstname value is: {}</h1></nowiki> |
− | <nowiki> <h1>The lastname value is: {}</h1>'''.format(firstname, lastname) </nowiki> | + | <nowiki><h1>The lastname value is: {}</h1>'''.format(firstname, lastname)</nowiki> |
return html_string1 | return html_string1 | ||
− | || Inside the '''if condition''' which checks the''' post method, '''type | + | || Inside the '''if condition''' which checks the''' post method, '''type this code. |
− | This code will display the | + | This code will display the '''firstname''' as well as the '''lastname'''. |
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Text Editor] | || [Text Editor] | ||
Line 608: | Line 619: | ||
return html_string2 | return html_string2 | ||
− | || Now outside | + | || Now outside this''' if condition''', we type this code. |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
This will simply display a '''web form''' in the output, if the '''request method''' is '''GET.''' | This will simply display a '''web form''' in the output, if the '''request method''' is '''GET.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Press Ctrl + S | || Press Ctrl + S | ||
|| Save the file. | || Save the file. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
|| Switch back to the '''terminal'''. | || Switch back to the '''terminal'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Press Ctrl+C | || Press Ctrl+C | ||
|| Stop the '''server''' by pressing '''Ctrl''' and '''C''' keys together. | || Stop the '''server''' by pressing '''Ctrl''' and '''C''' keys together. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Type python3 -m flask run | || Type python3 -m flask run | ||
|| Then run the '''server''' again. | || Then run the '''server''' again. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Firefox] | || [Firefox] | ||
Type [http://127.0.0.1:5000/form http://127.0.0.1:5000/form] | Type [http://127.0.0.1:5000/form http://127.0.0.1:5000/form] | ||
− | |||
Line 658: | Line 647: | ||
In the '''address bar''' type the '''URL''' as '''http://localhost:5000/form''' and press '''Enter.''' | In the '''address bar''' type the '''URL''' as '''http://localhost:5000/form''' and press '''Enter.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| | || | ||
|| The page is displayed with a '''form'''. | || The page is displayed with a '''form'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| | || | ||
|| Let us enter some values in the '''form'''. | || Let us enter some values in the '''form'''. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Type '''First name''' as '''Spoken.''' | || Type '''First name''' as '''Spoken.''' | ||
Line 676: | Line 665: | ||
And then click on '''Submit '''button''' '''located at the bottom of the''' web form.''' | And then click on '''Submit '''button''' '''located at the bottom of the''' web form.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Firefox] | || [Firefox] | ||
Line 683: | Line 672: | ||
The text in the browser | The text in the browser | ||
− | || Here we have | + | || Here we have received the '''firstname''' and '''lastname''' from the '''request object'''. |
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
− | + | ||
− | + | ||
− | + | ||
|| [Text Editor] | || [Text Editor] | ||
|| The last thing I want to talk in this section is about “'''500: Internal Server Error'''”. | || The last thing I want to talk in this section is about “'''500: Internal Server Error'''”. | ||
Line 696: | Line 682: | ||
This is one of the most frequent errors you will encounter during '''flask''' '''app''' development. | This is one of the most frequent errors you will encounter during '''flask''' '''app''' development. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| | || | ||
|| Let us write a '''code snippet''' to demonstrate this. | || Let us write a '''code snippet''' to demonstrate this. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Text Editor] | || [Text Editor] | ||
− | || Switch to the '''editor'''. | + | || Switch back to the '''editor'''. |
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Type inside user(name): | || Type inside user(name): | ||
Line 716: | Line 702: | ||
Save the file. | Save the file. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Terminal] | || [Terminal] | ||
|| Switch to the '''terminal.''' | || Switch to the '''terminal.''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Press Ctrl+C | || Press Ctrl+C | ||
|| Stop the '''server''' by pressing '''Ctrl''' and '''C''' keys together. | || Stop the '''server''' by pressing '''Ctrl''' and '''C''' keys together. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Type python3 -m flask run | || Type python3 -m flask run | ||
|| Now run the '''server''' again. | || Now run the '''server''' again. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Firefox] | || [Firefox] | ||
Line 737: | Line 723: | ||
In the '''address bar''' type the '''URL''' as '''http://localhost:5000/user/Sid''' and press '''Enter''' | In the '''address bar''' type the '''URL''' as '''http://localhost:5000/user/Sid''' and press '''Enter''' | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| [Firefox] | || [Firefox] | ||
− | || Observe that we have | + | || Observe that we have a '''ZeroDivisionError'''. |
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Highlight star | || Highlight star | ||
|| Let’s switch to the '''terminal''' to see the '''HTTP status code'''. | || Let’s switch to the '''terminal''' to see the '''HTTP status code'''. | ||
|- | |- | ||
− | | style=" | + | | style="border:1pt solid #000000;padding:0.176cm;" | [Terminal] |
Line 754: | Line 740: | ||
− | | style=" | + | | style="border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.095cm;padding-right:0.191cm;" | Here we can see '''HTTP response code''' as '''500.''' |
Line 760: | Line 746: | ||
− | The '''500''' error implies that, there’s something wrong in the '''web server'''. | + | The '''500''' error simply implies that, there’s something wrong in the '''web server'''. |
|- | |- | ||
− | | style=" | + | | style="border:1pt solid #000000;padding:0.176cm;" | |
− | | style=" | + | | style="border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.095cm;padding-right:0.191cm;" | Since we have the '''debug mode '''on, we know the specific reason for the error. |
|- | |- | ||
− | | style=" | + | | style="border:1pt solid #000000;padding:0.176cm;" | |
− | | style=" | + | | style="border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.095cm;padding-right:0.191cm;" | With this we come to the end of this tutorial. |
Let us summarise. | Let us summarise. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Slide 10: Summary | || Slide 10: Summary | ||
|| In this tutorial, we learnt about, | || In this tutorial, we learnt about, | ||
Line 781: | Line 767: | ||
|- | |- | ||
− | | style=" | + | | style="border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:1pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.079cm;padding-right:0.191cm;" | Slide: About Spoken Tutorial project |
− | | style=" | + | | style="border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.079cm;padding-right:0.191cm;" | The video at the following link summarises the Spoken Tutorial project. |
Please download and watch it. | Please download and watch it. | ||
|- | |- | ||
− | | style="background-color:#ffffff;border-top:1pt solid # | + | | style="background-color:#ffffff;border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:1pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.095cm;padding-right:0.191cm;" | Slide: |
Spoken Tutorial workshops | Spoken Tutorial workshops | ||
− | | style="background-color:#ffffff;border-top:1pt solid # | + | | style="background-color:#ffffff;border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.095cm;padding-right:0.191cm;" | <span style="background-color:#ffffff;">The </span><span style="background-color:#ffffff;">'''Spoken Tutorial Project'''</span><span style="background-color:#ffffff;"> team </span>conducts workshops and gives certificates. |
For more details, please write to us. | For more details, please write to us. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| Slide: | || Slide: | ||
Line 800: | Line 786: | ||
|| Please post your timed queries in this forum. | || Please post your timed queries in this forum. | ||
|- | |- | ||
− | | style="background-color:#ffffff;border-top:1pt solid # | + | | style="background-color:#ffffff;border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:1pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.095cm;padding-right:0.191cm;" | Slide: Acknowledgement |
− | | style=" | + | | style="border-top:1pt solid #000000;border-bottom:0.5pt solid #000000;border-left:0.5pt solid #000000;border-right:0.5pt solid #000000;padding-top:0cm;padding-bottom:0cm;padding-left:0.095cm;padding-right:0.191cm;" | Spoken Tutorial Project is funded by NMEICT, MHRD, Government of India. |
More information on this mission is available at this link. | More information on this mission is available at this link. | ||
− | |- style=" | + | |- style="border:1pt solid #000000;padding:0.176cm;" |
|| | || | ||
|| This is Siddhartha Sarkar signing off. | || This is Siddhartha Sarkar signing off. |
Revision as of 17:29, 21 January 2019
Title of script: The Request-Response Cycle in a Flask web app
Author: Siddhartha Sarkar
Keywords: Video tutorial, Python Flask, view functions, request object, HTTP response, debugging.
Visual Cue | Narration |
Slide 1: The Request-Response Cycle in a Flask web app | Welcome to the Spoken Tutorial on the request-response cycle in a Flask web app. |
Slide 2: Learning Objectives | In this tutorial, we will learn
|
Slides 3: System Requirements | To record this tutorial, I’m using
You can use any text editor and web browser of your choice. |
Slide 5:
Pre-requisites
|
To follow this tutorial, you should have working knowledge of* Linux commands
If not, then please go through the corresponding tutorials on this website. http://spoken-tutorial.org |
Slide 6: The request object | We already said that the Flask app instance has to process the received request.
|
Slide 6: The request object | A few objects are provided to the view functions, where the processing takes place.
|
Slide 7: The request object | The incoming request data can be of several forms. For example
|
Open a Terminal window
|
Let us open the Terminal by pressing Ctrl, Alt and T keys simultaneously on the keyboard. |
[Terminal]
Type cd project_flask & Press Enter |
Now go to the folder project underscore flask which we created earlier using cd command. |
[Terminal]
|
Let us activate our virtualenv.
And press Enter. |
[Terminal]
Highlight (flask_venv) |
Notice that we are now inside the virtual environment flask_venv. |
[Terminal]
Type $ atom hello_flask.py |
Let’s open the hello_flask.py file in a text editor, which we created earlier in this series.. |
[Text Editor]
|
Let’s look at how the request object is made available in a view function.
|
[Text editor]
Type in hello_world(): (As the first line)
|
The request object has many attributes.
|
Highlight
|
This will print the method attribute of the request object.
|
Press Ctrl+S | Save the file. |
[Terminal]
Type
|
Let us start the server to see the changes.
|
[Terminal]
Type
[Enter] |
Now type
python3 <space> hyphen m <space> flask <space> run
|
[Firefox]
Type And press Enter. |
Now, open a web browser.
|
Highlight the output | We got the output as Hello World. |
[Terminal] | Switch to the terminal once again. |
Highlight “Request method is Get” | Observe that the current request method is “GET”.
|
Only narration. | Now let us see how one can send data to the server using the request object.
|
[Text Editor]
Type
def query_args(): (Tab)framework = request.args['framework'] (Tab)return '''<h1>The framework value is: {}</h1>'''.format(framework) |
Let us define a new route to explain this.
|
Press Ctrl+S | Save the file. |
Highlight
|
Here we have written the statement inside the HTML’s h1 heading tag. |
Highlight args in
framework = request.args['framework']
|
Here we have an attribute called args in the request object.
|
[Terminal] | Switch to the terminal. |
Press Ctrl+C | Press Ctrl and C keys to stop the server. |
Type
|
Press the up arrow key to get the command to run the flask application.
|
[Firefox] | Switch to the web browser. |
Type
And press Enter. |
In the address bar, next to 5000 type slash query
and press Enter. |
Highlight the error | We get a “Bad request” error. |
[Terminal] | Switch back to the terminal. |
Highlight
|
Notice that this response has HTTP code 400.
|
Only narration. | So now we have to find out where this syntax issue has occurred.
|
[Text Editor]
|
For this, we have to start the server in the debug mode.
|
[Terminal]
Type $ export FLASK_ENV=development |
Then type export <space>FLASK <underscore> ENV <equal to> development
|
[Terminal]
Type
|
Now type
python3<space>(hyphen)m<space>flask<space>run
|
[Terminal]
|
Observe that now it says debug mode is on.
|
[Firefox]
|
Go back to the browser and refresh the page.
This means that we get the line numbers where the errors have occurred in different files. |
Highlight the different error lines in the traceback of errors.
|
The traceback includes the errors from the corresponding flask files as well.
This is because an error in one file causes errors in other files as well. This is termed as the cascading effect. We have to look for the error in a file that we have written. |
Highlight
|
Scroll down and search for the error in the file hello_flask.py |
Highlight
BadRequestKeyError
|
We have a BadRequestKeyError.
That means that the key “framework” for the dictionary request.args does not exist. To rectify this, we have to modify that line. |
[Text editor]
Type framework = request.args.get('framework') |
Switch to the editor.
Now change the line as shown.
|
Press Ctrl+S | Save the file. |
[Text Editor]
Highlight framework = request.args.get('framework') |
Now even if the key is not found, python will handle this properly.
|
[Terminal] | Switch to the terminal. |
Press Ctrl+C | Once again stop the server by pressing Ctrl and C keys together. |
Type python3 -m flask run | Then run the server again. |
[Firefox] | Go back to the browser and refresh the page. |
Click on the refresh button. | Now we have the output as expected.
|
Next, we will send some value for the framework via the URL. | |
[Firefox]
|
args gets the part of the URL after the question mark in the form of a python dictionary. |
[Firefox] | In the address bar, next to the word query type:
And press Enter. |
Highlight:
|
So now we have the framework attribute of the dictionary set to my_flask.
|
Slide 8: form attribute | The request object has one more important attribute called ‘form’.
|
[Text Editor]
|
We will see how form data can be sent and received using the request object.
|
[Text Editor]
if request.method == 'POST': firstname = request.form.get('firstname') lastname = request.form.get('lastname') |
Inside the form route, define a view function my_form()
|
Highlight:
firstname = request.form.get('firstname') lastname = request.form.get('lastname') |
This block will get executed, if the request is via POST method. |
Slide 9: POST method | In POST request method
|
Slide 9: POST method |
|
Only narration
|
Now let us store the form values into some variables.
|
Type
<h1>The lastname value is: {}</h1>'''.format(firstname, lastname)
|
Inside the if condition which checks the post method, type this code.
|
[Text Editor]
Firstname: <input type="text" name="firstname"> Lastname: <input type="text" name="lastname"> <input type="submit" value="Submit"> </form>
|
Now outside this if condition, we type this code.
This will simply display a web form in the output, if the request method is GET. |
Press Ctrl + S | Save the file. |
[Terminal] | Switch back to the terminal. |
Press Ctrl+C | Stop the server by pressing Ctrl and C keys together. |
Type python3 -m flask run | Then run the server again. |
[Firefox]
|
Switch to the browser.
|
The page is displayed with a form. | |
Let us enter some values in the form. | |
Type First name as Spoken.
|
I will type the First name as Spoken.
|
[Firefox]
The text in the browser |
Here we have received the firstname and lastname from the request object.
|
[Text Editor] | The last thing I want to talk in this section is about “500: Internal Server Error”.
|
Let us write a code snippet to demonstrate this. | |
[Text Editor] | Switch back to the editor. |
Type inside user(name):
|
In the user view function, before the return statement type
a <equal to> 10 slash zero
|
[Terminal] | Switch to the terminal. |
Press Ctrl+C | Stop the server by pressing Ctrl and C keys together. |
Type python3 -m flask run | Now run the server again. |
[Firefox]
|
Switch to the browser.
|
[Firefox] | Observe that we have a ZeroDivisionError. |
Highlight star | Let’s switch to the terminal to see the HTTP status code. |
[Terminal]
|
Here we can see HTTP response code as 500.
|
Since we have the debug mode on, we know the specific reason for the error. | |
With this we come to the end of this tutorial.
Let us summarise. | |
Slide 10: Summary | In this tutorial, we learnt about,
|
Slide: About Spoken Tutorial project | The video at the following link summarises the Spoken Tutorial project.
|
Slide:
Spoken Tutorial workshops |
The Spoken Tutorial Project team conducts workshops and gives certificates.
|
Slide:
Forum for specific questions: |
Please post your timed queries in this forum. |
Slide: Acknowledgement | Spoken Tutorial Project is funded by NMEICT, MHRD, Government of India.
|
This is Siddhartha Sarkar signing off.
Thanks for watching. |