Flask Tutorial – Creating A Simple Micro Blogging Application

Flask TutorialCreating a Simple Micro Blogging Application. Do you want to develop an application using Python and Flask? Here you have the opportunity to learn through examples. In this flask tutorial for beginners, Coding compiler will create a simple microblogging application. It only supports one user who can create a plain text entry without pushing or commenting, but it still has everything you need to start. I will use Flask and SQLite from the Python framework as a database, so you don’t need anything else. Let’s start learning Python Flask.

Python Flask Tutorial – Creating a Simple Micro Blogging Application Using SQLite

Here in this flask tutorial, you will learn how to create a simple microblogging application using Python flask and SQLite.

Flask Tutorial – Creating a Simple Micro Blogging Application
Introducing Flaskr Step 4: Request a database connection
Initial Step: Create a folder Step 5: View Functions
Step 1: Database mode Step 6: Template
Step 2: Application setup code Step 7: Add Styles
Step 3: Create a Database Test Application

Creating a Simple Micro Blogging Application Using Flask

Introducing Flaskr

Here we will call our blog as flskr, or we can take a lesser name than web 2.0. Basically, we want it to do the following things:

  1. According to the authentication in the configuration file, the user is allowed to log in and log out. Only one user is supported.
  2. When users log in, they can add new entries consisting of a plain text title and the HTML body. Because we trust the user’s HTML here is safe.
  3. The page displays all entries in reverse order (new entries first), and users can add new entries here after logging in.

We will use SQLite 3 directly in this application because it is sufficient for applications of this size. Using SQLAlchemy for larger applications makes sense.

It handles database connections in a more intelligent way, allowing you to connect multiple unused relational databases at once. You can also consider popular NoSQL databases if your data is more suitable for them.

Here is a screenshot of the final application:

Screenshot of the final application

Initial Step: Creating folders

Before we start, let’s create the required folder for this application:

/flaskr
    /static
    /templates

The flaskr folder is not a Python package, it’s just where we put the files. In the next step we will directly put the database schema and main module in this folder. The use of the application user can access the files in the static folder via HTTP . This is where the css and javascript files are stored. Flask will look for the Jinja2 template in the templates folder. The template created later in this tutorial will be in this folder.

Step 1: Database Mode

First, we need to create a database schema. Only one table is sufficient for this application, and we only want to support SQLite, so it is very simple. Just put the following into a file called schema.sql , and place the file in the flasskr folder you just created :

drop table if exists entries;
create table entries (
  id integer primary key autoincrement,
  title string not null,
  text string not null
);

This pattern consists of a single table called entries, where each row contains an id, a title, and a text. Id is an auto-incremented integer and it is a primary key, and the remaining two are non-empty strings.

Flask Tutorial – Creating A Simple Micro Blogging Application

Step 2: Application of the setup code

Now that we have the database schema, we can create application modules. Let’s call it flaskr.py and place it in the flaskr folder. For beginners, we will add all the required imports as in the configuration chapter. For small applications, it is feasible to place the configuration directly in the main module, just as we do now. However, a cleaner solution is to create a .ini or .py file separately and then load or import the values.

In flaskr.py :

# all the imports 
import  sqlite3 
from  flask  import  Flask ,  request ,  session ,  g ,  redirect ,  url_for , \
      abort ,  render_template ,  flash

# configuration 
DATABASE  =  '/tmp/flaskr.db' 
DEBUG  =  True 
SECRET_KEY  =  'development key' 
USERNAME  =  'admin' 
PASSWORD  =  'default'

Next we can create a real application and then initialize with the configuration in the same file (in flaskr.py ):

# create our little application :) 
app  =  Flask ( __name__ ) 
app . config . from_object ( __name__ )

from_object()It will look for the given object (if it is a string, it will import it) and search for all uppercase variables defined inside. In our case, the configuration file is just a few lines of code that we wrote above. You can also store them separately into multiple files.

It is usually a good idea to load the configuration from a configuration file. This is from_envvar()done by replacing it with the abovefrom_object()

App . config . from_envvar ( 'FLASKR_SETTINGS' ,  silent = True )

