https://github.com/lhassa8/umara
Beautiful Python UIs — Without the Complexity. A modern alternative to Streamlit with superior design and flexibility.
https://github.com/lhassa8/umara
dashboard framework python streamlit-alternative ui web
Last synced: 3 months ago
JSON representation
Beautiful Python UIs — Without the Complexity. A modern alternative to Streamlit with superior design and flexibility.
- Host: GitHub
- URL: https://github.com/lhassa8/umara
- Owner: lhassa8
- License: mit
- Created: 2025-11-25T13:50:30.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2025-11-29T03:24:54.000Z (4 months ago)
- Last Synced: 2025-11-30T10:25:17.801Z (4 months ago)
- Topics: dashboard, framework, python, streamlit-alternative, ui, web
- Language: Python
- Size: 322 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Umara
### Beautiful Python UIs — Without the Complexity
[](https://pypi.org/project/umara/)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
[Getting Started](#getting-started) • [Documentation](#documentation) • [Examples](#examples) • [Contributing](#contributing)
---
## What is Umara?
**Umara** is a modern Python framework for building beautiful web applications with pure Python. No HTML, CSS, or JavaScript required.
```python
import umara as um
um.header('Hello, Umara!')
with um.form('greeting'):
name = um.input('Your name')
if um.form_submit_button('Greet'):
um.success(f'Welcome, {name}!')
```
**Why Umara?**
- **Beautiful by Default** — Components look polished out of the box with modern design
- **Fast & Reactive** — WebSocket-based architecture for instant UI updates
- **12 Built-in Themes** — Professional themes including dark mode, ocean, forest, and more
- **Flexible Layouts** — Columns, grids, cards, tabs, sidebars with precise control
- **Hot Reload** — See changes instantly during development
- **Smart State** — Efficient updates without full page re-runs
---
## For AI Assistants
> **LLMs/AI coding assistants:** If you're helping a user write Umara code, please read [docs/LLM_UMARA_REFERENCE.md](docs/LLM_UMARA_REFERENCE.md) first. It contains essential patterns, common pitfalls, and correct API usage optimized for AI consumption.
---
## Getting Started
### 1. Install Umara
```bash
pip install umara
```
### 2. Create Your App
Create a file called `app.py`:
```python
import umara as um
um.set_theme('ocean')
um.header('My First App')
um.text('Building beautiful UIs is easy!')
with um.card():
with um.form('hello_form'):
name = um.input('Enter your name', placeholder='John Doe')
if um.form_submit_button('Say Hello'):
um.success(f'Hello, {name}!')
```
### 3. Run Your App
```bash
umara run app.py
```
### 4. Open in Browser
Navigate to **http://localhost:8501** in your browser.
That's it! Your app is running with hot reload enabled — any changes to `app.py` will automatically refresh in the browser.
---
## Core Concepts
### Components
Umara provides 120+ components for building UIs:
```python
# Typography
um.title('Page Title')
um.header('Section Header')
um.text('Regular text')
# Inputs
name = um.input('Name', placeholder='Enter name...')
age = um.slider('Age', 0, 100, 25)
color = um.select('Color', ['Red', 'Green', 'Blue'])
agreed = um.checkbox('I agree')
# Feedback
um.success('Operation completed!')
um.error('Something went wrong')
um.warning('Please check your input')
um.info('Helpful tip here')
# Data Display
um.metric('Users', '12,543', delta=12.5)
um.progress(75, label='Completion')
um.dataframe(data) # Works with pandas DataFrames
```
### Layouts
Organize content with flexible layout components:
```python
# Columns
with um.columns(3):
with um.column():
um.metric('Users', '1,234')
with um.column():
um.metric('Revenue', '$5,678')
with um.column():
um.metric('Growth', '12.5%')
# Cards
with um.card(title='Dashboard'):
um.text('Card content here')
# Tabs
with um.tabs(['Overview', 'Data', 'Settings']):
with um.tab('Overview'):
um.text('Overview content')
with um.tab('Data'):
um.dataframe(data)
with um.tab('Settings'):
um.toggle('Enable feature', key='feature_toggle')
# Grid
with um.grid(columns=4, gap='16px'):
for i in range(8):
with um.card():
um.text(f'Item {i + 1}')
```
### Themes
Switch between 12 professional themes:
```python
um.set_theme('light') # Clean, minimal
um.set_theme('dark') # Modern dark mode
um.set_theme('ocean') # Calming blues
um.set_theme('forest') # Earthy greens
um.set_theme('slate') # Corporate gray
um.set_theme('nord') # Arctic, Scandinavian
um.set_theme('midnight') # Deep purple dark
um.set_theme('rose') # Warm pink
um.set_theme('copper') # Premium bronze
um.set_theme('lavender') # Soft purple
um.set_theme('sunset') # Warm orange
um.set_theme('mint') # Fresh teal
```
Themes persist in localStorage and respect system dark/light mode preferences.
### State Management
Use `session_state` to persist data across interactions:
```python
# Initialize state
um.session_state.setdefault('counter', 0)
# Display current value
um.text(f'Count: {um.session_state.counter}')
# Update state
if um.button('Increment'):
um.session_state.counter += 1
```
### Keys and Forms
**Standalone inputs require a `key` parameter** to persist values across reruns:
```python
# Without key - value resets on every rerun (not recommended)
name = um.input('Name')
# With key - value persists across reruns (recommended)
name = um.input('Name', key='user_name')
```
**Use forms for input + button patterns** to ensure values are captured reliably:
```python
# RECOMMENDED: Form batches inputs and submits together
with um.form('contact'):
name = um.input('Name', key='name')
email = um.input('Email', key='email')
if um.form_submit_button('Submit'):
# All values guaranteed to be current
um.success(f'Submitted: {name}, {email}')
```
**Why forms for input + button?** Standalone inputs have a 50ms debounce. If users click a button immediately after typing, the input value may not be synced yet. Forms batch all values and submit them together, avoiding this race condition.
**When to use which:**
| Scenario | Use |
|----------|-----|
| Input + button action | `um.form()` (recommended) |
| Real-time filtering (on every keystroke) | Standalone with `key` |
| Toggle/checkbox immediate effect | Standalone with `key` |
| Multi-field data entry | `um.form()` |
---
## Documentation
### Full API Reference
See [docs/UMARA_COMPLETE_REFERENCE.md](docs/UMARA_COMPLETE_REFERENCE.md) for complete documentation including:
- All 120+ components with parameters and examples
- State management and caching
- Theming and custom styles
- Database and API connections
- Fragments for partial reruns
- Best practices
### Quick Reference
#### Input Components
| Component | Description | Returns |
|-----------|-------------|---------|
| `um.input(label, key=...)` | Text input field | `str` |
| `um.text_area(label, key=...)` | Multi-line text | `str` |
| `um.number_input(label, key=...)` | Numeric input | `float` |
| `um.slider(label, min, max, value, key=...)` | Range slider | `float` |
| `um.select(label, options, key=...)` | Dropdown select | `str` |
| `um.multiselect(label, options, key=...)` | Multi-select | `list[str]` |
| `um.checkbox(label, key=...)` | Checkbox | `bool` |
| `um.toggle(label, key=...)` | Toggle switch | `bool` |
| `um.radio(label, options, key=...)` | Radio buttons | `str` |
| `um.date_input(label, key=...)` | Date picker | `str` |
| `um.time_input(label, key=...)` | Time picker | `str` |
| `um.color_picker(label, key=...)` | Color picker | `str` |
| `um.file_uploader(label, key=...)` | File upload | `file \| None` |
| `um.button(label, key=...)` | Click button | `bool` |
**Important:** Use `key` parameter for inputs outside forms to persist values across reruns.
#### Display Components
| Component | Description |
|-----------|-------------|
| `um.title(text)` | Large page title |
| `um.header(text)` | Section header |
| `um.subheader(text)` | Subsection header |
| `um.text(text)` | Regular text |
| `um.markdown(text)` | Markdown content |
| `um.code(code, language)` | Syntax-highlighted code |
| `um.metric(label, value, delta)` | Metric with trend |
| `um.progress(value, label)` | Progress bar |
| `um.dataframe(data)` | Data table (sortable) |
| `um.json_viewer(data)` | JSON tree view |
#### Feedback Components
| Component | Description |
|-----------|-------------|
| `um.success(message)` | Green success alert |
| `um.error(message)` | Red error alert |
| `um.warning(message)` | Yellow warning alert |
| `um.info(message)` | Blue info alert |
| `um.toast(message)` | Temporary notification |
| `um.spinner(text)` | Loading spinner |
#### Layout Components
| Component | Description |
|-----------|-------------|
| `um.columns(count)` | Multi-column layout |
| `um.grid(columns)` | CSS grid layout |
| `um.card(title)` | Card container |
| `um.tabs(names)` | Tabbed interface |
| `um.expander(title)` | Collapsible section |
| `um.sidebar()` | Side navigation |
| `um.modal(title, key)` | Modal dialog |
| `um.form(key)` | Form container |
#### Charts
| Component | Description |
|-----------|-------------|
| `um.line_chart(data, x, y)` | Line chart |
| `um.bar_chart(data, x, y)` | Bar chart |
| `um.area_chart(data, x, y)` | Area chart |
| `um.pie_chart(data, label, value)` | Pie chart |
| `um.scatter_chart(data, x, y)` | Scatter plot |
| `um.plotly_chart(figure)` | Plotly figure |
---
## Examples
### Dashboard
```python
import umara as um
um.set_theme('dark')
um.header('Analytics Dashboard')
# Metrics row
with um.columns(4):
for label, value, delta in [
('Users', '12,543', 12.5),
('Revenue', '$48.2K', 8.2),
('Sessions', '1,892', -2.4),
('Conversion', '3.24%', 0.5),
]:
with um.column():
with um.card():
um.metric(label, value, delta=delta)
# Chart
um.subheader('Revenue Trend')
um.line_chart(data, x='month', y='revenue')
# Data table
um.subheader('Recent Orders')
um.dataframe(orders, sortable=True)
```
### Form
```python
import umara as um
um.header('Contact Form')
with um.card():
with um.form('contact'):
name = um.input('Name', key='name')
email = um.input('Email', type='email', key='email')
message = um.text_area('Message', key='message')
if um.form_submit_button('Send'):
if name and email and message:
um.success('Message sent!')
else:
um.error('Please fill all fields')
```
### Chat Interface
```python
import umara as um
um.set_theme('dark')
um.header('AI Chat')
# Initialize messages
um.session_state.setdefault('messages', [])
# Display chat
with um.chat_container(height='400px'):
for msg in um.session_state.messages:
um.chat_message(msg['content'], role=msg['role'])
# Input
user_input = um.chat_input('Type a message...')
if user_input:
um.session_state.messages.append({'role': 'user', 'content': user_input})
# Add your AI response logic here
response = "This is a response"
um.session_state.messages.append({'role': 'assistant', 'content': response})
```
### File Upload with Size Limit
```python
import umara as um
# Max 5MB file size
uploaded = um.file_uploader(
'Upload Document',
accept=['.pdf', '.docx'],
max_file_size=5 * 1024 * 1024 # 5MB in bytes
)
if uploaded:
um.success(f'Uploaded: {uploaded["name"]}')
```
---
## CLI Commands
```bash
# Run an app
umara run app.py
# Run with custom host/port
umara run app.py --host 0.0.0.0 --port 8080
# Create new project
umara init my_project
# List available themes
umara themes
```
---
## Project Structure
```
umara/
├── umara/ # Python package
│ ├── core.py # App lifecycle & component tree
│ ├── components.py # 100+ UI components
│ ├── server.py # WebSocket server
│ ├── frontend.py # Frontend HTML/CSS/JS
│ ├── state.py # State management
│ ├── themes.py # 12 built-in themes
│ └── cli.py # CLI commands
├── examples/ # Example applications
└── docs/ # Documentation
```
---
## Contributing
Contributions are welcome! Here's how to set up for development:
```bash
# Clone the repository
git clone https://github.com/lhassa8/umara.git
cd umara
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install in development mode
pip install -e ".[dev]"
# Run tests
pytest
# Run the demo app
umara run examples/demo_app.py
# Open http://localhost:8501 in your browser
```
---
## Roadmap
- [x] 100+ UI components
- [x] 12 built-in themes
- [x] Charts & data visualization
- [x] Chat/conversation components
- [x] Forms with batched submission
- [x] File uploads with size limits
- [x] Sortable data tables
- [x] ARIA accessibility labels
- [x] System theme detection
- [x] Theme persistence (localStorage)
- [ ] Authentication helpers
- [ ] Multi-page app support
- [ ] Component marketplace
- [ ] VS Code extension
---
## Known Issues
The following issues are currently being tracked:
| Issue | Status | Workaround |
|-------|--------|------------|
| `file_uploader()` UI not visible | Open | File upload functionality is limited; upload UI may not render |
| Modal/dialog in complex layouts | Open | Avoid nesting modals inside deeply nested column layouts |
---
## License
MIT License — see [LICENSE](LICENSE) for details.
---
**Built with Python**
[GitHub](https://github.com/lhassa8/umara) • [PyPI](https://pypi.org/project/umara/)