### 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.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 ```