Skip to main content

A low-code framework for building web applications with Flask and FastAPI

Project description

Flapi - FastAPI Low-Code Framework

Flapi is a low-code framework for building web applications that serve both human-facing webpages and JSON APIs. It supports Flask and FastAPI backends.

Installation

pip install ionbus_flapi

Quick Start

1. Create a Config File

Create config/windows.yaml (or linux.yaml):

app_type: fastapi  # or "flask"
host: 0.0.0.0
port: 5080
proxy_prefix: MyApp
title: My Application
shutdown_code: "secret123"  # Optional: enables /shutdown endpoint

2. Create an Endpoint Module

Create MyEndpoints/endpoints.py:

from __future__ import annotations

from ionbus_flapi import FlapiPage, HtmlComponent, register_endpoint

MODULE_NAME = "MyEndpoints"
HTML_DESCRIPTION = "<li>My custom endpoints.</li>"


def initialize() -> None:
    """Initialize endpoints in this module."""
    register_endpoint(
        MODULE_NAME,
        "HelloWorld",
        hello_world_endpoint,
        ep_description="A simple hello world example.",
    )


def hello_world_endpoint() -> FlapiPage:
    """Display a hello world page."""
    return FlapiPage(
        title="Hello World",
        objects=[
            HtmlComponent(html="<h2>Hello, World!</h2>"),
            "<p>This is my first Flapi endpoint.</p>",  # strings work too
        ],
    )

3. Create the Main App

Create app.py:

from __future__ import annotations

import sys
from ionbus_flapi import initialize, register_endpoint_group, serve

if __name__ == "__main__":
    if len(sys.argv) < 2:
        raise RuntimeError("Must provide .yaml config file")

    initialize(sys.argv[1])

    import MyEndpoints.endpoints

    register_endpoint_group(
        MyEndpoints.endpoints.initialize,
        MyEndpoints.endpoints.MODULE_NAME,
        MyEndpoints.endpoints.HTML_DESCRIPTION,
    )

    serve()

4. Run

python app.py config/windows.yaml

Visit http://localhost:5080/MyApp/ to see your endpoints.

Core Concepts

FlapiPage

The main container for building HTML pages:

from ionbus_flapi import FlapiPage

page = FlapiPage(
    title="My Page",
    objects=[...],           # List of components or strings
    theme_toggle=True,       # Show theme toggle button
    refresh_in_seconds=30,   # Auto-refresh interval
)

Components

Components are objects that render to HTML. Available components:

Component Description Example
HtmlComponent Raw HTML HtmlComponent(html="<h1>Title</h1>")
FrameComponent JQX Data Grid FrameComponent(frame=df)
PlotlyComponent Plotly Chart PlotlyComponent(plotly_obj=fig)
ImageComponent Base64 Image ImageComponent(encoded_image=b64)
MarkdownComponent Markdown Text MarkdownComponent(text="# Hello")
FormComponent HTML Forms See Forms section
ColumnsContainer Grid Layout ColumnsContainer(obj1, obj2)
Container Vertical Stack Container([obj1, obj2])

Automatic Type Conversion

FlapiPage automatically converts common types to components:

  • str -> HtmlComponent
  • list/tuple -> Container
  • pd.DataFrame -> FrameComponent
  • go.Figure (Plotly) -> PlotlyComponent
# These are equivalent:
FlapiPage(objects=[HtmlComponent(html="<p>Hello</p>")])
FlapiPage(objects=["<p>Hello</p>"])

Layouts with ColumnsContainer

Place components side-by-side:

from ionbus_flapi import ColumnsContainer

# Two equal columns
ColumnsContainer(chart1, chart2)

# Custom column widths
ColumnsContainer(
    chart1, chart2, chart3,
    column_desc="1fr 2fr 1fr"  # Middle column is 2x wider
)

DataFrames with FrameComponent

Display pandas DataFrames as sortable, filterable grids:

from ionbus_flapi import FrameComponent

frame = FrameComponent(
    frame=df,
    sortable=True,
    filterable=True,
)

# Configure columns
frame.format_dict = {
    "price": {"width": 100, "cellsformat": "D2"},
    "name": {"width": 200},
}

# Add sum row
frame.sum_columns = ["price", "quantity"]

Forms

Create interactive forms:

from ionbus_flapi import FormComponent, FormElement

form = FormComponent(
    elements=[
        FormElement(name="username", box=True, label="Username"),
        FormElement(name="role", values=["Admin", "User"]),
        FormElement(name="active", checkbox=True, default=True),
    ],
    submit="Save",
)

API Endpoints

Register JSON API endpoints:

from ionbus_flapi import register_api_endpoint

def my_api() -> dict:
    """Returns user data."""
    return {"users": [...], "count": 10}

register_api_endpoint(MODULE_NAME, "users", my_api, methods="GET")

Request Context

Access request data within endpoints:

from ionbus_flapi import get_request_context

def my_endpoint():
    ctx = get_request_context()
    user = ctx.username
    params = ctx.args
    theme = ctx.theme
    # ...

Cookies

Set cookies for persistence:

from ionbus_flapi import set_cookie

set_cookie("my_preference", "value")

Themes

Flapi supports three themes: system, light, and dark.

The theme toggle button cycles through themes when clicked. To add it:

FlapiPage(title="My Page", objects=[...], theme_toggle=True)

Directory Structure

Recommended project structure:

