From db7d7c88a0b69e18313f1fb404294f4fa5a29019 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Ekespong?=
<43400207+aekespong@users.noreply.github.com>
Date: Fri, 22 Dec 2023 12:40:33 +0100
Subject: [PATCH 1/4] Changed Table[User] to use data_model=User
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 0c1e0014..91708000 100644
--- a/README.md
+++ b/README.md
@@ -70,8 +70,9 @@ def users_table() -> list[AnyComponent]:
c.Page( # Page provides a basic container for components
components=[
c.Heading(text='Users', level=2), # renders `
Users
`
- c.Table[User]( # c.Table is a generic component parameterized with the model used for rows
+ c.Table(
data=users,
+ data_model=User, # data_model defines a model used for rows
# define two columns for the table
columns=[
# the first is the users, name rendered as a link to their profile
@@ -84,7 +85,6 @@ def users_table() -> list[AnyComponent]:
),
]
-
@app.get("/api/user/{user_id}/", response_model=FastUI, response_model_exclude_none=True)
def user_profile(user_id: int) -> list[AnyComponent]:
"""
From a75b1e0e3f2e8af0841e1b4f5fba03d3278a6631 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Ekespong?=
<43400207+aekespong@users.noreply.github.com>
Date: Fri, 22 Dec 2023 12:58:19 +0100
Subject: [PATCH 2/4] Added sample from README. It includes __init__.py which
is required.
---
Makefile | 4 +++
sample/__init__.py | 43 ++++++++++++++++++++++++
sample/main.py | 81 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 128 insertions(+)
create mode 100644 sample/__init__.py
create mode 100644 sample/main.py
diff --git a/Makefile b/Makefile
index bced37ae..5a9c8e5d 100644
--- a/Makefile
+++ b/Makefile
@@ -42,5 +42,9 @@ testcov: test
dev:
uvicorn demo:app --reload --reload-dir .
+.PHONY: sample
+sample:
+ uvicorn sample.main:app --reload --reload-dir .
+
.PHONY: all
all: testcov lint
diff --git a/sample/__init__.py b/sample/__init__.py
new file mode 100644
index 00000000..0494adbf
--- /dev/null
+++ b/sample/__init__.py
@@ -0,0 +1,43 @@
+from __future__ import annotations as _annotations
+
+import sys
+from contextlib import asynccontextmanager
+
+from fastapi import FastAPI
+from fastapi.responses import HTMLResponse, PlainTextResponse
+from fastui import prebuilt_html
+from fastui.dev import dev_fastapi_app
+from httpx import AsyncClient
+
+# from .app import create_db
+
+
+# @asynccontextmanager
+# async def lifespan(app_: FastAPI):
+# await create_db()
+# async with AsyncClient() as client:
+# app_.state.httpx_client = client
+# yield
+
+
+frontend_reload = '--reload' in sys.argv
+if frontend_reload:
+ # dev_fastapi_app reloads in the browser when the Python source changes
+ app = dev_fastapi_app()
+else:
+ app = FastAPI()
+
+
+@app.get('/robots.txt', response_class=PlainTextResponse)
+async def robots_txt() -> str:
+ return 'User-agent: *\nAllow: /'
+
+
+@app.get('/favicon.ico', status_code=404, response_class=PlainTextResponse)
+async def favicon_ico() -> str:
+ return 'page not found'
+
+
+@app.get('/{path:path}')
+async def html_landing() -> HTMLResponse:
+ return HTMLResponse(prebuilt_html(title='FastUI Demo'))
diff --git a/sample/main.py b/sample/main.py
new file mode 100644
index 00000000..5b3f2f73
--- /dev/null
+++ b/sample/main.py
@@ -0,0 +1,81 @@
+from datetime import date
+
+from fastapi import FastAPI, HTTPException
+from fastapi.responses import HTMLResponse
+from fastui import FastUI, AnyComponent, prebuilt_html, components as c
+from fastui.components.display import DisplayMode, DisplayLookup
+from fastui.events import GoToEvent, BackEvent
+from pydantic import BaseModel, Field
+
+
+class User(BaseModel):
+ id: int
+ name: str
+ dob: date = Field(title="Date of Birth")
+
+
+# define some users
+users = [
+ User(id=1, name="John", dob=date(1990, 1, 1)),
+ User(id=2, name="Jack", dob=date(1991, 1, 1)),
+ User(id=3, name="Jill", dob=date(1992, 1, 1)),
+ User(id=4, name="Jane", dob=date(1993, 1, 1)),
+]
+
+app = FastAPI()
+
+
+@app.get("/api/", response_model=FastUI, response_model_exclude_none=True)
+def users_table() -> list[AnyComponent]:
+ """
+ Show a table of four users, `/api` is the endpoint the frontend will connect to
+ when a user visits `/` to fetch components to render.
+ """
+ return [
+ c.Page( # Page provides a basic container for components
+ components=[
+ c.Heading(text="Users", level=2), # renders `Users
`
+ c.Table( # c.Table is a generic component parameterized with the model used for rows
+ data=users,
+ data_model=User, # data_model defines a model used for rows
+ # define two columns for the table
+ columns=[
+ # the first is the users, name rendered as a link to their profile
+ DisplayLookup(
+ field="name", on_click=GoToEvent(url="/user/{id}/")
+ ),
+ # the second is the date of birth, rendered as a date
+ DisplayLookup(field="dob", mode=DisplayMode.date),
+ ],
+ ),
+ ]
+ ),
+ ]
+
+
+@app.get(
+ "/api/user/{user_id}/", response_model=FastUI, response_model_exclude_none=True
+)
+def user_profile(user_id: int) -> list[AnyComponent]:
+ """
+ User profile page, the frontend will fetch this when the user visits `/user/{id}/`.
+ """
+ try:
+ user = next(u for u in users if u.id == user_id)
+ except StopIteration:
+ raise HTTPException(status_code=404, detail="User not found")
+ return [
+ c.Page(
+ components=[
+ c.Heading(text=user.name, level=2),
+ c.Link(components=[c.Text(text="Back")], on_click=BackEvent()),
+ c.Details(data=user),
+ ]
+ ),
+ ]
+
+
+@app.get("/{path:path}")
+async def html_landing() -> HTMLResponse:
+ """Simple HTML page which serves the React app, comes last as it matches all paths."""
+ return HTMLResponse(prebuilt_html(title="FastUI Demo"))
From 769b978bf4ac9514fdfb81d63c691c1f269b1ce0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Ekespong?=
<43400207+aekespong@users.noreply.github.com>
Date: Fri, 22 Dec 2023 12:16:07 +0000
Subject: [PATCH 3/4] Fixed lint error
---
README.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 91708000..505f5e2f 100644
--- a/README.md
+++ b/README.md
@@ -72,7 +72,8 @@ def users_table() -> list[AnyComponent]:
c.Heading(text='Users', level=2), # renders `Users
`
c.Table(
data=users,
- data_model=User, # data_model defines a model used for rows
+ # data_model defines a model used for rows
+ data_model=User,
# define two columns for the table
columns=[
# the first is the users, name rendered as a link to their profile
From 9973f4df926d0d2fadeeb2ec7364b76bbb86ae15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Ekespong?=
<43400207+aekespong@users.noreply.github.com>
Date: Fri, 22 Dec 2023 13:45:04 +0100
Subject: [PATCH 4/4] Revert "Added sample from README. It includes __init__.py
which is required."
This reverts commit a75b1e0e3f2e8af0841e1b4f5fba03d3278a6631.
---
Makefile | 4 ---
sample/__init__.py | 43 ------------------------
sample/main.py | 81 ----------------------------------------------
3 files changed, 128 deletions(-)
delete mode 100644 sample/__init__.py
delete mode 100644 sample/main.py
diff --git a/Makefile b/Makefile
index 55cf0a8a..023f415c 100644
--- a/Makefile
+++ b/Makefile
@@ -46,9 +46,5 @@ typescript-models:
dev:
uvicorn demo:app --reload --reload-dir .
-.PHONY: sample
-sample:
- uvicorn sample.main:app --reload --reload-dir .
-
.PHONY: all
all: testcov lint
diff --git a/sample/__init__.py b/sample/__init__.py
deleted file mode 100644
index 0494adbf..00000000
--- a/sample/__init__.py
+++ /dev/null
@@ -1,43 +0,0 @@
-from __future__ import annotations as _annotations
-
-import sys
-from contextlib import asynccontextmanager
-
-from fastapi import FastAPI
-from fastapi.responses import HTMLResponse, PlainTextResponse
-from fastui import prebuilt_html
-from fastui.dev import dev_fastapi_app
-from httpx import AsyncClient
-
-# from .app import create_db
-
-
-# @asynccontextmanager
-# async def lifespan(app_: FastAPI):
-# await create_db()
-# async with AsyncClient() as client:
-# app_.state.httpx_client = client
-# yield
-
-
-frontend_reload = '--reload' in sys.argv
-if frontend_reload:
- # dev_fastapi_app reloads in the browser when the Python source changes
- app = dev_fastapi_app()
-else:
- app = FastAPI()
-
-
-@app.get('/robots.txt', response_class=PlainTextResponse)
-async def robots_txt() -> str:
- return 'User-agent: *\nAllow: /'
-
-
-@app.get('/favicon.ico', status_code=404, response_class=PlainTextResponse)
-async def favicon_ico() -> str:
- return 'page not found'
-
-
-@app.get('/{path:path}')
-async def html_landing() -> HTMLResponse:
- return HTMLResponse(prebuilt_html(title='FastUI Demo'))
diff --git a/sample/main.py b/sample/main.py
deleted file mode 100644
index 5b3f2f73..00000000
--- a/sample/main.py
+++ /dev/null
@@ -1,81 +0,0 @@
-from datetime import date
-
-from fastapi import FastAPI, HTTPException
-from fastapi.responses import HTMLResponse
-from fastui import FastUI, AnyComponent, prebuilt_html, components as c
-from fastui.components.display import DisplayMode, DisplayLookup
-from fastui.events import GoToEvent, BackEvent
-from pydantic import BaseModel, Field
-
-
-class User(BaseModel):
- id: int
- name: str
- dob: date = Field(title="Date of Birth")
-
-
-# define some users
-users = [
- User(id=1, name="John", dob=date(1990, 1, 1)),
- User(id=2, name="Jack", dob=date(1991, 1, 1)),
- User(id=3, name="Jill", dob=date(1992, 1, 1)),
- User(id=4, name="Jane", dob=date(1993, 1, 1)),
-]
-
-app = FastAPI()
-
-
-@app.get("/api/", response_model=FastUI, response_model_exclude_none=True)
-def users_table() -> list[AnyComponent]:
- """
- Show a table of four users, `/api` is the endpoint the frontend will connect to
- when a user visits `/` to fetch components to render.
- """
- return [
- c.Page( # Page provides a basic container for components
- components=[
- c.Heading(text="Users", level=2), # renders `Users
`
- c.Table( # c.Table is a generic component parameterized with the model used for rows
- data=users,
- data_model=User, # data_model defines a model used for rows
- # define two columns for the table
- columns=[
- # the first is the users, name rendered as a link to their profile
- DisplayLookup(
- field="name", on_click=GoToEvent(url="/user/{id}/")
- ),
- # the second is the date of birth, rendered as a date
- DisplayLookup(field="dob", mode=DisplayMode.date),
- ],
- ),
- ]
- ),
- ]
-
-
-@app.get(
- "/api/user/{user_id}/", response_model=FastUI, response_model_exclude_none=True
-)
-def user_profile(user_id: int) -> list[AnyComponent]:
- """
- User profile page, the frontend will fetch this when the user visits `/user/{id}/`.
- """
- try:
- user = next(u for u in users if u.id == user_id)
- except StopIteration:
- raise HTTPException(status_code=404, detail="User not found")
- return [
- c.Page(
- components=[
- c.Heading(text=user.name, level=2),
- c.Link(components=[c.Text(text="Back")], on_click=BackEvent()),
- c.Details(data=user),
- ]
- ),
- ]
-
-
-@app.get("/{path:path}")
-async def html_landing() -> HTMLResponse:
- """Simple HTML page which serves the React app, comes last as it matches all paths."""
- return HTMLResponse(prebuilt_html(title="FastUI Demo"))