This method we can set a name FLASKR_SETTINGSEnvironment variables to set whether a configuration file is overwritten after the default value is loaded. The silent switch tells Flask not to care if this environment variable key exists.

Secret_key is needed to keep the client’s session safe. Choosing the key wisely makes it difficult to guess and as complex as possible. The debug flag enables or disables interactive debugging. Never let debug mode start in the production system because it will allow users to execute code on the server!

We also added a method that easily connects to the specified database. This method is used to open a connection when requested, and it can also be used in interactive Python shells and scripts. This is very convenient for the future.

Def  connect_db (): 
    return  sqlite3 . connect ( app . config [ 'DATABASE' ])

Finally, if we want to run that file as a standalone application, we only need to add this line at the end of the server startup file:

If  __name__  ==  '__main__' : 
    app . run ()

So we can successfully start running this application, using the following command:

Python flaskr.py

You will see a message that informs you of the server’s starting address, which you can access.

When you access the server in the browser to get a 404 page cannot find the error, because we do not have any views. We will follow these later. First of all, we should let the database work.

Flask Tutorial – Creating A Simple Micro Blogging Application

Step 3: Create a database

As mentioned earlier, Flaskr is a database-driven application. To be precise, Flaskr is an application that uses a relational database system. Such systems need a pattern to tell them how to store information. Therefore, it is important to create the database schema before starting the server for the first time.

You can create this schema by pipelining the schema.sql as the input to the sqlite3 command. The command is as follows:

the sqlite3  / tmp / flaskr . DB  <  Schema . SQL

The disadvantage of this method is the need to install sqlite 3 commands, not every system has an installation. And you must provide the path to the database or you will get an error. Adding a function is a good idea for initializing the database.

If you want to do, first of all you must import the package from contextlib contextlib.closing()function. And add the following content in the flskr.py file:

From  contextlib  import  closing

Then we can create a function called init_db , which is used to initialize the database. For this we can use the previously defined connect_db function. Just add this function under the connect_db function:

Def  init_db (): 
    with  closing ( connect_db ())  as  db : 
        with  app . open_resource ( 'schema.sql' )  as  f : 
            db . cursor () . executescript ( f . read ()) 
        db . commit ()

closing()The helper function allows us to keep the database connection available with in the block. Application object open_resource()which also supports this function block outside thereof, and therefore can be with direct blocks. This function opens a file from the resource location (your flaskr folder) and allows you to read it. We use it here to execute a script on a database connection.

When we connect to the database we get a database connection object (named db here ) that provides us with a database pointer. There is a method on the pointer that can execute the full script. Finally, we do not explicitly submit the changes. SQLite 3 or other transactional databases will not do so.

You can now create the database in the Python shell, import and call the function just now:

>>> from  flaskr  import  init_db 
>>> init_db ()

Troubleshooting

If you later get an exception that the table cannot find, check that you have called the init_db function and that your table name is correct (for example: singular vs. plural).

Flask Tutorial – Creating A Simple Micro Blogging Application

Step 4: Requesting a database connection

Now that we know how to set up database connections and use these connections in scripts, how can we gracefully do this in requests? All our functions require database connections, so it’s worthwhile to initialize them before the request and automatically close them after the request ends.

Flask allows us to use before_request()after_request()andteardown_request()decorators to achieve this function:

@app.before_request 
def  before_request (): 
    g . db  =  connect_db ()

@app.teardown_request 
def  teardown_request ( exception ): 
    g . db . close ()

Use before_request()decorator function will be called before the request and no parameters. Use after_request()decorator function will be called after an incoming request and response will be sent to the client.

They must return that response object or a different response object. But when an exception is thrown, they will not necessarily be executed, then you can use teardown_request()decorator. Its decorated function will be executed after the response is constructed, and it is not allowed to modify the request. The returned value will be ignored. If an exception is thrown when the request has already been processed, it is passed to each function, otherwise a None is passed .

We currently stored in the database connection Flask provides ga special object. This object can only save the requested information once and is available in every function. Do not use other objects to save information because it will not be feasible in a multi-threaded environment. Special objects gin the background are some magical mechanism to ensure that it is doing the right thing.