my_project/
├── app.py
├── config/
│   ├── windows.yaml
│   └── linux.yaml
├── static/
│   ├── base.css
│   ├── themes/
│   │   ├── system.css
│   │   ├── light.css
│   │   └── dark.css
│   └── assets/
├── sampleData/
└── MyEndpoints/
    ├── __init__.py
    └── endpoints.py

Dash Integration

Embed interactive Dash apps within Flapi pages:

from ionbus_flapi import register_dash_endpoint, DashComponent, FlapiPage
from dash import dcc, html

def initialize():
    # Register a standalone Dash app
    dash_app = register_dash_endpoint(
        MODULE_NAME,
        "my_dash_app",
        ep_description="Interactive Dash application",
        show_in_dir=True,
    )

    # Configure Dash layout
    dash_app.layout = html.Div([
        dcc.Dropdown(id="dropdown", options=[...]),
        dcc.Graph(id="graph"),
    ])

    # Add callbacks
    @dash_app.callback(...)
    def update_graph(...):
        ...

def my_page() -> FlapiPage:
    # Embed Dash app in a FlapiPage
    return FlapiPage(
        title="Page with Dash",
        objects=[
            DashComponent("my_dash_app", height="600px"),
        ],
    )

Server Shutdown

Configure graceful server shutdown with callbacks.

Config

Add shutdown_code to your YAML config:

app_type: fastapi
port: 5080
proxy_prefix: MyApp
shutdown_code: "my_secret_code"  # Required to enable shutdown endpoint

Shutdown Endpoint

Once configured, access /MyApp/shutdown?code=my_secret_code to shut down the server.

Shutdown Callbacks

Register functions to run before shutdown (cleanup resources, save state, etc.):

from ionbus_flapi import register_shutdown_callback

def cleanup_resources():
    """Called when server shuts down."""
    print("Cleaning up...")
    # Close database connections, save state, etc.

# Register during initialization
register_shutdown_callback(cleanup_resources)

Real-Time Data Streaming

Use EventStreamManager for Server-Sent Events (SSE) to push live data updates:

from ionbus_flapi import (
    EventStreamManager,
    EventStreamTypes,
    FlapiPage,
    HtmlComponent,
    get_flapi,
)
import threading

# Create manager supporting grid and div updates
esm = EventStreamManager(
    "MyStream",
    modes=EventStreamTypes.GRID | EventStreamTypes.DIV,
    include_pause=True,
)

def initialize():
    # Register with FlapiApp (after initialize(), before serve())
    esm.register(get_flapi())

    # Start data thread
    threading.Thread(target=data_thread, daemon=True).start()

def data_thread():
    while True:
        if esm.has_subscriptions():
            # Update a div
            esm.broadcast_event("ticker", {
                "MessageType": "div",
                "DivId": "myDiv",
                "Html": "Updated content",
            })
            # Update a grid
            esm.broadcast_event("ticker", {
                "MessageType": "grid",
                "GridName": "MyGrid",
                "UpdateId": "id",  # Column to match rows
                "Rows": [{"id": 1, "value": 42}],
            })
        time.sleep(0.5)

def live_page() -> FlapiPage:
    stream_addr = esm.get_stream_address("ticker")
    js = esm.javascript(stream_addr)
    html = esm.html()  # Pause button

    return FlapiPage(
        title="Live Data",
        objects=[HtmlComponent(html=f'''
            <div id="myDiv">Loading...</div>
            {html}
            <script>$(document).ready(function() {{ {js} }});</script>
        ''')],
    )

EventStreamTypes

Type Description
GRID Update JQX Grid rows
DIV Update div innerHTML
LINE_PLOT Extend Plotly line chart
OHLC_PLOT Extend Plotly OHLC chart

Combine types with |: EventStreamTypes.GRID | EventStreamTypes.DIV

URL Utilities

extract_variables_from_address

Parse query parameters from URL strings (useful in Dash callbacks):

from ionbus_flapi import extract_variables_from_address

url = "/MyApp/page?foo=bar&baz=123"
params = extract_variables_from_address(url)
# {'foo': 'bar', 'baz': '123'}

Setup Script

Use the setup script to create a new project:

python -m ionbus_flapi.setup_project my_new_project

This creates the full directory structure with a sample endpoint.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ionbus_flapi-0.1.2.4.tar.gz (72.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ionbus_flapi-0.1.2.4-py3-none-any.whl (69.5 kB view details)

Uploaded Python 3

File details

Details for the file ionbus_flapi-0.1.2.4.tar.gz.

File metadata

  • Download URL: ionbus_flapi-0.1.2.4.tar.gz
  • Upload date:
  • Size: 72.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for ionbus_flapi-0.1.2.4.tar.gz
Algorithm Hash digest
SHA256 9d7ac964780f067eedac227d6e47a6046ae7e5b7158f3572688d584c91ba8ba5
MD5 d03b0d11d73b4bbba9bac4608e87b2ab
BLAKE2b-256 645bc3d664ba0c77a48929344befedf53e6aeb2d6e88997cfd8536661200ff22

See more details on using hashes here.

File details

Details for the file ionbus_flapi-0.1.2.4-py3-none-any.whl.

File metadata

  • Download URL: ionbus_flapi-0.1.2.4-py3-none-any.whl
  • Upload date:
  • Size: 69.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for ionbus_flapi-0.1.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 aaf624f10fee4de258ef4b5ec1382bca306281449b6c8d39ce5fdc2581816e8e
MD5 ce3f2c24e2a1e471fe70bf8900d2b65f
BLAKE2b-256 a531c3798dcecc609da80473babbcb014d70b2bc690077e5f3c3410da83ecd2a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page