Skip to content

RyanJulyan/Flask-BDA

Repository files navigation

Flask Business Driven App (BDA)

Quickly create cross-platform, multi-tenant, SAAS-ready, mobile and web applications, and reactive web apps for any device. A Rapid Application Development (RAD) tool to assist with building flask python applications. Helping you build applications fast, right, and for the Future.

Note: Still under Development!

Status of the project

Current version: 0.0.0 Beta

Flask-BDA is still under initial development and is being tested with Python 3.8.6 version.

Current roadmap and high-level project plan: https://trello.com/b/uu4HNPBh/flask-bda-features-roadmap

Flask-BDA will follow semantic versioning for its releases, with a {major}.{minor}.{patch} scheme for versions numbers, where:

  • major versions might introduce breaking changes
  • minor versions usually introduce new features and might introduce deprecations
  • patch versions only introduce bug fixes

Deprecations will be kept in place for at least 3 minor versions, after version 0.0.1

Overview

Why use Flask-BDA

Other solutions such as Tableau, Power BI and Amazon QuickSight, while fantastic tools, focus on reporting but do not let you edit or add data to the platforms when needed, meaning you require additional solutions or software to achieve your business goals

Solutions like Excel are accessible to everyone and give you all the flexibility you might need. Still, your data is scattered and does not easily allow for a shared source of truth for your team and clients, and it is very easy for excel documents to be out of sync or even shared, opening your company up to a security risk.

Flask-BDA helps you by providing you with the control to deliver rapid, secure, Full-stack applications 2-5x (2-5 times) faster. With no vendor or environment lock-in, ever.

Flask is an open-source "micro-framework" written by Armin Ronacher that allows you to build web applications in Python. Shipping only a small core set of features provides an extensible base that allows developers to choose what additional tools they will need for their application.

Despite being called a micro-framework, Flask is well suited to build small and large web applications. Flask has been used in production systems by large companies such as Twilio, Pinterest, Lyft, LinkedIn, and Uber.

Flask-BDA helps you develop faster by providing you with a pre-existing flask application structure allowing you to:

Automatically deal with the tedious aspects that slow down software development

  • Create & manage all database connections and complex queries.
  • Application security with user and role-based access control
  • Automatic audits on every action

Flask-BDA is a low-code platform (meaning we will help you by writing a lot of the code for you) that provides the tools for companies to rapidly develop and deploy secure applications that run on any device.

We change the way software is built so you can rapidly create and deploy critical applications of any size that evolve with your business saving you time & money.

Developers can build and deploy a full range of applications - from consumer apps to critical internal business systems - designed to help developers deliver secure applications quickly and efficiently, so apps are delivered in weeks and even days.

Flask-BDA provides Full-stack development from; UI, business processes, custom logic, and data models to create cross-platform apps out of the box. Providing you with a scaffold that you can add your own custom code when needed. With no lock-in ever.

With pre-configured development environments, we reduce the pain (and cost) of getting to market, giving you the flexibility to choose where and how to deploy.

Free and Developer-Friendly, Flask-BDA is a free-to-use, source available, application development tool with a developer-friendly license.

Costs

Flask-BDA is completely FREE to use for commercial and personal projects.

However, Software development is always a costly exercise:

  • You will need to pay one or multiple Software Developers, Business Analysts, Designers, Project Managers, and other team members to build your product.
  • Your product is never finished. A software project will always need continued development.
    • When you deliver a product, your competition is already working on new and improved features, and you need to be able to stay ahead or at least keep up, or users will move to your competition.
    • Once you start using your product, you and your team will think of new features that will make it even better and improve your processes.
    • Continued maintenance. As users use the product, they will find ways to break it that you haven't thought of, and they need to be fixed.

Rough Costing Table (2020) For Normal Development

Project size Initial cost Ongoing cost
Small-sized projects (2 - 6 weeks of development) $11 250 $563 - $1 125 (±10%) / per month
Medium-sized projects (2 - 4 months of development) $33 750 $1 563 - $3 375 (±10%) / per month
Large-sized projects (6 - 18 months, or longer, of development) $156 250 $3 375 - $15 625 (±10%) / per month

Rough Costing Table (2020) For Flask-BDA Development

Project size Initial cost Ongoing cost
Small-sized projects (1 - 3 weeks of development) $3 750 $188 - $375 (±10%) / per month
Medium-sized projects (1 - 3 months of development) $11 250 $375 - $1 125 (±10%) / per month
Large-sized projects (2 - 6 months, or longer, of development) $52 084 $1 125 - $5 208 (±10%) / per month

With Flask-BDA, you DON'T LOOSE ANY of the flexibility of "Normal Development" as it uses standardized development patterns and tried and tested technologies.

Flask-BDA uses many Open Source technologies and leverages existing technology stacks so that you can easily find other developers who use the same technologies. As a result, you do not have to pay for costly license fees or environment costs regardless of how much revenue your company makes or where you are in your business.

Process

Step 1:

Download pre-configured development environment

Start your with a quick and easy pre-configured development environment in minutes.

No complex setup required. Only python (suggested 3.8.6) is required.

Step 2:

Update config and rapidly develop custom modules

Upsdate your configurations: Database connections and application settings.

Create your own modules and data structures (data model) allowing you to use different databases.

Step 3:

Fully functional pages

Auto-generated fully functional:

  • Admin and Mobile pages
  • REST APIs with a Swagger front-end
  • GraphQL API with a GraphiQL front-end easily managed per module.

Step 4:

Customize

Configure pages to your specific needs and easily share them with your team and clients.

Write your own custom code in an isolated module, so you do not affect other modules,

Easily integrate modules accross different projects.

Step 5:

Deploy

Use the same codebase to deploy to:

  • Desktop
  • Web
  • Mobile

Environments include:

  • Docker
  • AWS Serverless
  • Digital Ocean
  • Heroku
  • Shared hosting.

Requirements

  • Download and install Python (suggested 3.8.6) if you do not already have it installed.
    • Ensure pip is installed (pip should be installed already because it comes with the latest versions of python) in case it is not, please install it from here: https://pip.pypa.io/en/stable/installing/
      • To check if pip is installed, you can run the following command in your terminal
python -m pip --version

NOTE: This documentation assumes that you are running pip3 as pip, as such all instructions are written with pip. If you would like to make pip3 run when you call pip, from your tereminal, you can create a symlink to pip3 from pip:

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
      • You may need to run "cmd" as administrator to run pip install --upgrade pip
        • To do this, you run the command as sudo eg: sudo pip install --upgrade pip
nano ~/.bash_profile

In the file, paste the following:

alias pip='pip3'
alias python='python3'

NOTE: You may need to remove python 2.7 on MacOS as it is pre-installed on my distributions this like was very helpful to acheive this:

  1. Remove the third-party Python 2.7 framework
sudo rm -rf /Library/Frameworks/Python.framework/Versions/2.7
  1. Remove the Python 2.7 applications directory
sudo rm -rf "/Applications/Python 2.7"
  1. Remove the symbolic links, in /usr/local/bin, that point to this Python version. See them using
ls -l /usr/local/bin | grep '../Library/Frameworks/Python.framework/Versions/2.7'

and then run the following command to remove all the links:

cd /usr/local/bin/
ls -l /usr/local/bin | grep '../Library/Frameworks/Python.framework/Versions/2.7' | awk '{print $9}' | tr -d @ | xargs rm

Dependencies

Once you have installed Python and pip, you will need to install a dependency for the Flask-BDA command line functions to run correctly:

pip install click

Other Dependancies you may want to install globally (but should run automatically when you create a project) include:

pip install virtualenv
pip install flaskwebgui
pip install pyinstaller

Quickstart

To get started building your first project with Flask-BDA, follow the simple steps below to create your own pre-configured development environment up and running in minutes.

In this quickstart, we will create a project called "My Awesome Project". However, you can call the project anything you want.

Windows

  • Open a new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
  • Copy, paste and run the following code in the terminal
    • This will download the required create_project.py python file and run it to help you start a project
    • Please ensure you put quotes around your project name to prevent errors, e.g.: "My Awesome Project"