Flask Tutorial – Creating A Simple Micro Blogging Application

Step 5: View function

Now that the database connection is working we can start writing view functions. We need four view functions:

Display

This view shows all the entries stored in the database. It listens for the application’s root address and will query the database for headers and content. The entry with the highest id value (the latest entry) will be at the front.

The rows returned from the cursor are tuples organized by the columns declared in the select statement. It’s enough for small applications like ours, but you may want to convert them to dictionaries. If you are interested in how to convert words into the dictionary.

The view function will pass the entry as a dictionary to the show_entries.html template and return the rendering result:

@app.route ( '/' ) 
def  show_entries (): 
    cur  =  g . db . execute ( 'select title, text from entries order by id desc' ) 
    entries  =  [ dict ( title = row [ 0 ],  text = row [ 1 ])  for  row  in  cur . fetchall ()] 
    return  render_template ( 'show_entries.html' ,  entries = entries)

Adding new entries

This view allows logged-in users to add new entries. It only responds to POST requests. The actual form is shown on the show_entries page. If some work, then we use flash()down a request to flash a message and jump back show_entries page:

@app.route ( '/add' ,  methods = [ 'POST' ]) 
def  add_entry (): 
    if  not  session . get ( 'logged_in' ): 
        abort ( 401 ) 
    g . db . execute ( 'insert into entries (title , text) values ​​(?, ?)' , 
                 [ request . form [ 'title' ],  request . form [ 'text' ]]) 
    g . db . commit() 
    flash ( 'New entry was successfully posted' ) 
    return  redirect ( url_for ( 'show_entries' ))

Note that we check user logins here (the logged_in key exists in the session and is True).

safety warning

Make sure to use the question mark to build the SQL statement as in the above example. Otherwise, your application is vulnerable to SQL injection when you use a formatted string to build an SQL statement.

Login and Logout

These functions are for user login and log out. Check the username and password when logging in based on the values in the configuration and set the logged_in key value in the session. If the user successfully logs in, the logged_in key is set to True and jumps back to the show_entries page. In addition, a message flashes to prompt the user to log in successfully. If an error occurs, the template notifies and prompts you to log in again:

@app.route ( '/login' ,  methods = [ 'GET' ,  'POST' ]) 
def  login (): 
    error  =  None 
    if  request . method  ==  'POST' : 
        if  request . form [ 'username' ]  ! =  app . config [ 'USERNAME' ]: 
            error  =  'Invalid username' 
        elif  request . form [ 'password' ]  !=  app. Config [ 'PASSWORD' ]: 
            error  =  'Invalid password' 
        the else : 
            the session [ 'the logged_in' ]  =  True 
            Flash ( 'were logged in by You' ) 
            return  the redirect ( the url_for ( 'show_entries' )) 
    return  the render_template ( ' the login.html ' ,  error = error )

On the other hand, the logout function removes the logged_in key from the session. Here we use a big trick: If you use a dictionary pop()method and passing in the second argument (the default), this method will remove the key from the dictionary, if the key does not exist, do nothing. This is useful because we don’t need to check if the user is logged in.

@app.route ( '/logout' ) 
def  logout (): 
    session . pop ( 'logged_in' ,  None ) 
    flash ( 'You were logged out' ) 
    return  redirect ( url_for ( 'show_entries' ))

Flask Tutorial – Creating A Simple Micro Blogging Application

Step 6: Template

Now we should start writing templates. If we now request URLs, we will get an exception where Flask cannot find the template. The template uses the Jinja2 language and the default auto-escape is turned on. This means that unless you use the Markuptag in the template or use |safea filter, otherwise it will ensure that special characters such as Jinja2 <or >escaped into an equivalent XML entity.

We also use template inheritance to make it possible to reuse layouts on all pages of the site.

Please put the following template into the templates folder:

layout.html

This template contains the HTML body structure, title, and a login link (or logout if the user is logged in). If there is a flash message it will also show the flash message. Blocks can be replaced by blocks of the same name ( ) in the sub-template.{% block body%}body

