<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rittik Dasgupta</title>
    <description>The latest articles on DEV Community by Rittik Dasgupta (@hrk2023).</description>
    <link>https://dev.to/hrk2023</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F505105%2Fd79d8762-8cef-4acf-8f58-f2e2211cc57c.jpeg</url>
      <title>DEV Community: Rittik Dasgupta</title>
      <link>https://dev.to/hrk2023</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hrk2023"/>
    <language>en</language>
    <item>
      <title>Writing a Flask App the !Noob Way</title>
      <dc:creator>Rittik Dasgupta</dc:creator>
      <pubDate>Wed, 15 Sep 2021 21:33:09 +0000</pubDate>
      <link>https://dev.to/hrk2023/writing-a-flask-app-the-noob-way-cfk</link>
      <guid>https://dev.to/hrk2023/writing-a-flask-app-the-noob-way-cfk</guid>
      <description>&lt;p&gt;This tutorial is not meant for beginners. It is assumed that the reader is familiar with the flask framework.&lt;/p&gt;

&lt;p&gt;In this tutorial we will be writing a flask application using &lt;code&gt;Flask Blueprints&lt;/code&gt; and &lt;code&gt;Application Factory Pattern&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are blueprints?
&lt;/h3&gt;

&lt;p&gt;If you're working on a small project, keeping all of your code in one module isn't a bad idea. However, for large projects, it is usual practise to divide your project into numerous packages using Flask Blueprints.&lt;/p&gt;

&lt;p&gt;A blueprint is a file that contains a single piece of functionality in your application. Consider a flask application built with blueprints as a collection of critical bits of functionality that work together to produce a complete web application.&lt;/p&gt;

&lt;p&gt;It's a good idea to think about what blueprints you can break your application into before you start writing. I usually use three blueprints, &lt;code&gt;api&lt;/code&gt;, &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;admin&lt;/code&gt;, in my personal approach. The &lt;code&gt;api&lt;/code&gt; blueprint is added to handle programmatic access to the web application resources. The user-related functionality is handled by the &lt;code&gt;user&lt;/code&gt; blueprint, including registration, logout, login, password reset etc. The admin blueprint is in charge of the admin panel functionality and features.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;|-app.py
|-.gitignore
|-README.md
|-requirements.txt
|-logs/
|-app_name/
    |-__init__.py
    |-.env
    |-models/
    |-utils/
    |-forms/
    |-config/
        |-config.py
        |-database.py
    |-static/
    |-templates/
        |-layout.html
        |-400.html
        |-403.html
        |-404.html
        |-405.html
        |-500.html
    |-routes/
        |-__init__.py
        |-api.py
        |-user.py
        |-admin.py
        |-templates
            |-user/
                |-register.html
            |-admin/
                |-panel.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following table gives an overview of what each file and folder does&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;File or Folder&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;app.py&lt;/td&gt;
&lt;td&gt;The file that contains the flask application instance for starting the application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;requirements.py&lt;/td&gt;
&lt;td&gt;The file that contains all the dependencies of the application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;logs/&lt;/td&gt;
&lt;td&gt;The folder that contains application logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/.env&lt;/td&gt;
&lt;td&gt;"The file that contains environment variables like SECRET_KEY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/routes&lt;/td&gt;
&lt;td&gt;The folder that contains the blueprints and templates related to them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/__init__.py&lt;/td&gt;
&lt;td&gt;The file where we assemble the different components of the flask application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/models/&lt;/td&gt;
&lt;td&gt;The folder that contains the database models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/utils/&lt;/td&gt;
&lt;td&gt;The folder that contains the essential services like database access object (daos)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/forms/&lt;/td&gt;
&lt;td&gt;The folder that contains flask forms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/config/config.py&lt;/td&gt;
&lt;td&gt;The file that contains configurations of the flask application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/config/database.py&lt;/td&gt;
&lt;td&gt;The file that contains configurations of the database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/static&lt;/td&gt;
&lt;td&gt;"The folder that contains all the css&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;app_name/templates&lt;/td&gt;
&lt;td&gt;The folder that contains the base template and error pages of the application&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Because we've organised our application into blueprints, instead of sending requests to the flask application instance to be handled, the server now sends them to the appropriate blueprint.  The blueprints must "register" with the flask application instance in order for the flask application instance to know about the project's blueprints and routes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration Management
&lt;/h3&gt;

