But before that :-) just a quick note about the Flask application project structure.Each non-trivial computer application has a structure. For such application there exists a directory structure, with files stored in particular directories depending on their usage, type and other parameters. This way a project is easier to develop and maintain.
Well, Flask - as many other applications - takes a step further. They follow the 'convention over configuration' philosophy. For instance, in a Flask application static files go into a directory named static and templates go into a directory named templates. The reason for this is that you, the application writer, don't have to worry about naming your directories - so less work for you configuring your project. This also means less work for the next guy that eventually takes on maintaining that beautiful web app you have created. He alredy knows where everything is, just by looking at directory names. And, finally, this also means less work for flask.
The first thing to do is to navigate to your microblog directory that you have created in the first part of the tutorial:
[anon@test ~]$ cd Documents/microblog [anon@test microblog]$
And now, finally, directory creation time:
[anon@test ~]$ cd Documents/microblog [anon@test microblog]$ mkdir app [anon@test microblog]$ mkdir app/static [anon@test microblog]$ mkdir app/templates [anon@test microblog]$ mkdir tmp [anon@test microblog]$
Let's see what the contents of our microblog directory look like:
[anon@test microblog]$ ls app flask tmp [anon@test microblog]$
Apart from the directories just created there is also the flask directory created by the venv command. To show you the current project structure in a nice hierarchical fashion I've installed the tree command and ran it:
[anon@test microblog]$ tree > /home/anon/Documents/flask_app_structure [anon@test microblog]$
The greater than sign (>) means that I redirected tree output into a file named flask_app_structure in my Documents. Here is the flask_app_structure contents:
. ├── app │ ├── static │ └── templates ├── flask │ ├── bin │ │ ├── activate │ │ ├── activate.csh │ │ ├── activate.fish │ │ ├── coverage │ │ ├── coverage3 │ │ ├── coverage-3.6 │ │ ├── easy_install │ │ ├── easy_install-3.6 │ │ ├── flask │ │ ├── migrate │ │ ├── migrate-repository │ │ ├── pbr │ │ ├── pip │ │ ├── pip3 │ │ ├── pip3.6 │ │ ├── pybabel │ │ ├── python -> /usr/bin/python │ │ ├── python3 -> python │ │ └── sqlformat │ ├── include │ ├── lib │ │ └── python3.6 │ │ └── site-packages │ │ ├── babel ... ... ... │ ├── lib64 -> lib │ ├── pip-selfcheck.json │ └── pyvenv.cfg └── tmp 408 directories, 3827 files
So the microblog/flask directory really contains a whole Python environment, ready for you to play with.
Now, to write some code, finally.
In your microblog/app directory create a new empty Python file named __init__.py :
[anon@test microblog]$ > app/__init__.py [anon@test microblog]$
What is happening here is that we are redirecting nothing to a file that doesn't exist and a new empty file is created in the microblog/app directory.
Those lines before and after init.py are actually double underscores and they have a special meaning in Python. They are used to denote Python 'magic' objects and you, the user should never use double underscores for your variable, function or file names. A file named __init__.py has a special meaning and you can read about it in the Python documentation.
Just to confirm that __init__.py has been created:
[anon@test microblog]$ ls ./app __init__.py static templates [anon@test microblog]$When working in the terminal, the dot (.) refers to the current directory so with this command we are listing the contents of a directory named app that resides in our current directory - microblog. And, there it is - __init__.py has been created.
You can open the file in your favorite text editor to edit its contents. If you don't have a favorite programming editor, you can use what ever comes with your Linux distribution, like Gedit or Kate, or anything else really. The only two basic requirements are that the text you type in your editor is saved just the way you have typed it i.e. that your editor doesn't add any special characters to your files (in other words never use Libre Office Writer or MS Word as programming text editors). The other requirement is syntax highlighting, mening that different parts of your file have different colors. For instance, your keywords will be blue, comments green, variable names gray etc.
Before you open your file to edit you should make one last adjustment to your editor. In your editor menu find an entry named Preferences or Settings. When you open it there should be an option to set the tab key width. Set it to 4. Below it there should be a checkbox that, when checked, makes your editor replace tabs with spaces. In our case, each time you press the Tab key your editor will replace it with four spaces.
Python indents lines by four spaces. This is good form.
Now open the file and type in the Python code found in the original Flask tutorial:
from flask import Flask app = Flask(__name__) from app import views
and save the file. That's three lines of code, but there are still a few things that need explanation.
The first line: flask is a Python module you added to your Python installation earlier, using pip. What is Flask? If you look at the Flask documentation, you'll find out that Flask is the name of a class, and
Once it is created it will act as a central registry for the view functions, the URL rules, template configuration and much more.The first line of our script imports the name Flask thus making it available to the script. Note that this very important object, the Flask instance, has not been created yet, you just made it available to your script - imported it.
The second line of the script does just that - it creates a Python object that is an instance of the Flask class and assigns it to a variable named app. Look again at the Flask documentation - the only thing you have to pass to Flask when creating its instance is an argument named import_name, all other arguments are optional. This means that if they are ommited they will be given default values.
In our script we use __name__ as import_name. __name__ is one of Python's special variables, representing the name of the module (script). As always, you can learn more about __name__ and other Python special variables in the Python documentation.
Now the third line of the script. The tutorial says that:
I'm sure it'll sink in eventually so I'll just leave that one alone for now.
The script above simply creates the application object (of class Flask) and then imports the views module, which we haven't written yet. Do not confuse app the variable (which gets assigned the Flask instance) with app the package (from which we import the views module).
In Flask, responses to web requests are written as Python functions and are called views. Our views will always reside in the microblog/app/views.py file (remember the 'convention over configuration' motto). What a view looks like is (almost) up to you, the application author.
Let's create our views.py file:
[anon@test ~]$ cd Documents/microblog [anon@test microblog]$ > app/views.py [anon@test microblog]$
open it and type the view function code in:
from app import app @app.route('/') @app.route('index') def index(): return 'Hello, World!'
Remember the app variable that got assigned the Flask instance in your __init__.py? You are importing it right there in your first line. The package you are importing it from got its name from the directory name - microblog/app - hence the import app from app line. The variable name (app) is the same as the package name (app). You can learn more about Python modules and packages reading the documentaion.
Now on to the next two lines, beginning with the at sign (@). @ is a Python keyword that denotes a decorator,
... any callable Python object that is used to modify a function, method or class definition.If you look at the Flask class documentation again, you'll see that Flask.route(rule, **options)is
a decorator that is used to register a view function for a given URL rule.This means that the index() function that returns 'Hello, World' is executed every time a web browser requests your site root (/) or index (/index) page.
The last thing to do is to test your web application. In its root folder create a file named run.py:
[anon@test ~]$ cd Documents/microblog [anon@test microblog]$ > run.py [anon@test microblog]$
The code for run.py looks like this:
from app import app app.run(debug=True))
Again you are importing a Flask class instance. Its run(host=None, port=None, debug=None, **options) method starts the development web server that comes with Flask and you are ready to test your application. In your terminal type:
[anon@test microblog]$ python run.py
and you will be greeted with a message like this:
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger pin code: 178-776-905
The important part here is the line with the http://127.0.0.1:5000/ part. If you type this address in your browser you will see a humble 'Hello, World!' message delivered by your index() function to your browser. If you type http://127.0.0.1:5000/index you will get the same message.
That's not bad for a start, I guess.