Hello World! in Flask
Tags: flask, python, webdev, devincept
Published: 2021-06-26 02:48:53

<p><strong>Flask </strong>is a web application framework written in Python. <strong>Armin Ronacher</strong>, who leads an international group of Python enthusiasts named <strong>Pocco</strong>, developed it. Flask is based on <em>Werkzeug WSGI</em> toolkit and <em>Jinja2 </em>template engine. Both are Pocco projects.</p>

<h2>Installing Python</h2>

<p>If you don&#39;t have Python installed on your computer, go ahead and install it now. If your operating system does not provide you with a Python package, you can download an installer from the&nbsp;<a href="https://python.org/download/">Python official website</a>. If you are using Microsoft Windows along with WSL or Cygwin, note that you will not be using the Windows native version of Python, but a Unix-friendly version that you need to obtain from Ubuntu (if you are using WSL) or from Cygwin.</p>

<p>To make sure your Python installation is functional, you can open a terminal window and type&nbsp;<code>python3</code>, or if that does not work, just&nbsp;<code>python</code>. Here is what you should expect to see:</p>

<pre>
<code class="language-bash">$ python
Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  4 2021, 13:27:16) [MSC v.1928 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt;</code></pre>

<p>The Python interpreter is now waiting at an interactive prompt, where you can enter Python statements. In future chapters you will learn what kinds of things this interactive prompt is useful for. But for now, you have confirmed that Python is installed on your system. To exit the interactive prompt, you can type&nbsp;<code>exit()</code>&nbsp;and press Enter. On the Linux and Mac OS X versions of Python you can also exit the interpreter by pressing Ctrl-D. On Windows, the exit shortcut is Ctrl-Z followed by Enter.</p>

<h2>Installing Flask</h2>

<p>The next step is to install Flask, but before I go into that I want to tell you about the best practices associated with installing Python&nbsp;<em>packages</em>.</p>

<p>In Python, packages such as Flask are available in a public repository, from where anybody can download them and install them. The official Python package repository is called&nbsp;<a href="https://pypi.python.org/pypi">PyPI</a>, which stands for Python Package Index (some people also refer to this repository as the &quot;cheese shop&quot;). Installing a package from PyPI is very simple, because Python comes with a tool called&nbsp;<code>pip</code>&nbsp;that does this work (in Python 2.7&nbsp;<code>pip</code>&nbsp;does not come bundled with Python and needs to be installed separately).</p>

<p>To install a package on your machine, you use&nbsp;<code>pip</code>&nbsp;as follows:</p>

<pre>
<code class="language-bash">$ pip install &lt;package-name&gt;</code></pre>

<p>Interestingly, this method of installing packages will not work in most cases. If your Python interpreter was installed globally for all the users of your computer, chances are your regular user account is not going to have permission to make modifications to it, so the only way to make the command above work is to run it from an administrator account. But even without that complication, consider what happens when you install a package as above. The&nbsp;<code>pip</code>&nbsp;tool is going to download the package from PyPI, and then add it to your Python installation. From that point on, every Python script that you have on your system will have access to this package. Imagine a situation where you have completed a web application using version 0.11 of Flask, which was the most current version of Flask when you started, but now has been superseeded by version 0.12. You now want to start a second application, for which you&#39;d like to use the 0.12 version, but if you replace the 0.11 version that you have installed you risk breaking your older application. Do you see the problem? It would be ideal if it was possible to install Flask 0.11 to be used by your old application, and also install Flask 0.12 for your new one.</p>

<p>To address the issue of maintaining different versions of packages for different applications, Python uses the concept of&nbsp;<em>virtual environments</em>. A virtual environment is a complete copy of the Python interpreter. When you install packages in a virtual environment, the system-wide Python interpreter is not affected, only the copy is. So the solution to have complete freedom to install any versions of your packages for each application is to use a different virtual environment for each application. Virtual environments have the added benefit that they are owned by the user who creates them, so they do not require an administrator account.</p>

<p>Let&#39;s start by creating a directory where the project will live. I&#39;m going to call this directory&nbsp;<em>microblog</em>, since that is the name of the application:</p>

<pre>
<code class="language-bash">$ mkdir miniblog
$ cd miniblog</code></pre>

<p>If you are using a Python 3 version, virtual environment support is included in it, so all you need to do to create one is this:</p>

<pre>
<code class="language-bash">$ python3 -m venv venv</code></pre>

<p>With this command, I&#39;m asking Python to run the&nbsp;<code>venv</code>&nbsp;package, which creates a virtual environment named&nbsp;<code>venv</code>. The first&nbsp;<code>venv</code>&nbsp;in the command is the name of the Python virtual environment package, and the second is the virtual environment name that I&#39;m going to use for this particular environment. If you find this confusing, you can replace the second&nbsp;<code>venv</code>&nbsp;with a different name that you want to assign to your virtual environment. In general I create my virtual environments with the name&nbsp;<code>venv</code>&nbsp;in the project directory, so whenever I&nbsp;<code>cd</code>&nbsp;into a project I find its corresponding virtual environment.</p>

<p>Note that in some operating systems you may need to use&nbsp;<code>python</code>&nbsp;instead of&nbsp;<code>python3</code>&nbsp;in the command above. Some installations use&nbsp;<code>python</code>&nbsp;for Python 2.x releases and&nbsp;<code>python3</code>&nbsp;for the 3.x releases, while others map&nbsp;<code>python</code>&nbsp;to the 3.x releases.</p>

<p>After the command completes, you are going to have a directory named&nbsp;<em>venv</em>&nbsp;where the virtual environment files are stored.</p>

<p>If you are using any version of Python older than 3.4 (and that includes the 2.7 release), virtual environments are not supported natively. For those versions of Python, you need to download and install a third-party tool called&nbsp;<a href="https://virtualenv.pypa.io/">virtualenv</a>&nbsp;before you can create virtual environments. Once virtualenv is installed, you can create a virtual environment with the following command:</p>

<pre>
<code class="language-bash">$ virtualenv venv</code></pre>

<p>Regardless of the method you used to create it, you should have your virtual environment created. Now you have to tell the system that you want to use it, and you do that by&nbsp;<em>activating</em>&nbsp;it. To activate your brand new virtual environment you use the following command:</p>

<pre>
<code class="language-bash">$ source venv/bin/activate
(venv) $ _</code></pre>

<p>If you are using a Microsoft Windows command prompt window, the activation command is slightly different:</p>

<pre>
<code class="language-bash">$ venv\Scripts\activate
(venv) $ _</code></pre>

<p>When you activate a virtual environment, the configuration of your terminal session is modified so that the Python interpreter stored inside it is the one that is invoked when you type&nbsp;<code>python</code>. Also, the terminal prompt is modified to include the name of the activated virtual environment. The changes made to your terminal session are all temporary and private to that session, so they will not persist when you close the terminal window. If you work with multiple terminal windows open at the same time, it is perfectly fine to have different virtual environments activated on each one.</p>

<p>Now that you have a virtual environment created and activated, you can finally install Flask in it:</p>

<pre>
<code class="language-bash">(venv) $ pip install flask</code></pre>

<p>If you want to confirm that your virtual environment now has Flask installed, you can start the Python interpreter and&nbsp;<em>import</em>&nbsp;Flask into it:</p>

<pre>
<code class="language-bash">&gt;&gt;&gt; import flask
&gt;&gt;&gt; _</code></pre>

<p>If this statement does not give you any errors you can congratulate yourself, as Flask is installed and ready to be used.</p>

<h2><strong>A &quot;Hello, World&quot; Flask Application</strong></h2>

<p>If you go to the&nbsp;<a href="http://flask.pocoo.org/">Flask website</a>, you are welcomed with a very simple example application that has just five lines of code. Instead of repeating that trivial example, I&#39;m going to show you a slightly more elaborate one that will give you a good base structure for writing larger applications.</p>

<p>The application will exist in a&nbsp;<em>package</em>. In Python, a sub-directory that includes a&nbsp;<em>__init__.py</em>&nbsp;file is considered a package, and can be imported. When you import a package, the&nbsp;<em>__init__.py</em>&nbsp;executes and defines what symbols the package exposes to the outside world.</p>

<p>Let&#39;s create a package called&nbsp;<code>app</code>, that will host the application. Make sure you are in the&nbsp;<em>microblog</em>&nbsp;directory and then run the following command:</p>

<pre>
<code class="language-bash">(venv) $ mkdir app</code></pre>

<p>The&nbsp;<em>__init__.py</em>&nbsp;for the&nbsp;<code>app</code>&nbsp;package is going to contain the following code:</p>

<pre>
<code class="language-python">from flask import Flask

app = Flask(__name__)

from app import routes</code></pre>

<p>The script above simply creates the application object as an instance of class&nbsp;<code>Flask</code>&nbsp;imported from the flask package. The&nbsp;<code>__name__</code>&nbsp;variable passed to the&nbsp;<code>Flask</code>&nbsp;class is a Python predefined variable, which is set to the name of the module in which it is used. Flask uses the location of the module passed here as a starting point when it needs to load associated resources such as template files, which I will cover in&nbsp;<a href="https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-ii-templates">Chapter 2</a>. For all practical purposes, passing&nbsp;<code>__name__</code>&nbsp;is almost always going to configure Flask in the correct way. The application then imports the&nbsp;<code>routes</code>&nbsp;module, which doesn&#39;t exist yet.</p>

<p>One aspect that may seem confusing at first is that there are two entities named&nbsp;<code>app</code>. The&nbsp;<code>app</code>&nbsp;package is defined by the&nbsp;<em>app</em>&nbsp;directory and the&nbsp;<em>__init__.py</em>&nbsp;script, and is referenced in the&nbsp;<code>from app import routes</code>&nbsp;statement. The&nbsp;<code>app</code>&nbsp;variable is defined as an instance of class&nbsp;<code>Flask</code>&nbsp;in the&nbsp;<em>__init__.py</em>&nbsp;script, which makes it a member of the&nbsp;<code>app</code>&nbsp;package.</p>

<p>Another peculiarity is that the&nbsp;<code>routes</code>&nbsp;module is imported at the bottom and not at the top of the script as it is always done. The bottom import is a workaround to&nbsp;<em>circular imports</em>, a common problem with Flask applications. You are going to see that the&nbsp;<code>routes</code>&nbsp;module needs to import the&nbsp;<code>app</code>&nbsp;variable defined in this script, so putting one of the reciprocal imports at the bottom avoids the error that results from the mutual references between these two files.</p>

<p>So what goes in the&nbsp;<code>routes</code>&nbsp;module? The routes are the different URLs that the application implements. In Flask, handlers for the application routes are written as Python functions, called&nbsp;<em>view functions</em>. View functions are mapped to one or more route URLs so that Flask knows what logic to execute when a client requests a given URL.</p>

<p>Here is your first view function, which you need to write in the new module named&nbsp;<em>app/routes.py</em>:</p>

<pre>
<code class="language-python">from app import app

@app.route('/')
@app.route('/index')
def index():
    return "Hello, World!"</code></pre>

<p>This view function is actually pretty simple, it just returns a greeting as a string. The two strange&nbsp;<code>@app.route</code>&nbsp;lines above the function are&nbsp;<em>decorators</em>, a unique feature of the Python language. A decorator modifies the function that follows it. A common pattern with decorators is to use them to register functions as callbacks for certain events. In this case, the&nbsp;<code>@app.route</code>&nbsp;decorator creates an association between the URL given as an argument and the function. In this example there are two decorators, which associate the URLs&nbsp;<code>/</code>&nbsp;and&nbsp;<code>/index</code>&nbsp;to this function. This means that when a web browser requests either of these two URLs, Flask is going to invoke this function and pass the return value of it back to the browser as a response. If this does not make complete sense yet, it will in a little bit when you run this application.</p>

<p>To complete the application, you need to have a Python script at the top-level that defines the Flask application instance. Let&#39;s call this script&nbsp;<em>miniblog.py</em>, and define it as a single line that imports the application instance:</p>

<pre>
<code class="language-python">from app import app</code></pre>

<p>Remember the two&nbsp;<code>app</code>&nbsp;entities? Here you can see both together in the same sentence. The Flask application instance is called&nbsp;<code>app</code>&nbsp;and is a member of the&nbsp;<code>app</code>&nbsp;package. The&nbsp;<code>from app import app</code>&nbsp;statement imports the&nbsp;<code>app</code>&nbsp;variable that is a member of the&nbsp;<code>app</code>&nbsp;package. If you find this confusing, you can rename either the package or the variable to something else.</p>

<p>Just to make sure that you are doing everything correctly, below you can see a diagram of the project structure so far:</p>

<pre>
<code class="language-markdown">miniblog/
  venv/
  app/
    __init__.py
    routes.py
  miniblog.py</code></pre>

<p>&nbsp;</p>

<p>Believe it or not, this first version of the application is now complete! Before running it, though, Flask needs to be told how to import it, by setting the&nbsp;<code>FLASK_APP</code>&nbsp;environment variable:</p>

<pre>
<code class="language-bash">(venv) $ export FLASK_APP=miniblog.py</code></pre>

<p>If you are using Microsoft Windows, use&nbsp;<code>set</code>&nbsp;instead of&nbsp;<code>export</code>&nbsp;in the command above.</p>

<p>Are you ready to be blown away? You can run your first web application, with the following command:</p>

<pre>
<code class="language-bash">(venv) $ flask run
 * Serving Flask app "miniblog"
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)</code></pre>

