### Setup Development Environment
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/CONTRIBUTING.rst
Create a virtual environment, activate it, and install development dependencies.
```bash
$ python -m venv venv
$ source venv/bin/activate
$ pip install -r requirements/base.txt -r requirements/dev.txt -r requirements/extra.txt
```
--------------------------------
### Install Flask-AppBuilder
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/oauth/README.rst
Install the Flask-AppBuilder library using pip.
```bash
pip install flask-appbuilder
```
--------------------------------
### Install Flask-AppBuilder with Pip
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/installation.md
Use this command for a simple installation of the Flask-AppBuilder framework.
```bash
$ pip install flask-appbuilder
```
--------------------------------
### Install Flask-AppBuilder and Clone Skeleton
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/simpleform/README.rst
Use pip to install the Flask-AppBuilder library and git to clone the skeleton project repository.
```bash
pip install flask-appbuilder
git clone https://github.com/dpgaspar/Flask-AppBuilder-Skeleton.git
```
--------------------------------
### Run Flask Application
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/related_fields/README.rst
Start the Flask development server.
```bash
flask run
```
--------------------------------
### Setup Minimal Flask-AppBuilder Application
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/quickminimal.md
This code initializes a Flask application, configures it for Flask-AppBuilder with SQLite, sets up security features, and runs the development server. It's the most basic setup for a running application.
```python
import os
from flask import Flask
from flask_appbuilder import SQLA, AppBuilder
# init Flask
app = Flask(__name__)
# Basic config with security for forms and session cookie
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'app.db')
app.config['CSRF_ENABLED'] = True
app.config['SECRET_KEY'] = 'thisismyscretkey'
# Init SQLAlchemy
db = SQLA(app)
# Init F.A.B.
appbuilder = AppBuilder(app, db.session)
# Run the development server
app.run(host='0.0.0.0', port=8080, debug=True)
```
--------------------------------
### Install Virtualenv with EasyInstall
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/installation.md
Installs the virtualenv tool using easy_install. This is a prerequisite for creating isolated Python environments.
```bash
$ sudo easy_install virtualenv
```
--------------------------------
### Get Item Response with Specific Columns
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example response when fetching only 'name' and 'address'.
```json
{
"description_columns": {},
"id": "1",
"show_columns": [
"name",
"address"
],
"show_title": "Show Contact",
"label_columns": {
"address": "Address",
"name": "Name"
},
"result": {
"address": "Street phoung",
"name": "Wilko Kamboh"
}
}
```
--------------------------------
### Run Flask Application
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/base_filters/README.rst
Start the Flask development server to run the application.
```bash
$ flask run
```
--------------------------------
### Example Read Only Role Configuration
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/security.md
An example of a 'ReadOnly' role configuration using regex for broad access to list and show actions across views/APIs, and menu access.
```python
FAB_ROLES = {
"ReadOnly": [
=".*", "can_list"],
=".*", "can_show"],
=".*", "menu_access"],
=".*", "can_get"],
=".*", "can_info"]
]
}
```
--------------------------------
### Start Postgres with Docker Compose
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/CONTRIBUTING.rst
Use docker-compose to start a PostgreSQL database in detached mode.
```bash
$ docker-compose up -d
```
--------------------------------
### Clone Flask-AppBuilder Skeleton
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/oauth/README.rst
Clone the Flask-AppBuilder skeleton repository to get started with a sample application.
```bash
git clone https://github.com/dpgaspar/Flask-AppBuilder-Skeleton.git
```
--------------------------------
### AddOn Manager Example
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/addons.md
A simple example of an AddOn manager class that subclasses BaseManager. It demonstrates overriding the constructor, registering views, and pre/post processing hooks.
```python
import logging
from flask_appbuilder.basemanager import BaseManager
from flask_babel import lazy_gettext as _
from .model import MyModel
from .views import FirstModelView1
log = logging.getLogger(__name__)
class FirstAddOnManager(BaseManager):
def __init__(self, appbuilder):
"""
Use the constructor to setup any config keys specific for your app.
"""
super(FirstAddOnManager, self).__init__(appbuilder)
def register_views(self):
"""
This method is called by AppBuilder when initializing, use it to add you views
"""
self.appbuilder.add_view(FirstModelView1, "First View1",icon = "fa-user",category = "First AddOn")
def pre_process(self):
stuff = self.appbuilder.get_session.query(MyModel).filter(name == 'something').all()
# process stuff
def post_process(self):
pass
```
--------------------------------
### Get Item Response with Label Columns
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example response when fetching only 'label_columns' meta data.
```json
{
"id": "1",
"label_columns": {
"address": "Address",
"name": "Name"
},
"result": {
"address": "Street phoung",
"name": "Wilko Kamboh"
}
}
```
--------------------------------
### Custom List Widget Example
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/templates.md
Implement a custom list widget by extending `base_list.html`. This example adds a custom button in the `list_header` and custom rendering logic within `begin_loop_values` to display item details and action buttons.
```html
{% import 'appbuilder/general/lib.html' as lib %}
{% extends 'appbuilder/general/widgets/base_list.html' %}
{% block list_header %}
{{ super() }}
{% endblock %}
{% block begin_loop_values %}
{% for item in value_columns %}
{% set pk = pks[loop.index-1] %}
{% if actions %}
{% endif %}
{% if can_show or can_edit or can_delete %}
{{ lib.btn_crud(can_show, can_edit, can_delete, pk, modelview_name, filters) }}
{% endif %}
{% for value in include_columns %}
{% endfor %}
{% endfor %}
{% endblock %}
```
--------------------------------
### GET /error
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
An example endpoint demonstrating how to trigger a 500 Internal Server Error, utilizing predefined response components.
```APIDOC
## GET /error
### Description
This endpoint is designed to intentionally raise an exception, resulting in a 500 Internal Server Error.
### Method
GET
### Endpoint
/error
### Response
#### Error Response (500)
- **$ref**: '#/components/responses/500' - References a predefined 500 error response structure.
```
--------------------------------
### Run Flask Development Server
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/views.md
Command to start the Flask development server. Ensure the FLASK_APP environment variable is set to your application's entry point.
```bash
$ export FLASK_APP=app
$ flask run
```
--------------------------------
### Install Virtualenv on Debian/Ubuntu
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/installation.md
Installs the virtualenv package using the apt-get package manager on Debian-based systems like Ubuntu.
```bash
$ sudo apt-get install python-virtualenv
```
--------------------------------
### Install Pillow for Image Handling
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/installation.md
Installs the Pillow library, which is required for image processing and upload functionalities within Flask-AppBuilder.
```bash
pip install Pillow
```
--------------------------------
### Install Virtualenv with Pip
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/installation.md
Installs the virtualenv tool using pip. This is an alternative method for setting up isolated Python environments.
```bash
$ sudo pip install virtualenv
```
--------------------------------
### Get Help for a Specific FAB Command
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/cli.md
Access detailed help for any Flask-AppBuilder command, such as 'create-app', by appending the --help flag.
```bash
$ flask fab create-app --help
```
--------------------------------
### Create a Basic Custom View
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/views.md
Define a custom view by inheriting from BaseView and decorating methods with @expose. This example shows how to create two public methods with different routing parameters.
```python
from flask_appbuilder import AppBuilder, expose, BaseView
from app import appbuilder
class MyView(BaseView):
route_base = "/myview"
@expose('/method1/')
def method1(self, param1):
# do something with param1
# and return it
return param1
@expose('/method2/')
def method2(self, param1):
# do something with param1
# and render it
param1 = 'Hello %s' % (param1)
return param1
appbuilder.add_view_no_menu(MyView())
```
--------------------------------
### Panel Begin Macro
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/flask_appbuilder/templates/appbuilder/general/lib.html
Starts a UI panel with a given title and optional extra CSS classes. This macro is a structural element for organizing content.
```html
{% macro panel_begin(title, extra_class="") %} {% endmacro %}
```
--------------------------------
### Install AddOn using pip
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/addons.md
Install a developed AddOn into your Flask-AppBuilder project using pip, assuming the AddOn has been packaged and published to PyPI.
```bash
$ pip install fab_addon_audit
```
--------------------------------
### Rison for Fetching Permissions
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
An example of a Rison query to fetch only the 'permissions' meta data from the _info endpoint.
```json
(keys:!(permissions))
```
--------------------------------
### OAuth Remote App Configurations
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/security.md
Configuration examples for various OAuth providers including Keycloak, Azure, and Authentik. Ensure to replace placeholder values with your actual credentials and domain information.
```python
{
"token_key": "access_token",
"remote_app": {
"client_id": "KEYCLOAK_CLIENT_ID",
"client_secret": "KEYCLOAK_CLIENT_SECRET",
"api_base_url": "https://KEYCLOAK_DOMAIN/auth/realms/master/protocol/openid-connect",
"client_kwargs": {
"scope": "email profile"
},
"access_token_url": "KEYCLOAK_DOMAIN/auth/realms/master/protocol/openid-connect/token",
"authorize_url": "KEYCLOAK_DOMAIN/auth/realms/master/protocol/openid-connect/auth",
"request_token_url": None,
},
},
{
"name": "azure",
"icon": "fa-windows",
"token_key": "access_token",
"remote_app": {
"client_id": "AZURE_APPLICATION_ID",
"client_secret": "AZURE_SECRET",
"api_base_url": "https://login.microsoftonline.com/AZURE_TENANT_ID/oauth2",
"client_kwargs": {
"scope": "User.read name preferred_username email profile upn",
"resource": "AZURE_APPLICATION_ID",
# Recommended: verify Azure JWT signature
"verify_signature": True
},
"request_token_url": None,
"access_token_url": "https://login.microsoftonline.com/AZURE_TENANT_ID/oauth2/token",
"authorize_url": "https://login.microsoftonline.com/AZURE_TENANT_ID/oauth2/authorize",
},
},
{
"name": "authentik",
"token_key": "access_token",
"icon": "fa-fingerprint",
"remote_app": {
"api_base_url": "https://authentik.mydomain.com",
"client_kwargs": {
"scope": "email profile",
"verify_signature": True,
},
"access_token_url": (
"https://authentik.mydomain.com/application/o/token/"
),
"authorize_url": (
"https://authentik.mydomain.com/application/o/authorize/"
),
"request_token_url": None,
"client_id": "CLIENT_ID",
"client_secret": "CLIENT_SECRET",
'jwks_uri': 'https://authentik.mydomain.com/application/o/APPLICATION_NAME/jwks/',
},
},
]
```
--------------------------------
### Run Flask Development Server
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/installation.md
Starts the Flask development server to run your application. The application will typically be accessible at http://localhost:8080.
```bash
(venv)$ flask run
```
--------------------------------
### Run Flask-AppBuilder Development Server
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/productsale/README.rst
Execute this command to start the built-in development server for your Flask-AppBuilder application. This is useful for local development and testing.
```bash
$ fabmanager run
```
--------------------------------
### Create Tag via API
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example of creating a new tag using a POST request to the tag API endpoint.
```bash
$ curl -XPOST http://localhost:8080/api/v1/tag/ -d \
$ '{"name": "T1"}' \
$ -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN"
```
```bash
$ curl -XPOST http://localhost:8080/api/v1/tag/ -d \
$ '{"name": "T2"}' \
$ -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN"
```
--------------------------------
### Create Contact with Tags via API
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example of creating a new contact and associating existing tags using a POST request to the contact API endpoint.
```bash
$ curl -XPOST http://localhost:8080/api/v1/contact/ -d \
$ '{"name": "C1", "contact_group": 1, "gender": 1, "tags": [1, 2]}' \
$ -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN"
```
--------------------------------
### Model Inheritance Change
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/versionmigration.md
Example showing the inheritance structure for models. No change is indicated in the provided snippet.
```python
class MyModel(Model):
id = Column(Integer, primary_key=True)
first_name = Column(String(64), nullable=False)
```
--------------------------------
### Fetch Label Columns using Rison
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example of using Rison to fetch only 'label_columns' meta data along with 'name' and 'address'.
```rison
(columns:!(name,address),keys:!(label_columns))
```
--------------------------------
### Initialize Flask-Talisman
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/security.md
Initialize Flask-Talisman with your Flask application. This setup is required to enable security features like CSP nonces.
```python
from flask import Flask
from flask_appbuilder import AppBuilder
from flask_talisman import Talisman
app = Flask(__name__)
app.config.from_object('config')
db = SQLA(app)
appbuilder = AppBuilder(app, db.session)
Talisman(app)
```
--------------------------------
### Curl Command to Fetch Label Columns
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example curl command to fetch 'label_columns' meta data along with 'name' and 'address'.
```bash
curl 'http://localhost:8080/api/v1/contact/1?q=(columns:!(name,address),keys:!(label_columns))' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN"
```
--------------------------------
### GET /greeting4 with Rison arguments
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Demonstrates integrating Rison arguments and JSON schema for parameter validation in an OpenAPI specification.
```APIDOC
## GET /greeting4
### Description
This endpoint accepts Rison arguments, validates them against a defined schema, and returns a personalized greeting.
### Method
GET
### Endpoint
/greeting4
### Parameters
#### Query Parameters
- **greeting_schema** (object) - Required - Defines the schema for Rison arguments, including a 'name' property.
### Response
#### Success Response (200)
- **message** (string) - A personalized greeting message.
### Response Example
```json
{
"message": "Hello John Doe"
}
```
```
--------------------------------
### Curl Request to Fetch Permissions and Add Form Fields
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example cURL command to fetch both permissions and add_columns meta data from the _info endpoint.
```bash
$ curl 'http://localhost:8080/api/v1/group/_info?q=(keys:!(permissions,add_columns))' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN"
```
--------------------------------
### Get Item Response with No Meta Data
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example response when all meta data is discarded.
```json
{
"id": "1",
"result": {
"address": "Street phoung",
"name": "Wilko Kamboh"
}
}
```
--------------------------------
### Customize Class and Method Permissions
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/security.md
Combine `class_permission_name` and `method_permission_name` to achieve granular control over generated permissions. This example aggregates all methods under the 'access' permission.
```python
class OneApi(ModelRestApi):
datamodel = SQLAInterface(Contact)
class_permission_name = "api"
method_permission_name = {
"get_list": "access",
"get": "access",
"post": "access",
"put": "access",
"delete": "access",
"info": "access"
}
class TwoApi(ModelRestApi):
datamodel = SQLAInterface(Contact)
class_permission_name = "api"
method_permission_name = {
"get_list": "access",
"get": "access",
"post": "access",
"put": "access",
"delete": "access",
"info": "access"
}
```
--------------------------------
### Run Development Server (0.6.X to 0.7.X)
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/versionmigration.md
After performing database migrations, run your development server using this command.
```bash
python run.py
```
--------------------------------
### Initialize Translation Catalogs
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/i18n.md
Use these commands to initialize translation catalogs for different languages (e.g., Portuguese, Spanish, German). This creates the necessary directory structure and initial .po files.
```bash
pybabel init -i ./babel/messages.pot -d app/translations -l pt
pybabel init -i ./babel/messages.pot -d app/translations -l es
pybabel init -i ./babel/messages.pot -d app/translations -l de
```
--------------------------------
### Run Simple Employees Application
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/employees/README.rst
Set the FLASK_APP environment variable, create an admin user, and run the Flask development server.
```bash
export FLASK_APP=app/__init__.py
flask fab create-admin
flask run
```
--------------------------------
### Custom Query for Related Fields (Multiple Filters)
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/advanced.md
Apply multiple custom filters to related fields. This example filters 'group' by 'name' starting with 'W' and 'gender' by 'name' starting with 'M'.
```python
class ContactModelView(ModelView):
datamodel = SQLAInterface(Contact)
add_form_query_rel_fields = {
'group': [['name', FilterStartsWith, 'W']],
'gender': [['name', FilterStartsWith, 'M']]
}
```
--------------------------------
### Simplified fab create-app Command
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/versionmigration.md
The `--engine SQLAlchemy` parameter is removed in v5.x. SQLAlchemy is now the default and only supported engine.
```bash
fab create-app myapp --engine SQLAlchemy
```
```bash
fab create-app myapp
```
--------------------------------
### Restrict Show Columns in Model API
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example of restricting fields for the get item endpoint using `show_columns` in the Model API.
```python
class ContactModelApi(ModelRestApi):
resource_name = 'contact'
datamodel = SQLAInterface(Contact)
show_columns = ['name']
```
--------------------------------
### Custom Query for Related Fields (Single Filter)
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/advanced.md
Filter related fields in add/edit/search forms. This example filters the 'group' field to show only entries where the 'name' starts with 'W'.
```python
from flask_appbuilder.models.sqla.filters import FilterStartsWith
class ContactModelView(ModelView):
datamodel = SQLAInterface(Contact)
add_form_query_rel_fields = {'group': [['name', FilterStartsWith, 'W']]}
```
--------------------------------
### Get Item Response Structure
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
The default response structure for the get item endpoint.
```json
{
"id": ""
"description_columnns": {},
"label_columns": {},
"show_columns": [],
"show_title": "",
"result": {}
}
```
--------------------------------
### Configure User Registration Settings
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/user_registration.md
Set these global config keys in config.py to enable user registration with database authentication, Recaptcha, and email notifications.
```default
AUTH_TYPE = AUTH_DB
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = 'Public'
# Config for Flask-WTF Recaptcha necessary for user registration
RECAPTCHA_PUBLIC_KEY = 'GOOGLE PUBLIC KEY FOR RECAPTCHA'
RECAPTCHA_PRIVATE_KEY = 'GOOGLE PRIVATE KEY FOR RECAPTCHA'
# Config for Flask-Mail necessary for user registration
MAIL_SERVER = 'smtp.gmail.com'
MAIL_USE_TLS = True
MAIL_USERNAME = 'yourappemail@gmail.com'
MAIL_PASSWORD = 'passwordformail'
MAIL_DEFAULT_SENDER = 'fabtest10@gmail.com'
```
--------------------------------
### GET /greeting
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Defines a simple GET endpoint that returns a JSON greeting message.
```APIDOC
## GET /greeting
### Description
This endpoint returns a simple greeting message.
### Method
GET
### Endpoint
/greeting
### Response
#### Success Response (200)
- **message** (string) - The greeting message.
### Response Example
```json
{
"message": "Hello"
}
```
```
--------------------------------
### Set Environment Variable and Create Admin
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/extendsecurity/README.rst
Configure the Flask application and create an administrator user.
```bash
$ export FLASK_APP="app:create_app('config')"
$ flask fab create-admin
```
--------------------------------
### Initialize and Manage Database Migrations
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/quickmigrate/README.rst
Use Flask-Migrate to manage database schema changes. Ensure Flask is set to your application's entry point before running commands.
```bash
$ export FLASK_APP=app/__init__.py
$ flask db init
$ flask db migrate
# Check the migration script
$ flask db upgrate --sql
$ flask db upgrade
```
--------------------------------
### Install Flask-AppBuilder in Virtual Environment
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/installation.md
Installs Flask-AppBuilder within an activated virtual environment. This ensures all dependencies are isolated to this environment.
```bash
(venv)$ pip install flask-appbuilder
```
--------------------------------
### Create Skeleton Application
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/cli.md
Use the 'create-app' command to generate a new skeleton application. This requires an internet connection to download the skeleton from GitHub.
```bash
Usage: flask fab create-app [OPTIONS]
Create a Skeleton application
Options:
--name TEXT Your application name, directory will have
this name
--help Show this message and exit.
```
--------------------------------
### Run Flask-AppBuilder Application
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/enums/README.rst
Set the FLASK_APP environment variable, create an administrator, and then run the development server. This is typically done in the project's root directory.
```bash
$ export FLASK_APP=app/__init__.py
```
```bash
$ flask fab create-admin
```
```bash
$ flask run
```
--------------------------------
### Create a Secured Custom View with Menu Integration
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/views.md
Implement a custom view with secured methods using @has_access. This example also demonstrates how to add the view and links to the application's menu.
```python
from flask_appbuilder import AppBuilder, BaseView, expose, has_access
from app import appbuilder
class MyView(BaseView):
default_view = 'method1'
@expose('/method1/')
@has_access
def method1(self):
# do something with param1
# and return to previous page or index
return 'Hello'
@expose('/method2/')
@has_access
def method2(self, param1):
# do something with param1
# and render template with param
param1 = 'Goodbye %s' % (param1)
return param1
appbuilder.add_view(MyView, "Method1", category='My View')
appbuilder.add_link("Method2", href='/myview/method2/john', category='My View')
```
--------------------------------
### Define OpenAPI Spec for GET Request
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Use YAML in the docstring to define the OpenAPI specification for a GET endpoint, including response schema.
```python
@expose('/greeting')
def greeting(self):
"""Send a greeting
---
get:
responses:
200:
description: Greet the user
content:
application/json:
schema:
type: object
properties:
message:
type: string
"""
return self.response(200, message="Hello")
```
--------------------------------
### Define OpenAPI Spec for POST and GET Requests
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Define OpenAPI specifications for endpoints that support multiple HTTP methods (POST and GET), detailing responses for each.
```python
@expose('/greeting2', methods=['POST', 'GET'])
def greeting2(self):
"""Send a greeting
---
get:
responses:
200:
description: Greet the user
content:
application/json:
schema:
type: object
properties:
message:
type: string
post:
responses:
201:
description: Greet the user
content:
application/json:
schema:
type: object
properties:
message:
type: string
"""
if request.method == 'GET':
return self.response(200, message="Hello (GET)")
return self.response(201, message="Hello (POST)")
```
--------------------------------
### Instantiate Classes in add_view (0.1.X to 0.2.X)
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/versionmigration.md
When migrating from 0.1.X to 0.2.X, ensure that you instantiate the view classes when calling 'baseapp.add_view'.
```python
baseapp = BaseApp(app)
baseapp.add_view(GroupGeneralView(), "List Groups","/groups/list","th-large","Contacts")
baseapp.add_view(PersonGeneralView(), "List Contacts","/persons/list","earphone","Contacts")
baseapp.add_view(PersonChartView(), "Contacts Chart","/persons/chart","earphone","Contacts")
```
--------------------------------
### Download and Run DB Migration Scripts (0.6.X to 0.7.X)
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/versionmigration.md
For SQLite, MySQL, or PostgreSQL databases, download and execute these Python scripts to migrate the security models schema. Ensure you back up your database before proceeding.
```bash
cd /your-main-project-folder/
wget https://raw.github.com/dpgaspar/Flask-AppBuilder/master/bin/migrate_db_0.7.py
python migrate_db_0.7.py
wget https://raw.github.com/dpgaspar/Flask-AppBuilder/master/bin/hash_db_password.py
python hash_db_password.py
```
--------------------------------
### Custom Aggregation Function Example
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/quickcharts.md
Example of a custom aggregation function 'aggregate_count' decorated for automatic labeling. This demonstrates how to create and use custom aggregation logic.
```python
@aggregate(_('Count of'))
def aggregate_count(items, col):
return len(list(items))
```
--------------------------------
### LDAP TLS Configuration (STARTTLS)
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/security.md
Configure LDAP authentication to use STARTTLS for a secure connection. Set AUTH_LDAP_SERVER to ldap:// and AUTH_LDAP_USE_TLS to True.
```python
AUTH_LDAP_SERVER = "ldap://ldap.example.com"
AUTH_LDAP_USE_TLS = True
```
--------------------------------
### Fetching Specific Meta Data Keys using Rison
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Demonstrates how to use Rison URI arguments to select specific meta-data keys, such as fetching only permissions.
```json
{
"keys": [ ... LIST OF META DATA KEYS ... ]
}
```
--------------------------------
### Getting Column Formatter
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/flask_appbuilder/templates/appbuilder/general/widgets/list.html
Retrieves the formatter function for a specific column.
```html
{% set formatter = formatters_columns.get(value) %}
```
--------------------------------
### Getting Primary Key
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/flask_appbuilder/templates/appbuilder/general/widgets/list.html
Retrieves the primary key for the current row.
```html
{% set pk = pks[loop.index-1] %}
```
--------------------------------
### Configure SAML Authentication in config.py
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/security.md
Set AUTH_TYPE to AUTH_SAML and configure user registration, role synchronization, and role mapping. Define SAML providers and global Service Provider settings.
```python
AUTH_TYPE = AUTH_SAML
# registration configs
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Public"
# Sync roles at login from SAML assertion
AUTH_ROLES_SYNC_AT_LOGIN = True
# Map SAML group names to FAB roles
AUTH_ROLES_MAPPING = {
"admins": ["Admin"],
"users": ["Public"],
}
# SAML Identity Providers
SAML_PROVIDERS = [
{
"name": "entra_id",
"icon": "fa-microsoft",
"idp": {
"entityId": "https://sts.windows.net//",
"singleSignOnService": {
"url": "https://login.microsoftonline.com//saml2",
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
},
"singleLogoutService": {
"url": "https://login.microsoftonline.com//saml2",
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
},
"x509cert": "",
},
"attribute_mapping": {
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress": "email",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname": "first_name",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname": "last_name",
"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "username",
"http://schemas.microsoft.com/ws/2008/06/identity/claims/groups": "role_keys",
},
},
]
# Global SAML Service Provider configuration
SAML_CONFIG = {
"strict": True,
"debug": False,
"sp": {
"entityId": "https://myapp.example.com/saml/metadata/",
"assertionConsumerService": {
"url": "https://myapp.example.com/saml/acs/",
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
},
"singleLogoutService": {
"url": "https://myapp.example.com/saml/slo/",
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect",
},
"NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
"x509cert": "",
# "privateKey": "",
},
"security": {
"nameIdEncrypted": False,
"authnRequestsSigned": False,
"logoutRequestSigned": False,
"logoutResponseSigned": False,
"signMetadata": False,
"wantMessagesSigned": False,
"wantAssertionsSigned": True,
"wantAssertionsEncrypted": False,
"wantNameId": True,
"wantNameIdEncrypted": False,
"wantAttributeStatement": True,
},
}
```
--------------------------------
### Getting Link Order
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/flask_appbuilder/templates/appbuilder/general/widgets/list.html
Determines the link order for a given column.
```html
{% set res = item | get_link_order(modelview_name) %}
```
--------------------------------
### Multiple HTTP Methods
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Defines an endpoint that supports both GET and POST requests.
```APIDOC
## POST /api/v1/example/greeting2
### Description
An endpoint that handles both GET and POST requests, returning different messages based on the method.
### Method
GET, POST
### Endpoint
/api/v1/example/greeting2
### Response
#### Success Response (200 - GET)
- **message** (string) - "Hello (GET)"
#### Success Response (201 - POST)
- **message** (string) - "Hello (POST)"
#### Response Example (GET)
```json
{
"message": "Hello (GET)"
}
```
#### Response Example (POST)
```json
{
"message": "Hello (POST)"
}
```
```
--------------------------------
### Configure Application and Create Admin User
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/installation.md
Sets the FLASK_APP environment variable and then uses the 'flask fab create-admin' command to create the initial administrator user. You will be prompted for username, name, email, and password.
```bash
(venv)$ cd first_app
(venv)$ export FLASK_APP=app
(venv)$ flask fab create-admin
Username [admin]:
User first name [admin]:
User last name [user]:
Email [admin@fab.org]:
Password:
Repeat for confirmation:
```
--------------------------------
### Remove OpenID and Login Initialization (0.2.X to 0.3.X)
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/versionmigration.md
For migrations from 0.2.X to 0.3.X, remove the initialization of 'LoginManager' and 'OpenID' from your '_init_.py' file as these are no longer handled in the same way.
```python
app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)
from app import models, views
```
--------------------------------
### Model with Python Function for Response
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example SQLAlchemy model including a `some_function` method that can be included in `show_columns`.
```python
class Contact(Model):
id = Column(Integer, primary_key=True)
name = Column(String(150), unique=True, nullable=False)
address = Column(String(564))
birthday = Column(Date, nullable=True)
personal_phone = Column(String(20))
personal_celphone = Column(String(20))
contact_group_id = Column(Integer, ForeignKey('contact_group.id'), nullable=False)
contact_group = relationship("ContactGroup")
gender_id = Column(Integer, ForeignKey('gender.id'), nullable=False)
gender = relationship("Gender")
def __repr__(self):
return self.name
def some_function(self):
return f"Hello {self.name}"
```
--------------------------------
### Insert Test Data
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/quickimages/README.rst
Execute this script to populate the application with initial test data.
```bash
python testdata.py
```
--------------------------------
### Fetch Specific Columns using Rison
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example of using Rison to fetch only 'name' and 'address' for a Contact.
```rison
(columns:!(name,address))
```
--------------------------------
### Create Custom Show Widget
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/templates.md
Create a custom ShowWidget by extending the base ShowWidget class and specifying a custom template.
```python
from flask_appbuilder.widgets import ShowWidget
class MyShowWidget(ShowWidget):
template = 'widgets/show.html'
```
--------------------------------
### Protected Endpoint Example
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Demonstrates how to define and protect an API endpoint using Flask-AppBuilder's decorators.
```APIDOC
## GET /api/v1/example/private
### Description
This endpoint is protected and requires authentication.
### Method
GET
### Endpoint
/api/v1/example/private
### Parameters
#### Query Parameters
None
#### Request Body
None
### Request Example
```bash
curl 'http://localhost:8080/api/v1/example/private' -H "Authorization: Bearer "
```
### Response
#### Success Response (200)
- **message** (string) - A success message indicating access to the private endpoint.
#### Response Example
```json
{
"message": "This is private"
}
```
#### Error Response (401)
- **msg** (string) - Error message indicating missing or invalid authorization.
#### Response Example
```json
{
"msg": "Missing Authorization Header"
}
```
```
--------------------------------
### Rison Parameter Parsing
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Utilizes the @rison decorator to parse complex GET parameters from a Rison-formatted query string.
```APIDOC
## POST /api/v1/example/greeting3
### Description
An endpoint that accepts a 'name' parameter via Rison encoding in the query string and returns a personalized greeting.
### Method
GET
### Endpoint
/api/v1/example/greeting3
### Query Parameters
- **q** (string) - Required - Rison encoded query parameters. Expected format: `(name:your_name)`
### Response
#### Success Response (200)
- **message** (string) - Personalized greeting message.
#### Error Response (400)
- **message** (string) - Error message if 'name' is not provided.
#### Response Example (Success)
```json
{
"message": "Hello daniel"
}
```
#### Response Example (Error)
```json
{
"message": "Please send your name"
}
```
```
--------------------------------
### Display Application Icon or Name in Header
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/flask_appbuilder/templates/appbuilder/navbar.html
Conditionally displays the application icon if available, otherwise shows the application name. Both link to the application's index page.
```html
{% set menu = appbuilder.menu %} {% set languages = appbuilder.languages %}
{% if appbuilder.app_icon %} [ ]({{appbuilder.get_url_for_index}}){% else %} [{{ appbuilder.app_name }}]({{appbuilder.get_url_for_index}}) {% endif %}
```
--------------------------------
### SQLAlchemy Query Syntax Comparison
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/versionmigration.md
Illustrates changes in SQLAlchemy query syntax for compatibility with SQLAlchemy 2.x. Old patterns may require updates.
```python
# Old query patterns that may need updates
users = session.query(User).filter_by(active=True).all()
result = session.execute("SELECT * FROM users WHERE active = 1")
```
```python
# After (SQLAlchemy 2.x compatible):
```
--------------------------------
### Basic API Endpoint
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Defines a simple GET endpoint '/greeting' with a default base route '/api/v1/'.
```APIDOC
## POST /api/v1/exampleapi/greeting
### Description
Exposes a simple greeting endpoint that returns a JSON message.
### Method
GET
### Endpoint
/api/v1/exampleapi/greeting
### Response
#### Success Response (200)
- **message** (string) - A greeting message.
#### Response Example
```json
{
"message": "Hello"
}
```
```
--------------------------------
### Implement Custom Form View
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/views.md
Create a custom form view by subclassing SimpleFormView. Implement `form_get` for pre-filling data and `form_post` for processing submitted data. Use `flash` for user feedback.
```python
from flask import flash
from flask_appbuilder import SimpleFormView
from flask_babel import lazy_gettext as _
class MyFormView(SimpleFormView):
form = MyForm
form_title = 'This is my first form view'
message = 'My form submitted'
def form_get(self, form):
form.field1.data = 'This was prefilled'
def form_post(self, form):
# post process form
flash(self.message, 'info')
appbuilder.add_view(MyFormView, "My form View", icon="fa-group", label=_('My form View'),
category="My Forms", category_icon="fa-cogs")
```
--------------------------------
### Include Python Function in Show Columns
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example of including a Python function (`some_function`) in the `show_columns` of the Model API.
```python
class ContactModelApi(ModelRestApi):
resource_name = 'contact'
datamodel = SQLAInterface(Contact)
show_columns = ['name', 'some_function']
```
--------------------------------
### Update BaseApp Initialization (0.2.X to 0.3.X)
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/versionmigration.md
When migrating from 0.2.X to 0.3.X, update the BaseApp initialization in your 'views.py' file to include the 'db' object.
```python
baseapp = BaseApp(app, db)
```
--------------------------------
### Curl Command to Discard All Meta Data
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example curl command to discard all meta data using Rison.
```bash
curl 'http://localhost:8080/api/v1/contact/1?q=(columns:!(name,address),keys:!(none))' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN"
```
--------------------------------
### Curl Request to Fetch Permissions
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/docs/rest_api.md
Example cURL command to fetch only the permissions meta data from the _info endpoint.
```bash
$ curl 'http://localhost:8080/api/v1/group/_info?q=(keys:!(permissions))' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN"
```
--------------------------------
### Insert Test Data
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/examples/base_filters/README.rst
Run this script to create test users (user1, user2, user3) with the password 'password' for the application.
```bash
$ python testdata.py
```
--------------------------------
### Upload Package to PyPI
Source: https://github.com/dpgaspar/flask-appbuilder/blob/master/RELEASE.rst
Execute this command to build and upload the Flask-AppBuilder package to the Python Package Index (PyPI). Ensure you have the necessary build tools and credentials configured.
```bash
python setup.py sdist upload
```