brickflowui 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.
Files changed (56) hide show
  1. brickflowui-0.1.0/.gitignore +11 -0
  2. brickflowui-0.1.0/LICENSE +21 -0
  3. brickflowui-0.1.0/PKG-INFO +449 -0
  4. brickflowui-0.1.0/README.md +384 -0
  5. brickflowui-0.1.0/brickflowui/__init__.py +141 -0
  6. brickflowui-0.1.0/brickflowui/app.py +304 -0
  7. brickflowui-0.1.0/brickflowui/auth.py +222 -0
  8. brickflowui-0.1.0/brickflowui/cli/__init__.py +4 -0
  9. brickflowui-0.1.0/brickflowui/cli/main.py +109 -0
  10. brickflowui-0.1.0/brickflowui/cli/templates/default/.env.example +20 -0
  11. brickflowui-0.1.0/brickflowui/cli/templates/default/app.py +44 -0
  12. brickflowui-0.1.0/brickflowui/cli/templates/default/app.yaml +17 -0
  13. brickflowui-0.1.0/brickflowui/cli/templates/default/requirements.txt +5 -0
  14. brickflowui-0.1.0/brickflowui/components.py +529 -0
  15. brickflowui-0.1.0/brickflowui/databricks/__init__.py +5 -0
  16. brickflowui-0.1.0/brickflowui/databricks/env.py +77 -0
  17. brickflowui-0.1.0/brickflowui/databricks/sql.py +133 -0
  18. brickflowui-0.1.0/brickflowui/databricks/uc.py +147 -0
  19. brickflowui-0.1.0/brickflowui/server.py +559 -0
  20. brickflowui-0.1.0/brickflowui/state.py +203 -0
  21. brickflowui-0.1.0/brickflowui/theme.json +26 -0
  22. brickflowui-0.1.0/brickflowui/theme.py +163 -0
  23. brickflowui-0.1.0/brickflowui/vdom.py +165 -0
  24. brickflowui-0.1.0/bricksflowui/__init__.py +6 -0
  25. brickflowui-0.1.0/bricksflowui/cli/__init__.py +1 -0
  26. brickflowui-0.1.0/bricksflowui/cli/main.py +5 -0
  27. brickflowui-0.1.0/docs/API_REFERENCE.md +111 -0
  28. brickflowui-0.1.0/docs/BUILD.md +75 -0
  29. brickflowui-0.1.0/docs/GETTING_STARTED.md +64 -0
  30. brickflowui-0.1.0/docs/PUBLISHING.md +88 -0
  31. brickflowui-0.1.0/docs/THEMING.md +59 -0
  32. brickflowui-0.1.0/docs/TUTORIAL.md +166 -0
  33. brickflowui-0.1.0/examples/auth_portal/app.py +382 -0
  34. brickflowui-0.1.0/examples/auth_portal/app.yaml +7 -0
  35. brickflowui-0.1.0/examples/auth_portal/astellas_theme.yaml +27 -0
  36. brickflowui-0.1.0/examples/auth_portal/requirements.txt +1 -0
  37. brickflowui-0.1.0/examples/counter/app.py +48 -0
  38. brickflowui-0.1.0/examples/demo_app/app.py +519 -0
  39. brickflowui-0.1.0/examples/demo_app/app.yaml +11 -0
  40. brickflowui-0.1.0/examples/demo_app/requirements.txt +2 -0
  41. brickflowui-0.1.0/examples/operations_finance_portal/app.py +451 -0
  42. brickflowui-0.1.0/examples/operations_finance_portal/app.yaml +7 -0
  43. brickflowui-0.1.0/examples/operations_finance_portal/portal_theme.yaml +27 -0
  44. brickflowui-0.1.0/examples/operations_finance_portal/requirements.txt +1 -0
  45. brickflowui-0.1.0/examples/showcase/app.py +242 -0
  46. brickflowui-0.1.0/examples/showcase/theme.yaml +22 -0
  47. brickflowui-0.1.0/examples/weather_dashboard/app.py +121 -0
  48. brickflowui-0.1.0/pyproject.toml +91 -0
  49. brickflowui-0.1.0/tests/_branding_test.yaml +4 -0
  50. brickflowui-0.1.0/tests/test_app_server.py +152 -0
  51. brickflowui-0.1.0/tests/test_cli.py +39 -0
  52. brickflowui-0.1.0/tests/test_databricks_uc.py +17 -0
  53. brickflowui-0.1.0/tests/test_package_alias.py +10 -0
  54. brickflowui-0.1.0/tests/test_state.py +116 -0
  55. brickflowui-0.1.0/tests/test_theme.py +67 -0
  56. brickflowui-0.1.0/tests/test_vdom.py +84 -0