&lt;p&gt;There are several ways to configure a flask application, but in this tutorial we will be using an &lt;code&gt;.env&lt;/code&gt; file and python objects.&lt;/p&gt;

&lt;p&gt;In practise, you wouldn't want to hardcode the value of important parameters like the &lt;code&gt;secret key&lt;/code&gt;, &lt;code&gt;mail server username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt;, and many more in the &lt;code&gt;config.py&lt;/code&gt; file for security reasons.&lt;/p&gt;

&lt;p&gt;The production-grade or the &lt;strong&gt;!noob&lt;/strong&gt; way of setting important &lt;br&gt;
parameters is to write them in an &lt;code&gt;.env&lt;/code&gt; file. The python package &lt;code&gt;python-dotenv&lt;/code&gt; is a handy little tool. After you've installed the package, you'll need to create a &lt;code&gt;.env&lt;/code&gt; file in your project's root directory to define all of your environment variables. The &lt;code&gt;load_dotenv()&lt;/code&gt; function in your config.py file is then used to load the environment configuration settings from the&lt;br&gt;
&lt;code&gt;.env&lt;/code&gt; file. You must remember to include the &lt;code&gt;.env&lt;/code&gt; file to your &lt;code&gt;.gitignore&lt;/code&gt; file if you use this technique.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;.env&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CONFIG_ENV = Development
ENV = development
SECRET_KEY = 'DamnSIMpLeSecREtKEy'
DATABASE_URI = 
'mysql+pymysql://user:password@hostname:port/database_name'
MAIL_USERNAME = mail_user
MAIL_PASSWORD = mail_password
MAIL_DEFAULT_SENDER = mail_sender
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;config.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt; 
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="c1"&gt;# Absolute path of app_name directory
&lt;/span&gt;&lt;span class="n"&gt;BASE_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abspath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="c1"&gt;# Loading configuration variable into the environment from .env file
&lt;/span&gt;&lt;span class="n"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BASE_DIR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'.env'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;"""
    Base class configuration, common to all other config classes
    """&lt;/span&gt;

    &lt;span class="n"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'SECRET_KEY'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'samplesecret_key'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;WTF_CSRF_ENABLED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;SQLALCHEMY_TRACK_MODIFICATIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;MAIL_SERVER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'smtp.googlemail.com'&lt;/span&gt;
    &lt;span class="n"&gt;MAIL_USE_SSL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;MAIL_PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;465&lt;/span&gt;
    &lt;span class="n"&gt;MAIL_USE_TLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;MAIL_SUPPRESS_SEND&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;MAIL_USERNAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'MAIL_USERNAME'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;MAIL_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'MAIL_PASSWORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;MAIL_DEFAULT_SENDER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'MAIL_USERNAME'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Development&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
   &lt;span class="s"&gt;"""Configuration settings for development environment"""&lt;/span&gt;
    &lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;TESTING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;ENV&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'development'&lt;/span&gt;
    &lt;span class="n"&gt;DATABASE_URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DATABASE_URI"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Production&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""Configuration settings for production environment"""&lt;/span&gt;
    &lt;span class="n"&gt;DEBUG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;TESTING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;ENV&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'production'&lt;/span&gt;
    &lt;span class="n"&gt;DATABASE_URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PROD_DATABASE_URI"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Testing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""Configuration settings for testing environment"""&lt;/span&gt;
    &lt;span class="n"&gt;TESTING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;WTF_CSRF_ENABLED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;MAIL_SUPPRESS_SEND&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;DATABASE_URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TEST_DATABASE_URI"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;app_name/__init__.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.config.config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Development&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Production&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_app&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'CONFIG_ENV'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'Development'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Development&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Production&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'&amp;lt;h2&amp;gt;App is Running&amp;lt;/h2&amp;gt;'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;app.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;app_name&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_app&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"__main__"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating Blueprints
