Python package for @nssivanitesh/react-ubiquitous — typed config models and fluent builders
Project description
react-ubiquitous-put
Typed Pydantic models and fluent builders for @nssivanitesh/react-ubiquitous UI configuration.
Overview
react-ubiquitous-put lets you build react-ubiquitous UI configurations entirely in Python. It provides:
- Validated models — Pydantic v2 models for every element, section, page, and stage type.
- CamelCase interop — Python attributes use
snake_case; JSON keys automatically usecamelCaseto match the TypeScript API. - Fluent builders — immutable builder classes that make it easy to construct nested configs without mutation bugs.
Installation
pip install react-ubiquitous-put
Requirements: Python ≥ 3.10, Pydantic ≥ 2.0
Quick Start
from react_ubiquitous_put import (
ElementBuilder,
SectionBuilder,
PageBuilder,
StageBuilder,
InputElementConfig,
GridSectionConfig,
)
# 1. Build an input element
email_field = (
ElementBuilder(InputElementConfig)
.with_id("email")
.with_name("email")
.with_field(input_type="email")
.with_label("Email Address")
.with_order(1)
.with_required(True)
.add_validation("required")
.add_validation("email", message="Enter a valid email address.")
.build()
)
# 2. Place it in a grid section
form_section = (
SectionBuilder(GridSectionConfig)
.with_id("contact-form")
.with_title("Contact Details")
.with_order(1)
.with_field(grid_template_columns="repeat(2, 1fr)", gap="1rem")
.add_element(email_field)
.build()
)
# 3. Add the section to a page
contact_page = (
PageBuilder()
.with_id("contact")
.with_title("Contact")
.with_order(1)
.add_section(form_section)
.build()
)
# 4. Assemble the top-level stage
stage = (
StageBuilder()
.with_id("main")
.with_title("My Application")
.with_default_page_id("contact")
.add_page(contact_page)
.build()
)
# 5. Serialize to camelCase JSON (ready for react-ubiquitous)
payload = stage.model_dump(by_alias=True, exclude_none=True)
Example JSON output (click to expand)
{
"id": "main",
"title": "My Application",
"defaultPageId": "contact",
"pages": [
{
"id": "contact",
"title": "Contact",
"order": 1,
"sections": [
{
"id": "contact-form",
"layout": "grid",
"title": "Contact Details",
"order": 1,
"gridTemplateColumns": "repeat(2, 1fr)",
"gap": "1rem",
"elements": [
{
"id": "email",
"name": "email",
"type": "input",
"inputType": "email",
"label": "Email Address",
"order": 1,
"required": true,
"validations": [
{ "rule": "required" },
{ "rule": "email", "message": "Enter a valid email address." }
]
}
]
}
]
}
]
}
Builders
All builders follow the same immutable pattern — each with_* / add_* call returns a new builder, leaving the original unchanged.
ElementBuilder
Builds any element config model.
from react_ubiquitous_put import ElementBuilder, InputElementConfig, ButtonElementConfig
# Text input with validation
first_name = (
ElementBuilder(InputElementConfig)
.with_id("first-name")
.with_name("firstName")
.with_label("First Name")
.with_order(1)
.with_required(True)
.with_tooltip("Enter your legal first name")
.with_width(6)
.with_class_name("form-input")
.add_validation("required")
.add_validation("maxLength", value=50)
.build()
)
# Submit button
submit_btn = (
ElementBuilder(ButtonElementConfig)
.with_id("submit-btn")
.with_name("submit")
.with_field(text="Submit", button_type="submit", variant="primary")
.with_order(99)
.build()
)
| Method | Description |
|---|---|
with_id(id) |
Set element id |
with_name(name) |
Set element name |
with_label(label) |
Set display label |
with_label_position(position) |
Set label placement ("top", "left", …) |
with_order(order) |
Set render order |
with_tooltip(tooltip) |
Set tooltip/help text |
with_width(width) |
Set column width (string or int) |
with_class_name(class_name) |
Set CSS class |
with_style(style) |
Set inline style dict |
with_required(required) |
Mark element as required |
with_disabled(disabled) |
Mark element as disabled |
with_readonly(readonly) |
Mark element as read-only |
with_hidden(hidden) |
Hide the element |
add_validation(rule, value, message) |
Append a ValidationRule |
with_field(**kwargs) |
Set any model-specific fields |
build() |
Validate and return the model instance |
SectionBuilder
Builds any section layout config model.
from react_ubiquitous_put import SectionBuilder, GridSectionConfig, FlexSectionConfig
# Grid section
grid = (
SectionBuilder(GridSectionConfig)
.with_id("personal-info")
.with_title("Personal Information")
.with_order(1)
.with_field(grid_template_columns="repeat(3, 1fr)", gap="1rem")
.add_element(first_name)
.add_element(submit_btn)
.build()
)
# Flex toolbar
toolbar = (
SectionBuilder(FlexSectionConfig)
.with_id("toolbar")
.with_field(flex_direction="row", justify_content="flex-end", gap="0.5rem")
.add_element(submit_btn)
.build()
)
| Method | Description |
|---|---|
with_id(id) |
Set section id |
with_title(title) |
Set section title |
with_description(description) |
Set section description |
with_order(order) |
Set render order |
with_class_name(class_name) |
Set CSS class |
with_style(style) |
Set inline style dict |
add_element(element) |
Append a built element |
with_field(**kwargs) |
Set any layout-specific fields |
build() |
Validate and return the model instance |
PageBuilder
Builds a UIPageConfig (a single tab/page within a stage).
from react_ubiquitous_put import PageBuilder
page = (
PageBuilder()
.with_id("settings")
.with_title("Settings")
.with_order(2)
.with_icon("settings")
.with_description("Application settings")
.with_visible(True)
.add_section(grid)
.add_section(toolbar)
.build()
)
| Method | Description |
|---|---|
with_id(id) |
Set page id |
with_title(title) |
Set page title |
with_description(description) |
Set page description |
with_icon(icon) |
Set page icon name |
with_order(order) |
Set tab order |
with_class_name(class_name) |
Set CSS class |
with_visible(visible) |
Show/hide the page tab |
add_section(section) |
Append a built section |
build() |
Validate and return a UIPageConfig |
StageBuilder
Builds a UIStageConfig — the top-level container.
from react_ubiquitous_put import StageBuilder
stage = (
StageBuilder()
.with_id("app")
.with_title("My Application")
.with_description("Powered by react-ubiquitous")
.with_default_page_id("settings")
.add_page(page)
.build()
)
| Method | Description |
|---|---|
with_id(id) |
Set stage id |
with_title(title) |
Set stage title |
with_description(description) |
Set stage description |
with_default_page_id(page_id) |
Set the initially active page |
add_page(page) |
Append a built page |
build() |
Validate and return a UIStageConfig |
Models
All models inherit from _CamelModel, which:
- Accepts both
snake_caseandcamelCasefield names on input. - Serializes to camelCase when
by_alias=Trueis passed tomodel_dump()/model_dump_json().
Element Models
| Model | type |
Key Fields |
|---|---|---|
InputElementConfig |
"input" |
input_type, placeholder, default_value, min, max, step, datalist_id |
CheckboxElementConfig |
"checkbox" |
default_checked, checked, value |
RadioElementConfig |
"radio" |
options: list[RadioOption], default_value, orientation |
TextareaElementConfig |
"textarea" |
placeholder, rows, cols, resize, max_length |
SelectElementConfig |
"select" |
options: list[SelectOption | SelectOptGroup], multiple, size |
ButtonElementConfig |
"button" |
text, button_type, variant, size, icon, icon_position |
LabelElementConfig |
"label" |
text, html_for |
FieldsetElementConfig |
"fieldset" |
legend, children: list[UIElementConfig] |
DatalistElementConfig |
"datalist" |
options: list[str | SelectOption] |
OutputElementConfig |
"output" |
value, default_value, format, html_for |
DatePickerElementConfig |
"datepicker" |
default_value, min, max, include_time, placeholder |
MultiSelectElementConfig |
"multiselect" |
options: list[SelectOption], default_value, max_items, placeholder |
AutocompleteElementConfig |
"autocomplete" |
options: list[SelectOption], default_value, placeholder |
FileUploadElementConfig |
"fileupload" |
accept, multiple, max_size, placeholder |
ColorPickerElementConfig |
"colorpicker" |
default_value, value, format |
RangeSliderElementConfig |
"rangeslider" |
min, max, step, default_value: tuple[float, float] |
RatingElementConfig |
"rating" |
max, default_value, allow_half |
OtpInputElementConfig |
"otpinput" |
length, default_value, mask |
PhoneInputElementConfig |
"phoneinput" |
default_country, default_value, placeholder |
CustomElementConfig |
"custom" |
component, props: dict |
Validation Rules
from react_ubiquitous_put import ValidationRule
# Simple rule
required = ValidationRule(rule="required")
# Rule with value and message
min_length = ValidationRule(rule="minLength", value=8, message="At least 8 characters.")
# Custom async validator
custom = ValidationRule(
rule="custom",
validator="checkUsername",
config={"endpoint": "/api/validate/username"},
)
Section Models
| Model | layout |
Key Fields |
|---|---|---|
FlexSectionConfig |
"flex" |
flex_direction, flex_wrap, justify_content, align_items, gap |
GridSectionConfig |
"grid" |
grid_template_columns, grid_template_rows, gap, align_items, justify_items |
HeroSectionConfig |
"hero" |
subtitle, background_type, gradient_from, gradient_to, overlay, link_url |
MediaSectionConfig |
"media" |
items: list[MediaItem], aspect_ratio, show_arrows, show_dots |
ListDetailSectionConfig |
"list-detail" |
list_items, list_endpoint, filter_endpoint, detail_endpoint, detail_pages |
TreeViewSectionConfig |
"tree-view" |
tree_nodes: list[TreeViewNode], tree_title, tree_width, tree_mode, detail_pages |
ChatSectionConfig |
"chat" |
conversations: list[ChatConversation], list_title, current_user_name, input_placeholder |
NavbarSectionConfig |
"navbar" |
logo_text, logo_url, links: list[NavLink], position, theme |
SidebarSectionConfig |
"sidebar" |
items: list[SidebarItem], default_collapsed, collapsible, width |
BreadcrumbsSectionConfig |
"breadcrumbs" |
items: list[BreadcrumbItem], separator |
PaginationSectionConfig |
"pagination" |
total_items, page_size, current_page, show_first_last, max_page_buttons |
StepperSectionConfig |
"stepper" |
steps: list[StepperStep], current_step, orientation |
TabsSectionConfig |
"tabs" |
tabs: list[TabItem], default_tab_id |
AlertSectionConfig |
"alert" |
severity, dismissible, icon |
ProgressSectionConfig |
"progress" |
variant, value, show_label, size, color, indeterminate |
SkeletonSectionConfig |
"skeleton" |
shape, lines, avatar, width, height |
ToastSectionConfig |
"toast" |
message, severity, duration, position, visible |
ModalSectionConfig |
"modal" |
open, size, close_on_backdrop, show_close_button, confirm_label, cancel_label |
DrawerSectionConfig |
"drawer" |
open, placement, size, close_on_backdrop, show_close_button |
TooltipSectionConfig |
"tooltip" |
content, placement, trigger_label |
PopoverSectionConfig |
"popover" |
placement, trigger_label, content |
TableSectionConfig |
"table" |
columns: list[TableColumn], rows, searchable, page_size, empty_message |
BadgeSectionConfig |
"badge" |
badges: list[BadgeItem], appearance, size |
AvatarSectionConfig |
"avatar" |
avatars: list[AvatarItem], size, stacked |
TimelineSectionConfig |
"timeline" |
events: list[TimelineEvent] |
StatSectionConfig |
"stat" |
stats: list[StatItem], columns |
EmptyStateSectionConfig |
"empty-state" |
heading, message, icon, action_label, action_href |
CodeBlockSectionConfig |
"code-block" |
code, language, line_numbers, copyable |
ChartSectionConfig |
"chart" |
chart_type, data, series: list[ChartSeries], show_grid, show_legend, height |
IframeSectionConfig |
"iframe" |
src, query_params, frame_width, frame_height, sandbox, frame_title |
AccordionSectionConfig |
"accordion" |
panels: list[AccordionPanel], allow_multiple |
CollapseSectionConfig |
"collapse" |
label, default_open, icon |
DividerSectionConfig |
"divider" |
label, orientation, variant |
CardSectionConfig |
"card" |
bordered, shadow, padded, footer_elements |
Example — Hero section
from react_ubiquitous_put import HeroSectionConfig
hero = HeroSectionConfig(
id="hero",
title="Welcome to Our Platform",
subtitle="Build better UIs faster",
background_type="gradient",
gradient_from="#6366f1",
gradient_to="#1e293b",
gradient_direction="to bottom right",
overlay=True,
overlay_opacity=40,
min_height="60vh",
text_align="center",
link_text="Get Started",
link_url="/signup",
)
Example — Accordion section
from react_ubiquitous_put import (
AccordionSectionConfig,
AccordionPanel,
LabelElementConfig,
)
faq = AccordionSectionConfig(
id="faq",
title="Frequently Asked Questions",
allow_multiple=False,
panels=[
AccordionPanel(
id="q1",
label="What is react-ubiquitous?",
default_open=True,
elements=[
LabelElementConfig(
id="a1",
name="answer1",
text="A declarative JSON-driven React UI library.",
order=1,
)
],
),
],
)
Example — Card section
from react_ubiquitous_put import CardSectionConfig, ButtonElementConfig
save_btn = ButtonElementConfig(
id="save", name="save", text="Save Changes", button_type="submit", order=1
)
card = CardSectionConfig(
id="profile-card",
title="Profile",
bordered=True,
shadow="sm",
padded=True,
footer_elements=[save_btn],
)
Example — List-Detail section
from react_ubiquitous_put import (
ListDetailSectionConfig,
ListItem,
ListEndpoint,
FilterEndpoint,
DetailEndpoint,
)
contacts = ListDetailSectionConfig(
id="contacts",
list_title="Contacts",
list_width="300px",
page_size=20,
list_items=[
ListItem(id="c1", label="Alice Smith", sublabel="alice@example.com", badge="Admin"),
],
list_endpoint=ListEndpoint(
url="/api/contacts",
from_param="offset",
from_value=0,
to_param="limit",
to_value=20,
),
filter_endpoint=FilterEndpoint(url="/api/contacts/search", query_param="q"),
detail_endpoint=DetailEndpoint(url="/api/contacts/:id", selected_param="id"),
)
Example — Table section
from react_ubiquitous_put import TableSectionConfig, TableColumn
users_table = TableSectionConfig(
id="users-table",
title="Users",
columns=[
TableColumn(key="name", label="Name", sortable=True, width="200px"),
TableColumn(key="email", label="Email", sortable=True),
TableColumn(key="role", label="Role", sortable=False),
],
rows=[
{"name": "Alice Smith", "email": "alice@acme.com", "role": "Admin"},
{"name": "Bob Jones", "email": "bob@acme.com", "role": "Viewer"},
],
searchable=True,
page_size=10,
empty_message="No users found.",
)
Example — Chart section
from react_ubiquitous_put import ChartSectionConfig, ChartSeries
sales_chart = ChartSectionConfig(
id="sales-chart",
chart_type="bar",
height=300,
show_grid=True,
show_legend=True,
series=[
ChartSeries(key="revenue", label="Revenue", color="#6366f1"),
ChartSeries(key="expenses", label="Expenses", color="#f43f5e"),
],
data=[
{"label": "Jan", "revenue": 12000, "expenses": 8000},
{"label": "Feb", "revenue": 15000, "expenses": 9500},
{"label": "Mar", "revenue": 11000, "expenses": 7000},
],
)
Example — Tabs section
from react_ubiquitous_put import TabsSectionConfig, TabItem, GridSectionConfig
info_tabs = TabsSectionConfig(
id="info-tabs",
default_tab_id="overview",
tabs=[
TabItem(
id="overview",
label="Overview",
sections=[GridSectionConfig(id="overview-grid", order=1)],
),
TabItem(
id="settings",
label="Settings",
sections=[GridSectionConfig(id="settings-grid", order=1)],
),
],
)
Example — Alert section
from react_ubiquitous_put import AlertSectionConfig
success_alert = AlertSectionConfig(
id="save-success",
title="Saved",
description="Your changes have been saved successfully.",
severity="success",
dismissible=True,
icon=True,
)
Example — Stepper section
from react_ubiquitous_put import StepperSectionConfig, StepperStep
onboarding_steps = StepperSectionConfig(
id="onboarding-steps",
current_step=1,
orientation="horizontal",
steps=[
StepperStep(id="s1", label="Account", description="Create your account", status="complete"),
StepperStep(id="s2", label="Profile", description="Fill in profile details", status="current"),
StepperStep(id="s3", label="Confirm", description="Review and confirm"),
],
)
UIStageConfig — top-level fields
| Field | Type | Description |
|---|---|---|
id |
str |
Unique stage identifier |
title |
str | None |
Heading above the tab bar |
description |
str | None |
Stage subtitle |
default_page_id |
str | None |
ID of the tab to show first |
pages |
list[UIPageConfig] |
Ordered list of pages / tabs |
theme |
str | None |
"light" | "dark" | "html" | "custom" |
class_name |
str | None |
Extra CSS class on the stage wrapper |
page_transition |
str | None |
"none" | "fade" | "slide-left" | "slide-right" |
from react_ubiquitous_put import UIStageConfig, UIPageConfig
stage = UIStageConfig(
id="app",
title="My App",
theme="light",
page_transition="fade",
class_name="my-app-wrapper",
default_page_id="home",
pages=[UIPageConfig(id="home", title="Home", order=1)],
)
Framework Integration
Flask
Install Flask alongside the package:
pip install react-ubiquitous-put flask
Use the built-in ui_response() helper in any Flask route. It serialises the
model to camelCase JSON (omitting None values) and returns a proper
application/json response:
from flask import Flask
from react_ubiquitous_put import (
UIStageConfig, UIPageConfig,
GridSectionConfig, FlexSectionConfig,
InputElementConfig, ButtonElementConfig,
)
from react_ubiquitous_put.flask_utils import ui_response
app = Flask(__name__)
@app.get("/stages/<stage_id>")
def get_stage(stage_id: str):
config = UIStageConfig(
id=stage_id,
title="My Application",
default_page_id="home",
theme="light",
pages=[
UIPageConfig(
id="home",
title="Home",
order=1,
sections=[
GridSectionConfig(
id="form",
order=1,
grid_template_columns="repeat(2, 1fr)",
gap="1rem",
elements=[
InputElementConfig(
id="name",
name="name",
input_type="text",
label="Full Name",
required=True,
order=1,
),
],
),
FlexSectionConfig(
id="actions",
order=2,
flex_direction="row",
justify_content="flex-end",
gap="0.5rem",
elements=[
ButtonElementConfig(
id="submit",
name="submit",
text="Submit",
button_type="submit",
variant="default",
order=1,
),
],
),
],
),
],
)
return ui_response(config)
if __name__ == "__main__":
app.run(debug=True)
ui_response(config, status=200) accepts any Pydantic model and any HTTP
status code (useful for 201 Created, 202 Accepted, etc.).
FastAPI
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from react_ubiquitous_put import UIStageConfig, UIPageConfig, GridSectionConfig
app = FastAPI()
@app.get("/stages/{stage_id}")
async def get_stage(stage_id: str) -> JSONResponse:
config = UIStageConfig(
id=stage_id,
title="My Application",
pages=[
UIPageConfig(id="home", title="Home", order=1, sections=[
GridSectionConfig(id="form", order=1, grid_template_columns="repeat(2, 1fr)"),
]),
],
)
return JSONResponse(content=config.model_dump(by_alias=True, exclude_none=True))
JSON Serialization
Use model_dump(by_alias=True, exclude_none=True) to produce clean camelCase JSON:
import json
payload = stage.model_dump(by_alias=True, exclude_none=True)
print(json.dumps(payload, indent=2))
# Or serialize directly to a JSON string:
json_str = stage.model_dump_json(by_alias=True)
# Round-trip from JSON:
from react_ubiquitous_put import UIStageConfig
restored = UIStageConfig.model_validate_json(json_str)
Models also accept camelCase keys on input, making it trivial to parse API responses:
data = {
"id": "s1",
"defaultPageId": "home",
"pages": [{"id": "home", "title": "Home", "order": 1}],
}
stage = UIStageConfig.model_validate(data)
assert stage.default_page_id == "home"
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
License
MIT © nssivanitesh
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 react_ubiquitous_py-1.1.0.tar.gz.
File metadata
- Download URL: react_ubiquitous_py-1.1.0.tar.gz
- Upload date:
- Size: 56.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37057b1a3674aefaf2623b39e452e3f807721a1a76bf9597545212527b3cc930
|
|
| MD5 |
34bb54dfb6cd4406c82a765711f3df67
|
|
| BLAKE2b-256 |
c0c14b1cf4f3beb63af710e828afd63471a04bbe3de5320a095bdd26d81fec59
|
Provenance
The following attestation bundles were made for react_ubiquitous_py-1.1.0.tar.gz:
Publisher:
publish.yml on nssivanitesh/react-ubiquitous-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
react_ubiquitous_py-1.1.0.tar.gz -
Subject digest:
37057b1a3674aefaf2623b39e452e3f807721a1a76bf9597545212527b3cc930 - Sigstore transparency entry: 1005202204
- Sigstore integration time:
-
Permalink:
nssivanitesh/react-ubiquitous-py@c707730ef956d04320343c78169c192ba9218156 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/nssivanitesh
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c707730ef956d04320343c78169c192ba9218156 -
Trigger Event:
release
-
Statement type:
File details
Details for the file react_ubiquitous_py-1.1.0-py3-none-any.whl.
File metadata
- Download URL: react_ubiquitous_py-1.1.0-py3-none-any.whl
- Upload date:
- Size: 18.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c4da3c8efd49b4298a85d812ef442a53543232c8486549da9e4fd1615e05896
|
|
| MD5 |
13ac8c55f6f2a19105a56711da99dd88
|
|
| BLAKE2b-256 |
064eac8536e23ac8a11742830e19479867f500d7b642e1894b9fafb6e2eea9af
|
Provenance
The following attestation bundles were made for react_ubiquitous_py-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on nssivanitesh/react-ubiquitous-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
react_ubiquitous_py-1.1.0-py3-none-any.whl -
Subject digest:
7c4da3c8efd49b4298a85d812ef442a53543232c8486549da9e4fd1615e05896 - Sigstore transparency entry: 1005202205
- Sigstore integration time:
-
Permalink:
nssivanitesh/react-ubiquitous-py@c707730ef956d04320343c78169c192ba9218156 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/nssivanitesh
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c707730ef956d04320343c78169c192ba9218156 -
Trigger Event:
release
-
Statement type: