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->HtmlComponentlist/tuple->Containerpd.DataFrame->FrameComponentgo.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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ionbus_flapi-0.1.2.1.tar.gz.
File metadata
- Download URL: ionbus_flapi-0.1.2.1.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23463508caf21f117b4a7694be565767ac27bdafc251a0fc990528f7a69df73e
|
|
| MD5 |
7400ac54132138d21cac347502668ed2
|
|
| BLAKE2b-256 |
fd90a58afeddc591196e3272be51732336c2342111126da6503213fa563f02dd
|
File details
Details for the file ionbus_flapi-0.1.2.1-py3-none-any.whl.
File metadata
- Download URL: ionbus_flapi-0.1.2.1-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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62f446bf14cf7a37ddc360f688edf4e9956a970345a49b2848574da9f0d3622a
|
|
| MD5 |
39e82f04b1aadf5fc75d7273d5b70134
|
|
| BLAKE2b-256 |
3500b080e32e0510dab9a18d44cf2bb391e76a4d03882f8e574133672d351eb0
|