&lt;/h3&gt;

&lt;p&gt;Blueprints are defined by instantiating an instance of the Blueprint class. The arguments passed to the class constructor are the name of the blueprint and the name of the folder containing the templates belonging to the blueprint and a url prefix to differentiate between the similar routes of different blueprints. You then need to write the routes of that blueprint.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;app_name/routes/api.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_blueprint&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="s"&gt;"""Instantiating api blueprint and returning it"""&lt;/span&gt;

    &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'api'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;template_folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'templates'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'/api'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/info'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'&amp;lt;h2&amp;gt;Sample Route&amp;lt;/h2&amp;gt;'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;app_name/routes/user.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_blueprint&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="s"&gt;"""Instantiating user blueprint and returning it"""&lt;/span&gt;

    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;template_folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'templates/user'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'/user'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/register'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'register.html'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;app_name/routes/admin.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_blueprint&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="s"&gt;"""Instantiating admin blueprint and returning it"""&lt;/span&gt;

    &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;template_folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'templates/admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'/admin'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/panel'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;panel&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'panel.html'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Important points to remember when working with blueprints
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Any references to the &lt;code&gt;app&lt;/code&gt; object must be replaced with references to the &lt;code&gt;current_app&lt;/code&gt; object. This is because you no longer have direct access to the flask application instance when dealing with blueprints. It is only accessible through its proxy, &lt;code&gt;current_app&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure the &lt;code&gt;url_for()&lt;/code&gt; method refers to the view function's blueprint. This is done to reflect the reality that certain blueprints have distinct view functionalities. &lt;code&gt;url_for(user.register)&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make that the blueprint object is used by the decorator used to define any route.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Application Factory Pattern
&lt;/h3&gt;

&lt;p&gt;We want to create flask applications with different configurations(&lt;code&gt;Development, Production, Testing&lt;/code&gt;) without changing much in the actual code. Here, the function of &lt;code&gt;factory method&lt;/code&gt; is to spin up different flask applications according to our need. The Application Factory Pattern is nothing but the well-known design pattern &lt;code&gt;Factory Method Pattern&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Format to make an Application Factory Function
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Instantiation of Flask Application&lt;/li&gt;
&lt;li&gt;Loading Configurations of Flask Application&lt;/li&gt;
&lt;li&gt;Registration of BLueprints&lt;/li&gt;
&lt;li&gt;Registration of Error Handlers&lt;/li&gt;
&lt;li&gt;Configuration of Logging Module&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We covered the first two steps in the previous sections, so we will be continuing from the third step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registration of Blueprints
&lt;/h3&gt;

