releasing to npm (#14)

This commit is contained in:
Samuel Colvin
2023-11-30 15:54:15 +00:00
committed by GitHub
parent 5de625e562
commit 93de285444
34 changed files with 444 additions and 141 deletions

View File

@@ -46,7 +46,7 @@ jobs:
- run: npm install
- run: npm run build
- run: tree packages-dist
- run: tree packages
check: # This job does nothing and is only used for the branch protection
if: always()

View File

@@ -11,7 +11,7 @@ install:
update-lockfiles:
@echo "Updating requirements files using pip-compile"
pip-compile -q --strip-extras -o python/requirements/lint.txt python/requirements/lint.in
pip-compile -q --strip-extras -o python/requirements/pyproject.txt pyproject.toml
pip-compile -q --strip-extras -o python/requirements/pyproject.txt pyproject.toml --extra=fastapi
pip install --dry-run -r python/requirements/all.txt
.PHONY: format
@@ -38,7 +38,7 @@ testcov: test
.PHONY: dev
dev:
uvicorn python.demo.main:app --reload
uvicorn python.demo:app --reload
.PHONY: all
all: testcov lint

View File

@@ -5,4 +5,8 @@
[![versions](https://img.shields.io/pypi/pyversions/fastui.svg)](https://github.com/samuelcolvin/FastUI)
[![license](https://img.shields.io/github/license/samuelcolvin/FastUI.svg)](https://github.com/samuelcolvin/FastUI/blob/main/LICENSE)
WIP
Packages:
- npm: [`@pydantic/fastui`](https://www.npmjs.com/package/@pydantic/fastui)
- npm: [`@pydantic/fastui-bootstrap`](https://www.npmjs.com/package/@pydantic/fastui-bootstrap)
- cdn: [`@pydantic/fastui-prebuilt`](https://www.jsdelivr.com/package/npm/@pydantic/fastui-prebuilt) (via npm package)

180
package-lock.json generated
View File

@@ -347,6 +347,7 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -363,6 +364,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -379,6 +381,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -395,6 +398,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -411,6 +415,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -427,6 +432,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
@@ -443,6 +449,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
@@ -459,6 +466,7 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -475,6 +483,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -491,6 +500,7 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -507,6 +517,7 @@
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -523,6 +534,7 @@
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -539,6 +551,7 @@
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -555,6 +568,7 @@
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -571,6 +585,7 @@
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -587,6 +602,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -603,6 +619,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
@@ -619,6 +636,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
@@ -635,6 +653,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
@@ -651,6 +670,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -667,6 +687,7 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -683,6 +704,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -847,6 +869,18 @@
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@pydantic/fastui": {
"resolved": "packages/fastui",
"link": true
},
"node_modules/@pydantic/fastui-bootstrap": {
"resolved": "packages/fastui-bootstrap",
"link": true
},
"node_modules/@pydantic/fastui-prebuilt": {
"resolved": "packages/fastui-prebuilt",
"link": true
},
"node_modules/@react-aria/ssr": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.0.tgz",
@@ -907,6 +941,7 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -920,6 +955,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -933,6 +969,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -946,6 +983,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -959,6 +997,7 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -972,6 +1011,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -985,6 +1025,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -998,6 +1039,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1011,6 +1053,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1024,6 +1067,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -1037,6 +1081,7 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -1050,6 +1095,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -1060,6 +1106,7 @@
"version": "1.3.96",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.96.tgz",
"integrity": "sha512-zwE3TLgoZwJfQygdv2SdCK9mRLYluwDOM53I+dT6Z5ZvrgVENmY3txvWDvduzkV+/8IuvrRbVezMpxcojadRdQ==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"@swc/counter": "^0.1.1",
@@ -1100,6 +1147,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -1115,6 +1163,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -1130,6 +1179,7 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1145,6 +1195,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1160,6 +1211,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1175,6 +1227,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1190,6 +1243,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1205,6 +1259,7 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -1220,6 +1275,7 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -1235,6 +1291,7 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -1246,7 +1303,8 @@
"node_modules/@swc/counter": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.2.tgz",
"integrity": "sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw=="
"integrity": "sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==",
"dev": true
},
"node_modules/@swc/helpers": {
"version": "0.5.3",
@@ -1259,7 +1317,8 @@
"node_modules/@swc/types": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz",
"integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw=="
"integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==",
"dev": true
},
"node_modules/@types/debug": {
"version": "4.1.12",
@@ -1307,7 +1366,7 @@
"version": "20.9.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.2.tgz",
"integrity": "sha512-WHZXKFCEyIUJzAwh3NyyTHYSR35SevJ6mZ1nWwJafKtiQbqRTIKSRcw3Ma3acqgsent3RRDqeVwpHntMk+9irg==",
"devOptional": true,
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
}
@@ -1577,6 +1636,7 @@
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.5.0.tgz",
"integrity": "sha512-1PrOvAaDpqlCV+Up8RkAh9qaiUjoDUcjtttyhXDKw53XA6Ve16SOp6cCOpRs8Dj8DqUQs6eTW5YkLcLJjrXAig==",
"dev": true,
"dependencies": {
"@swc/core": "^1.3.96"
},
@@ -2347,6 +2407,7 @@
"version": "0.19.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz",
"integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==",
"dev": true,
"hasInstallScript": true,
"peer": true,
"bin": {
@@ -2908,14 +2969,6 @@
"reusify": "^1.0.4"
}
},
"node_modules/fastui": {
"resolved": "packages/fastui",
"link": true
},
"node_modules/fastui-bootstrap": {
"resolved": "packages/fastui-bootstrap",
"link": true
},
"node_modules/fault": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
@@ -4881,6 +4934,7 @@
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"dev": true,
"funding": [
{
"type": "github",
@@ -5179,7 +5233,8 @@
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
"dev": true
},
"node_modules/picomatch": {
"version": "2.3.1",
@@ -5196,6 +5251,7 @@
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
"dev": true,
"funding": [
{
"type": "opencollective",
@@ -5648,6 +5704,7 @@
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.5.0.tgz",
"integrity": "sha512-41xsWhzxqjMDASCxH5ibw1mXk+3c4TNI2UjKbLxe6iEzrSQnqOzmmK8/3mufCPbzHNJ2e04Fc1ddI35hHy+8zg==",
"dev": true,
"peer": true,
"bin": {
"rollup": "dist/bin/rollup"
@@ -6207,7 +6264,7 @@
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"devOptional": true
"dev": true
},
"node_modules/unified": {
"version": "11.0.4",
@@ -6312,10 +6369,6 @@
}
}
},
"node_modules/vanilla": {
"resolved": "packages/vanilla",
"link": true
},
"node_modules/vfile": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz",
@@ -6347,6 +6400,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.0.tgz",
"integrity": "sha512-ESJVM59mdyGpsiNAeHQOR/0fqNoOyWPYesFto8FFZugfmhdHx8Fzd8sF3Q/xkVhZsyOxHfdM7ieiVAorI9RjFw==",
"dev": true,
"peer": true,
"dependencies": {
"esbuild": "^0.19.3",
@@ -6547,7 +6601,9 @@
}
},
"packages/fastui": {
"version": "0.0.0",
"name": "@pydantic/fastui",
"version": "0.0.6",
"license": "MIT",
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
@@ -6561,7 +6617,9 @@
}
},
"packages/fastui-bootstrap": {
"version": "0.0.0",
"name": "@pydantic/fastui-bootstrap",
"version": "0.0.6",
"license": "MIT",
"dependencies": {
"bootstrap": "^5.3.2",
"react": "^18.2.0",
@@ -6570,22 +6628,26 @@
"sass": "^1.69.5"
},
"peerDependencies": {
"fastui": "0.0.0"
"@pydantic/fastui": "0.0.6"
}
},
"packages/vanilla": {
"dependencies": {
"packages/fastui-prebuilt": {
"name": "@pydantic/fastui-prebuilt",
"version": "0.0.6",
"license": "MIT",
"devDependencies": {
"@vitejs/plugin-react-swc": "^3.3.2",
"vite": "^4.4.5"
}
},
"packages/vanilla/node_modules/@esbuild/android-arm": {
"packages/fastui-prebuilt/node_modules/@esbuild/android-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -6594,13 +6656,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/android-arm64": {
"packages/fastui-prebuilt/node_modules/@esbuild/android-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz",
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -6609,13 +6672,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/android-x64": {
"packages/fastui-prebuilt/node_modules/@esbuild/android-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz",
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -6624,13 +6688,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/darwin-arm64": {
"packages/fastui-prebuilt/node_modules/@esbuild/darwin-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz",
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -6639,13 +6704,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/darwin-x64": {
"packages/fastui-prebuilt/node_modules/@esbuild/darwin-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz",
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -6654,13 +6720,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/freebsd-arm64": {
"packages/fastui-prebuilt/node_modules/@esbuild/freebsd-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz",
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
@@ -6669,13 +6736,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/freebsd-x64": {
"packages/fastui-prebuilt/node_modules/@esbuild/freebsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz",
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
@@ -6684,13 +6752,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/linux-arm": {
"packages/fastui-prebuilt/node_modules/@esbuild/linux-arm": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz",
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -6699,13 +6768,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/linux-arm64": {
"packages/fastui-prebuilt/node_modules/@esbuild/linux-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz",
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -6714,13 +6784,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/linux-ia32": {
"packages/fastui-prebuilt/node_modules/@esbuild/linux-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz",
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -6729,13 +6800,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/linux-loong64": {
"packages/fastui-prebuilt/node_modules/@esbuild/linux-loong64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz",
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -6744,13 +6816,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/linux-mips64el": {
"packages/fastui-prebuilt/node_modules/@esbuild/linux-mips64el": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz",
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -6759,13 +6832,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/linux-ppc64": {
"packages/fastui-prebuilt/node_modules/@esbuild/linux-ppc64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz",
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -6774,13 +6848,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/linux-riscv64": {
"packages/fastui-prebuilt/node_modules/@esbuild/linux-riscv64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz",
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -6789,13 +6864,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/linux-s390x": {
"packages/fastui-prebuilt/node_modules/@esbuild/linux-s390x": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz",
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -6804,13 +6880,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/linux-x64": {
"packages/fastui-prebuilt/node_modules/@esbuild/linux-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz",
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -6819,13 +6896,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/netbsd-x64": {
"packages/fastui-prebuilt/node_modules/@esbuild/netbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz",
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
@@ -6834,13 +6912,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/openbsd-x64": {
"packages/fastui-prebuilt/node_modules/@esbuild/openbsd-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz",
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
@@ -6849,13 +6928,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/sunos-x64": {
"packages/fastui-prebuilt/node_modules/@esbuild/sunos-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz",
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
@@ -6864,13 +6944,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/win32-arm64": {
"packages/fastui-prebuilt/node_modules/@esbuild/win32-arm64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz",
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -6879,13 +6960,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/win32-ia32": {
"packages/fastui-prebuilt/node_modules/@esbuild/win32-ia32": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz",
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -6894,13 +6976,14 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/@esbuild/win32-x64": {
"packages/fastui-prebuilt/node_modules/@esbuild/win32-x64": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz",
"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -6909,10 +6992,11 @@
"node": ">=12"
}
},
"packages/vanilla/node_modules/esbuild": {
"packages/fastui-prebuilt/node_modules/esbuild": {
"version": "0.18.20",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz",
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@@ -6945,10 +7029,11 @@
"@esbuild/win32-x64": "0.18.20"
}
},
"packages/vanilla/node_modules/rollup": {
"packages/fastui-prebuilt/node_modules/rollup": {
"version": "3.29.4",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
"integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
"dev": true,
"bin": {
"rollup": "dist/bin/rollup"
},
@@ -6960,10 +7045,11 @@
"fsevents": "~2.3.2"
}
},
"packages/vanilla/node_modules/vite": {
"packages/fastui-prebuilt/node_modules/vite": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz",
"integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==",
"dev": true,
"dependencies": {
"esbuild": "^0.18.10",
"postcss": "^8.4.27",

View File

@@ -5,8 +5,8 @@
"packages/*"
],
"scripts": {
"dev": "npm run --workspace=vanilla dev",
"build": "rm -rf packages-dist && npm run build --workspaces --if-present",
"dev": "npm run --workspace=@pydantic/fastui-prebuilt dev",
"build": "npm run --workspaces prepublishOnly",
"typecheck": "npm run --workspaces typecheck",
"lint": "eslint packages --ext .ts,.tsx --report-unused-disable-directives --max-warnings 0",
"lint-fix": "npm run lint -- --fix",

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2023 to present Samuel Colvin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,3 @@
# FastUI Bootstrap
Bootstrap components for [FastUI](https://github.com/samuelcolvin/FastUI).

View File

@@ -1,8 +1,23 @@
{
"name": "fastui-bootstrap",
"version": "0.0.0",
"name": "@pydantic/fastui-bootstrap",
"version": "0.0.6",
"description": "Boostrap renderer for FastUI",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"author": "Samuel Colvin",
"license": "MIT",
"homepage": "https://github.com/samuelcolvin/fastui",
"private": false,
"keywords": [
"fastui",
"bootstrap",
"jsx",
"typescript",
"react",
"fastapi"
],
"scripts": {
"build": "tsc",
"prepublishOnly": "rm -rf dist && tsc",
"typecheck": "tsc --noEmit",
"typewatch": "tsc --noEmit --watch"
},
@@ -14,6 +29,6 @@
"sass": "^1.69.5"
},
"peerDependencies": {
"fastui": "0.0.0"
"@pydantic/fastui": "0.0.6"
}
}

View File

@@ -1,7 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../packages-dist",
"outDir": "dist",
"paths": {
"fastui": ["../fastui/src"]
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2023 to present Samuel Colvin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,3 @@
# FastUI pre-build
Pre-built files for FastUI.

View File

@@ -0,0 +1,28 @@
{
"name": "@pydantic/fastui-prebuilt",
"version": "0.0.6",
"description": "Pre-built files for FastUI",
"main": "dist/index.html",
"type": "module",
"author": "Samuel Colvin",
"license": "MIT",
"homepage": "https://github.com/samuelcolvin/fastui",
"private": false,
"keywords": [
"fastui",
"jsx",
"typescript",
"react",
"fastapi"
],
"scripts": {
"dev": "vite",
"prepublishOnly": "rm -rf dist && tsc --noEmit && vite build",
"typecheck": "tsc --noEmit",
"typewatch": "tsc --noEmit --watch"
},
"devDependencies": {
"@vitejs/plugin-react-swc": "^3.3.2",
"vite": "^4.4.5"
}
}

View File

@@ -25,7 +25,15 @@ export default () => {
server: serverConfig,
preview: serverConfig,
build: {
outDir: '../../packages-dist/vanilla',
sourcemap: true,
// we don't need hashes in URLs, we the URL will change when we release a new version
rollupOptions: {
output: {
entryFileNames: `assets/[name].js`,
chunkFileNames: `assets/[name].js`,
assetFileNames: `assets/[name].[ext]`,
},
},
},
})
}

21
packages/fastui/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2023 to present Samuel Colvin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,3 @@
# FastUI
[FastUI](https://github.com/samuelcolvin/FastUI) React library.

View File

@@ -1,7 +1,22 @@
{
"name": "fastui",
"version": "0.0.0",
"name": "@pydantic/fastui",
"version": "0.0.6",
"description": "Build better UIs faster.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"author": "Samuel Colvin",
"license": "MIT",
"homepage": "https://github.com/samuelcolvin/fastui",
"private": false,
"keywords": [
"fastui",
"jsx",
"typescript",
"react",
"fastapi"
],
"scripts": {
"prepublishOnly": "rm -rf dist && tsc",
"typecheck": "tsc --noEmit",
"typewatch": "tsc --noEmit --watch"
},

View File

@@ -19,8 +19,6 @@ export function useRequest(): (args: RequestArgs) => Promise<[number, any]> {
}
export function useSSE(url: string, onMessage: (data: any) => void): void {
const { setError } = useContext(ErrorContext)
useEffect(() => {
const source = new EventSource(url)
source.onmessage = (e) => {
@@ -28,12 +26,19 @@ export function useSSE(url: string, onMessage: (data: any) => void): void {
onMessage(data)
}
source.onerror = (e) => {
setError({ title: 'SSE Error', description: (e as any)?.message })
// we don't raise an error her as this can happen when the server is restarted
console.debug('SSE error', e)
}
return () => {
const cleanup = () => {
source.onerror = null
source.close()
}
}, [url, setError, onMessage])
window.addEventListener('beforeunload', cleanup)
return () => {
window.removeEventListener('beforeunload', cleanup)
cleanup()
}
}, [url, onMessage])
}
export interface RequestArgs {

View File

@@ -1,7 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../packages-dist/fastui"
"outDir": "dist"
},
"include": ["src"]
}

View File

@@ -1,13 +0,0 @@
{
"private": true,
"scripts": {
"dev": "vite",
"build": "tsc --noEmit && vite build",
"typecheck": "tsc --noEmit",
"typewatch": "tsc --noEmit --watch"
},
"dependencies": {
"@vitejs/plugin-react-swc": "^3.3.2",
"vite": "^4.4.5"
}
}

View File

@@ -13,7 +13,7 @@ path = "python/fastui/__init__.py"
[project]
name = "fastui"
description = "Build UIs fast."
description = "Build better UIs faster."
authors = [{ name = "Samuel Colvin", email = "s@muelcolvin.com" }]
license = "MIT"
readme = "README.md"
@@ -30,18 +30,19 @@ classifiers = [
'Programming Language :: Python :: 3.12',
"Intended Audience :: Developers",
"Intended Audience :: Information Technology",
"Framework :: Pydantic :: 2",
"Framework :: FastAPI",
]
requires-python = ">=3.8"
dependencies = [
"pydantic>=2.5.2",
"fastapi>=0.104.0",
]
dependencies = ["pydantic>=2.5.2"]
dynamic = ["version"]
[project.optional-dependencies]
fastapi = ["fastapi>=0.104"]
[project.urls]
Homepage = "https://github.com/samuelcolvin/FastUI"
[tool.ruff]
line-length = 120
extend-select = ["Q", "RUF100", "UP", "I"]

View File

@@ -0,0 +1,46 @@
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 .main import router as main_router
from .tables import router as table_router
@asynccontextmanager
async def lifespan(app_: FastAPI):
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(lifespan=lifespan)
else:
app = FastAPI(lifespan=lifespan)
app.include_router(main_router, prefix='/api')
app.include_router(table_router, prefix='/api/table')
@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'))

View File

@@ -1,39 +1,31 @@
from __future__ import annotations as _annotations
import asyncio
import sys
from collections import defaultdict
from datetime import datetime
from enum import StrEnum
from typing import Annotated, Literal
from typing import Annotated, AsyncIterable, Literal
from fastapi import FastAPI, UploadFile
from fastui import AnyComponent, FastUI, dev_fastapi_app
from fastapi import APIRouter, Request, UploadFile
from fastapi.responses import StreamingResponse
from fastui import AnyComponent, FastUI
from fastui import components as c
from fastui.events import GoToEvent, PageEvent
from fastui.forms import FormFile, FormResponse, SelectSearchResponse, fastui_form
from httpx import AsyncClient
from pydantic import BaseModel, Field, SecretStr, field_validator
from pydantic_core import PydanticCustomError
from sse_starlette import EventSourceResponse
from .shared import navbar
from .tables import router
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.include_router(router, prefix='/api/table')
router = APIRouter()
def panel(*components: AnyComponent) -> AnyComponent:
return c.Div(class_name='col border rounded m-1 p-2 pb-3', components=list(components))
@app.get('/api/', response_model=FastUI, response_model_exclude_none=True)
@router.get('/', response_model=FastUI, response_model_exclude_none=True)
def api_index() -> list[AnyComponent]:
return [
c.PageTitle(text='FastUI Demo'),
@@ -100,7 +92,7 @@ assert x + y == 3
]
@app.get('/api/modal', response_model=FastUI, response_model_exclude_none=True)
@router.get('/modal', response_model=FastUI, response_model_exclude_none=True)
async def modal_view() -> list[AnyComponent]:
await asyncio.sleep(0.5)
return [c.Text(text='Modal Content Dynamic')]
@@ -144,30 +136,30 @@ class MyFormModel(BaseModel):
return v
@app.get('/api/search', response_model=SelectSearchResponse)
async def search_view(q: str) -> SelectSearchResponse:
async with AsyncClient() as client:
path_ends = f'name/{q}' if q else 'all'
r = await client.get(f'https://restcountries.com/v3.1/{path_ends}')
if r.status_code == 404:
options = []
else:
r.raise_for_status()
data = r.json()
if path_ends == 'all':
# if we got all, filter to the 20 most populous countries
data.sort(key=lambda x: x['population'], reverse=True)
data = data[0:20]
data.sort(key=lambda x: x['name']['common'])
@router.get('/search', response_model=SelectSearchResponse)
async def search_view(request: Request, q: str) -> SelectSearchResponse:
path_ends = f'name/{q}' if q else 'all'
client: AsyncClient = request.app.state.httpx_client
r = await client.get(f'https://restcountries.com/v3.1/{path_ends}')
if r.status_code == 404:
options = []
else:
r.raise_for_status()
data = r.json()
if path_ends == 'all':
# if we got all, filter to the 20 most populous countries
data.sort(key=lambda x: x['population'], reverse=True)
data = data[0:20]
data.sort(key=lambda x: x['name']['common'])
regions = defaultdict(list)
for co in data:
regions[co['region']].append({'value': co['cca3'], 'label': co['name']['common']})
options = [{'label': k, 'options': v} for k, v in regions.items()]
regions = defaultdict(list)
for co in data:
regions[co['region']].append({'value': co['cca3'], 'label': co['name']['common']})
options = [{'label': k, 'options': v} for k, v in regions.items()]
return SelectSearchResponse(options=options)
@app.get('/api/form/{kind}', response_model=FastUI, response_model_exclude_none=True)
@router.get('/form/{kind}', response_model=FastUI, response_model_exclude_none=True)
def form_view(kind: Literal['one', 'two', 'three']) -> list[AnyComponent]:
return [
navbar(),
@@ -205,7 +197,7 @@ def form_view(kind: Literal['one', 'two', 'three']) -> list[AnyComponent]:
]
@app.get('/api/form/content/{kind}', response_model=FastUI, response_model_exclude_none=True)
@router.get('/form/content/{kind}', response_model=FastUI, response_model_exclude_none=True)
def form_content(kind: Literal['one', 'two', 'three']):
match kind:
case 'one':
@@ -240,19 +232,19 @@ def form_content(kind: Literal['one', 'two', 'three']):
raise ValueError(f'Invalid kind {kind!r}')
@app.post('/api/form')
@router.post('/form')
async def form_post(form: Annotated[MyFormModel, fastui_form(MyFormModel)]) -> FormResponse:
return FormResponse(event=GoToEvent(url='/'))
async def sse_generator():
async def sse_generator() -> AsyncIterable[str]:
while True:
d = datetime.now()
m = FastUI(root=[c.Div(components=[c.Text(text=f'Time {d:%H:%M:%S.%f}'[:-4])], class_name='font-monospace')])
yield dict(data=m.model_dump_json(by_alias=True))
yield f'data: {m.model_dump_json(by_alias=True)}\n\n'
await asyncio.sleep(0.09)
@app.get('/api/sse', response_class=EventSourceResponse)
async def sse_experiment():
return EventSourceResponse(sse_generator())
@router.get('/sse')
async def sse_experiment() -> StreamingResponse:
return StreamingResponse(sse_generator(), media_type='text/event-stream')

View File

@@ -1,12 +1,46 @@
__version__ = '0.0.1'
import pydantic
from .components import AnyComponent
from .dev import dev_fastapi_app
__all__ = 'AnyComponent', 'FastUI', 'dev_fastapi_app'
__version__ = '0.2.0'
__all__ = 'AnyComponent', 'FastUI', 'prebuilt_html'
class FastUI(pydantic.RootModel):
"""
The root component of a FastUI application.
"""
root: list[AnyComponent]
_PREBUILT_VERSION = '0.0.6'
_PREBUILT_CDN_URL = f'https://cdn.jsdelivr.net/npm/@pydantic/fastui-prebuilt@{_PREBUILT_VERSION}/dist/assets'
def prebuilt_html(title: str = ''):
"""
Returns a very simple HTML page which includes the FastUI react frontend, loaded from https://www.jsdelivr.com/.
Arguments:
title: page title
Returns:
HTML string which can be returned by an endpoint to serve the FastUI frontend.
"""
# language=HTML
return f"""\
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title}</title>
<script type="module" crossorigin src="{_PREBUILT_CDN_URL}/index.js"></script>
<link rel="stylesheet" crossorigin href="{_PREBUILT_CDN_URL}/index.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
"""

View File

@@ -4,9 +4,12 @@ import signal
import typing
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from starlette import types
try:
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
from starlette import types
except ImportError as e:
raise ImportError('fastui.dev requires fastapi to be installed, install with `pip install fastui[fastapi]`') from e
def dev_fastapi_app(reload_path: str = '/api/__dev__/reload', **fastapi_kwargs) -> FastAPI:

View File

@@ -5,15 +5,19 @@ import typing
from itertools import groupby
from operator import itemgetter
import fastapi
import pydantic
import pydantic_core
import typing_extensions
from pydantic_core import core_schema
from starlette import datastructures as ds
from . import events
try:
import fastapi
from starlette import datastructures as ds
except ImportError as e:
raise ImportError('fastui.dev requires fastapi to be installed, install with `pip install fastui[fastapi]`') from e
if typing.TYPE_CHECKING:
from . import json_schema

View File

@@ -2,7 +2,7 @@
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --output-file=python/requirements/pyproject.txt --strip-extras pyproject.toml
# pip-compile --extra=fastapi --output-file=python/requirements/pyproject.txt --strip-extras pyproject.toml
#
annotated-types==0.6.0
# via pydantic
@@ -14,11 +14,11 @@ fastapi==0.104.1
# via fastui (pyproject.toml)
idna==3.4
# via anyio
pydantic==2.5.0b1
pydantic==2.5.2
# via
# fastapi
# fastui (pyproject.toml)
pydantic-core==2.14.1
pydantic-core==2.14.5
# via pydantic
sniffio==1.3.0
# via anyio

View File

@@ -18,6 +18,9 @@
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true
"noUncheckedIndexedAccess": true,
/* Output */
"declaration": true
}
}