curl -L https://raw.githubusercontent.com/RyanJulyan/Flask-BDA/main/create_project_git.py --ssl-no-revok -o create_project_git.py

python create_project_git.py --project="My Awesome Project"

Linux / Mac

  • Open a new terminal
    • "Control + Option + Shift + T" to open the terminal
  • Copy, paste and run the following code in the terminal
    • This will download the required create_project.py python file and run it to help you start a project
    • Please ensure you put quotes around your project name to prevent errors, e.g.: "My Awesome Project"
curl -L https://raw.githubusercontent.com/RyanJulyan/Flask-BDA/main/create_project_git.py --ssl-no-revok -o create_project_git.py

python create_project_git.py --project="My Awesome Project"

Note: If you did not fill in a valid project name, you would get prompted to do so:

  • Fill in your project name when prompted, e.g.:
    • Please ensure you put quotes around your project name to prevent errors, e.g.: "My Awesome Project"
Invalid Project Name!
Please enter a valid project name:
"My Awesome Project"

Note: You will notice this creates a folder in the same path as the file: "create_project_git.py". This folder will be lower case and will have stripped out all of the special characters and replaced spaces with underscores, e.g.: my_awesome_project

Note: During development, you may wish to use another branch or repo entirely. This can help with testing or if you have broken away from the core Flask-BDA project.

  • You can specify the Owner, Repo and Branch when creating a new project.
curl -L https://raw.githubusercontent.com/RyanJulyan/Flask-BDA/RyanJulyan-Dev/create_project_git.py --ssl-no-revok -o create_project_git.py

python create_project_git.py --project="My Awesome Project" --owner="RyanJulyan" --repo="Flask-BDA" --branch="RyanJulyan-Dev" --create_venv=True

Update Database

Note: Still to be tested for all connection types!

Database connections are quick and easy in Flask-BDA. You can have 1 or multiple databases, and different tenants can have their own database connections as well as their own database type (SQLite, MySQL, SQL Server, PostgreSQL)

By default, Flask-BDA has an SQLite database set up. This is really because you do not require additional infrastructure to set it up and get going, making SQLite a fast and easy choice.

MySQL

To change the default database:

  • Create a new MySQL Database (flaskbda), User (flaskbda_user) and Password (password)
  • Open the file config.py
  • Comment out the DATABASE_ENGINE for SQLite, and comment in the mysql DATABASE_ENGINE.
  • Comment out the DATABASE_NAME for SQLite, and comment in the mysql:
    • DATABASE_HOST
    • DATABASE_PORT
    • DATABASE_USERNAME
    • DATABASE_PASSWORD
    • DATABASE_NAME
  • Comment out the SQLALCHEMY_DATABASE_URI for SQLite, and comment in the mysql SQLALCHEMY_DATABASE_URI.
##########
# SQLite #
##########
# DATABASE_ENGINE = 'sqlite:///'
# DATABASE_NAME = os.path.join(BASE_DIR, 'databases/sqlite/default.db')

# SQLALCHEMY_DATABASE_URI = DATABASE_ENGINE + DATABASE_NAME

#########
# MySQL #
#########
DATABASE_ENGINE = 'mysql://'
DATABASE_HOST = ''
DATABASE_PORT = '1433'
DATABASE_USERNAME = ''
DATABASE_PASSWORD = ''
DATABASE_NAME = ''

SQLALCHEMY_DATABASE_URI = DATABASE_ENGINE + DATABASE_USERNAME + ':' + DATABASE_PASSWORD + '@' + DATABASE_HOST + ':' + DATABASE_PORT + '/' + DATABASE_NAME
  • You will then need to update the database connection details with your own details:
    • DATABASE_HOST
    • DATABASE_PORT
    • DATABASE_USERNAME
    • DATABASE_PASSWORD
    • DATABASE_NAME
DATABASE_HOST = 'localhost'
DATABASE_PORT = '3306'
DATABASE_USERNAME = 'flaskbda_user'
DATABASE_PASSWORD = 'password'
DATABASE_NAME = 'flaskbda'

SQL Server

To change the default database:

  • Create a new MySQL Database (flaskbda), User (flaskbda_user) and Password (password)
  • Open the file config.py
  • Comment in the SQLServer import pyodbc.
  • Comment in the SQLServer DATABASE_DRIVER.
  • Comment out the DATABASE_ENGINE for SQLite, and for example comment in the SQLServer DATABASE_ENGINE.
  • Comment out the DATABASE_NAME for SQLite, and comment in the SQLServer:
    • DATABASE_HOST
    • DATABASE_PORT
    • DATABASE_USERNAME
    • DATABASE_PASSWORD
    • DATABASE_NAME
  • Comment out the SQLALCHEMY_DATABASE_URI for SQLite, and comment in the try and except for the SQLServer SQLALCHEMY_DATABASE_URI.

Note: if you are running and trying to connect to SQLEXPRESS. Please uncomment the SQLServer SQLEXPRESS variable. This will be handled in the try and except to create the correct SQLALCHEMY_DATABASE_URI

Note: if you want windows authentication. Please uncomment the SQLServer TRUSTED_CONNECTION variable. This will be handled in the try and except to create the correct SQLALCHEMY_DATABASE_URI

##########
# SQLite #
##########
# DATABASE_ENGINE = 'sqlite:///'
# DATABASE_NAME = os.path.join(BASE_DIR, 'databases/sqlite/default.db')

# SQLALCHEMY_DATABASE_URI = DATABASE_ENGINE + DATABASE_NAME

#############
# SQLServer #
#############
import pyodbc   # noqa: E402
DATABASE_ENGINE = 'mssql+pyodbc://'
# SQLEXPRESS = '\\SQLEXPRESS'  # for SQLEXPRESS
# TRUSTED_CONNECTION = 'yes'  # for windows authentication.
DATABASE_DRIVER = 'SQL+Server+Native+Client+11.0'  # for windows authentication.
DATABASE_HOST = ''
DATABASE_PORT = '1433'
DATABASE_USERNAME = ''
DATABASE_PASSWORD = ''
DATABASE_NAME = ''

try:
    if SQLEXPRESS == '\\SQLEXPRESS':
        try:
            if TRUSTED_CONNECTION == 'yes':
                SQLALCHEMY_DATABASE_URI = DATABASE_ENGINE + DATABASE_HOST + ':' + DATABASE_PORT + SQLEXPRESS + '/' + DATABASE_NAME + '?trusted_connection=' + TRUSTED_CONNECTION + '&driver=' + DATABASE_DRIVER
            else:
                SQLALCHEMY_DATABASE_URI = DATABASE_ENGINE + DATABASE_USERNAME + ':' + DATABASE_PASSWORD + '@' + DATABASE_HOST + ':' + DATABASE_PORT  + SQLEXPRESS + '/' + DATABASE_NAME + '&driver=' + DATABASE_DRIVER
        except NameError:
            SQLALCHEMY_DATABASE_URI = DATABASE_ENGINE + DATABASE_USERNAME + ':' + DATABASE_PASSWORD + '@' + DATABASE_HOST + ':' + DATABASE_PORT  + SQLEXPRESS + '/' + DATABASE_NAME + '&driver=' + DATABASE_DRIVER
except NameError:
    try:
        if TRUSTED_CONNECTION == 'yes':
            SQLALCHEMY_DATABASE_URI = DATABASE_ENGINE + DATABASE_HOST + ':' + DATABASE_PORT + '/' + DATABASE_NAME+ '?trusted_connection=' + TRUSTED_CONNECTION + '&driver=' + DATABASE_DRIVER
        else:
            SQLALCHEMY_DATABASE_URI = DATABASE_ENGINE + DATABASE_USERNAME + ':' + DATABASE_PASSWORD + '@' + DATABASE_HOST + ':' + DATABASE_PORT  + SQLEXPRESS + '/' + DATABASE_NAME + '&driver=' + DATABASE_DRIVER
    except NameError:
        SQLALCHEMY_DATABASE_URI = DATABASE_ENGINE + DATABASE_USERNAME + ':' + DATABASE_PASSWORD + '@' + DATABASE_HOST + ':' + DATABASE_PORT + '/' + DATABASE_NAME + '&driver=' + DATABASE_DRIVER
  • You will then need to update the database connection details with your own details:
    • DATABASE_HOST
    • DATABASE_PORT
    • DATABASE_USERNAME
    • DATABASE_PASSWORD
    • DATABASE_NAME