<p>After the server initializes it will wait for client connections. The output from&nbsp;<code>flask run</code>&nbsp;indicates that the server is running on IP address 127.0.0.1, which is always the address of your own computer. This address is so common that is also has a simpler name that you may have seen before:&nbsp;<em>localhost</em>. Network servers listen for connections on a specific port number. Applications deployed on production web servers typically listen on port 443, or sometimes 80 if they do not implement encryption, but access to these ports require administration rights. Since this application is running in a development environment, Flask uses the freely available port 5000. Now open up your web browser and enter the following URL in the address field:</p>

<pre>
<code>    http://localhost:5000/</code></pre>

<p>Alternatively you can use this other URL:</p>

<pre>
<code>    http://localhost:5000/index</code></pre>

<p>Do you see the application route mappings in action? The first URL maps to&nbsp;<code>/</code>, while the second maps to&nbsp;<code>/index</code>. Both routes are associated with the only view function in the application, so they produce the same output, which is the string that the function returns. If you enter any other URL you will get an error, since only these two URLs are recognized by the application.</p>

<p><img alt="" src="https://res.cloudinary.com/dlomjljb6/image/upload/v1/media/blog/uploads/2021/04/22/ch01-hello-world_polifg" /></p>

<p>When you are done playing with the server you can just press Ctrl-C to stop it.</p>

<p>Congratulations, you have completed the first big step to become a web developer!</p>

<p>Before I end this chapter, I want to mention one more thing. Since environment variables aren&#39;t remembered across terminal sessions, you may find tedious to always have to set the&nbsp;<code>FLASK_APP</code>&nbsp;environment variable when you open a new terminal window. Starting with version 1.0, Flask allows you to register environment variables that you want to be automatically imported when you run the&nbsp;<code>flask</code>&nbsp;command. To use this option you have to install the&nbsp;<em>python-dotenv</em>&nbsp;package:</p>

<pre>
<code class="language-bash">(venv) $ pip install python-dotenv</code></pre>

<p>Then you can just write the environment variable name and value in a&nbsp;<em>.flaskenv</em>&nbsp;file in the top-level directory of the project:</p>

<p><em>.flaskenv</em>: Environment variables for flask command</p>

<pre>
<code class="language-bash">FLASK_APP=miniblog.py</code></pre>

<p>Doing this is optional. If you prefer to set the environment variable manually, that is perfectly fine, as long as you always remember to do it.</p>