Start Here
Introduction
Zenaura is a Python-based framework designed for building web applications with simplicity, developer experience, and event-driven design.
Architecture Guidelines
- Modular components for scalability.
- Event-driven architecture via
dispatcher.bind
. - Python-first approach, enabling PyScript and Pyodide integration.
Why Zenaura
- Simplified async programming.
- Intuitive routing and state management.
- Easy integration with Python and JS packages.
Rules
Do's
- Use
dispatcher.bind
anddispatcher.dispatch
for event management: - Ensure
render
in components has a single parent and one child level: Use functional components for nested children: - Follow the hierarchy:
HTML tags -> Functional Components -> Class Components -> Pages -> Layout
. - For multiple layouts, use:
- Microfrontend architecture.
- Conditional rendering (discussed in Layout section).
- Use
subject
andobserver
for shared states:
Don'ts
- Don’t use inline event handlers like
on_click
. - Don’t deeply nest child elements in
render
. - Don’t use
builder
calls for UI construction. - Don’t hard-code shared states or use global variables.
Quick Overview
Basics
HTML Tags
Simplified tag usage:
from zenaura.ui import div, h1, button
from zenaura.client.component import Component
class MyComponent(Component):
def render(self):
return div(
h1("Welcome to Zenaura"),
button("Click Me", id="my-button"),
)
Special Attributes
Attributes conflicting with Python keywords use _
suffix:
Components
Define reusable components:
from zenaura.client.component import Component, Reuseable
@Reuseable
class WelcomeComponent(Component):
def render(self):
return div("Welcome to Zenaura", class_="welcome")
@Reuseable
if missing.
State Management
Integrated event-driven patterns:
Dispatcher
Bind events with dispatcher.bind
:
from zenaura.client.dispatcher import dispatcher
dispatcher.bind("my-button", "click", counter.increment)
dispatcher.dispatch
.
Beyond Basics
Router
Simplified routing:
from zenaura.client.app import App
from zenaura.client.page import Page
app = App()
home_page = Page([WelcomeComponent()])
app.add_route("/", home_page)
app.run()
Pages
Encapsulate components:
Layout
Define app layout:
from zenaura.client.layout import Layout
from zenaura.client.app import App
app = App()
my_app_layout = Layout(
top=[NavigationAuthNotAuth],
routes=app.routes,
bottom=[FooterAuthNotAuth]
)
Global State
Share state between components:
from zenaura.client.observer import Subject
counter_subject = Subject()
counter_subject.state = {"counter1": 0}
class CounterObserver(Observer):
pass
class Counter1(Component, CounterObserver):
async def increment(self, event):
counter_subject.state["counter1"] += 1
counter_subject.notify()
def update(self, value):
# Logic for state update
Forms
Handle forms:
def render_form():
return form(
input_(type="text", id="name"),
button("Submit", id="submit-button")
)
Advanced Concepts
Virtual DOM
Minimizes re-rendering by efficiently patching changes.
Component Lifecycle
attached
: Runs after mounting.on_mutation
: Runs before DOM updates.on_settled
: Runs after DOM updates.
API Integration
Fetch data with async handlers:
from zenaura.client.mutator import mutator
@mutator
async def fetch_data():
data = await fetch("/api/data")
return data
PyScript and Pyodide
- PyScript: Run Python in the browser.
- Pyodide: Python interpreter in WebAssembly.
Deployment
- Configure
config.json
. - Host static files on a CDN/server.
External JS or CSS
Add scripts to build.py
:
from zenaura.server import ZenauraServer
ZenauraServer.hydrate_app(app, scripts=[
"""
<script>
const ws = new WebSocket("ws://localhost:5000/refresh");
ws.onmessage = () => location.reload();
</script>
"""
])
from zenaura.web.utils import to_js
def use_js_function():
from js import my_js_function
my_js_function(to_js({"data": 1}))
External Python Packages
List dependencies in config.json
:
Zenaura CLI
Zenaura cli is a tool to use, to quickly intialize, build, and run application
zenaura init
will initialize basic zenaura application.zenaura build
will build the zenaura application, and run everytime you change a file in zenaura public folder.zenaura run
run the application on port 5000, you can change the port from index.py
Zenaura UI
Multiple ready to use UI components.
Zenaura Charts
Multiple ready to use charts, built on top of chartjs