Difference between revisions of "Python-Flask/C2/First-Flask-Web-App/English"
(Script synced with video.) |
Pravin1389 (Talk | contribs) |
||
Line 7: | Line 7: | ||
− | {| | + | {| border=1 |
− | |- | + | |- |
− | | | + | | | '''Visual Cue''' |
− | | | + | | | '''Narration''' |
− | |- | + | |- |
|| '''Slide 1: First Flask web app''' | || '''Slide 1: First Flask web app''' | ||
|| Welcome to the spoken tutorial on''' '''the first '''Flask web application.''' | || Welcome to the spoken tutorial on''' '''the first '''Flask web application.''' | ||
− | |- | + | |- |
|| '''Slide 2: Learning Objectives''' | || '''Slide 2: Learning Objectives''' | ||
|| In this tutorial, we will learn | || In this tutorial, we will learn | ||
− | * | + | * To write and analyze our first '''Flask application'''. |
− | * | + | * The concept of '''Routes '''and''' View''' '''functions'''. |
− | * | + | * About '''Dynamic content''' served by dynamic '''URLs'''. |
− | + | |- | |
− | |- | + | |
|| '''Slides 3: System Requirements''' | || '''Slides 3: System Requirements''' | ||
|| To record this tutorial, I’m using | || To record this tutorial, I’m using | ||
− | * | + | * '''Ubuntu Linux 16.04''' '''OS''' |
− | * | + | * '''Python''' '''3.5.2''' |
− | * | + | * '''Atom text editor 1.22.1 '''and''' ''' |
− | * | + | * '''Firefox web browser''' |
− | + | ||
You can use any text editor and web browser of your choice. | You can use any text editor and web browser of your choice. | ||
− | |- | + | |- |
|| '''Slide 5:''' | || '''Slide 5:''' | ||
'''Pre-requisites''' | '''Pre-requisites''' | ||
− | |||
− | |||
|| To follow this tutorial, you should have working knowledge on | || To follow this tutorial, you should have working knowledge on | ||
− | * | + | * '''Linux commands''' and |
− | + | ||
− | + | ||
+ | * Basic '''Python programming''' | ||
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 | ||
|- | |- | ||
− | | | + | || Open a Terminal window |
− | + | ||
− | + | ||
− | | | + | || Let us open the '''Terminal''' by pressing '''Ctrl''', '''Alt''' and '''T''' keys simultaneously on the keyboard. |
− | |- | + | |- |
|| [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.''' | ||
− | |- | + | |- |
|| [Terminal] | || [Terminal] | ||
− | |||
$ . flask_venv/bin/activate | $ . flask_venv/bin/activate | ||
− | |||
[Enter] | [Enter] | ||
|| Let us activate our '''virtualenv'''. | || Let us activate our '''virtualenv'''. | ||
− | |||
Type the command | Type the command | ||
− | |||
'''Dot space flask_venv slash bin slash activate''' | '''Dot space flask_venv slash bin slash activate''' | ||
− | |||
And press '''Enter'''. | And press '''Enter'''. | ||
− | |||
'''(dot)''' refers to the present working '''directory'''. | '''(dot)''' refers to the present working '''directory'''. | ||
− | |- | + | |- |
|| [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.''' | ||
− | |- | + | |- |
|| Only narration | || Only narration | ||
|| Open the file '''hello_flask.py '''in a '''text editor'''. | || Open the file '''hello_flask.py '''in a '''text editor'''. | ||
− | |||
I will be using the '''atom text editor '''but you can use your prefered '''text editor.''' | I will be using the '''atom text editor '''but you can use your prefered '''text editor.''' | ||
− | |- | + | |- |
|| [Terminal] | || [Terminal] | ||
− | |||
$ atom hello_flask.py | $ atom hello_flask.py | ||
− | || I will type the command. | + | || I will type the command. '''atom<space> hello underscore flask dot py''' |
− | + | ||
− | '''atom<space> hello underscore flask dot py''' | + | |
− | + | ||
and press '''Enter.''' | and press '''Enter.''' | ||
− | |||
− | |||
− | |||
Now let us understand what the code does, line by line. | Now let us understand what the code does, line by line. | ||
− | |- | + | |- |
|| [Text Editor] | || [Text Editor] | ||
Line 112: | Line 91: | ||
“from flask import Flask” | “from flask import Flask” | ||
|| The first line is '''from flask import Flask.''' | || The first line is '''from flask import Flask.''' | ||
− | |||
It simply says '''import''' '''Flask''' '''module''' from '''flask''' folder. | It simply says '''import''' '''Flask''' '''module''' from '''flask''' folder. | ||
− | |- | + | |- |
|| [Text Editor] | || [Text Editor] | ||
Point to the left pane of Atom. | Point to the left pane of Atom. | ||
− | |||
Collapse flask_venv->lib->python3.5->site-packages | Collapse flask_venv->lib->python3.5->site-packages | ||
And hover over flask foder. | And hover over flask foder. | ||
− | || Look at the '''directory structure | + | || Look at the '''directory structure |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
Observe that there is no '''flask''' folder in the '''project'''. | Observe that there is no '''flask''' folder in the '''project'''. | ||
− | |||
So how does the '''compiler''' find and import the '''Flask module'''? | So how does the '''compiler''' find and import the '''Flask module'''? | ||
− | |||
'''Python''' is set to look for '''modules''' in the '''site-packages'''. | '''Python''' is set to look for '''modules''' in the '''site-packages'''. | ||
− | |- | + | |- |
|| Highlight | || Highlight | ||
− | |||
app = Flask(__name__) | app = Flask(__name__) | ||
|| In the second line, we have created an '''object''' for the '''flask class.''' | || In the second line, we have created an '''object''' for the '''flask class.''' | ||
− | |||
This '''object''' of the '''Flask class''' is our '''WSGI application.''' | This '''object''' of the '''Flask class''' is our '''WSGI application.''' | ||
− | |||
'''WSGI''' stands for '''Web Server Gateway Interface.''' | '''WSGI''' stands for '''Web Server Gateway Interface.''' | ||
− | |||
We will come to what '''WSGI''' is later. | We will come to what '''WSGI''' is later. | ||
− | |||
This takes an '''argument double underscore name double underscore. ''' | This takes an '''argument double underscore name double underscore. ''' | ||
− | |||
This '''argument''' basically refers to the name of the file. | This '''argument''' basically refers to the name of the file. | ||
− | |||
In our case it is “'''hello_flask'''”. | In our case it is “'''hello_flask'''”. | ||
− | |||
'''Flask''' uses this '''argument''' to determine the '''root path''' of the '''application'''. | '''Flask''' uses this '''argument''' to determine the '''root path''' of the '''application'''. | ||
− | |- | + | |- |
|| [Text Editor] | || [Text Editor] | ||
− | |||
Highlight | Highlight | ||
Line 173: | Line 134: | ||
@app.route('/') | @app.route('/') | ||
|| In the next line, the''' route function''' of the '''Flask class''' is a '''decorator.''' | || In the next line, the''' route function''' of the '''Flask class''' is a '''decorator.''' | ||
− | |||
It tells the '''application''', which '''URL''' should call the associated '''function'''. | It tells the '''application''', which '''URL''' should call the associated '''function'''. | ||
− | |||
In this case, '''root slash''' is the '''URL'''. | In this case, '''root slash''' is the '''URL'''. | ||
− | |||
It refers to '''home''' or top '''domain'''. | It refers to '''home''' or top '''domain'''. | ||
− | |- | + | |- |
|| [Text Editor] | || [Text Editor] | ||
− | |||
Highlight | Highlight | ||
Line 190: | Line 147: | ||
@app.route('/') | @app.route('/') | ||
|| '''Decorators''' are a standard feature of the '''Python''' language. | || '''Decorators''' are a standard feature of the '''Python''' language. | ||
− | |||
They can modify the behavior of a '''function''' in different ways. | They can modify the behavior of a '''function''' in different ways. | ||
− | |||
In our case, it is used to associate a '''function''' with a '''URL'''. | In our case, it is used to associate a '''function''' with a '''URL'''. | ||
− | |||
To know more about '''decorators''' you may refer to the '''Python Spoken Tutorial series'''. | To know more about '''decorators''' you may refer to the '''Python Spoken Tutorial series'''. | ||
− | |- | + | |- |
|| '''Slide 5: Routes (img 1)''' | || '''Slide 5: Routes (img 1)''' | ||
|| Let us understand the concept of '''routes''' in detail now. | || Let us understand the concept of '''routes''' in detail now. | ||
− | |||
Look at this diagram. | Look at this diagram. | ||
− | |||
This shows a simplified '''client''' and '''server''' diagram. | This shows a simplified '''client''' and '''server''' diagram. | ||
− | |- | + | |- |
|| '''Slide 6: Routes (img 2)''' | || '''Slide 6: Routes (img 2)''' | ||
− | |||
− | |||
|| The client sends a '''request''' to the '''web server'''. | || The client sends a '''request''' to the '''web server'''. | ||
− | |||
In our case, the '''web browser''' is the '''client'''. | In our case, the '''web browser''' is the '''client'''. | ||
− | |- | + | |- |
|| '''Slide 7: Routes (img 3)''' | || '''Slide 7: Routes (img 3)''' | ||
|| Then the '''web server''' has to process the '''request''' and generate a '''response'''. | || Then the '''web server''' has to process the '''request''' and generate a '''response'''. | ||
− | |||
And the '''Flask application '''instance does this job. | And the '''Flask application '''instance does this job. | ||
− | |||
The '''web server''' sends the '''request''' to the '''Flask application''' instance. | The '''web server''' sends the '''request''' to the '''Flask application''' instance. | ||
− | |- | + | |- |
|| '''Slide 8: Routes (img 4)''' | || '''Slide 8: Routes (img 4)''' | ||
|| On receiving the '''request''' the '''app''' matches it with the available '''route patterns'''. | || On receiving the '''request''' the '''app''' matches it with the available '''route patterns'''. | ||
− | + | |- | |
− | + | ||
− | |- | + | |
|| '''Slide 9: Routes ''' | || '''Slide 9: Routes ''' | ||
|| | || | ||
− | * | + | * Thus the '''application''' instance knows which '''function''' to execute for which '''URL'''. |
− | * | + | * This happens because it keeps a mapping of the '''URLs''' to '''functions'''. |
− | * | + | * Here we need the concept of '''routes'''. |
− | + | ||
− | |- | + | |- |
|| '''Slide 9: Routes ''' | || '''Slide 9: Routes ''' | ||
|| | || | ||
− | * | + | * The association between a '''URL''' and the '''function''' that handles it, is called a '''route'''. |
− | * | + | * The '''Flask app''' executes the associated '''function''' and returns a '''response'''. |
− | + | |- | |
− | |- | + | |
|| '''Slide 9: Routes ''' | || '''Slide 9: Routes ''' | ||
|| | || | ||
− | * | + | * '''Routes''' can be either '''static''' or '''dynamic'''. |
− | * | + | * In the present case, we have a static '''route'''. |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
We will discuss '''dynamic routes''' in a moment. | We will discuss '''dynamic routes''' in a moment. | ||
− | |- | + | |- |
|| [Text Editor] | || [Text Editor] | ||
− | |||
Highlight | Highlight | ||
Line 266: | Line 204: | ||
def hello_world(): | def hello_world(): | ||
|| Let’s come back to our '''“hello world” app.''' | || Let’s come back to our '''“hello world” app.''' | ||
− | |||
In the next line, we define the associated '''function''' for this '''route'''. | In the next line, we define the associated '''function''' for this '''route'''. | ||
− | |||
This '''function''' gets executed when the '''root URL''' is hit. | This '''function''' gets executed when the '''root URL''' is hit. | ||
− | + | In our case the '''root''' '''URL''' is http://127.0.0.1:5000/ | |
− | In our case the '''root''' '''URL''' is | + | |
− | + | ||
Here, we have named the '''function''' as “'''hello_world'''”. | Here, we have named the '''function''' as “'''hello_world'''”. | ||
− | |||
However, you may choose any other name of your choice. | However, you may choose any other name of your choice. | ||
− | |||
This '''function''' associated with a '''route '''is called ‘'''view function'''’. | This '''function''' associated with a '''route '''is called ‘'''view function'''’. | ||
− | |- | + | |- |
|| [Text Editor] | || [Text Editor] | ||
− | |||
Highlight | Highlight | ||
Line 292: | Line 223: | ||
return 'Hello, World!' | return 'Hello, World!' | ||
|| The next line says '''return 'Hello, World!'''' | || The next line says '''return 'Hello, World!'''' | ||
− | |||
So this '''view function''' simply returns a '''string “Hello World”. ''' | So this '''view function''' simply returns a '''string “Hello World”. ''' | ||
− | |- | + | |- |
|| [Text Editor] | || [Text Editor] | ||
− | |||
Type | Type | ||
− | |||
if __name__ == '__main__':(Tab) app.run() | if __name__ == '__main__':(Tab) app.run() | ||
|| Now let us add a few more lines of code at the end. | || Now let us add a few more lines of code at the end. | ||
− | |||
Line 8 and 9. | Line 8 and 9. | ||
− | |- | + | |- |
|| [Text Editor] | || [Text Editor] | ||
− | |||
Highlight | Highlight | ||
− | |||
if __name__ == '__main__':(Tab) app.run() | if __name__ == '__main__':(Tab) app.run() | ||
|| This is a customary common practice. | || This is a customary common practice. | ||
− | |||
This ensures that '''server '''is launched only if the '''script''' runs directly from the '''terminal'''. | This ensures that '''server '''is launched only if the '''script''' runs directly from the '''terminal'''. | ||
− | |||
Otherwise '''app dot run''' is skipped. | Otherwise '''app dot run''' is skipped. | ||
− | |||
It may happen that a '''script''' is being called from another '''script'''. | It may happen that a '''script''' is being called from another '''script'''. | ||
− | |||
In that case the imported '''script''' should not start a new '''server'''. | In that case the imported '''script''' should not start a new '''server'''. | ||
− | |||
Hence we follow this practice. | Hence we follow this practice. | ||
− | |- | + | |- |
|| '''Ctrl+S''' | || '''Ctrl+S''' | ||
|| Let us save the file by pressing '''Ctrl''' and '''S''' keys. | || Let us save the file by pressing '''Ctrl''' and '''S''' keys. | ||
− | |- | + | |- |
|| [Terminal] | || [Terminal] | ||
Type | Type | ||
− | |||
$ export FLASK_APP=hello_flask.py | $ export FLASK_APP=hello_flask.py | ||
|| Now back in the '''terminal''' and run the''' hello world app.''' | || Now back in the '''terminal''' and run the''' hello world app.''' | ||
− | |||
Type '''export <space> FLASK_APP <equal to > hello underscore flask dot py''' | Type '''export <space> FLASK_APP <equal to > hello underscore flask dot py''' | ||
− | |||
Press '''Enter'''. | Press '''Enter'''. | ||
− | |- | + | |- |
|| [Terminal] | || [Terminal] | ||
− | Type | + | Type $ python3 -m flask run |
− | + | ||
− | + | ||
− | $ python3 -m flask run | + | |
|| Now type | || Now type | ||
− | |||
'''python3 <space> hyphen m <space> flask <space> run''' | '''python3 <space> hyphen m <space> flask <space> run''' | ||
− | |||
And press '''Enter'''. | And press '''Enter'''. | ||
− | + | We can see a message '''“Running on http://127.0.0.1:5000/”''' | |
− | We can see a message '''“Running on | + | |
− | + | ||
Here, '''127.0.0.1''' is the '''IP''' '''address''' for the '''localhost'''. | Here, '''127.0.0.1''' is the '''IP''' '''address''' for the '''localhost'''. | ||
− | |||
'''Flask app''' is running in the '''local host''' on '''port 5000.''' | '''Flask app''' is running in the '''local host''' on '''port 5000.''' | ||
− | |- | + | |- |
|| [Firefox] | || [Firefox] | ||
− | + | Type http://127.0.0.1:5000/ | |
− | Type | + | |
− | + | ||
− | + | ||
And press Enter. | And press Enter. | ||
|| Now, open any '''web browser. ''' | || Now, open any '''web browser. ''' | ||
− | + | In the '''address bar''', type http://127.0.0.1:5000/ and press '''Enter'''. | |
− | In the '''address bar''', type | + | |- |
− | |- | + | |
|| [Firefox] | || [Firefox] | ||
Highlight ‘Hello, World!’ | Highlight ‘Hello, World!’ | ||
|| We can see the message ‘'''Hello, World!'''’ written in the browser window. | || We can see the message ‘'''Hello, World!'''’ written in the browser window. | ||
− | |- | + | |- |
|| | || | ||
|| Switch back to the '''terminal'''. | || Switch back to the '''terminal'''. | ||
− | |||
Stop the '''server''' by pressing '''Ctrl''' and '''C '''keys together. | Stop the '''server''' by pressing '''Ctrl''' and '''C '''keys together. | ||
− | |- | + | |- |
|| [Terminal] | || [Terminal] | ||
− | |||
atom hello_flask.py | atom hello_flask.py | ||
|| Now we will write code for a '''dynamic''' '''route''' and also define a '''view function''' called '''hello_user'''. | || Now we will write code for a '''dynamic''' '''route''' and also define a '''view function''' called '''hello_user'''. | ||
− | |||
Switch to '''the editor window.''' | Switch to '''the editor window.''' | ||
− | |- | + | |- |
|| Type | || Type | ||
− | |||
@app.route('/user/<username>') | @app.route('/user/<username>') | ||
Line 414: | Line 315: | ||
<nowiki>(Tab) return '<h1>Hello, %s!</h1>' % username </nowiki> | <nowiki>(Tab) return '<h1>Hello, %s!</h1>' % username </nowiki> | ||
|| Before the''' if condition''', type the code as shown here. | || Before the''' if condition''', type the code as shown here. | ||
− | + | |- | |
− | + | ||
− | + | ||
− | |- | + | |
|| Highlight | || Highlight | ||
− | |||
@app.route('/user/<username>') | @app.route('/user/<username>') | ||
− | |||
− | |||
|| This '''route''' has a '''URL''', '''home/user/<username>''' | || This '''route''' has a '''URL''', '''home/user/<username>''' | ||
− | |||
where '''home''' is the '''root''' '''domain''' '''URL''' of the '''server'''. | where '''home''' is the '''root''' '''domain''' '''URL''' of the '''server'''. | ||
− | |||
whereas, '''username''' is a '''variable'''. | whereas, '''username''' is a '''variable'''. | ||
− | |||
We will use this '''variable '''in the '''view''' '''function''' to change the content in the browser. | We will use this '''variable '''in the '''view''' '''function''' to change the content in the browser. | ||
− | |- | + | |- |
|| Highlight | || Highlight | ||
Line 443: | Line 335: | ||
<nowiki>(Tab) return '<h1>Hello, %s!</h1>' % username </nowiki> | <nowiki>(Tab) return '<h1>Hello, %s!</h1>' % username </nowiki> | ||
|| This '''function '''will simply return a string '''‘Hello’''' '''username'''. | || This '''function '''will simply return a string '''‘Hello’''' '''username'''. | ||
− | |||
Note that the output in the '''browser '''will vary as per the '''username''' in the '''URL'''. | Note that the output in the '''browser '''will vary as per the '''username''' in the '''URL'''. | ||
− | |||
'''h1''' is the level one '''heading tag '''of '''HTML'''. | '''h1''' is the level one '''heading tag '''of '''HTML'''. | ||
− | |- | + | |- |
|| | || | ||
|| Let us save the file by pressing '''Ctrl''' and '''S''' keys | || Let us save the file by pressing '''Ctrl''' and '''S''' keys | ||
− | |||
Switch back to the terminal. | Switch back to the terminal. | ||
− | |- | + | |- |
|| [Terminal] | || [Terminal] | ||
Line 461: | Line 350: | ||
|| Run the '''app''' by executing the following command. | || Run the '''app''' by executing the following command. | ||
− | + | |- | |
− | + | ||
− | |- | + | |
|| [Firefox] | || [Firefox] | ||
− | + | Type http://127.0.0.1:5000/user/Sid | |
− | Type | + | |
− | + | ||
− | + | ||
[Enter] | [Enter] | ||
|| Switch to the '''web browser'''. | || Switch to the '''web browser'''. | ||
− | + | In the''' address bar''', type http://127.0.0.1:5000/user/Sid | |
− | In the''' address bar''', type | + | |
− | + | ||
and press '''Enter'''. | and press '''Enter'''. | ||
− | |- | + | |- |
|| [Firefox] | || [Firefox] | ||
− | + | Type http://127.0.0.1:5000/user/Tom | |
− | Type | + | |
− | + | ||
− | + | ||
[Enter] | [Enter] | ||
|| We got the output as '''“Hello Sid!”.''' | || We got the output as '''“Hello Sid!”.''' | ||
− | |||
Now let’s try '''Tom''' instead of '''Sid''' | Now let’s try '''Tom''' instead of '''Sid''' | ||
In the '''address bar''', replace '''Sid''' with '''Tom.''' | In the '''address bar''', replace '''Sid''' with '''Tom.''' | ||
− | |||
Press '''Enter'''. | Press '''Enter'''. | ||
− | |||
The output has changed to '''‘Hello Tom!’ ''' | The output has changed to '''‘Hello Tom!’ ''' | ||
− | |||
We have a dynamic '''URL''' in play here. | We have a dynamic '''URL''' in play here. | ||
− | |- | + | |- |
|| Slide 10: Example URL | || Slide 10: Example URL | ||
|| This is what you may have observed in '''facebook''' as well. | || This is what you may have observed in '''facebook''' as well. | ||
− | |||
'''Facebook''' individual '''users''' have a '''URL''' of the type: | '''Facebook''' individual '''users''' have a '''URL''' of the type: | ||
− | + | www.facebook.com/profile_id | |
− | + | ||
Here '''profile_id''' refers to the unique '''ID''' of a '''facebook user.''' | Here '''profile_id''' refers to the unique '''ID''' of a '''facebook user.''' | ||
+ | Depending on the unique '''ID, facebook server''' fetches the individual '''profile pages'''. | ||
− | + | Switch to the '''browser window'''. | |
− | |- | + | |- |
|| [Firefox] | || [Firefox] | ||
− | + | Type http://127.0.0.1:5000/posts | |
− | Type | + | |
− | + | ||
− | + | ||
[Enter] | [Enter] | ||
− | || | + | || Switch to the '''browser '''window. |
− | + | ||
− | + | ||
− | Switch to the '''browser '''window. | + | |
+ | Let’s try a '''URL''' for which we did not define a '''route'''. | ||
Replace '''/user/tom''' with '''posts '''and press '''Enter.''' | Replace '''/user/tom''' with '''posts '''and press '''Enter.''' | ||
− | |||
Observe that we got '''Not found''' message. | Observe that we got '''Not found''' message. | ||
− | |- | + | |- |
|| [Terminal] | || [Terminal] | ||
− | |||
Highlight 404. | Highlight 404. | ||
− | |||
Highlight 200’s. | Highlight 200’s. | ||
|| Switch to the '''terminal'''. | || Switch to the '''terminal'''. | ||
− | |||
Observe that, the '''server''' has returned a '''404 response code.''' | Observe that, the '''server''' has returned a '''404 response code.''' | ||
− | |||
This '''error code''' indicates that the web page requested for, does not exist. | This '''error code''' indicates that the web page requested for, does not exist. | ||
− | |||
Whereas most previous '''response codes''' were '''200'''. | Whereas most previous '''response codes''' were '''200'''. | ||
− | |||
We will discuss in detail these '''HTTP responses''' in the upcoming tutorials. | We will discuss in detail these '''HTTP responses''' in the upcoming tutorials. | ||
|- | |- | ||
− | | | + | || Press Ctrl+c simultaneously |
− | | | + | || To stop the '''server''', press '''Ctrl''' and '''C''' keys simultaneously. |
|- | |- | ||
− | | | + | || [Terminal] |
− | + | ||
Type deactivate and press Enter | Type deactivate and press Enter | ||
− | | | + | || We will deactivate the '''Virtual Environment.''' |
− | + | ||
Type '''deactivate''' and press '''Enter'''. | Type '''deactivate''' and press '''Enter'''. | ||
|- | |- | ||
− | | | + | || |
− | | | + | || This brings us to the end of this tutorial. |
− | + | ||
Let us summarise | Let us summarise | ||
− | |- | + | |- |
|| Slide 10: Summary | || Slide 10: Summary | ||
|| In this tutorial, we learnt about | || In this tutorial, we learnt about | ||
− | + | * The working of our first '''Flask application.''' | |
− | * | + | * The concepts of '''routes '''and the view '''functions.''' |
− | * | + | * Running a '''Flask app '''in a '''Web''' '''browser'''. |
− | * | + | * '''Dynamic content''' served by dynamic '''URLs'''. |
− | * | + | |
− | + | ||
|- | |- | ||
− | | | + | || Slide: About Spoken Tutorial project |
− | | | + | || The video at the following link summarises the Spoken Tutorial project. |
− | + | ||
Please download and watch it. | Please download and watch it. | ||
|- | |- | ||
− | | | + | || Slide: |
Spoken Tutorial workshops | Spoken Tutorial workshops | ||
− | | | + | || The ''Spoken Tutorial Project''' team conducts workshops and gives certificates. |
− | + | ||
For more details, please write to us. | For more details, please write to us. | ||
− | |- | + | |- |
|| Slide 13: | || Slide 13: | ||
Line 606: | Line 461: | ||
|| Please post your timed queries in this forum. | || Please post your timed queries in this forum. | ||
|- | |- | ||
− | | | + | || Slide: Acknowledgement |
− | | | + | || 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. | ||
− | |- | + | |- |
|| | || | ||
|| This is Siddhartha Sarkar signing off. | || This is Siddhartha Sarkar signing off. |
Revision as of 14:50, 28 January 2019
Title of script: First Flask web application
Author: Siddhartha Sarkar
Keywords: Video tutorial, Python Flask, Hello World, Routes, View Functions, HTTP protocol.
Visual Cue | Narration |
Slide 1: First Flask web app | Welcome to the spoken tutorial on the first Flask web application. |
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 on
If not, then please go through the corresponding tutorials on this website. http://spoken-tutorial.org |
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]
$ . flask_venv/bin/activate [Enter] |
Let us activate our virtualenv.
Type the command Dot space flask_venv slash bin slash activate And press Enter. (dot) refers to the present working directory. |
[Terminal]
Highlight (flask_venv) |
Notice that we are now inside the virtual environment flask_venv. |
Only narration | Open the file hello_flask.py in a text editor.
I will be using the atom text editor but you can use your prefered text editor. |
[Terminal]
$ atom hello_flask.py |
I will type the command. atom<space> hello underscore flask dot py
and press Enter. Now let us understand what the code does, line by line. |
[Text Editor]
Highlight “from flask import Flask” |
The first line is from flask import Flask.
It simply says import Flask module from flask folder. |
[Text Editor]
Point to the left pane of Atom. Collapse flask_venv->lib->python3.5->site-packages And hover over flask foder. |
Look at the directory structure
Observe that there is no flask folder in the project. So how does the compiler find and import the Flask module? Python is set to look for modules in the site-packages. |
Highlight
app = Flask(__name__) |
In the second line, we have created an object for the flask class.
This object of the Flask class is our WSGI application. WSGI stands for Web Server Gateway Interface. We will come to what WSGI is later. This takes an argument double underscore name double underscore. This argument basically refers to the name of the file. In our case it is “hello_flask”. Flask uses this argument to determine the root path of the application. |
[Text Editor]
Highlight @app.route('/') |
In the next line, the route function of the Flask class is a decorator.
It tells the application, which URL should call the associated function. In this case, root slash is the URL. It refers to home or top domain. |
[Text Editor]
Highlight @app.route('/') |
Decorators are a standard feature of the Python language.
They can modify the behavior of a function in different ways. In our case, it is used to associate a function with a URL. To know more about decorators you may refer to the Python Spoken Tutorial series. |
Slide 5: Routes (img 1) | Let us understand the concept of routes in detail now.
Look at this diagram. This shows a simplified client and server diagram. |
Slide 6: Routes (img 2) | The client sends a request to the web server.
In our case, the web browser is the client. |
Slide 7: Routes (img 3) | Then the web server has to process the request and generate a response.
And the Flask application instance does this job. The web server sends the request to the Flask application instance. |
Slide 8: Routes (img 4) | On receiving the request the app matches it with the available route patterns. |
Slide 9: Routes |
|
Slide 9: Routes |
|
Slide 9: Routes |
We will discuss dynamic routes in a moment. |
[Text Editor]
Highlight def hello_world(): |
Let’s come back to our “hello world” app.
In the next line, we define the associated function for this route. This function gets executed when the root URL is hit. In our case the root URL is http://127.0.0.1:5000/ Here, we have named the function as “hello_world”. However, you may choose any other name of your choice. This function associated with a route is called ‘view function’. |
[Text Editor]
Highlight return 'Hello, World!' |
The next line says return 'Hello, World!'
So this view function simply returns a string “Hello World”. |
[Text Editor]
Type if __name__ == '__main__':(Tab) app.run() |
Now let us add a few more lines of code at the end.
Line 8 and 9. |
[Text Editor]
Highlight if __name__ == '__main__':(Tab) app.run() |
This is a customary common practice.
This ensures that server is launched only if the script runs directly from the terminal. Otherwise app dot run is skipped. It may happen that a script is being called from another script. In that case the imported script should not start a new server. Hence we follow this practice. |
Ctrl+S | Let us save the file by pressing Ctrl and S keys. |
[Terminal]
Type $ export FLASK_APP=hello_flask.py |
Now back in the terminal and run the hello world app.
Type export <space> FLASK_APP <equal to > hello underscore flask dot py Press Enter. |
[Terminal]
Type $ python3 -m flask run |
Now type
python3 <space> hyphen m <space> flask <space> run And press Enter. We can see a message “Running on http://127.0.0.1:5000/” Here, 127.0.0.1 is the IP address for the localhost. Flask app is running in the local host on port 5000. |
[Firefox]
And press Enter. |
Now, open any web browser.
In the address bar, type http://127.0.0.1:5000/ and press Enter. |
[Firefox]
Highlight ‘Hello, World!’ |
We can see the message ‘Hello, World!’ written in the browser window. |
Switch back to the terminal.
Stop the server by pressing Ctrl and C keys together. | |
[Terminal]
atom hello_flask.py |
Now we will write code for a dynamic route and also define a view function called hello_user.
Switch to the editor window. |
Type
@app.route('/user/<username>') def hello_user(username): (Tab) return '<h1>Hello, %s!</h1>' % username |
Before the if condition, type the code as shown here. |
Highlight
@app.route('/user/<username>') |
This route has a URL, home/user/<username>
where home is the root domain URL of the server. whereas, username is a variable. We will use this variable in the view function to change the content in the browser. |
Highlight
(Tab) return '<h1>Hello, %s!</h1>' % username |
This function will simply return a string ‘Hello’ username.
Note that the output in the browser will vary as per the username in the URL. h1 is the level one heading tag of HTML. |
Let us save the file by pressing Ctrl and S keys
Switch back to the terminal. | |
[Terminal]
$ python3 -m flask run [Enter] |
Run the app by executing the following command. |
[Firefox]
Type http://127.0.0.1:5000/user/Sid [Enter] |
Switch to the web browser.
In the address bar, type http://127.0.0.1:5000/user/Sid and press Enter. |
[Firefox]
Type http://127.0.0.1:5000/user/Tom [Enter] |
We got the output as “Hello Sid!”.
Now let’s try Tom instead of Sid In the address bar, replace Sid with Tom. Press Enter. The output has changed to ‘Hello Tom!’ We have a dynamic URL in play here. |
Slide 10: Example URL | This is what you may have observed in facebook as well.
Facebook individual users have a URL of the type: www.facebook.com/profile_id Here profile_id refers to the unique ID of a facebook user. Depending on the unique ID, facebook server fetches the individual profile pages. Switch to the browser window. |
[Firefox]
Type http://127.0.0.1:5000/posts [Enter] |
Switch to the browser window.
Let’s try a URL for which we did not define a route. Replace /user/tom with posts and press Enter. Observe that we got Not found message. |
[Terminal]
Highlight 404. Highlight 200’s. |
Switch to the terminal.
Observe that, the server has returned a 404 response code. This error code indicates that the web page requested for, does not exist. Whereas most previous response codes were 200. We will discuss in detail these HTTP responses in the upcoming tutorials. |
Press Ctrl+c simultaneously | To stop the server, press Ctrl and C keys simultaneously. |
[Terminal]
Type deactivate and press Enter |
We will deactivate the Virtual Environment.
Type deactivate and press Enter. |
This brings us 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.
Please download and watch it. |
Slide:
Spoken Tutorial workshops |
The Spoken Tutorial Project' team conducts workshops and gives certificates.
For more details, please write to us. |
Slide 13:
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.
More information on this mission is available at this link. |
This is Siddhartha Sarkar signing off.
|