DATABASE_HOST = 'MSSQLSERVER'
DATABASE_PORT = '1433'
DATABASE_USERNAME = 'flaskbda_user'
DATABASE_PASSWORD = 'password'
DATABASE_NAME = 'flaskbda'

Ensure that your MS-SQL instance has remote connection rights set up and enabled reference (here)[https://knowledgebase.apexsql.com/configure-remote-access-connect-remote-sql-server-instance-apexsql-tools/]:

  • Right-click on the server
  • Select the Properties option.
    • In the Server Properties dialogue, select the Connections tab (on the left)
      • Check the "Allow remote connections to this server" checkbox

Ensure that the "SQL server configuration management" settings are configured correctly

NOTE: Your installation will require Client Tools Connectivity, if you cannot find "SQL server configuration management", then you may need to modify your installation to include Client Tools Connectivity

  • if you cannot find the "" you may need to use the "Use the Computer Management" tool instead. to access it.
    • this seems to be a Windows 10 issue
  • Start-> Programs -> Microsoft SQL Server <Version eg: 2019>
    • Select "SQL Server Configuration Manager"
      • In the left pane of SQL Server Configuration Manager, select the "SQL Server Network Configuration."
        • select Protocols for <your server name, e.g., MSSQLSERVER>
          • Make sure that TCP/IP protocol is enabled and right-click on TCP/IP, and select the Properties option. In the TCP/IP Properties dialogue, select the IP Addresses tab and scroll down to IPAII. If the TCP Dynamic Ports dialogue box contains 0, which indicates that the Database Engine is listening on dynamic ports, delete the 0 and set the TCP Dynamic Ports to blank and TCP Port to 1433. Port 1433 is the default instance that SQL Server uses.
          • When you click the OK button, you will be prompted with a message to restart the service
  • In the left pane of SQL Server Configuration Manager, select "SQL Server Services."
    • right-click SQL Server<instance_name eg: MSSQLSERVER>
      • click Restart

Multi Tenants

Isolated Databases with the same functionality

Multitenancy is a software architecture in which a single instance of software runs on a server and serves multiple tenants (clients). Multitenant software allows multiple independent instances of one or multiple applications operate in a shared environment.

Flask-BDA supports veritically partitioned multi-tenancy. Vertical partitioning means that each tenant has a different database (and database connection string).

By default, Flask-BDA connects to a tenant called default. This is done using the SQLALCHEMY_BINDS object (found in config.py), which should have the specific connection details you require for each tenant. The default connection details are combined into a string called SQLALCHEMY_DATABASE_URI, which was meant to allow for a quick and easy single tenant setup.

You can use this same structure, however, to have multiple tenants you can quickly add them to the SQLALCHEMY_BINDS object. To add a new tenant, simply:

  • Create a new line in the SQLALCHEMY_BINDS object, with the name of the tenant and the connection string details
    • Remember to create the database before trying to connect to it.
    • The database connection types (SQLite, MySQL, SQL Server, PostgreSQL) do not have to be the same. each tenant in the same application can have different connection types (meaning different tenants can use different databases and different engines)
SQLALCHEMY_BINDS = {
    "default": SQLALCHEMY_DATABASE_URI,
    "client1": 'sqlite:///databases/sqlite/client1.db',
}

You can now interact with an isolated tenant database by adding the argument organization= to your URL, e.g.: example.com?organization=client1 where client1 is the name that you added in the SQLALCHEMY_BINDS object.

This works by intercepting the @app.before_request in app/_init_.py and changing the db engine binding by using db.choose_tenant(g.organization) from the app/mod_tenancy/multi_tenant.py by using the global variable g.organization which gets set by fetching the URL argument organization. This allows the same code in the app, to be used by every tenant's database while keeping the data seperated.

Interacting with different Databases in the same function

Sometimes you need to interact with different databases in a single function (especially when integrating systems, or reading data from different sources).

By default all controllers will have MultiBindSQLAlchemy imported.

# import multiple bindings
from app.mod_tenancy.multi_bind import MultiBindSQLAlchemy

Under the import there is commented out code intended to assist you with quickly implementing linking to different databases in a single function. Firstly the database binding needs to be added to the SQLALCHEMY_BINDS object. Reference the Isolated Databases with the same functionality to better understand how to add new databases to the SQLALCHEMY_BINDS object.

You can then create a new object attached to the db object following the stucture of db.<binding> e.g.: db.first where first is the name you want to reference the binding in the rest of the code. You can then assign this variable to the MultiBindSQLAlchemy e.g.: db.first = MultiBindSQLAlchemy('first').

This now allows you to call custom code that will allow you to access the new database binding as well as the main tenant in a single function e.g.: db.first.execute(...), where you can execute raw SQL code.

db.first = MultiBindSQLAlchemy('first')
##################################################
## this will only work for the execute function ##
##################################################
db.first.execute(...)

**Note: ** this will only work for the execute function, there are some advanced techniques to still use the SQLAlchemy ORM that can be found here: SQLAlchemy execute tutorial

Create a new module

A module is a self-contained component, making it easier to manage as the program grows. Modules in Flask-BDA help you create: a Data Model, Routes and associated functions for controlling the logic and Views.

When you create a new CRUD module, all the elements from the folder create_module_template are copied into the app directory and renamed to the module name you provide by replacing all xyz values with your module name and adding additional data model information as described below

How to create a new module

  • To create your own custom modules, Open and run the file: <Path To>/<my_awesome_project>/create_module_json.py
    • Where <Path To>/<my_awesome_project>/ is the path to the project you created
    • Fill in the instructions, e.g.:
cd <Path To>/<my_awesome_project>/

python create_module_json.py --module=Projects
  • You can then create a table with columns by following the prompts, e.g.:
Create new field Name (type the string: 'STOP_CREATING_FIELDS' to exit): "name"
What datatype is name
        Choose one of the following options
        ('String'
         ,'Int'
         ,'Float'
         ,'Numeric'
         ,'Text'
         ,'Date'
         ,'DateTime'
         ,'Boolean'
         ,'BigInt'
         ,'Enum'
         ,'JSON'
         ,'LargeBinary'): "String"
String Length (1-256): 256
Is name nullable ('True', 'False'): False
Is name unique ('True', 'False'): True
Does the name have a Relationship with another Data Model? ('True', 'False'): False
Default value: 

Note: This will keep looping until you type and submit the exact words: "STOP_CREATING_FIELDS".

This allows you to create multiple fields for your module quickly and easily.

  • Try creating a few more fields like:
    • "Start Date" as a 'Date' field type
    • "Budget" as a 'Float'
    • "Status" as an 'Enum' with the options: 'Pitch', 'Active' and 'Completed'

The above fields should show you have different field types interact and create multiple fields.

Note: Relationships will always be made on the id of the model provided.

A ForeignKey is created on the field, as well as a lazy relationship between the model provided id field

  • When you have finished creating all the fields you want to create, type and submit the words: "STOP_CREATING_FIELDS".
Create new field Name (type the string: 'STOP_CREATING_FIELDS' to exit): STOP_CREATING_FIELDS
  • You will then be prompted if you would like to create this module logic from the data model. Generate a module from a JSON file in "app/generated_config/models//models.json", where is the name of the module you input. if you want to create all the views, type and submit "True"
Create module logic from Data Model? ('True', 'False'): True

Note: you can also generate a module from a JSON file in "app/generated_config/models//models.json", where is the name of the module you input to do this you can, Open and run the file: <Path To>/<my_awesome_project>/create_module.py * Where <Path To>/<my_awesome_project>/ is the path to the project you created * Fill in the instructions eg:

cd <Path To>/<my_awesome_project>/

python create_module.py --module=projects

This will then create the required files and folders as described below in the App changes

App changes

Files and folders from the create_module_template folder are created for the Projects module and then added to the app folder

This will create a scaffolded admin CRUD views, a REST API (With Bulk Insert and Update), a GraphQL API, and public-facing views and logic to allow you to immediately interact with the module you created.

From the admin panel, you will be able to perform the following actions: Create, Read, Update, and Delete ("CRUD") for your new module.

The public-facing views allows guest users (users not logged in) to see a view of the information provided

└── `my_awesome_project`
       └── app
            ├── generated_config
            │     └── models
            │          └── `projects`
            │               └── models.json
            └── `mod_projects`
                  ├── templates
                  │     ├── mobile
                  │     │    └── `projects`
                  │     │         ├── admin
                  │     │         │    ├── create.html
                  │     │         │    ├── edit.html
                  │     │         │    ├── index.html
                  │     │         │    └── show.html
                  │     │         └── public
                  │     │              └── public_list.html
                  │     └── `projects`
                  │          ├── admin
                  │          │    ├── create.html
                  │          │    ├── edit.html
                  │          │    ├── index.html
                  │          │    └── show.html
                  │          └── public
                  │               └── public_list.html
                  ├── api_controllers.py
                  ├── controllers.py
                  ├── forms.py
                  ├── models.py
                  └── types.py

Module Functionality

Creating a new module will provide you with 3 ways to interact with your new system Public, Admin, REST API and GraphQL API.

To access these, they will require the app to be running on an environment.

Public View

The Public view is a non-authenticated view of the data provided in the module.

It can be accessed from (where xyz is the name of the module):

  • ../xyz/
    • Returns: [list elements]
    • Function name: public_list

Admin View

The Admin views are authenticated view of the data provided in the module.

It can be accessed from (where xyz is the name of the module):

  • ../admin/xyz/
    • Type: View
    • Returns: [list elements]
    • Function name: index
  • ../admin/xyz/create
    • Type: View
    • Returns: [single element]
    • Function name: create
  • ../admin/xyz/store
    • Type: POST URL
    • Returns: [single element]
    • Function name: store
  • ../admin/xyz/show/{id}
    • Type: View
    • Returns: [single element]
    • Function name: show
  • ../admin/xyz/edit/{id}
    • Type: View
    • Returns: [single element]
    • Function name: edit
  • ../admin/xyz/update/{id}
    • Type: PUT URL
    • Returns: [single element]
    • Function name: update
  • ../admin/xyz/destroy/{id}
    • Type: DELETE URL
    • Returns: [single element]
    • Function name: destroy

REST API

The API views are a list of REST API endpoints, associated documentation and execution playground.

Flask BDA uses SwaggerUI to present the REST API to a user/client.

SwaggerUI allows anyone — be it your development team or your end consumers — to visualize and interact with the API’s resources without having any of the implementation logic in place. Instead, it’s automatically generated from your OpenAPI (formerly known as Swagger) Specification, with visual documentation making it easy for back-end implementation and client-side consumption.

To access the SwaggerUI:

To access the REST API without SwaggerUI:

  • Go to your browser or go to postman and insert the URL <base_URL>/
    • ../api/xyz
      • Method: GET
      • Returns: [list elements]
      • Function name: XyzListResource > get
    • ../api/xyz
      • Method: POST
      • Returns: [single element]
      • Function name: XyzListResource > post
    • ../api/xyz/{id}
      • Method: GET
      • Returns: [single element]
      • Function name: XyzResource > get
    • ../api/xyz/{id}
      • Method: PUT
      • Returns: [single element]
      • Function name: XyzResource > update
    • ../api/xyz/{id}
      • Method: DELETE
      • Returns: [single element]
      • Function name: XyzResource > delete
    • ../api/xyz/bulk
      • Method: POST
      • Returns: [multiple elements]
      • Function name: XyzBulkListResource > post
    • ../api/xyz/bulk
      • Method: PUT
      • Returns: [multiple elements]
      • Function name: XyzBulkListResource > update
    • ../api/xyz/aggregate
      • Method: GET
      • Returns: [single return, of multiple elements aggregated]
      • Function name: XyzAggregateResource > get

GraphQL API

The graphql views are a GraphiQL views, API endpoints, associated documentation and execution playground.

Flask BDA uses graphene-python and GraphiQL to present the GraphQL API to a user/client, providing a simple but extendable API for making developers' lives easier.

GraphQL is a data query language provides an alternative to REST and ad-hoc webservice architectures.

To access the GraphiQL:

To access the GraphQL API without GraphiQL:

  • Go to your browser or go to postman and insert the URL <base_URL>/
    • ../graphql
      • Method: GET
      • Returns: [list elements]
      • Function name: mod_graphql > query > Query > all_xyz
    • ../graphql
      • Method: POST
      • Returns: [list elements]
      • Function name: mod_graphql > mutation > Mutation > createXyz

Environments

There are currently 7 out of the box environments supported (with plans for more to be supported soon) with instructions on how to configure each for Windows / Linux / Mac, and you could run them at the same time if you want.

Local Environment

To create and develop a local application, we are using virtualenv. A tool for creating isolated virtual python environments.

Windows

  • Open new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
      • You may need to run "cmd" as administrator to run pip install --upgrade pip
        • To do this, you can search for "cmd" in your windows search
        • Right-click on the icon, and click on the "Run as administrator" option
          • You may need to navigate to your project when running as administrator cd <Path To>/my_awesome_project
cd <Path To>/my_awesome_project

pip install --upgrade pip
pip install virtualenv
virtualenv venv

venv\Scripts\activate

pip install --upgrade pip
pip install --no-cache-dir -r requirements.txt

set FLASK_APP=app
set FLASK_ENV=development

flask run --port 5000

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
      • You may need to run "cmd" as administrator to run pip install --upgrade pip
        • To do this, you run the command as sudo eg: sudo pip install --upgrade pip
cd <Path To>/my_awesome_project

pip install --upgrade pip
pip install virtualenv
virtualenv venv

source venv/bin/activate

pip install --upgrade pip
pip install --no-cache-dir -r requirements.txt

export FLASK_APP=app
export FLASK_ENV=development

flask run --port 5000

Shared Hosting

Some shared hosting services offer the ability to run python applications on their servers. I personally have used A2hosting. Their support has been amazing, and the price to features is one of the best I have come across.

Note: You are not limited to A2 as a shared hosting option. However, this is where I have tested Flask-BDA and have my experience in uploading and running a shared hosting option. If your shared hosting option offers a similar set of features, please feel free to use them.

For A2, you will need to set up your server to run a python application which may require some configuration for example.

To get your custom application to work:

  • You will first need to upload your files (I find this easiest to zip and then upload them to the required location).
    • Unzip them on the server and ensure they are in the folder location you require

Note: In a Linux exvironment the requirement pyodbc will not work by default. Because of this, and being a shared environment - you may not have rights to add the requirements to make it work, the easiest way to ensure that the installation does not fail is to comment out this requirement on the server.

  • Open the requirements.txt file, and search for pyodbc and put a # with a space before the package name.
# pyodbc==4.0.30

  • SSH into the environment
  • Install the environment requirements (similar to the local environment) from the requirements.txt
    • ensure that you run this in the SSH window that you logged into in the previous step
pip install --upgrade pip
pip install --no-cache-dir -r requirements.txt
  • Log in to cPanel again to update the python configuration
    • Click the Setup Python App again
    • Edit the existing application
    • Change the Application startup file to run_shared_server.py
    • Restart the server, and your application should now be working as expected.

Docker Environment

To create and deploy a containerized application, we are using Docker, which helps developers and development teams build and ship apps. In addition, Docker is used for the building and sharing of containerized applications and microservices.

Note: If you are using Github and have docker installed (details on how to install later in the documentation), you will get a new image built every time you push or do a pull_request on Github, which is set up in the file: docker-image.yml however if you want to do this manually, please follow the steps below:

Windows

  • Open a browser and install docker desktop
  • "Windows-Key + R" will show you the 'RUN' box
    • Type "C:\Program Files\Docker\Docker\Docker Desktop.exe" to open docker
  • Open a new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
cd <Path To>/my_awesome_project

docker build -t flask_app:latest .
docker run -p 5000:5000 flask_app

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

systemctl start docker
  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
cd <Path To>/my_awesome_project

docker build -t flask_app:latest .
docker run -it -p 5000:5000 flask_app

AWS Serverless

Note: Still under development

To create and deploy a serverless application, we are using The Serverless Framework, which allows for a zero-friction serverless development, allowing you to easily build apps that auto-scale on low cost, next-gen cloud infrastructure.

The Serverless framework is an open-source tool that provides an easy YAML + CLI development and deployment to AWS, Azure, Google Cloud, Knative & more.

Note: You may need to adjust the default database strings before del=polying as serverless does not support "SQLite" as the function does not keep state.

To update the database strings, please refer to [Config]

Via npm

Windows

  • Open a new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
npm update -g serverless

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
npm update -g serverless

Via terminal/console

Windows

  • Open a browser and install Chocolatey:
  • Open a new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
choco install serverless

Note: If the package does not install, you may need to run the command as an admin.

press the "Windows-Key" type "cmd", "Right-Click" on the word "Command Prompt" and select the option "Run as administrator" and then follow the previous steps again

  • Open a browser and install docker desktop:
  • "Windows-Key + R" will show you the 'RUN' box
    • Type "C:\Program Files\Docker\Docker\Docker Desktop.exe" to open docker
  • Open a new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
serverless

cd <Path To>/my_awesome_project

sls plugin install -n serverless-python-requirements
sls plugin install -n serverless-wsgi

serverless deploy

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
curl -o- -L https://slss.io/install | bash
  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

systemctl start docker

cd <Path To>/my_awesome_project

sls plugin install -n serverless-python-requirements
sls plugin install -n serverless-wsgi

serverless deploy

Digital Ocean

Note: Still under development

Digital Ocean is a platform as a service (PaaS). Develop, manage, and scale your applications on DigitalOcean’s complete cloud platform. Digital Ocean provides you with simple, predictable pricing. Confidently build and release with scalable compute products in the cloud, fully managed databases, highly available and scalable storage options, and more. With virtual machines with a healthy amount of memory tuned to host and scale applications and databases Digital Ocean offers simple solutions for complex issues.

To create and deploy an application to Heroku from the terminal you will need to:

  • Create a droplet
    • Suggested [ubuntu-18-04]
    • Once you see the IP address, you can log in to your Droplet.
      • Make sure you copy/have access to the droplets <ip_address> e.g.: 138.197.67.25
  • Connect with SSH
    • NOTE if you have not connected via SSH you should recieve the password via the email that you registered the account, for Digital Ocean, with.

  • Initial server setup

Windows

  • Open new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
cd <Path To>/<my_awesome_project>/

scp -r <my_awesome_project> root@<ip_address>:/

ssh root@<ip_address>

Where <Path To>/<my_awesome_project>/ is the path to the project you created and where <ip_address> is the droplets <ip_address> e.g.: 138.197.67.25

NOTE: Follow any prompts presended by the ssh such as allowing access from the remote server.

Once you are logged in you should be able to see a terminal with:

root@<droplet_name>:

cd <Path To>/<my_awesome_project>/

chmod +x setup.sh

bash setup.sh

virtualenv venv

source venv/bin/activate

sudo pip install --upgrade pip
sudo pip install --no-cache-dir -r requirements.txt
sudo pip install uwsgi

sudo ufw allow 5000

export FLASK_APP=app

uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

Where 5000 is the port number
and <droplet_name> is the name

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
cd <Path To>/<my_awesome_project>/

scp -r <my_awesome_project> root@<ip_address>:/

ssh root@<ip_address>

Where <Path To>/<my_awesome_project>/ is the path to the project you created and where <ip_address> is the droplets <ip_address> e.g.: 138.197.67.25

NOTE: Follow any prompts presended by the ssh such as allowing access from the remote server.

Once you are logged in you should be able to see a terminal with:

root@<droplet_name>:

cd <Path To>/<my_awesome_project>/

chmod +x setup.sh

bash setup.sh

virtualenv venv

source venv/bin/activate

sudo pip install --upgrade pip
sudo pip install --no-cache-dir -r requirements.txt
sudo pip install uwsgi

sudo ufw allow 5000

export FLASK_APP=app

uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

Where 5000 is the port number
and <droplet_name> is the name

Heroku

Note: Still under development

Heroku is a platform as a service (PaaS). Heroku allows you to start with zero commitment, pay as you go with no lock in. Developers, teams, and businesses of all sizes can use Heroku to deploy, manage, and scale apps. Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you a simple path to delivering apps quickly.

To create and deploy an application to Heroku from the terminal you will need to download and install the Heroku CLI. to verify the installation, you can check the Heroku version from the terminal:

heroku --version

Note: Make sure you have changed your database connection, as Heroku does not suggest using SQLite, since the data may be lost on the files. Heroku does offer a free Postgres Database. see their plans and choose the right plan for you as there are limits on the different plans.

Windows

  • Download the Heroku CLI
  • Open new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
cd <Path To>/my_awesome_project

heroku login
  • Follow the prompts to log into the Heroku system from the CLI
  • Next, create a unique name for your Web app <my_awesome_project-flask-bda-app>, where <my_awesome_project-flask-bda-app> is the name you gave your project.
  • Push your code to Heroku with git
heroku create my_awesome_project-flask-bda-app
git push heroku master

Linux

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
cd <Path To>/my_awesome_project

sudo snap install --classic heroku

heroku login
  • Follow the prompts to log into the Heroku system from the CLI
  • Next, create a unique name for your Web app <my_awesome_project-flask-bda-app>, where <my_awesome_project-flask-bda-app> is the name you gave your project.
  • Push your code to Heroku with git
heroku create my_awesome_project-flask-bda-app
git push heroku master

Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
cd <Path To>/my_awesome_project

brew tap heroku/brew && brew install heroku

heroku login
  • Follow the prompts to log into the Heroku system from the CLI
  • Next, create a unique name for your Web app <my_awesome_project-flask-bda-app>, where <my_awesome_project-flask-bda-app> is the name you gave your project.
  • Push your code to Heroku with git
heroku create my_awesome_project-flask-bda-app
git push heroku master

React Native

For native mobile apps, we are using react-native. Specifically, we use expo as a framework and a platform for universal React applications. It is a set of tools and services built around React Native and native platforms that help you develop, build, deploy, and quickly iterate on iOS, Android, and web apps from the same JavaScript/TypeScript codebase.

We have pre-sett up push notifications, so you don't have to. This means that it is faster and easier for you to get started and up and running. In addition, we are leveraging the default expo-notifications package it allows for a simplified implementation and approach.

Advantages include faster build and testing workflows/processes, remote testing while developing with Over The Air (OTA) updates with changes visible on saving during development.

However, there are some disadvantages and Limitations Expo is aware of these and describes them quite well. We suggest reviewing these limitations before using our pre-built method.

Build one project that runs natively on all your users' devices.

Install Expo

Windows

  • Open new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
cd <Path To>/my_awesome_project_mobile_app

npm install -g expo-cli

npm install

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
cd <Path To>/my_awesome_project_mobile_app

npm install -g expo-cli

npm install

Changing the App URL

Because Flask BDA does not dictate where you should host your website, you will need to tell your Mobile App where to go.

In the quickstart example, we created a project called "My Awesome Project". However, you may have called the project something else. This would have created a folder where the name is all in lower case and stripped out all of the special characters, and replaced spaces with underscores, e.g.: my_awesome_project.

For mobile, we will have automatically created a separate "_mobile_app" folder where the prefix of the folder is your project name, e.g. my_awesome_project_mobile_app. This is to prevent issues with the Serverless configuration package.json and allow you not to deploy all the code for a mobile app onto your web server.

run a local instance on Public URL with ngrok

If you are still in development and/or have not chosen a service provider for hosting yet, you could use: Ngrok to create a temporary public development URL that tunnels to your local environment. Ngrok exposes local servers behind NATs and firewalls to the public internet over secure tunnels. This allows you to demo websites on a public URL and test mobile apps connected to your locally running backend without deploying.

  • Start the local development server by following the Local Environment instructions

  • If you have not registered for ngrok before:

  • If you have already registered but do not have it installed:

  • Once the ngrok terminal is open, create a tunnel from your local server to ngrok

    • create the tunnel to ngrok from the:
      • If you have changed the port number from the default 5000, then replace the number after http to allow the correct tunnel to be created.
ngrok http 5000
  • This should return a randomly generated URL that you can now use for testing, e.g.:
ngrok by @inconshreveable
(Ctrl+C to quit) 
Session Status                online
Session Expires               1 hour, 59 minutes
Version                       2.3.40
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://573d4ec93267.ngrok.io -> http://localhost:5000
Forwarding                    https://573d4ec93267.ngrok.io -> http://localhost:5000

Connections
ttl     opn     rt1     rt5     p50     p90
0       0       0.00    0.00    0.00    0.00

Note: the free version only keeps this server alive for 2 hours, so you may need to follow this process in the future, and if you push this URL to your "Repo", it may not work for the next person.

Update the mobile App URL

  • Open the Mobile App folder my_awesome_project_mobile_app
    • Once open, select the app.json file and edit line 2 "server_base_url": "https://github.com/RyanJulyan/Flask-BDA" by replacing https://github.com/RyanJulyan/Flask-BDA with your own server name.

Run App

Once you have the app installed on your phone, you can start a development server on your local machine.

Windows

  • Open new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
cd <Path To>/my_awesome_project_mobile_app

expo start

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
cd <Path To>/my_awesome_project_mobile_app

expo start

This will open a webpage with a QR code on it. This will allow you to use the Expo app if you are on Android or use the camera if you are on iOS to scan the code and open your app directly from the development server.

Note: if you wish for people not on your network to be able to scan and test the App remotely, press the tunnel tab button above the QR code.

Deploying to stores

Part of the recommendations is to ensure that images are optimized. To do this expo has recommended the expo-optimize package which can assist with optimizing images. In addition, optimizing images can improve your native app TTI (or time-to-interaction), which means less time on splash screens and quicker delivery over poor network connections.

Windows

  • Open new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
cd <Path To>/my_awesome_project_mobile_app

npm install -g sharp-cli

npx expo-optimize --quality 0.9

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
cd <Path To>/my_awesome_project_mobile_app

npm install -g sharp-cli

npx expo-optimize --quality 0.9

Desktop Native

To create and develop a desktop application, we are using flaskwebgui. A tool for creating and running your flask web application in a chrome wrapper. To distribute the desktop application, we are using PyInstaller. PyInstaller freezes (packages) Python applications into stand-alone executables under Windows, GNU/Linux, Mac OS X, FreeBSD, Solaris and AIX.

Each deployment needs to be created on the specific platform that you wish to run it. We have created scripts that will allow you to manage these deployments by placing the build and dist folders into parent folders for the respective platform. These folders will be prefixed with desktop_ followed by the platform. This is done purely to allow you to manage the distribution and build processes for the specific platforms and not overwrite them when building on different platforms.

To allow for the export to desktop to work correctly, we require some code changes. By default, Flask-BDA is intended for web and mobile development, and we have implemented a rate-limiter on the site. Unfortunately, you require a server to rate limit, and since you are exporting the system to a desktop application, it is not running a server.

as such, you need to remove all references to the limiter. These can be found at app/__init__.py. To do this, open the file in a text editor and comment out the following lines:

# from flask_limiter import Limiter
# from flask_limiter.util import get_remote_address

# limiter = Limiter(
#     app,
#     key_func=get_remote_address,
#     default_limits=app.config['DEFAULT_LIMITS']
# )

Note: if you added a custom limiter, search for @limiter.limit, which would be found in your controllers. You will need to comment out all of those references and the import references, e.g.: from app import limiter

This will allow you to export the application as a desktop executable file without errors.

Windows

  • Open new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
      • You may need to run "cmd" as administrator to run pip install --upgrade pip
        • To do this, you can search for "cmd" in your windows search
        • Right-click on the icon, and click on the "Run as administrator" option
          • You may need to navigate to your project when running as administrator cd <Path To>/my_awesome_project
cd <Path To>/my_awesome_project

pip install --upgrade pip
pip install virtualenv
virtualenv venv

venv\Scripts\activate

pip install --upgrade pip
pip install --no-cache-dir -r requirements.txt

python create_desktop_installer_windows.py

Linux

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
      • You may need to run "cmd" as administrator to run pip install --upgrade pip
        • To do this, you run the command as sudo eg: sudo pip install --upgrade pip
cd <Path To>/my_awesome_project

pip install --upgrade pip
pip install virtualenv
virtualenv venv

source venv/bin/activate

pip install --upgrade pip
pip install --no-cache-dir -r requirements.txt

python create_desktop_installer_lunix.py

Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
      • You may need to run "cmd" as administrator to run pip install --upgrade pip
        • To do this, you run the command as sudo eg: sudo pip install --upgrade pip
cd <Path To>/my_awesome_project

pip install --upgrade pip
pip install virtualenv
virtualenv venv

source venv/bin/activate

pip install --upgrade pip
pip install --no-cache-dir -r requirements.txt

python create_desktop_installer_mac.py

This will open a maximized window that will run like a normal desktop application. This will use the locally installed chrome browser to serve the content.

By default, this application will be served on port 7000. However, you can edit the port in the run_desktop.py file if that conflicts with any existing applications.

Installing Additional Python Packages

If you include additional python packages in your project, don't forget to run pip freeze from your terminal to ensure you get the correct packages for your deployments

pip freeze > requirements.txt

Note: It is suggested that you install and freeze Additional Python Packages from a virtual environment rather than globally. This keeps your requirements.txt small and limited to the packages you are using in your specific project.

OpenAPI/Swagger API

Flask BDA uses SwaggerUI by default to assist and present the API to a user/client.

SwaggerUI allows anyone — be it your development team or your end consumers — to visualize and interact with the API’s resources without having any of the implementation logic in place. Instead, it’s automatically generated from your OpenAPI (formerly known as Swagger) Specification, with visual documentation making it easy for back-end implementation and client-side consumption.

To Access the SwaggerUI:

Import API to Postman

Many developers will prefer Postman over SwaggerUI to test and integrate APIs with their code. We have assisted by providing a direct collection export for Postman.

To import the collection on Postman:

  • Ensure you have downloaded and installed Postman
  • Once installed, click on 'file' (on the top left of the application menu bar)
  • Choose Import... (CTRL+O)
  • Select Link from the Tabs
  • Insert the URL <base_URL>/api/postman eg: http://localhost:5000/api/postman
  • Press Continue
  • This will show you the name of the API as defined in the API config
  • Review and click Import

This will import a postman collection which will become available on the left-hand side as a folder (with subfolders from each of the endpoints you created).

You can generate code for many different lanuages and frameworks using Postman. These Languages include but are not limited to:

  • C
  • C#
  • Go
  • Java
  • Javascript
  • Node
  • PHP
  • Python
  • Powershell
  • Ruby
  • Swift

Allowing you to integrate your newly created API with existing projects

External API Requests

Sometimes, you need to make external requests (e.g. to an external API). You could approach this using Ajax Requests, but sometimes you need to make these requests from the server-side, for example, if you want to update currency conversions automatically. When you want to access external APIs through the server, you do not want to rely on a user actively being on the webpage to send the command. Instead, you want the server to be able to activate this comment. To achieve this, we use the requests module.

  • The structure of a request is:
import requests

requests.methodname(params)

Get Request Method

import requests

params = {"model": "Mustang"}

x = requests.get('https://w3schools.com/python/demopage.php', params = params)
print(x.status_code)
print(x.text)

Post Request Method

import requests

data = {"Name":"Example"}
headers = {"Authorization": "Bearer <token>"}

x = requests.post('https://w3schools.com/python/demopage.php', data = data, headers = headers)
print(x.status_code)
print(x.text)

Post JSON Request Method

import requests
import json

data = {"Name":"Example"}
headers = {"Authorization": "Bearer <token>"}

x = requests.post('https://w3schools.com/python/demopage.php', json = data, headers = headers)
print(x.status_code)
print(x.text)

# use this to load JSON returned as a python dictionary
return_data = json.loads(x.text)

Put Request Method

import requests

data = {"Name":"Example"}
headers = {"Authorization": "Bearer <token>"}

x = requests.put('https://w3schools.com/python/demopage.php', data = data, headers = headers)
print(x.status_code)
print(x.text)

Put JSON Request Method

import requests
import json

data = {"Name":"Example"}
headers = {"Authorization": "Bearer <token>"}

x = requests.put('https://w3schools.com/python/demopage.php', json = data, headers = headers)
print(x.status_code)
print(x.text)

# use this to load JSON returned as a python dictionary
return_data = json.loads(x.text)

Delete Request Method

import requests

x = requests.delete('https://w3schools.com/python/demopage.php')
print(x.status_code)
print(x.text)

Ajax Requests

Ajax requests, typically an HTTP request made by (browser-client) in Javascript that uses XML/JSON to request data and/or response data from either an internal or external system. Ajax requests are made using </> htmx by default.

htmx is a dependency-free library that allows you to access AJAX, CSS Transitions, WebSockets, and Server-Sent Events directly in HTML, using attributes so that you can build modern user interfaces with the simplicity and power of hypertext. For details on how to use htmx, please refer to the docs and for a full reference on the functionality, please refer to https://htmx.org/reference/

You can use htmx to implement many common UX patterns, such as Active Search:

<input type="text" name="q" 
    hx-get="/trigger_delay" 
    hx-trigger="keyup changed delay:500ms" 
    hx-target="#search-results" 
    placeholder="Search..."/>

<div id="search-results"></div>

This input named q will issue a request to /trigger_delay 500 milliseconds after a key-up event if the input has been changed and inserts the results into the div with the id search-results.

End-to-End Encryption

Despite the advantages of symmetric encryption, there is a flaw in this method that allows unauthorized individuals to access a message's secret keys.

One of the most effective ways to prevent unauthorized access to a message's secret keys is by implementing a one-way function like the Diffie-Hellman algorithm. This method only allows the sender and receiver to decrypt the message.

One-way functions are typically implemented using a type of algorithm that allows them to calculate an output for every input received. However, this method is not feasible to derive the exact result from a random key.

Testing

Testing is a vital part of ensuring a project runs successfully

There are 3 aspects of testing provided in Flask BDA:

  • CI/CD through Github actions workflow which is already set up to implement but can also be used independently from GitHub:
    • Python flake8 code linting.
      • It displays the warnings in a per-file, merged output. Flake8 is a wrapper around these tools:
        • PyFlakes
        • pycodestyle
        • Ned Batchelder’s McCabe script
    • Python unittest originally inspired by JUnit and has a similar flavour as major unit testing frameworks in other languages.

Python flake8

Note: To manually run Python unittest, ensure that you have installed the local environements

Windows

  • Open new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
cd <Path To>/my_awesome_project

venv\Scripts\activate

flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=11 --max-line-length=127 --statistics

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
cd <Path To>/my_awesome_project

source venv/bin/activate

flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

Python unittest

Note: To manually run Python unittest, ensure that you have installed the local environements

Windows

  • Open new terminal
    • "Windows-Key + R" will show you the 'RUN' box
    • Type "cmd" to open the terminal
cd <Path To>/my_awesome_project

venv\Scripts\activate

python -m unittest discover

Linux / Mac

  • Open new terminal
    • "Control + Option + Shift + T" to open the terminal
cd <Path To>/my_awesome_project

venv/bin/activate

python -m unittest discover

Features List

  • Single file run and setup

  • Starter flask project, which builds a project folder structure with

    • Flask microframework
      • Quick and easy
      • Ability to scale up
      • One of the most popular Python web application frameworks.
      • Doesn't enforce any dependencies or project layout.
    • Progressive Web App (PWA) to make it more friendly towards desktop and allow native installs from the web, cache for offline support, page sharing and push notifications, etc.
    • Responsive layouts
    • Mobile-specific views through Flask-Mobility
      • Responsive bottom menu for tablet and mobile devices
        • Centered for tablet at under 992px
        • Centered for mobile at under 500px
        • Badges for notifications are included to allow for driving user behaviour
      • Controllers use the @mobile_template decorator, allowing template views to be tailored for a better mobile experience if needed.
      • Mobile view identification meaning specific mobile logic, can be added with {% if request.MOBILE %}True{% else %}False{% endif %}
    • SEO ready page index template file
    • Isolated module code and templates
    • Configuration file config.py for quick access and management of the environment and environment variables and default SEO
    • Debugging built-in and accessible through the Configuration file config.py
    • A Landing page with a call to action and features
    • A 403 page which all forbidden pages go to
    • A 404 page which all unknown pages go to
    • .gitignore files with defaults
    • Testing with Python flake8 Linting and Test cases Python unittest
    • CI/CD through Github actions workflow
    • Can run in any cloud or your data centre.
    • Great UI by default with AdminLTE specifically v3
      • Highly customizable and flexible
      • Pre-setup via CDN
      • Versatile
      • Widely used and easy to pick up as it is based on Bootstrap 4.6
  • Create custom module files and folders that fit into the flask project structure from the create_module.py file with prompts to create the following:

    • Model
      • Dynamically create a table data model
    • Web Controller
      • Public
        • public_list
      • Admin
        • index
        • create
        • store
        • show
        • edit
        • update
        • destroy
    • API Controller
      • ListResource
        • get
        • post
      • Resource
        • get
        • update
        • delete
    • Forms
    • SQLAlchemy Events. Pre-configured before and after changes on a data model event listeners for:
      • Insert
      • Update
      • Delete
    • URL's (prefixed by the module name and replace 'xyz' with the module name in the below details)
      • Web Routes:
        • Public
          • View ../xyz/ [list elements] public_list
        • Admin
          • View ../admin/xyz/ [list elements] index
          • View ../admin/xyz/create [single element] create
          • POST URL ../admin/xyz/store [single element] store
          • View ../admin/xyz/show/{id} [single element] show
          • View ../admin/xyz/edit/{id} [single element] edit
          • PUT URL ../admin/xyz/update/{id} [single element]update
          • DELETE URL ../admin/xyz/destroy/{id} [single element] destroy
      • API Routes:
        • GET URL ../api/xyz [list elements] get
        • POST URL ../api/xyz [single element] post
        • GET URL ../api/xyz/{id} [single element] get
        • PUT URL ../api/xyz/{id} [single element] update
        • DELETE URL ../api/xyz/{id} [single element]delete
        • POST URL ../api/xyz/bulk [multiple elements] post
        • PUT URL ../api/xyz/bulk [multiple elements] update
        • GET URL ../api/xyz/aggregate [single return, of multiple elements aggregated] get
    • Views for:
      • Public
        • public_list.html (list elements)
      • Admin
        • index.html (list elements)
        • create.html (single element form)
        • show.html (single element)
        • edit.html (single element form)
      • API
        • api/docs (URL)
  • Browser Support (last 1 major version not dead)

    • Chrome >= 45
    • Firefox >= 38
    • Edge >= 12
    • Explorer >= 10
    • iOS >= 9
    • Safari >= 9
    • Android >= 4.4
    • Opera >= 30

Project Structure

└── `project_name`
       ├── .github
       │    └── workflows
       │          ├── docker-image.yml
       │          └── run_tests.yml
       ├── app
       │    ├── generated_config
       │    │     ├── model_editor
       │    │     └── models
       │    │           ├── hierarchies
       │    │           │   └── models.json
       │    │           └── organisations
       │    │               └── models.json
       │    ├── mod_audit
       │    │     ├── __init__.py
       │    │     ├── controllers.py
       │    │     └── models.py
       │    ├── mod_users
       │    │     ├── templates
       │    │     │     ├── mobile
       │    │     │     │    └── auth
       │    │     │     │         ├── admin
       │    │     │     │         │    ├── create.html
       │    │     │     │         │    ├── edit.html
       │    │     │     │         │    ├── index.html
       │    │     │     │         │    └── show.html
       │    │     │     │         └── public
       │    │     │     │              └── public_list.html
       │    │     │     ├── email
       │    │     │     │    ├── activate.html
       │    │     │     │    └── reset.html
       │    │     │     └── users
       │    │     │          ├── admin
       │    │     │          │    ├── create.html
       │    │     │          │    ├── edit.html
       │    │     │          │    ├── index.html
       │    │     │          │    └── show.html
       │    │     │          └── public
       │    │     │               └── public_list.html
       │    │     ├── __init__.py
       │    │     ├── controllers.py
       │    │     ├── forms.py
       │    │     └── models.py
       │    ├── mod_email
       │    │     ├── __init__.py
       │    │     ├── controllers.py
       │    │     └── models.py
       │    ├── mod_file_upload
       │    │     ├── templates
       │    │     │    └── file_upload
       │    │     │         └── upload.html
       │    │     ├── __init__.py
       │    │     ├── controllers.py
       │    │     ├── forms.py
       │    │     └── models.py
       │    ├── static
       │    │     ├── css
       │    │     ├── images
       │    │     ├── js
       │    │     ├── manifest.json
       │    │     └── sw.js
       │    ├── templates
       │    │     ├── admin
       │    │     │     └── index.html
       │    │     ├── email
       │    │     │     └── auth
       │    │     │         ├── activate.html
       │    │     │         └── reset.html
       │    │     ├── mobile
       │    │     ├── public
       │    │     │     └── index.html
       │    │     ├── 403.html
       │    │     ├── 404.html
       │    │     └── index.html
       │    └── __init__.py
       ├── create_module_template
       │    ├── generated_config
       │    │     └── models
       │    │          └── xyz
       │    │               └── models.json
       │    └── mod_xyz
       │          ├── templates
       │          │     ├── mobile
       │          │     │    └── xyz
       │          │     │         ├── admin
       │          │     │         │    ├── create.html
       │          │     │         │    ├── edit.html
       │          │     │         │    ├── index.html
       │          │     │         │    └── show.html
       │          │     │         └── public
       │          │     │              └── public_list.html
       │          │     └── xyz
       │          │          ├── admin
       │          │          │    ├── create.html
       │          │          │    ├── edit.html
       │          │          │    ├── index.html
       │          │          │    └── show.html
       │          │          └── public
       │          │               └── public_list.html
       │          ├── api_controllers.py
       │          ├── controllers.py
       │          ├── forms.py
       │          └── models.py
       ├── databases
       │    └── sqlite
       │          ├── core.db
       │          └── default.db
       ├── .dockerignore
       ├── .gitignore
       ├── config.py
       ├── create_all_models_json.py
       ├── create_desktop_installer_lunix.py
       ├── create_desktop_installer_mac.py
       ├── create_desktop_installer_windows.py
       ├── create_module.py
       ├── create_module_json.py
       ├── Dockerfile
       ├── FLASK-BDA LICENSE
       ├── LICENSE
       ├── package.json
       ├── package-lock.json
       ├── Procfile
       ├── README.md
       ├── requirements.txt
       ├── run.py
       ├── run_desktop.py
       ├── run_shared_server.py
       └── serverless.yml

Glossary

Modules

Introduction

A module is a part of a program. Programs are composed of one or more independently developed modules that, when combined, create the program.

A module is a self-contained component, making it easier to manage as the program grows.

Modules in Flask-BDA help you create: a Data Model, Routes, and associated functions for controlling the logic and Views

Controllers:

Introduction

Controllers can group related request handling logic into a single class. For example, a UserController class might handle all incoming requests related to users, including showing, creating, updating, and deleting users.

CRUD

Definition

Create, Read, Update, and Delete ("CRUD")

Linting

Definition

Linting is the automated checking of your source code for programmatic and stylistic errors. This is done by using a lint tool (otherwise known as linter). A lint tool is a basic static code analyzer.

lint, or a linter, is a static code analysis tool used to flag programming errors, bugs, stylistic errors, and suspicious constructs.

Unit Testing

Definition

In computer programming, unit testing is a software testing method by which individual units of source code—sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures—are tested to determine whether they are fit for use.

Low-code platform

Definition

A low-code development platform provides a development environment to create application software through programmatic or graphical user interfaces and configurations instead of traditional hand-coded computer programming.


How can I help?

We would be delighted if you contributed to the project in one or all of these ways:

  • Talking about Emmett with friends and on the web
  • Adding issues and features requests here on GitHub
  • Participating in discussions about new features and issues here on GitHub
  • Improving the documentation
  • Forking the project and writing beautiful code

License

Python 3

View license information for Python 3. (https://docs.python.org/3.8/license.html) and other legal agreements (https://www.python.org/about/legal/)


Docker

View license information for Docker. (https://www.docker.com/legal/components-licenses) and other legal agreements (https://www.docker.com/legal)

As with all Docker images, these likely also contain other software which may be under other licenses (such as Bash, etc., from the base distribution, along with any direct or indirect dependencies of the primary software being contained).

Some additional license information that could be auto-detected might be found in the repo-info repository's python/ directory.

As for any pre-built image usage, the image user's responsibility is to ensure that any use of this image complies with any relevant licenses for all software contained within.


Serverless Framework

View license information for Serverless Framework and other legal agreements (https://app.serverless.com/legal/terms).

It is the user's responsibility to ensure that adhere to the Acceptable Use Policy (https://app.serverless.com/legal/aup)


Expo Framework

View license information for the Expo Framework and other legal agreements (https://github.com/expo/expo/blob/master/LICENSE).


The Flask-BDA License

Flask-BDA is created and distributed under the developer-friendly Flask-BDA License. The Flask-BDA License is derived from the popular Apache 2.0 license.

The Flask-BDA License is the legal requirement for you or your company to use and distribute Flask-BDA and derivative works such as the applications you make with it. Your application or project can have a different license, but it still needs to comply with the original one.

The license grants you the following permissions:

  • You are free to commercialize any software created using original or modified (derivative) versions of Flask-BDA
  • You are free to commercialize any plugin, extension, or tool created for use with Flask-BDA
  • You are free to modify Flask-BDA, and you are not required to share the changes
  • You are free to distribute original or modified (derivative) versions of Flask-BDA
  • You are given a license to any patent that covers Flask-BDA

The license prevents you from doing the following:

  • You can not commercialize original or modified (derivative) versions of the Flask-BDA editor, creator and/or engine
  • You can not hold Flask-BDA or Ryan Julyan liable for damages caused by the use of Flask-BDA
  • You can not bring any warranty claims to Flask-BDA or Ryan Julyan
  • You can not use the Flask-BDA trademark unless express permission has been given (see exceptions and additional information) The license requires that you do the following:
    • You must include the Flask-BDA license and copyright notice in any work you create
    • You must state significant changes made to Flask-BDA

License and copyright notice inclusion

The Flask-BDA License requires that you must include the license and copyright notice with all copies of Flask-BDA and in any derived work created using Flask-BDA. It is up to you to decide how you wish to distribute the license and notice. Below are some examples of how this can be done:

  • Show the license and notice at the end of a credits screen if your application has one
  • Show the license and notice from a dedicated license screen or popup in your application
  • Print the license and notice to an output log when your application starts
  • Put the license and notice in a text file and include it with the distribution of your application
  • Put the license and notice in a printed manual included with your application

Copyright 2021 Flask-BDA, Ryan Julyan Licensed under the Flask-BDA License version 0.1 (the "License"); you may not use Flask-BDA except in compliance with the License. You may obtain a copy of the License, at https://github.com/RyanJulyan/Flask-BDA/blob/main/LICENSE Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.