Skip to main content

PyStructUI 🎨

Transform data structures into beautiful UIs for any Python web framework

PyStructUI is a universal presentation layer that lets you build web UIs using pure data structures instead of HTML templates. Works with Flask, Django, FastAPI, and any Python web framework.

Why PyStructUI?

Traditional web development:

<!-- 100s of HTML template files -->
<div class="card">
  <div class="card-header">{{ title }}</div>
  <div class="card-body">{{ content }}</div>
</div>

With PyStructUI:

{'type': 'card', 'title': 'Hello', 'body': 'World'}

Benefits:

  • No HTML templates - Define UI as data
  • Framework agnostic - Works with Flask, Django, FastAPI, etc.
  • UI framework swappable - Switch between Bootstrap, Tailwind, Material with one line
  • 90% less code - Data structures are more concise than HTML
  • AI-friendly - LLMs understand data better than HTML
  • Testable - Test data structures, not HTML strings

Installation

pip install pystructui

Or install with framework support:

pip install pystructui[flask]
pip install pystructui[django]
pip install pystructui[fastapi]

Quick Start

Basic Usage

from pystructui import render

# Define UI as data
ui_data = {
    'type': 'page',
    'title': 'My App',
    'components': [
        {'type': 'navbar', 'brand': 'PyStructUI'},
        {'type': 'hero', 'title': 'Welcome!', 'subtitle': 'Build UIs with data'},
        {'type': 'button', 'text': 'Get Started', 'variant': 'primary'}
    ]
}

# Render to HTML
html = render(ui_data)

Flask Integration

from flask import Flask
from pystructui import flask_integration

app = Flask(__name__)
ui = flask_integration(app)

@app.route('/')
@ui.render
def index():
    return {
        'type': 'page',
        'title': 'Flask App',
        'components': [
            {'type': 'card', 'title': 'Hello Flask!', 'body': 'No templates needed!'}
        ]
    }

Django Integration

# views.py
from pystructui import django_integration

ui = django_integration()

def index(request):
    data = {
        'type': 'page',
        'title': 'Django App',
        'components': [
            {'type': 'navbar', 'brand': 'Django + PyStructUI'},
            {'type': 'hero', 'title': 'No templates!'}
        ]
    }
    return ui.render_response(data)

FastAPI Integration

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from pystructui import fastapi_integration

app = FastAPI()
ui = fastapi_integration()

@app.get("/", response_class=HTMLResponse)
async def index():
    data = {
        'type': 'page',
        'components': [{'type': 'card', 'title': 'FastAPI + PyStructUI'}]
    }
    return ui.render(data)

Component Reference

Page Structure

{
    'type': 'page',
    'title': 'Page Title',
    'components': [...]  # List of components
}

Navigation

{
    'type': 'navbar',
    'brand': 'My App',
    'links': [
        {'text': 'Home', 'url': '/'},
        {'text': 'About', 'url': '/about'}
    ]
}

Cards

{
    'type': 'card',
    'title': 'Card Title',
    'body': 'Card content or nested component',
    'footer': {'type': 'button', 'text': 'Action'}
}

Forms

{
    'type': 'form',
    'method': 'POST',
    'action': '/submit',
    'fields': [
        {
            'type': 'text',
            'name': 'username',
            'label': 'Username',
            'required': True
        },
        {
            'type': 'textarea',
            'name': 'message',
            'label': 'Message'
        }
    ]
}

Tables

{
    'type': 'table',
    'headers': ['Name', 'Email', 'Status'],
    'rows': [
        ['John', 'john@example.com', 'Active'],
        ['Jane', 'jane@example.com', 'Pending']
    ]
}

Grids

{
    'type': 'grid',
    'columns': 3,
    'items': [
        {'type': 'card', 'title': 'Card 1'},
        {'type': 'card', 'title': 'Card 2'},
        {'type': 'card', 'title': 'Card 3'}
    ]
}

Alerts

{
    'type': 'alert',
    'message': 'Operation successful!',
    'variant': 'success',  # success, danger, warning, info
    'dismissible': True
}

Switching UI Frameworks

from pystructui import PresentationLayer
from pystructui.renderers import BootstrapRenderer, TailwindRenderer

pl = PresentationLayer()

# Use Bootstrap
pl.add_renderer('bootstrap', BootstrapRenderer())
html = pl.render(data, 'bootstrap')

# Switch to Tailwind - same data, different output!
pl.add_renderer('tailwind', TailwindRenderer())
html = pl.render(data, 'tailwind')

Custom Renderers

