fastui2 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fastui2-0.1.0/PKG-INFO +454 -0
- fastui2-0.1.0/README.md +417 -0
- fastui2-0.1.0/fastui/__init__.py +11 -0
- fastui2-0.1.0/fastui/__meta__.py +1 -0
- fastui2-0.1.0/fastui/app.py +502 -0
- fastui2-0.1.0/fastui/components.py +519 -0
- fastui2-0.1.0/fastui/openapi/__init__.py +8 -0
- fastui2-0.1.0/fastui/openapi/generator.py +163 -0
- fastui2-0.1.0/fastui/openapi/swagger.py +107 -0
- fastui2-0.1.0/fastui/openapi/urls.py +21 -0
- fastui2-0.1.0/fastui/py.typed +0 -0
- fastui2-0.1.0/fastui/router.py +160 -0
- fastui2-0.1.0/fastui2.egg-info/PKG-INFO +454 -0
- fastui2-0.1.0/fastui2.egg-info/SOURCES.txt +17 -0
- fastui2-0.1.0/fastui2.egg-info/dependency_links.txt +1 -0
- fastui2-0.1.0/fastui2.egg-info/requires.txt +10 -0
- fastui2-0.1.0/fastui2.egg-info/top_level.txt +1 -0
- fastui2-0.1.0/pyproject.toml +85 -0
- fastui2-0.1.0/setup.cfg +4 -0
fastui2-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fastui2
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Build web UIs with Python decorators, compile to HTML, zero JavaScript required
|
|
5
|
+
Author-email: White NEFOR <n7for8572@gmail.com>
|
|
6
|
+
Maintainer-email: White NEFOR <n7for8572@gmail.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/ndugram/fastui2
|
|
9
|
+
Project-URL: Documentation, https://fastui.ndugram.dev
|
|
10
|
+
Project-URL: Repository, https://github.com/ndugram/fastui2
|
|
11
|
+
Project-URL: Issues, https://github.com/ndugram/fastui2/issues
|
|
12
|
+
Keywords: fastui,ui,web,html,decorators,python,pydantic,no-js
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: Software Development :: User Interfaces
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
Requires-Dist: annotated-doc>=0.0.4
|
|
29
|
+
Requires-Dist: pydantic>=2.13.4
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.15.15; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy>=1.15.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mkdocs>=1.6.0; extra == "dev"
|
|
35
|
+
Requires-Dist: mkdocs-material>=9.5.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pymdown-extensions>=10.21.3; extra == "dev"
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<img src="https://fastui.ndugram.dev/ru/latest/logo.png" style="background:white; padding:12px; border-radius:10px; width:350">
|
|
40
|
+
</p>
|
|
41
|
+
<p align="center">
|
|
42
|
+
<em>FastUI — build web UIs with Python decorators, compile to HTML, zero JavaScript required.</em>
|
|
43
|
+
</p>
|
|
44
|
+
<p align="center">
|
|
45
|
+
<a href="https://github.com/ndugram/fastui2/actions/workflows/tests.yml" target="_blank">
|
|
46
|
+
<img src="https://github.com/ndugram/fastui2/actions/workflows/tests.yml/badge.svg" alt="Tests">
|
|
47
|
+
</a>
|
|
48
|
+
<a href="https://pypi.org/project/fastui2" target="_blank">
|
|
49
|
+
<img src="https://img.shields.io/pypi/v/fastui2?color=%2334D058&label=pypi%20package" alt="Package version">
|
|
50
|
+
</a>
|
|
51
|
+
<a href="https://www.python.org/" target="_blank">
|
|
52
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/ndugram/fastui/master/docs/endpoints/python.json" alt="Python">
|
|
53
|
+
</a>
|
|
54
|
+
<a href="https://pypi.org/project/fastui2" target="_blank">
|
|
55
|
+
<img src="https://img.shields.io/pypi/dm/fastui2?color=%2334D058&label=downloads" alt="Monthly downloads">
|
|
56
|
+
</a>
|
|
57
|
+
<a href="https://pepy.tech/projects/fastui2" target="_blank">
|
|
58
|
+
<img src="https://img.shields.io/pepy/dt/fastui2?color=%2334D058&label=total%20downloads" alt="Total downloads">
|
|
59
|
+
</a>
|
|
60
|
+
<a href="https://pydantic.dev" target="_blank">
|
|
61
|
+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/pydantic/pydantic/main/docs/badge/v2.json" alt="Pydantic v2">
|
|
62
|
+
</a>
|
|
63
|
+
</p>
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
**Documentation**: <a href="https://fastui.ndugram.dev/ru/latest/" target="_blank">https://fastui.ndugram.dev/ru/latest/</a>
|
|
68
|
+
|
|
69
|
+
**Source Code**: <a href="https://github.com/ndugram/fastui2" target="_blank">https://github.com/ndugram/fastui2</a>
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
FastUI is a modern **server-rendered UI library** for Python. It brings a decorator-based API — similar to FastAPI, but for building HTML pages — with Pydantic-validated components, URL routing, server-side actions, and a built-in Swagger UI.
|
|
74
|
+
|
|
75
|
+
Key features:
|
|
76
|
+
|
|
77
|
+
- **Fast** — components compile directly to HTML, no template engine overhead. Built-in hot reload for development.
|
|
78
|
+
- **Simple** — define pages as decorated Python functions, return component lists, no HTML templates.
|
|
79
|
+
- **Typed** — full type annotations throughout; all components are Pydantic-validated models with strict validation.
|
|
80
|
+
- **Zero JS** — everything compiles to plain HTML. Buttons with server actions use a lightweight POST mechanism.
|
|
81
|
+
- **Routed** — URL patterns with typed parameters (`/user/{id:int}`, `/post/{year:int}/{slug}`).
|
|
82
|
+
- **Interactive** — built-in Swagger UI via `/docs` to browse and test page routes in the browser.
|
|
83
|
+
- **Extensible** — custom CSS, external stylesheets, inline styles, component protocol for custom components.
|
|
84
|
+
|
|
85
|
+
## Requirements
|
|
86
|
+
|
|
87
|
+
Python 3.10+
|
|
88
|
+
|
|
89
|
+
FastUI depends on:
|
|
90
|
+
|
|
91
|
+
- <a href="https://docs.pydantic.dev/" target="_blank"><code>pydantic</code></a> — component model validation and serialization.
|
|
92
|
+
- <a href="https://pypi.org/project/annotated-doc/" target="_blank"><code>annotated-doc</code></a> — parameter documentation via `Annotated[type, Doc("...")]`.
|
|
93
|
+
|
|
94
|
+
## Installation
|
|
95
|
+
|
|
96
|
+
```console
|
|
97
|
+
$ pip install fastui2
|
|
98
|
+
|
|
99
|
+
---> 100%
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Example
|
|
103
|
+
|
|
104
|
+
### Create it
|
|
105
|
+
|
|
106
|
+
Create a file `main.py`:
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from fastui import App, ui
|
|
110
|
+
|
|
111
|
+
app = App()
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
@app.page("/")
|
|
115
|
+
def home():
|
|
116
|
+
return [
|
|
117
|
+
ui.heading("FastUI", level=1),
|
|
118
|
+
ui.text("Build UIs with Python. No JavaScript required."),
|
|
119
|
+
ui.button("About", on_click="/about"),
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@app.page("/about")
|
|
124
|
+
def about():
|
|
125
|
+
return [
|
|
126
|
+
ui.heading("About", level=1),
|
|
127
|
+
ui.text("FastUI compiles Pydantic components to HTML."),
|
|
128
|
+
ui.link("Back", url="/"),
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if __name__ == "__main__":
|
|
133
|
+
app.run()
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Run it
|
|
137
|
+
|
|
138
|
+
```console
|
|
139
|
+
$ python main.py
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Check it
|
|
143
|
+
|
|
144
|
+
You will see output like:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
╔════════════════════════════════════════════╗
|
|
148
|
+
║ FastUI Dev Server ║
|
|
149
|
+
╠════════════════════════════════════════════╣
|
|
150
|
+
║ ║
|
|
151
|
+
║ → http://127.0.0.1:8000 ║
|
|
152
|
+
║ ║
|
|
153
|
+
║ ♻ Hot reload ║
|
|
154
|
+
║ ║
|
|
155
|
+
║ 📖 Docs http://127.0.0.1:8000/docs ║
|
|
156
|
+
║ ║
|
|
157
|
+
║ Routes: ║
|
|
158
|
+
║ • / ║
|
|
159
|
+
║ • /about ║
|
|
160
|
+
║ ║
|
|
161
|
+
╚════════════════════════════════════════════╝
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Open `http://127.0.0.1:8000` in your browser.
|
|
165
|
+
|
|
166
|
+
### Interactive API docs
|
|
167
|
+
|
|
168
|
+
Now go to <a href="http://127.0.0.1:8000/docs" target="_blank">http://127.0.0.1:8000/docs</a>.
|
|
169
|
+
|
|
170
|
+
You will see the automatic interactive API documentation with all registered routes:
|
|
171
|
+
|
|
172
|
+
<img src="docs/photo/swagger_ui_home.png">
|
|
173
|
+
|
|
174
|
+
Each route shows its URL pattern, summary, parameters, and response schema:
|
|
175
|
+
|
|
176
|
+
<img src="docs/photo/swagger_ui_check_web.png">
|
|
177
|
+
|
|
178
|
+
Routes with path parameters (`{id:int}`, `{slug}`) have input fields for testing:
|
|
179
|
+
|
|
180
|
+
<img src="docs/photo/swagger_ui_check_execute.png">
|
|
181
|
+
|
|
182
|
+
### Upgrade the example
|
|
183
|
+
|
|
184
|
+
Now modify `main.py` to get more out of FastUI. Each upgrade below builds on the previous one.
|
|
185
|
+
|
|
186
|
+
<details markdown="1">
|
|
187
|
+
<summary>With typed URL parameters...</summary>
|
|
188
|
+
|
|
189
|
+
Add a route with an integer parameter:
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
@app.page("/user/{id:int}", title="Profile")
|
|
193
|
+
def user_profile(id: int):
|
|
194
|
+
return [
|
|
195
|
+
ui.heading(f"User #{id}", level=1),
|
|
196
|
+
ui.text(f"Profile page for user {id}."),
|
|
197
|
+
ui.link("Back", url="/"),
|
|
198
|
+
]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Visit `http://127.0.0.1:8000/user/42`. The `id` parameter is automatically converted to `int`.
|
|
202
|
+
|
|
203
|
+
</details>
|
|
204
|
+
|
|
205
|
+
<details markdown="1">
|
|
206
|
+
<summary>With server actions (POST handlers)...</summary>
|
|
207
|
+
|
|
208
|
+
Buttons can call Python functions on the server via POST:
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
counter = 0
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def increment() -> list:
|
|
215
|
+
global counter
|
|
216
|
+
counter += 1
|
|
217
|
+
return [
|
|
218
|
+
ui.heading(f"Count: {counter}", level=1),
|
|
219
|
+
ui.button("+1", on_click=increment),
|
|
220
|
+
ui.link("Back", url="/counter"),
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
@app.page("/counter")
|
|
225
|
+
def counter_page():
|
|
226
|
+
return [
|
|
227
|
+
ui.heading("Counter", level=1),
|
|
228
|
+
ui.text(f"Value: {counter}"),
|
|
229
|
+
ui.button("+1", on_click=increment),
|
|
230
|
+
]
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
When `on_click` receives a callable, the framework registers it as a POST endpoint and
|
|
234
|
+
replaces it with the action URL before rendering.
|
|
235
|
+
|
|
236
|
+
</details>
|
|
237
|
+
|
|
238
|
+
<details markdown="1">
|
|
239
|
+
<summary>With custom CSS...</summary>
|
|
240
|
+
|
|
241
|
+
Pass custom CSS to the `App` constructor:
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
CUSTOM = """
|
|
245
|
+
body { background: #1a1a2e; color: #e0e0e0; }
|
|
246
|
+
h1 { color: #e94560; }
|
|
247
|
+
button { background: #e94560; color: #fff; border: none; }
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
app = App(css=CUSTOM)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Or use external stylesheets:
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
app.stylesheets = [
|
|
257
|
+
"https://cdn.jsdelivr.net/npm/bootstrap@5.3/dist/css/bootstrap.min.css",
|
|
258
|
+
]
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
</details>
|
|
262
|
+
|
|
263
|
+
<details markdown="1">
|
|
264
|
+
<summary>With OpenAPI tags...</summary>
|
|
265
|
+
|
|
266
|
+
Group routes in the Swagger UI with tags:
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
@app.page("/users", title="Users", tags=["users"])
|
|
270
|
+
def users():
|
|
271
|
+
return [ui.heading("Users", level=1)]
|
|
272
|
+
|
|
273
|
+
@app.page("/items", title="Items", tags=["items"])
|
|
274
|
+
def items():
|
|
275
|
+
return [ui.heading("Items", level=1)]
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Tags appear as a filter in the Swagger UI header.
|
|
279
|
+
|
|
280
|
+
</details>
|
|
281
|
+
|
|
282
|
+
<details markdown="1">
|
|
283
|
+
<summary>With a multi-page layout...</summary>
|
|
284
|
+
|
|
285
|
+
Share navigation across pages with a helper function:
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
def nav() -> ui.page:
|
|
289
|
+
return ui.page([
|
|
290
|
+
ui.link("Home", url="/", style="margin-right: 1rem;"),
|
|
291
|
+
ui.link("Blog", url="/blog", style="margin-right: 1rem;"),
|
|
292
|
+
ui.link("About", url="/about"),
|
|
293
|
+
], style="padding: 1rem; background: #f0f0f0; border-radius: 8px; margin-bottom: 1rem;")
|
|
294
|
+
|
|
295
|
+
@app.page("/")
|
|
296
|
+
def home():
|
|
297
|
+
return [nav(), ui.heading("Home", level=1), ui.text("Welcome!")]
|
|
298
|
+
|
|
299
|
+
@app.page("/about")
|
|
300
|
+
def about():
|
|
301
|
+
return [nav(), ui.heading("About", level=1), ui.text("FastUI details.")]
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
</details>
|
|
305
|
+
|
|
306
|
+
## Components
|
|
307
|
+
|
|
308
|
+
All built-in components are available through the `ui` builder:
|
|
309
|
+
|
|
310
|
+
| Component | Builder | HTML |
|
|
311
|
+
|---|---|---|
|
|
312
|
+
| Heading | `ui.heading("text", level=1)` | `<h1>text</h1>` |
|
|
313
|
+
| Text | `ui.text("content")` | `<p>content</p>` |
|
|
314
|
+
| Button | `ui.button("label", on_click=...)` | `<button>label</button>` |
|
|
315
|
+
| Input | `ui.input(label="Name")` | `<label>Name<input></label>` |
|
|
316
|
+
| Link | `ui.link("text", url="/")` | `<a href="/">text</a>` |
|
|
317
|
+
| Code | `ui.code("code")` | `<pre><code>code</code></pre>` |
|
|
318
|
+
| Divider | `ui.divider()` | `<hr>` |
|
|
319
|
+
| Page | `ui.page([...])` | `<div>...</div>` |
|
|
320
|
+
|
|
321
|
+
Every component accepts optional styling:
|
|
322
|
+
|
|
323
|
+
```python
|
|
324
|
+
ui.heading("Styled", level=2, style="color: red;")
|
|
325
|
+
ui.button("Big", class_name="btn-lg", style="padding: 1rem;")
|
|
326
|
+
ui.text("Centered", style="text-align: center;")
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Routing
|
|
330
|
+
|
|
331
|
+
Routes map URL patterns to handler functions. Patterns support typed parameters:
|
|
332
|
+
|
|
333
|
+
| Pattern | Example URL | Handler receives |
|
|
334
|
+
|---|---|---|
|
|
335
|
+
| `/` | `/` | — |
|
|
336
|
+
| `/about` | `/about` | — |
|
|
337
|
+
| `/user/{id:int}` | `/user/42` | `id=42` (int) |
|
|
338
|
+
| `/hello/{name}` | `/hello/world` | `name='world'` (str) |
|
|
339
|
+
| `/post/{year:int}/{slug}` | `/post/2025/hello` | `year=2025, slug='hello'` |
|
|
340
|
+
|
|
341
|
+
Routes are registered in order; the first match wins.
|
|
342
|
+
|
|
343
|
+
## Server actions
|
|
344
|
+
|
|
345
|
+
Buttons can call server-side Python functions via POST:
|
|
346
|
+
|
|
347
|
+
```python
|
|
348
|
+
def handle_click() -> list:
|
|
349
|
+
return [
|
|
350
|
+
ui.heading("Clicked!", level=2, style="color: green;"),
|
|
351
|
+
ui.link("Back", url="/"),
|
|
352
|
+
]
|
|
353
|
+
|
|
354
|
+
@app.page("/")
|
|
355
|
+
def index():
|
|
356
|
+
return [
|
|
357
|
+
ui.button("Click me", on_click=handle_click),
|
|
358
|
+
]
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
The framework automatically:
|
|
362
|
+
|
|
363
|
+
1. Registers the callable as a POST endpoint at `/_ui/action/<id>`
|
|
364
|
+
2. Replaces the callable with the action URL in the rendered HTML
|
|
365
|
+
3. On click, the browser POSTs to the action URL
|
|
366
|
+
4. The handler runs and returns new components rendered as HTML
|
|
367
|
+
|
|
368
|
+
## OpenAPI documentation
|
|
369
|
+
|
|
370
|
+
FastUI auto-generates OpenAPI 3.0 schema for all routes. Available at `/docs` (Swagger UI)
|
|
371
|
+
and `/openapi.json` by default.
|
|
372
|
+
|
|
373
|
+
```python
|
|
374
|
+
app = App(
|
|
375
|
+
title="My API",
|
|
376
|
+
version="2.0.0",
|
|
377
|
+
description="API description in **Markdown**.",
|
|
378
|
+
docs_url="/api-docs",
|
|
379
|
+
openapi_url="/api-schema.json",
|
|
380
|
+
)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Disable docs:
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
app = App(docs=False)
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
## Hot reload
|
|
390
|
+
|
|
391
|
+
Enable auto-refresh on file changes:
|
|
392
|
+
|
|
393
|
+
```python
|
|
394
|
+
app.run(hot_reload=True)
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
The server polls `.py` files in the current directory and the `fastui` package directory.
|
|
398
|
+
On change, the browser refreshes automatically.
|
|
399
|
+
|
|
400
|
+
## Examples
|
|
401
|
+
|
|
402
|
+
See the [examples](examples/) directory for 20 complete, runnable programs:
|
|
403
|
+
|
|
404
|
+
| # | Example | What it shows |
|
|
405
|
+
|---|---|---|
|
|
406
|
+
| 1 | [hello_world](examples/01_hello_world.py) | Minimal app — one page, one heading |
|
|
407
|
+
| 2 | [all_components](examples/02_all_components.py) | Every built-in component type |
|
|
408
|
+
| 3 | [route_params](examples/03_route_params.py) | URL patterns with typed parameters |
|
|
409
|
+
| 4 | [server_actions](examples/04_server_actions.py) | POST callback handlers |
|
|
410
|
+
| 5 | [custom_css](examples/05_custom_css.py) | Dark theme with custom CSS |
|
|
411
|
+
| 6 | [forms](examples/06_forms.py) | Input fields and form layout |
|
|
412
|
+
| 7 | [navigation](examples/07_navigation.py) | Multi-page navigation with links |
|
|
413
|
+
| 8 | [docs_config](examples/08_docs_config.py) | Custom OpenAPI docs metadata |
|
|
414
|
+
| 9 | [layout_page](examples/09_layout_page.py) | Page component for grouping |
|
|
415
|
+
| 10 | [counter](examples/10_counter.py) | Interactive counter with actions |
|
|
416
|
+
| 11 | [todo](examples/11_todo.py) | Simple todo application |
|
|
417
|
+
| 12 | [hot_reload](examples/12_hot_reload.py) | Hot reload demo |
|
|
418
|
+
| 13 | [multi_page](examples/13_multi_page.py) | Shared navigation layout |
|
|
419
|
+
| 14 | [no_docs](examples/14_no_docs.py) | Running without docs |
|
|
420
|
+
| 15 | [external_stylesheets](examples/15_external_stylesheets.py) | Bootstrap integration |
|
|
421
|
+
| 16 | [single_component](examples/16_single_component.py) | Returning single vs list |
|
|
422
|
+
| 17 | [advanced_routing](examples/17_advanced_routing.py) | Complex multi-param routes |
|
|
423
|
+
| 18 | [inline_styles](examples/18_inline_styles.py) | All style combinations |
|
|
424
|
+
| 19 | [minimal](examples/19_minimal.py) | Absolute minimal app (7 lines) |
|
|
425
|
+
| 20 | [dynamic_routes](examples/20_dynamic_routes.py) | Dynamically generated routes |
|
|
426
|
+
|
|
427
|
+
## FAQ
|
|
428
|
+
|
|
429
|
+
- **Why would I use FastUI instead of Flask + Jinja2?**
|
|
430
|
+
FastUI eliminates the template layer — you write UIs entirely in Python without HTML files.
|
|
431
|
+
It's ideal for small to medium apps where the overhead of a template engine isn't justified.
|
|
432
|
+
|
|
433
|
+
- **Why would I use FastUI instead of Streamlit?**
|
|
434
|
+
FastUI gives you explicit control over routing, URL parameters, and page structure.
|
|
435
|
+
Streamlit is script-based and re-runs everything on every interaction; FastUI uses
|
|
436
|
+
traditional request-response with proper URL routing.
|
|
437
|
+
|
|
438
|
+
- **Does FastUI support async handlers?**
|
|
439
|
+
Not yet. Handlers are synchronous. Async support is planned.
|
|
440
|
+
|
|
441
|
+
- **Can I use FastUI with an existing HTTP server?**
|
|
442
|
+
The `App` class runs its own dev server. For production, you'd wrap it in ASGI/WSGI —
|
|
443
|
+
this is on the roadmap.
|
|
444
|
+
|
|
445
|
+
- **Does FastUI support WebSockets?**
|
|
446
|
+
Not currently. Server-sent events and WebSocket support may be added later.
|
|
447
|
+
|
|
448
|
+
- **Can I write my own components?**
|
|
449
|
+
Yes. Any object with a `to_html()` method satisfies the `Component` protocol.
|
|
450
|
+
Pydantic models with `to_html()` work seamlessly.
|
|
451
|
+
|
|
452
|
+
- **Is FastUI production-ready?**
|
|
453
|
+
FastUI is in early development (v0.1.0). The API may change. It's suitable for
|
|
454
|
+
internal tools and prototypes but not yet for customer-facing production apps.
|