&lt;p&gt;Blueprints are registered by passing the blueprint object to the &lt;code&gt;register_blueprint()&lt;/code&gt; method the flask application instance exposes.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;utils/register_blueprints.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;app_name.routes&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register_blueprints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""Registering all the blueprint objects"""&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register_blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_blueprint&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register_blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_blueprint&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register_blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_blueprint&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;app_name/__init__.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.config.config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Development&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Production&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.utils.register_blueprints&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;register_blueprints&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_app&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'CONFIG_ENV'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'Development'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Development&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Production&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;


    &lt;span class="c1"&gt;# Registering Blueprints
&lt;/span&gt;    &lt;span class="n"&gt;register_blueprints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'&amp;lt;h2&amp;gt;App is Running&amp;lt;/h2&amp;gt;'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What is Logging?
&lt;/h3&gt;

&lt;p&gt;It is the process of keeping official record of your application. It is used for recording events as they occur and is a great tool for debugging any issues and gaining information about your application's working.&lt;/p&gt;

&lt;p&gt;You should log application specific errors as well as database specific errors. You may also opt to log important functionalities of your application. Any kind of sensitive information should not be logged as logs are stored in plaintext format.&lt;/p&gt;

&lt;h3&gt;
  
  
  Logging Module
&lt;/h3&gt;

&lt;p&gt;Generally standard python logging module is used. The standard looging module has 4 submodules, which are &lt;code&gt;loggers&lt;/code&gt;, &lt;code&gt;handlers&lt;/code&gt;, &lt;code&gt;filters&lt;/code&gt; and &lt;code&gt;formatters&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loggers&lt;/strong&gt; are the objects that create log messages. When you produce a log message, you have to specify its criticality by using the function associated with the criticality level.The following are the criticalility levels (also known as logging levels), their numeric representations, and the functions that go with them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debug → 10 → debug()&lt;/li&gt;
&lt;li&gt;Info → 20 → info()&lt;/li&gt;
&lt;li&gt;Warning → 30 → warning()&lt;/li&gt;
&lt;li&gt;Error → 40 → error()&lt;/li&gt;
&lt;li&gt;Critical → 50 → critical()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A default &lt;code&gt;logger&lt;/code&gt; object can be accessed and utilised without the requirement for any configuration. The &lt;code&gt;app.logger&lt;/code&gt; object is exposed by every flask instance. If you're using blueprints, you'll need to use the &lt;code&gt;current_app&lt;/code&gt; object, which is a proxy for the flask application instance.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;app_name/routes/admin.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;current_app&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_blueprint&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="s"&gt;"""Instantiating admin blueprint and returning it"""&lt;/span&gt;

    &lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;template_folder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'templates/admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'/admin'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'/panel'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;panel&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;current_app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Admin Panel Accessed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'panel.html'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;admin&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default logger, unfortunately, simply prints to the console. As a result, if you want to log to a file, you must create a new logger instance. The default logger will continue to log, but you can turn it off if you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask.logging&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;default_handler&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;removeHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can set the minimum criticality level of the messages that should be logged when configuring a new logger instance. All log messages with a criticality of this value or greater will be logged, while those with a criticality of less than this value will be ignored. This is handy in instances where you don't want&lt;br&gt;
to delete log calls from your source code but still want to limit the number of log messages. You can increase the minimum log level of messages that are written to the log, such as &lt;strong&gt;ERROR&lt;/strong&gt; messages and higher.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handlers&lt;/strong&gt; are the objects that route log messages to the appropriate location. A stream handler is the default handler, and it transmits log messages to the terminal. To route log messages to different destinations, you can build different handler objects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A &lt;code&gt;FileHandler&lt;/code&gt; is used to log to a file. A &lt;code&gt;SMTPHandler&lt;/code&gt; is used to deliver log messages as email.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;FileHandler&lt;/code&gt; function accepts the &lt;code&gt;location&lt;/code&gt; and &lt;code&gt;name&lt;/code&gt; of the log file you wish to write to and creates a &lt;code&gt;FileHandler&lt;/code&gt; object that sends log messages to that file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In most cases, the &lt;code&gt;logs&lt;/code&gt; folder is used to store files that execute during runtime (logs and database files). This folder must be added to your &lt;code&gt;.gitignore&lt;/code&gt; file in order for version control to ignore it.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="n"&gt;file_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'logs/application.log'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The log messages are written to a single log file via the &lt;code&gt;FileHandler&lt;/code&gt; object. As a result, the log file might quickly grow in size. Using the &lt;code&gt;RotatingFileHandler&lt;/code&gt; object is a better option. It likewise saves log messages to a file, but if the existing log file surpasses a certain size, it produces a new one (&lt;code&gt;maxBytes&lt;/code&gt;). Before overwriting the current files, it will generate a new file up to a given number of files (&lt;code&gt;backupCount&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;logging.handlers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RotatingFileHandler&lt;/span&gt;

&lt;span class="n"&gt;file_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RotatingFileHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'logs/application.log'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxBytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16384&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backupCount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Filters&lt;/strong&gt; are used to add contextual information to log messages. When logging requests, for example, you can add a filter that includes the request's external IP address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Formatters&lt;/strong&gt; are used to specify the format of the log messages. A &lt;code&gt;LogRecord&lt;/code&gt; object represents each log message. Log formatters are used to specify which &lt;code&gt;LogRecord&lt;/code&gt; characteristics should be displayed and in what order they should be displayed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Some Attributes of LogRecords:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;%(asctime)s - datetime when the LogRecord was created&lt;/li&gt;
&lt;li&gt;%(filename)s - filename portion of pathname&lt;/li&gt;
&lt;li&gt;%(funcName)s - name of function containing the logging call&lt;/li&gt;
&lt;li&gt;%(levelname)s - logging level for the message&lt;/li&gt;
&lt;li&gt;%(lineno)d - line number of source code where the logging call 
was issued (if available)&lt;/li&gt;
&lt;li&gt;%(message)s - the logged message&lt;/li&gt;
&lt;li&gt;%(module)s - module from which the logging call was issued&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configure Logging
&lt;/h3&gt;

&lt;p&gt;You should configure &lt;code&gt;logging&lt;/code&gt; before creating the flask application instance, otherwise it will use the default handler which writes log messages to the console. This is why the application factory function is used to configure logging.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;utils/log_config.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask.logging&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;default_handler&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;logging.handlers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RotatingFileHandler&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c1"&gt;# Deactivate default flask logger 
&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;removeHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default_handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# File handler object
&lt;/span&gt;    &lt;span class="n"&gt;file_handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RotatingFileHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'logs/application.log'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;maxBytes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16384&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backupCount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Set logging level of the file handler object so that it logs INFO and up
&lt;/span&gt;    &lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# file formatter object
&lt;/span&gt;    &lt;span class="n"&gt;file_formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'%(asctime)s %(levelname)s: %(message)s [in %(filename)s: %(lineno)d]'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Apply file formatter object to the file handler object
&lt;/span&gt;
    &lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setFormatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_formatter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Add file handler object to the logger
&lt;/span&gt;    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Customized Error Handling
&lt;/h3&gt;

&lt;p&gt;An HTTP status code is included in the response message when a client sends a request to a web server. It's a three-digit number that represents the outcome of the request processing. Based on the initial digit, status codes are divided into five categories, each representing a different type of response:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;1xx — Informational response&lt;/li&gt;
&lt;li&gt;2xx — Successful responses 

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;200&lt;/code&gt; (OK), for successful processing of the request&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3xx — Redirects

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;302&lt;/code&gt; (Found), for successfuly redirecting the client to a new URL&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;4xx — Client errors 

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;400&lt;/code&gt; (Bad Request): when the client makes a request that the 
server can’t understand or doesn’t allow.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;403&lt;/code&gt; (Forbidden): when the client tries to access a restricted 
resource and doesn’t have authorization to do so.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;404&lt;/code&gt; (Not Found): when a client requests a URL that the server 
does not recognise. The error message given should be 
something along the lines of “Sorry, what you are looking for 
just isn’t there!”.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;405&lt;/code&gt; (Method Not Allowed): when a request method is not 
accepted by the view function that handles requests for a 
given route. The error message given should be along the 
lines of “Sorry, the method requested is not supported by 
this resource!”.

&lt;ol&gt;
&lt;li&gt;5xx — Server errors&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;500&lt;/code&gt; (Internal Server Error): Usually occurs due to 
programming errors or the server getting overloaded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create your custom error pages eg: &lt;code&gt;403.html&lt;/code&gt;, &lt;code&gt;500.html&lt;/code&gt;, &lt;code&gt;404.html&lt;/code&gt; and then render these error pages using error_handlers.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;utils/error_handlers.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;error_handlers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="c1"&gt;# 403 - Forbidden
&lt;/span&gt;    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errorhandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forbidden&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'403.html'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;403&lt;/span&gt;

    &lt;span class="c1"&gt;# 400 - Bad Request
&lt;/span&gt;    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errorhandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bad_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'400.html'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;

    &lt;span class="c1"&gt;# 404 - Page Not Found
&lt;/span&gt;    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errorhandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;page_not_found&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'404.html'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;

    &lt;span class="c1"&gt;# 405 - Method Not Allowed
&lt;/span&gt;    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errorhandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;405&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_not_allowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'405.html'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;405&lt;/span&gt;

    &lt;span class="c1"&gt;# 500 - Internal Server Error
&lt;/span&gt;    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;errorhandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;server_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'500.html'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Final &lt;code&gt;app_name/__init__.py&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.config.config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Development&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Production&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.utils.register_blueprints&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;register_blueprints&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.utils.error_handlers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;error_handlers&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.utils.log_config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;log_config&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_app&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'CONFIG_ENV'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'Development'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Development&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;from_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Production&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;


    &lt;span class="c1"&gt;# Registering Blueprints
&lt;/span&gt;    &lt;span class="n"&gt;register_blueprints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Configure Logging
&lt;/span&gt;    &lt;span class="n"&gt;log_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Registering Error Handlers
&lt;/span&gt;    &lt;span class="n"&gt;error_handlers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'GET'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;'&amp;lt;h2&amp;gt;App is Running&amp;lt;/h2&amp;gt;'&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;You may now brag to your buddies about not being a noob flask developer. &lt;/p&gt;

&lt;p&gt;I hope you all enjoyed the article.&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>programming</category>
      <category>flask</category>
    </item>
    <item>
      <title>Markdown Preview in Vim</title>
      <dc:creator>Rittik Dasgupta</dc:creator>
      <pubDate>Thu, 15 Apr 2021 11:53:53 +0000</pubDate>
      <link>https://dev.to/hrk2023/markdown-preview-in-vim-44bl</link>
      <guid>https://dev.to/hrk2023/markdown-preview-in-vim-44bl</guid>
      <description>&lt;p&gt;When we edit a markdown file in vim, we are not able to preview the markdown file simultaneously. I have also faced this situation, so I decided why not make one.&lt;/p&gt;

&lt;p&gt;To be able to preview a markdown, first, we need a &lt;code&gt;markdown parser&lt;/code&gt;.&lt;br&gt;
I got to know about &lt;a href="https://github.com/charmbracelet/glow" rel="noopener noreferrer"&gt;Glow&lt;/a&gt;, which renders markdown on the Command Line Interface(CLI).&lt;/p&gt;

&lt;p&gt;To install glow, you can follow the instructions given in the Github repo of &lt;a href="https://github.com/charmbracelet/glow" rel="noopener noreferrer"&gt;Glow&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After installing Glow I added a few lines to my vimrc&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktsv8vwvcf09im8efwvs.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktsv8vwvcf09im8efwvs.PNG" alt="Vim Function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function finds the path of the current file and adds it in the &lt;code&gt;.lastpreview.log&lt;/code&gt; file. After that &lt;code&gt;bel vert terminal&lt;/code&gt; command is executed, which opens up the terminal buffer in vim, side by side.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;nmap &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;F4&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;call&lt;/span&gt; PreviewerMarkdown&lt;span class="p"&gt;()&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;clear&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;glo $&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;cat&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt;/&lt;span class="p"&gt;.&lt;/span&gt;lastpreview&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&amp;lt;&lt;/span&gt;CR&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, I made this custom mapping in vimrc. I bound my &lt;code&gt;F4&lt;/code&gt; key to the &lt;code&gt;PreviewerMarkdown()&lt;/code&gt;. After PreviewerMarkdown is executed the &lt;code&gt;clear&lt;/code&gt; command runs which clears the terminal buffer, and after this &lt;code&gt;glo&lt;/code&gt; command runs, which is basically an alias I made for &lt;code&gt;glow -s dark | less&lt;/code&gt;. The &lt;code&gt;glo&lt;/code&gt; command opens the file path present in the &lt;code&gt;lastpreview.log&lt;/code&gt; file with a &lt;code&gt;pager (here less)&lt;/code&gt; and a suitable color scheme, and boom our markdown preview is now ready to be used.&lt;/p&gt;

&lt;p&gt;There is room for adding more functionality to the &lt;code&gt;PreviewerMarkdown()&lt;/code&gt;, but for this post, I chose to keep only the core functionality.  &lt;/p&gt;

</description>
      <category>productivity</category>
      <category>vim</category>
      <category>markdown</category>
      <category>linux</category>
    </item>
    <item>
      <title>Overview of Vim</title>
      <dc:creator>Rittik Dasgupta</dc:creator>
      <pubDate>Mon, 16 Nov 2020 11:58:51 +0000</pubDate>
      <link>https://dev.to/hrk2023/overview-of-vim-3544</link>
      <guid>https://dev.to/hrk2023/overview-of-vim-3544</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;What is Vi?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Vi was the first screen-oriented text editor created for Unix, it was designed to be simple yet powerful for text manipulation.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is Vim(Vi IMproved)?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Vim is not just any text editor, it is an open-source configurable text editor that we can program according to our needs. It is an extremely fast and powerful text editor.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Philosophy of Vim&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When programming, you spend most of your time reading/editing, not writing. For this reason, Vim is a modal editor: it has different modes for inserting text vs manipulating text. Vim is programmable (with Vimscript and also other languages like Python), and Vim’s interface itself is a programming language: keystrokes (with mnemonic names) are commands, and these commands are composable. Vim avoids the use of the mouse because it’s too slow; Vim even avoids using the arrow keys because it requires too much movement.&lt;br&gt;
The end result is an editor that can match the speed at which you think.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Advantages of VIM&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vim is Always Available:&lt;/strong&gt; Vim is available on most, if not all Linux distributions out there, you can install it from your distro’s official software repositories as follows:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;vim &lt;span class="o"&gt;[&lt;/span&gt;On Debian/Ubuntu]
yum &lt;span class="nb"&gt;install &lt;/span&gt;vim &lt;span class="o"&gt;[&lt;/span&gt;On RHEL/CentOS]
dnf &lt;span class="nb"&gt;install &lt;/span&gt;vim &lt;span class="o"&gt;[&lt;/span&gt;Fedora 22+]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;WSL and WSL2 can be used in Windows to be able to use VIM. Also, Vim GUI can be downloaded for Windows to use VIM. &lt;a href="https://www.vim.org/download.php#pc"&gt;Click Here&lt;/a&gt; to download Vim GUI.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Vim Is Very Customizable and Extensible&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vim Uses Less Amount of System Resources&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vim Supports All Programming Languages and File Formats&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vim Has A Vibrant Community&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Disadvantages of VIM&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Difficult learning curve&lt;/li&gt;
&lt;li&gt;High effort to customize&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Modes in VIM&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Vim’s design is based on the idea that a lot of programmer time is spent reading, navigating, and making small edits, as opposed to writing long streams of text. For this reason, Vim has multiple operating modes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Normal:&lt;/strong&gt; for moving around a file and making edits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insert:&lt;/strong&gt; for inserting text&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replace:&lt;/strong&gt; for replacing text&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual (plain, line, or block):&lt;/strong&gt; for selecting blocks of text&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Command-line:&lt;/strong&gt; for running a command&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;My Opinion on Vim:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Stick with using vim for all your text editing needs (even if it slows you down initially). If you can cross the initial learning period then it could be a boon for you.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>programming</category>
      <category>productivity</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
