Flask Application Structure

[TOC]

Flask Web Application DevOps

Flask Application Structure

1. Flask Application Structure:

Let’s say you have a Flask project with the following structure:

1
2
3
4
5
6
7
8
myapp/

├── app/
│ ├── __init__.py
│ ├── routes.py
│ └── ...

└── run.py

In this structure, app is the package containing your Flask application, routes.py contains route definitions, and run.py is the entry point for running the app.

2. Initializing Flask App (__init__.py):

In app/__init__.py, you initialize your Flask application:

1
2
3
4
5
from flask import Flask

app = Flask(__name__)

from app import routes

In this file, you create an instance of Flask called app. After the instance is created, you import the routes. It is important that the import statement for routes comes after the creation of the Flask instance to avoid circular imports.

3. Defining Routes (routes.py):

In routes.py, you define your route handlers:

1
2
3
4
5
from app import app

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

Here, you’re importing the app instance from your app package and using the route decorator to tell Flask what URL should trigger the index function.

4. Running the Flask App (run.py):

Finally, in run.py, you run the application:

1
2
3
4
from app import app

if __name__ == '__main__':
app.run(debug=True)

When you execute run.py, it imports the app instance from the app package. This import statement triggers the execution of __init__.py, which in turn initializes the Flask app and imports routes.py. As a result, the routes you defined in routes.py are registered with the Flask app.

5. Running the Application:

To start the Flask application, you would run the run.py script:

1
python run.py

This starts the Flask web server, and your application should be accessible according to the routes you’ve defined in routes.py.

This modular setup helps in keeping the code organized and makes it easier to maintain and scale your Flask application.

Chapter-1

Chapter-2

Chapter-3

Chapter-4

Chapter-5 Database

  1. Database Configuration: Introduction to database configuration in Flask, explaining how to set up and configure a database for use with a Flask application. This likely includes choosing a database system (like SQLite for development purposes) and setting up the database URI in the Flask app’s configuration.

  2. ORM (Object-Relational Mapping): Discussion of using an ORM like SQLAlchemy in Flask. ORM allows developers to interact with the database using Python classes and objects instead of writing raw SQL queries.

  3. Database Models: Explanation of how to define database models in Flask. This involves creating Python classes that define the tables and relationships in the database. For example, defining a User model for a user table.

  4. Database Migrations: Introduction to database migration tools, such as Flask-Migrate, which is an extension that handles SQLAlchemy database migrations for Flask applications. The tutorial likely covers how to create and apply database migrations, which is essential for evolving the database schema over time without losing data.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # Creating The Migration Repository
    (venv) $ flask db init

    # Generating the migration script
    (venv) $ flask db migrate -m "users table"

    # The flask db migrate command does not make any changes to the database, it just generates the migration script. To apply the changes to the database, the flask db upgrade command must be used.
    (venv) $ flask db upgrade

    # Flask db downgrade command, which undoes the last migration
    # The first command tells Flask-Migrate to apply the database migrations in reverse order. When the downgrade command is not given a target, it downgrades one revision. The base target causes all migrations to be downgraded, until the database is left at its initial state, with no tables.
    # The upgrade command re-applies all the migrations in forward order. The default target for upgrades is head, which is a shortcut for the most recent migration.
    # Since database migrations do not preserve the data stored in the database, downgrading and then upgrading has the effect of quickly emptying all the tables.
    (venv) $ flask db downgrade base
    (venv) $ flask db upgrade
  5. Database Operations: Overview of basic database operations like creating, reading, updating, and deleting records (CRUD operations). This section might include examples of how to perform these operations using SQLAlchemy in a Flask app.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    # import modules
    >>> from app import app, db
    >>> from app.models import User, Post
    >>> import sqlalchemy as sa
    >>> app.app_context().push()

    # For Flask and its extensions to have access to the Flask application without having to pass app as an argument into every function, an application context must be created and pushed.
    >>> app.app_context().push()

    # Create a user, changes are only written to the database when a commit is issued with db.session.commit()
    >>> u = User(username='john', email='john@example.com')
    >>> db.session.add(u)
    >>> db.session.commit()

    # Add another user
    >>> u = User(username='susan', email='susan@example.com')
    >>> db.session.add(u)
    >>> db.session.commit()

    # query the suer
    >>> query = sa.select(User)
    >>> users = db.session.scalars(query).all()
    >>> users
    [<User john>, <User susan>]

    # use the results iterator in a for-loop instead of converting it to a list
    >>> users = db.session.scalars(query)
    >>> for u in users:
    ... print(u.id, u.username)
    ...
    1 john
    2 susan

    # Another way to query, if you know the id of a user, you can retrieve that user as follows
    >>> u = db.session.get(User, 1)
    >>> u
    <User john>


    # Add a blog post
    >>> u = db.session.get(User, 1)
    >>> p = Post(body='my first post!', author=u)
    >>> db.session.add(p)
    >>> db.session.commit()


    ## --------- more useful db queries

    >>> # get all posts written by a user
    >>> u = db.session.get(User, 1)
    >>> u
    <User john>
    >>> query = u.posts.select()
    >>> posts = db.session.scalars(query).all()
    >>> posts
    [<Post my first post!>]

    >>> # same, but with a user that has no posts
    >>> u = db.session.get(User, 2)
    >>> u
    <User susan>
    >>> query = u.posts.select()
    >>> posts = db.session.scalars(query).all()
    >>> posts
    []

    >>> # print post author and body for all posts
    >>> query = sa.select(Post)
    >>> posts = db.session.scalars(query)
    >>> for p in posts:
    ... print(p.id, p.author.username, p.body)
    ...
    1 john my first post!

    # get all users in reverse alphabetical order
    >>> query = sa.select(User).order_by(User.username.desc())
    >>> db.session.scalars(query).all()
    [<User susan>, <User john>]

    # get all users that have usernames starting with "s"
    >>> query = sa.select(User).where(User.username.like('s%'))
    >>> db.session.scalars(query).all()
    [<User susan>]
  6. Integrating with Flask Application: Steps to integrate the database with the main Flask application, including initializing the database with the app and possibly creating a shell context for working with the database in the Flask shell.

    without flask shell, it is boring to test database as you need to import the modules/db models everytime.

    1
    2
    3
    4
    >>> from app import app, db
    >>> from app.models import User, Post
    >>> import sqlalchemy as sa
    >>> app.app_context().push()
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # The following function in microblog.py creates a shell context that adds the database instance and models to the shell session:
    import sqlalchemy as sa
    import sqlalchemy.orm as so
    from app import app, db
    from app.models import User, Post

    @app.shell_context_processor
    def make_shell_context():
    return {'sa': sa, 'so': so, 'db': db, 'User': User, 'Post': Post}

    After you add the shell context processor function you can work with database entities without having to import them:

    1
    2
    3
    4
    5
    6
    7
    (venv) $ flask shell
    >>> db
    <SQLAlchemy sqlite:////home/miguel/microblog/app.db>
    >>> User
    <class 'app.models.User'>
    >>> Post
    <class 'app.models.Post'>

Chapter-19 Deployment on Docker Containers


Flask Application Structure
https://blog.excelsre.com/2024/01/14/flask-web-application-devops/
作者
Felix Yang
发布于
2024年1月15日
许可协议