Create your own renderer for any UI framework:

from pystructui import Renderer

class CustomRenderer(Renderer):
    def render(self, data):
        # Your rendering logic
        return html

    def render_component(self, component):
        # Component rendering
        return html

# Use it
pl.add_renderer('custom', CustomRenderer())

Advanced Features

Nested Components

Components can be nested infinitely:

{
    'type': 'card',
    'body': {
        'type': 'grid',
        'columns': 2,
        'items': [
            {'type': 'button', 'text': 'Yes'},
            {'type': 'button', 'text': 'No'}
        ]
    }
}

Raw HTML

When needed, include raw HTML:

{
    'type': 'raw',
    'content': '<custom-element>Custom HTML</custom-element>'
}

Dynamic Rendering

Use Python to generate dynamic UIs:

def dashboard(user_data):
    return {
        'type': 'grid',
        'columns': 3,
        'items': [
            {
                'type': 'card',
                'title': metric['name'],
                'body': metric['value']
            }
            for metric in user_data.metrics
        ]
    }

Why Data Structures?

  1. Simplicity - No template syntax to learn
  2. Portability - Same structure works with any renderer
  3. Testability - Assert on data, not HTML strings
  4. AI-friendly - LLMs excel at data transformation
  5. Version control - Data diffs are cleaner than HTML diffs
  6. Performance - No template compilation overhead

Comparison

Traditional Django Template

{% extends "base.html" %}
{% block content %}
<div class="container">
  <div class="row">
    {% for item in items %}
    <div class="col-md-4">
      <div class="card">
        <div class="card-body">
          <h5 class="card-title">{{ item.title }}</h5>
          <p class="card-text">{{ item.description }}</p>
          <a href="{{ item.url }}" class="btn btn-primary">View</a>
        </div>
      </div>
    </div>
    {% endfor %}
  </div>
</div>
{% endblock %}

With PyStructUI

{
    'type': 'grid',
    'columns': 3,
    'items': [
        {
            'type': 'card',
            'title': item['title'],
            'body': item['description'],
            'footer': {'type': 'button', 'text': 'View', 'url': item['url']}
        }
        for item in items
    ]
}

Real-World Example

Building a complete todo app:

from flask import Flask
from pystructui import flask_integration

app = Flask(__name__)
ui = flask_integration(app)

todos = []

@app.route('/')
@ui.render
def index():
    return {
        'type': 'page',
        'components': [
            {'type': 'navbar', 'brand': 'Todo App'},
            {
                'type': 'card',
                'title': 'My Todos',
                'body': {
                    'type': 'table',
                    'headers': ['Task', 'Status'],
                    'rows': [[t['text'], t['status']] for t in todos]
                }
            }
        ]
    }

# That's it! No templates needed!

Contributing

We welcome contributions! PyStructUI is designed to be extensible:

  • Add new component types
  • Create renderers for more UI frameworks
  • Add framework integrations
  • Improve documentation

License

MIT License - Use PyStructUI in any project!

Philosophy

"Code is about data structures. UI should be too."

PyStructUI embraces the fundamental truth that all programming is data transformation. Instead of mixing logic with presentation through templates, we keep them separate: logic produces data, renderers transform data to UI.

This is the future of web development - where humans define intent through data structures, and machines handle the implementation details.

Support


Built with ❤️ by the DBBasic team. Part of the movement to make web development simpler, faster, and more enjoyable.

Release files for pystructui 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pystructui 0.1.0
File Size Uploaded
pystructui-0.1.0.tar.gz 15.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pystructui 0.1.0
File Interpreter ABI Platform
pystructui-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.6 kB

Release files / pystructui-0.1.0.tar.gz

Download URL pystructui-0.1.0.tar.gz
Size 15.5 kB
Tags Source
SHA-256 checksum
How to use checksums
65b770a9a57c1d7d1f6938df4fcc1ed5acf0b152eda0fe726f447c054b948ae6
BLAKE2b-256 checksum
How to use checksums
a188b7aa3341847a97dc5391d3e8a9148a5a6fd0ca805045d9cf05cb696ea69d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.1

Release files / pystructui-0.1.0-py3-none-any.whl

Download URL pystructui-0.1.0-py3-none-any.whl
Size 11.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
849fc5f21f14ac2834ea5b752f08fc55f8add62cd407cf87a364941300d9d1da
BLAKE2b-256 checksum
How to use checksums
96e1351c8c4ace9363c26254a1012d08e8078b2ff66eb19d4c5df98b15da3a5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.1

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page