@@ -0,0 +1,11 @@
1
+ .pytest_cache/
2
+ .tmp/
3
+ .venv/
4
+ build/
5
+ dist/
6
+ frontend/node_modules/
7
+ *.egg-info/
8
+ *.pyc
9
+ __pycache__/
10
+ tests/_tmp_cli/
11
+ frontend/tsc_errors.txt
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BrickflowUI Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,449 @@
1
+ Metadata-Version: 2.4
2
+ Name: brickflowui
3
+ Version: 0.1.0
4
+ Summary: A Databricks-first Python UI framework for building secure dashboards, portals, and web apps with pure Python.
5
+ Project-URL: Homepage, https://github.com/brickflowui/bricksflowui
6
+ Project-URL: Documentation, https://github.com/brickflowui/bricksflowui/tree/main/docs
7
+ Project-URL: Repository, https://github.com/brickflowui/bricksflowui
8
+ Project-URL: Issues, https://github.com/brickflowui/bricksflowui/issues
9
+ Author: BrickflowUI Contributors
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 BrickflowUI Contributors
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: dashboard,databricks,fastapi,portal,python-framework,ui
33
+ Classifier: Development Status :: 3 - Alpha
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Programming Language :: Python :: 3.10
38
+ Classifier: Programming Language :: Python :: 3.11
39
+ Classifier: Programming Language :: Python :: 3.12
40
+ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
41
+ Classifier: Topic :: Software Development :: User Interfaces
42
+ Requires-Python: >=3.10
43
+ Requires-Dist: fastapi>=0.110.0
44
+ Requires-Dist: python-dotenv>=1.0.0
45
+ Requires-Dist: pyyaml>=6.0.0
46
+ Requires-Dist: starlette>=0.37.0
47
+ Requires-Dist: typer>=0.12.0
48
+ Requires-Dist: uvicorn[standard]>=0.29.0
49
+ Requires-Dist: websockets>=12.0
50
+ Provides-Extra: all
51
+ Requires-Dist: bricksflowui[databricks,dev,viz]; extra == 'all'
52
+ Provides-Extra: databricks
53
+ Requires-Dist: databricks-sdk>=0.20.0; extra == 'databricks'
54
+ Requires-Dist: databricks-sql-connector>=3.0.0; extra == 'databricks'
55
+ Requires-Dist: pandas>=2.0.0; extra == 'databricks'
56
+ Provides-Extra: dev
57
+ Requires-Dist: httpx>=0.27.0; extra == 'dev'
58
+ Requires-Dist: mypy>=1.10.0; extra == 'dev'
59
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
60
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
61
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
62
+ Provides-Extra: viz
63
+ Requires-Dist: plotly>=5.0.0; extra == 'viz'
64
+ Description-Content-Type: text/markdown
65
+
66
+ # BricksFlowUI
67
+
68
+ > Canonical package name: `bricksflowui`
69
+ >
70
+ > Install with:
71
+ >
72
+ > ```bash
73
+ > pip install bricksflowui
74
+ > ```
75
+ >
76
+ > Import with:
77
+ >
78
+ > ```python
79
+ > import brickflowui as db
80
+ > ```
81
+ >
82
+ > Start here:
83
+ > - [Getting Started](./docs/GETTING_STARTED.md)
84
+ > - [Build Guide](./docs/BUILD.md)
85
+ > - [API Reference](./docs/API_REFERENCE.md)
86
+ > - [Theming](./docs/THEMING.md)
87
+ > - [Publishing](./docs/PUBLISHING.md)
88
+
89
+ ## Release Notes
90
+
91
+ - PyPI package name is now `bricksflowui`
92
+ - CLI commands supported: `brickflowui` and `bricksflowui`
93
+ - Standard Python import remains `brickflowui`
94
+ - Source distributions and wheels include bundled frontend assets plus docs/examples
95
+
96
+ > **Databricks-first, React-style Python UI library** for building composable, production-ready Databricks Apps — without writing a single line of JavaScript.
97
+
98
+ [![Python](https://img.shields.io/badge/python-3.10+-blue.svg)](https://python.org)
99
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
100
+
101
+ ---
102
+
103
+ ## What is BricksFlowUI?
104
+
105
+ BricksFlowUI lets data engineers build beautiful, interactive Databricks Apps in **pure Python**. It ships a pre-built React frontend and communicates over WebSocket, so you get:
106
+
107
+ - ⚡ **No full-script reruns** — only changed components re-render (unlike Streamlit)
108
+ - 🧩 **React-style component model** — composable functions, hooks, one-way data flow
109
+ - 🔒 **Databricks-native** — reads `DATABRICKS_APP_PORT`, Unity Catalog helpers, SQL warehouse wrappers
110
+ - 🎨 **Beautiful dark theme** — Databricks-inspired design system, no CSS required
111
+
112
+ ---
113
+
114
+ ## Quick Start
115
+
116
+ ```bash
117
+ pip install bricksflowui
118
+
119
+ # Scaffold a new app
120
+ brickflowui new my_app
121
+ cd my_app
122
+
123
+ # Run locally
124
+ brickflowui dev
125
+ # → open http://localhost:8050
126
+ ```
127
+
128
+ Or manually:
129
+
130
+ ```python
131
+ # app.py
132
+ import brickflowui as db
133
+
134
+ app = db.App(title="My Databricks App")
135
+
136
+ @app.page("/", title="Home", icon="Home")
137
+ def home():
138
+ count, set_count = db.use_state(0)
139
+ return db.Column([
140
+ db.Text("Counter", variant="h1"),
141
+ db.Text(f"Count: {count}", variant="h3"),
142
+ db.Button("Increment", on_click=lambda: set_count(count + 1)),
143
+ ], padding=6)
144
+
145
+ if __name__ == "__main__":
146
+ app.run()
147
+ ```
148
+
149
+ ---
150
+
151
+ ## Core Concepts
152
+
153
+ ### Components
154
+
155
+ Every UI element is a plain Python function returning a `VNode`:
156
+
157
+ ```python
158
+ import brickflowui as db
159
+
160
+ # Layout
161
+ db.Column(children, gap=4, padding=6)
162
+ db.Row(children, gap=2, justify="between")
163
+ db.Grid(children, cols=3, gap=4)
164
+ db.Card(children, title="My Card")
165
+
166
+ # Typography
167
+ db.Text("Hello!", variant="h1") # h1, h2, h3, h4, body, caption, label, code
168
+
169
+ # Controls
170
+ db.Button("Click me", on_click=handler, variant="primary")
171
+ db.Input(name="q", label="Search", on_change=setter)
172
+ db.Select(name="w", options=[{"label": "A", "value": "a"}], on_change=setter)
173
+ db.Checkbox(name="x", label="Enable", on_change=setter)
174
+ db.Toggle(name="y", label="Dark mode", on_change=setter)
175
+ db.Slider(name="s", min=0, max=100, on_change=setter)
176
+
177
+ # Data
178
+ db.Table(data=rows, columns=[{"key": "id", "label": "ID"}], pagination=20)
179
+ db.Badge("Active", color="green")
180
+ db.Alert("Something went wrong", type="error")
181
+ db.Progress(value=65, max=100)
182
+ db.Stat(label="Queries", value="248K", delta="+12%", delta_type="increase")
183
+
184
+ # Charts
185
+ db.AreaChart(data=rows, x_key="date", y_keys=["value"], colors=["#FF3621"])
186
+ db.BarChart(data=rows, x_key="category", y_keys=["count"])
187
+ db.LineChart(data=rows, x_key="day", y_keys=["metric"])
188
+ db.DonutChart(data=rows, value_key="count", label_key="name")
189
+
190
+ # Navigation
191
+ db.Tabs([db.TabItem("Tab A", [db.Text("Content A")]), ...])
192
+ db.Sidebar([db.NavItem("Home", "/", icon="Home"), ...], brand_name="My App")
193
+ db.Modal(visible=True, title="Confirm", children=[...], on_close=handler)
194
+
195
+ # Forms
196
+ db.Form(action="/api/submit", success_redirect="/", children=[
197
+ db.Input(name="username", label="Username"),
198
+ db.Button("Submit", html_type="submit"),
199
+ ])
200
+
201
+ # Databricks-specific
202
+ db.CatalogBrowser(on_select=handler)
203
+ db.WarehouseSelector(on_select=handler)
204
+ db.JobTrigger(job_id="123", label="Run Pipeline")
205
+ ```
206
+
207
+ ### State (Hooks)
208
+
209
+ ```python
210
+ @app.page("/")
211
+ def my_page():
212
+ count, set_count = db.use_state(0) # local state
213
+ data = db.use_memo(load_data, deps=[count]) # memoized compute
214
+ db.use_effect(lambda: print("mounted"), []) # side effects
215
+ theme = db.use_context("theme") # session context
216
+
217
+ return db.Button(str(count), on_click=lambda: set_count(count + 1))
218
+ ```
219
+
220
+ ### Multi-page Apps
221
+
222
+ ```python
223
+ app = db.App(title="Ops Hub")
224
+
225
+ @app.page("/", title="Dashboard", icon="LayoutDashboard")
226
+ def dashboard(): ...
227
+
228
+ @app.page("/tables", title="Tables", icon="Database")
229
+ def tables(): ...
230
+
231
+ @app.page("/settings", title="Settings", icon="Settings")
232
+ def settings(): ...
233
+ ```
234
+
235
+ ### Auth And Access Control
236
+
237
+ ```python
238
+ import brickflowui as db
239
+
240
+ app = db.App(
241
+ title="Ops Hub",
242
+ auth_mode="hybrid", # "app", "user", or "hybrid"
243
+ auth_provider=db.HeaderAuthProvider(),
244
+ )
245
+
246
+ @app.page("/", title="Home")
247
+ def home():
248
+ principal = db.current_principal()
249
+ return db.Text(f"Hello {principal.display_name or principal.subject}")
250
+
251
+ @app.page("/admin", title="Admin", access="user", roles=["admin"])
252
+ def admin():
253
+ user = db.require_role("admin")
254
+ return db.Text(f"Welcome, {user.subject}")
255
+
256
+ @app.route("/api/profile", methods=["GET"], access="user")
257
+ async def profile():
258
+ user = db.require_auth()
259
+ return {"user": user.subject, "roles": list(user.roles)}
260
+ ```
261
+
262
+ `access` supports:
263
+
264
+ - `public` — anyone can access it
265
+ - `authenticated` — any authenticated principal
266
+ - `user` — requires a signed-in user identity
267
+ - `app` — restricted to the shared application identity
268
+
269
+ ### Branding And Themes
270
+
271
+ ```python
272
+ app = db.App(theme="branding.yaml")
273
+ ```
274
+
275
+ Example `branding.yaml`:
276
+
277
+ ```yaml
278
+ branding:
279
+ title: "Acme Ops Portal"
280
+ logo: "/static/acme-logo.svg"
281
+ favicon: "/static/acme-favicon.ico"
282
+
283
+ colors:
284
+ primary: "#FF5F2E"
285
+ primary_hover: "#D9481C"
286
+ background: "#F7F7F5"
287
+ surface: "#FFFFFF"
288
+ text: "#18181B"
289
+ text_muted: "#71717A"
290
+ border: "#E4E4E7"
291
+
292
+ typography:
293
+ font_family: "'IBM Plex Sans', sans-serif"
294
+ base_size: "15px"
295
+
296
+ spacing:
297
+ unit: "6px"
298
+
299
+ borders:
300
+ radius: "14px"
301
+ ```
302
+
303
+ Supported theme model sections:
304
+
305
+ - `branding`: `title`, `logo`, `favicon`
306
+ - `colors`: `primary`, `primary_hover`, `background`, `surface`, `text`, `text_muted`, `border`, `success`, `warning`, `error`, `link`
307
+ - `typography`: `font_family`, `font_mono`, `base_size`
308
+ - `spacing`: `unit`
309
+ - `borders`: `radius`
310
+
311
+ You can also keep using the lower-level internal keys like `primary-hover`, `bg`, `text-muted`, `sans`, and `base-size` if you prefer.
312
+
313
+ ### Custom API Routes
314
+
315
+ ```python
316
+ @app.route("/api/submit", methods=["POST"])
317
+ async def submit_handler():
318
+ from fastapi.responses import JSONResponse
319
+ return JSONResponse({"status": "ok"})
320
+ ```
321
+
322
+ ---
323
+
324
+ ## Databricks Integration
325
+
326
+ ### SQL Queries
327
+
328
+ ```python
329
+ from brickflowui.databricks import sql
330
+
331
+ # Returns a pandas DataFrame
332
+ df = sql.query("SELECT * FROM catalog.schema.table LIMIT 100")
333
+
334
+ # Returns list[dict] (for db.Table component)
335
+ rows = sql.query_to_records("SELECT id, name FROM my_table")
336
+ return db.Table(data=rows)
337
+ ```
338
+
339
+ Set environment variables (or use `app.yaml`):
340
+
341
+ ```env
342
+ DATABRICKS_HOST=https://adb-xxx.azuredatabricks.net
343
+ DATABRICKS_TOKEN=dapiXXXXXXXX
344
+ DATABRICKS_WAREHOUSE_ID=your-warehouse-id
345
+ ```
346
+
347
+ ### Unity Catalog
348
+
349
+ ```python
350
+ from brickflowui.databricks import uc
351
+
352
+ catalogs = uc.list_catalogs()
353
+ schemas = uc.list_schemas("main")
354
+ tables = uc.list_tables("main", "gold")
355
+ rows = uc.get_table("main", "gold", "fact_orders", limit=50)
356
+ ```
357
+
358
+ ---
359
+
360
+ ## Deploying to Databricks Apps
361
+
362
+ ### `app.yaml`
363
+
364
+ ```yaml
365
+ command:
366
+ - python
367
+ - app.py
368
+
369
+ env:
370
+ - name: DATABRICKS_WAREHOUSE_ID
371
+ value: your-warehouse-id
372
+ ```
373
+
374
+ Then in the Databricks workspace:
375
+ 1. Create a new Databricks App
376
+ 2. Upload your project as a ZIP (include `app.py`, `app.yaml`, `requirements.txt`)
377
+ 3. The app binds to `DATABRICKS_APP_PORT` automatically
378
+
379
+ ### `requirements.txt`
380
+
381
+ ```text
382
+ bricksflowui>=0.1.0
383
+ # bricksflowui[databricks] # for SQL + Unity Catalog
384
+ ```
385
+
386
+ ---
387
+
388
+ ## CLI Reference
389
+
390
+ | Command | Description |
391
+ |---------|-------------|
392
+ | `brickflowui new <name>` | Scaffold a new app |
393
+ | `brickflowui dev` | Run local dev server (hot reload) |
394
+
395
+ ---
396
+
397
+ ## Project Structure
398
+
399
+ ```text
400
+ brickflowui/
401
+ ├── __init__.py # Public API
402
+ ├── app.py # App class
403
+ ├── vdom.py # Virtual DOM + diff algorithm
404
+ ├── state.py # Hooks (use_state, use_effect, use_memo)
405
+ ├── components.py # All component primitives
406
+ ├── server.py # FastAPI ASGI + WebSocket server
407
+ ├── cli/
408
+ │ ├── main.py # CLI (typer)
409
+ │ └── templates/ # App scaffolding templates
410
+ ├── databricks/
411
+ │ ├── env.py # DATABRICKS_* env helpers
412
+ │ ├── sql.py # SQL connector wrappers
413
+ │ └── uc.py # Unity Catalog helpers
414
+ └── frontend/
415
+ └── dist/ # Pre-built React bundle (served automatically)
416
+
417
+ examples/
418
+ ├── counter/ # Minimal Counter example
419
+ └── demo_app/ # Full multi-page dashboard demo
420
+ ├── app.py
421
+ ├── app.yaml
422
+ └── requirements.txt
423
+ ```
424
+
425
+ ---
426
+
427
+ ## Architecture
428
+
429
+ ```
430
+ Python App (app.py)
431
+
432
+ │ Component tree (VNode)
433
+
434
+ BrickflowUI Runtime
435
+ │ FastAPI ASGI Server
436
+ │ WS /events ──── JSON patches ────▶ React Frontend
437
+ │ GET / ◀─── HTML shell ──────
438
+ │ GET /static/* ◀─── React bundle ────
439
+
440
+
441
+ Databricks Runtime
442
+ (DATABRICKS_APP_PORT, SQL warehouse, Unity Catalog)
443
+ ```
444
+
445
+ ---
446
+
447
+ ## License
448
+
449
+ MIT © BrickflowUI Contributors