sessionThe dictionary is also available in the template, and you can use it to check if the user is logged in. Note that in Jinja you can access an object that does not exist/dictionary attributes or member, as the following code, even if the 'logged_in'key does not exist, you can still work:

<!doctype html>
<title>Flaskr</title>
<link rel=stylesheet type=text/css href="{{ url_for('static', filename='style.css') }}">
<div class=page>
  <h1>Flaskr</h1>
  <div class=metanav>
  {% if not session.logged_in %}
    <a href="{{ url_for('login') }}">log in</a>
  {% else %}
    <a href="{{ url_for('logout') }}">log out</a>
  {% endif %}
  </div>
  {% for message in get_flashed_messages() %}
    <div class=flash>{{ message }}</div>
  {% endfor %}
  {% block body %}{% endblock %}
</div>

show_entries.html

This template inherits the layout.html template above to display information. Note for traversing all we render_template() function incoming information. We also tell the form to submit add_entry function and use HTTP ‘s POST method:

{% extends "layout.html" %}
{% block body %}
  {% if session.logged_in %}
    <form action="{{ url_for('add_entry') }}" method=post class=add-entry>
      <dl>
        <dt>Title:
        <dd><input type=text size=30 name=title>
        <dt>Text:
        <dd><textarea name=text rows=5 cols=40></textarea>
        <dd><input type=submit value=Share>
      </dl>
    </form>
  {% endif %}
  <ul class=entries>
  {% for entry in entries %}
    <li><h2>{{ entry.title }}</h2>{{ entry.text|safe }}
  {% else %}
    <li><em>Unbelievable.  No entries here so far</em>
  {% endfor %}
  </ul>
{% endblock %}

login.html

The last is the login template, which basically shows only one form that allows the user to log in:

{% extends "layout.html" %}
{% block body %}
  <h2>Login</h2>
  {% if error %}<p class=error><strong>Error:</strong> {{ error }}{% endif %}
  <form action="{{ url_for('login') }}" method=post>
    <dl>
      <dt>Username:
      <dd><input  >usernamename =texttype = 
      <dt>Password:
      <dd><input type=password name=password>
      <dd><input type=submit value=Login>
    </dl>
  </form>
{% endblock %}

Flask Tutorial – Creating A Simple Micro Blogging Application

Step 7: Add Style

Now that everything else is working, it’s time to add some style to the application. Just create a new style sheet called style.css in the static folder we created earlier :

body            { font-family: sans-serif; background: #eee; }
a, h1, h2       { color: #377BA8; }
h1, h2          { font-family: 'Georgia', serif; margin: 0; }
h1              { border-bottom: 2px solid #eee; }
h2              { font-size: 1.2em; }

.page           { margin: 2em auto; width: 35em; border: 5px solid #ccc;
                  padding: 0.8em; background: white; }
.entries        { list-style: none; margin: 0; padding: 0; }
.entries li     { margin: 0.8em 1.2em; }
.entries li h2  { margin-left: -1em; }
.add-entry      { font-size: 0.9em; border-bottom: 1px solid #ccc; }
.add-entry dl   { font-weight: bold; }
.metanav        { text-align: right; font-size: 0.8em; padding: 0.3em;
                  margin-bottom: 1em; background: #fafafa; }
.flash          { background: #CEE5F5; padding: 0.5em;
                  border: 1px solid #AACBE2; }
.error          { background: #F0D6D6; padding: 0.5em; }

Benefits: Test Application

Now that you have completed the application and everything works as expected, adding automated tests to simplify future changes is not a bad idea.

Related Python Tutorials

Python Getting Started Guide Python Input and Output
Introduction to Python Python Errors and Exceptions
Python Interpreter Tutorial Python Classes and Objects
Learn Python In One Day Python Standard Library
Python For Machine Learning Python Standard Library Part – 2
Python Data Structures Python Interview Questions
Python Modules Python Programming Interview Questions

1 COMMENT

  1. I’m not sure the place you are getting your info,
    however good topic. I must spend some time finding
    out much more or working out more. Thank you for excellent info I used to be in search of
    this info for my mission.

LEAVE A REPLY

Please enter your comment!
Please enter your name here