flet-web 0.25.0.dev3487__py3-none-any.whl

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.

Potentially problematic release.


This version of flet-web might be problematic. Click here for more details.

Files changed (52) hide show
  1. flet_web/__init__.py +9 -0
  2. flet_web/fastapi/README.md +146 -0
  3. flet_web/fastapi/__init__.py +6 -0
  4. flet_web/fastapi/app.py +120 -0
  5. flet_web/fastapi/flet_app.py +431 -0
  6. flet_web/fastapi/flet_app_manager.py +166 -0
  7. flet_web/fastapi/flet_fastapi.py +128 -0
  8. flet_web/fastapi/flet_oauth.py +66 -0
  9. flet_web/fastapi/flet_static_files.py +188 -0
  10. flet_web/fastapi/flet_upload.py +95 -0
  11. flet_web/fastapi/oauth_state.py +11 -0
  12. flet_web/fastapi/serve_fastapi_web_app.py +93 -0
  13. flet_web/patch_index.py +104 -0
  14. flet_web/uploads.py +54 -0
  15. flet_web/version.py +5 -0
  16. flet_web/web/.last_build_id +1 -0
  17. flet_web/web/assets/AssetManifest.bin +2 -0
  18. flet_web/web/assets/AssetManifest.bin.json +1 -0
  19. flet_web/web/assets/AssetManifest.json +1 -0
  20. flet_web/web/assets/FontManifest.json +1 -0
  21. flet_web/web/assets/NOTICES +37060 -0
  22. flet_web/web/assets/fonts/MaterialIcons-Regular.otf +0 -0
  23. flet_web/web/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf +0 -0
  24. flet_web/web/assets/packages/flutter_map/lib/assets/flutter_map_logo.png +0 -0
  25. flet_web/web/assets/packages/media_kit/assets/web/hls1.4.10.js +2 -0
  26. flet_web/web/assets/packages/record_web/assets/js/record.fixwebmduration.js +507 -0
  27. flet_web/web/assets/packages/record_web/assets/js/record.worklet.js +400 -0
  28. flet_web/web/assets/packages/wakelock_plus/assets/no_sleep.js +230 -0
  29. flet_web/web/assets/packages/window_manager/images/ic_chrome_close.png +0 -0
  30. flet_web/web/assets/packages/window_manager/images/ic_chrome_maximize.png +0 -0
  31. flet_web/web/assets/packages/window_manager/images/ic_chrome_minimize.png +0 -0
  32. flet_web/web/assets/packages/window_manager/images/ic_chrome_unmaximize.png +0 -0
  33. flet_web/web/assets/shaders/ink_sparkle.frag +126 -0
  34. flet_web/web/favicon.png +0 -0
  35. flet_web/web/flutter.js +4 -0
  36. flet_web/web/flutter_bootstrap.js +28 -0
  37. flet_web/web/flutter_service_worker.js +218 -0
  38. flet_web/web/icons/apple-touch-icon-192.png +0 -0
  39. flet_web/web/icons/icon-192.png +0 -0
  40. flet_web/web/icons/icon-512.png +0 -0
  41. flet_web/web/icons/icon-maskable-192.png +0 -0
  42. flet_web/web/icons/icon-maskable-512.png +0 -0
  43. flet_web/web/icons/loading-animation.png +0 -0
  44. flet_web/web/index.html +99 -0
  45. flet_web/web/main.dart.js +225762 -0
  46. flet_web/web/manifest.json +35 -0
  47. flet_web/web/python-worker.js +47 -0
  48. flet_web/web/python.js +28 -0
  49. flet_web/web/version.json +1 -0
  50. flet_web-0.25.0.dev3487.dist-info/METADATA +25 -0
  51. flet_web-0.25.0.dev3487.dist-info/RECORD +52 -0
  52. flet_web-0.25.0.dev3487.dist-info/WHEEL +4 -0
flet_web/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ from flet_web.patch_index import patch_index_html, patch_manifest_json
5
+
6
+
7
+ def get_package_web_dir():
8
+ web_root_dir = os.environ.get("FLET_WEB_PATH")
9
+ return web_root_dir or str(Path(__file__).parent.joinpath("web"))
@@ -0,0 +1,146 @@
1
+ # Flet - a better UI for FastAPI
2
+
3
+ Flet for FastAPI allows adding interactive real-time dashboards to your FastAPI app as well as host any Flet web app inside FastAPI with production-grade reliability.
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ pip install flet-fastapi
9
+ ```
10
+
11
+ ## First app
12
+
13
+ Create `counter.py` with the following content:
14
+
15
+ ```python
16
+ import flet as ft
17
+ import flet_fastapi
18
+
19
+ async def main(page: ft.Page):
20
+ counter = ft.Text("0", size=50, data=0)
21
+
22
+ async def add_click(e):
23
+ counter.data += 1
24
+ counter.value = str(counter.data)
25
+ counter.update()
26
+
27
+ page.floating_action_button = ft.FloatingActionButton(
28
+ icon=ft.icons.ADD, on_click=add_click
29
+ )
30
+ await page.add_async(
31
+ ft.Container(counter, alignment=ft.alignment.center, expand=True)
32
+ )
33
+
34
+ app = flet_fastapi.app(main)
35
+ ```
36
+
37
+ That's a simple app displaying a counter and a button at the right bottom to increment that counter.
38
+
39
+ `flet_fastapi.app()` configures a single Flet app at the root of FastAPI app with `main()` sessions handler and the following endpoints:
40
+
41
+ `/ws` (WS) - WebSocket handler for the Flet app.
42
+
43
+ `/upload` (PUT) - file uploads handler.
44
+
45
+ `/oauth_callback` (GET) - OAuth flow callback handler.
46
+
47
+ `/` (GET) - Flet app static files with SPA catch-all handler.
48
+
49
+ ## Running the app locally
50
+
51
+ Install [Uvicorn](https://www.uvicorn.org/) web server:
52
+
53
+ ```
54
+ pip install uvicorn
55
+ ```
56
+
57
+ Start `uvicorn` with:
58
+
59
+ ```
60
+ uvicorn counter:app
61
+ ```
62
+
63
+ Open the browser and navigate to http://127.0.0.1:8000 to see the app running.
64
+
65
+ ## Hosting multiple Flet apps under the same domain
66
+
67
+ ```python
68
+ import flet as ft
69
+ import flet_fastapi
70
+
71
+
72
+ async def root_main(page: ft.Page):
73
+ await page.add_async(ft.Text("This is root app!"))
74
+
75
+
76
+ async def sub_main(page: ft.Page):
77
+ await page.add_async(ft.Text("This is sub app!"))
78
+
79
+
80
+ app = flet_fastapi.FastAPI()
81
+
82
+
83
+ app.mount("/sub-app", flet_fastapi.app(sub_main))
84
+ app.mount("/", flet_fastapi.app(root_main))
85
+ ```
86
+
87
+ Sub-apps must be mapped before the root Flet app as it configures catch-all `index.html` for SPA.
88
+
89
+ Run the app with `uvicorn` and visit http://127.0.0.1:8000 and then http://127.0.0.1:8000/sub-app/ to see both Flet apps running. Notice the trailing slash in `/sub-app/` URL - without the slash the request will be routed to a root app.
90
+
91
+ ## Adding Flet to the existing FastAPI app
92
+
93
+ ```python
94
+ from contextlib import asynccontextmanager
95
+
96
+ import flet as ft
97
+ import flet_fastapi
98
+ from fastapi import FastAPI
99
+
100
+ @asynccontextmanager
101
+ async def lifespan(app: FastAPI):
102
+ await flet_fastapi.app_manager.start()
103
+ yield
104
+ await flet_fastapi.app_manager.shutdown()
105
+
106
+ app = FastAPI(lifespan=lifespan)
107
+
108
+ async def main(page: ft.Page):
109
+ await page.add_async(ft.Text("Hello, Flet!"))
110
+
111
+ app.mount("/flet-app", flet_fastapi.app(main))
112
+ ```
113
+
114
+ When adding Flet app to the existing FastAPI app you need to call `flet_fastapi.app_manager.start()` on app start and `flet_fastapi.app_manager.shutdown()` on shutdown. Use the way that best suites you: lifespan (in the example above) or app events.
115
+
116
+ `app_manager.start()` method starts background tasks cleaning up expired sessions and OAuth flow states.
117
+
118
+ `app_manager.shutdown()` method removes any temporary files created by a Flet app.
119
+
120
+ ## Running the app in production
121
+
122
+ It is recommended to run FastAPI in production with [Hypercorn](https://github.com/pgjones/hypercorn/) which is ASGI web server, but it is also possible to run FastAPI apps with [Gunicorn](https://gunicorn.org/) which is a WSGI server, but has more features, like passing proxy headers.
123
+
124
+ To install Gunicorn:
125
+
126
+ ```
127
+ pip install gunicorn
128
+ ```
129
+
130
+ Start `gunicorn` with:
131
+
132
+ ```
133
+ gunicorn -k uvicorn.workers.UvicornWorker counter:app
134
+ ```
135
+
136
+ ## Reference
137
+
138
+ ### Environment variables
139
+
140
+ `FLET_SECRET_KEY` - secret key to sign upload requests. Must be set if upload directory is configured.
141
+
142
+ `FLET_SESSION_TIMEOUT` - the number of seconds to keep session alive after user has disconnected. Default is 3,600 seconds.
143
+
144
+ `FLET_OAUTH_STATE_TIMEOUT` - OAuth state lifetime, in seconds, which is a maximum allowed time between starting OAuth flow and redirecting to OAuth callback URL. Default is 600 seconds.
145
+
146
+ `FLET_MAX_UPLOAD_SIZE` - max allowed size of an uploaded file, bytes.
@@ -0,0 +1,6 @@
1
+ from flet_web.fastapi.app import app
2
+ from flet_web.fastapi.flet_app import FletApp
3
+ from flet_web.fastapi.flet_app_manager import app_manager
4
+ from flet_web.fastapi.flet_fastapi import FastAPI
5
+ from flet_web.fastapi.flet_static_files import FletStaticFiles
6
+ from flet_web.fastapi.flet_upload import FletUpload
@@ -0,0 +1,120 @@
1
+ import asyncio
2
+ import os
3
+ from typing import Awaitable, Callable, Optional, Union
4
+
5
+ from fastapi import Request, WebSocket
6
+ from flet_core.page import Page
7
+ from flet_core.types import WebRenderer
8
+ from flet_web.fastapi.flet_app import (
9
+ DEFAULT_FLET_OAUTH_STATE_TIMEOUT,
10
+ DEFAULT_FLET_SESSION_TIMEOUT,
11
+ FletApp,
12
+ )
13
+ from flet_web.fastapi.flet_fastapi import FastAPI
14
+ from flet_web.fastapi.flet_oauth import FletOAuth
15
+ from flet_web.fastapi.flet_static_files import FletStaticFiles
16
+ from flet_web.fastapi.flet_upload import FletUpload
17
+
18
+
19
+ def app(
20
+ session_handler: Union[Callable[[Page], Awaitable], Callable[[Page], None]],
21
+ proxy_path: Optional[str] = None,
22
+ assets_dir: Optional[str] = None,
23
+ app_name: Optional[str] = None,
24
+ app_short_name: Optional[str] = None,
25
+ app_description: Optional[str] = None,
26
+ web_renderer: WebRenderer = WebRenderer.CANVAS_KIT,
27
+ use_color_emoji: bool = False,
28
+ route_url_strategy: str = "path",
29
+ upload_dir: Optional[str] = None,
30
+ upload_endpoint_path: Optional[str] = None,
31
+ max_upload_size: Optional[int] = None,
32
+ secret_key: Optional[str] = None,
33
+ session_timeout_seconds: int = DEFAULT_FLET_SESSION_TIMEOUT,
34
+ oauth_state_timeout_seconds: int = DEFAULT_FLET_OAUTH_STATE_TIMEOUT,
35
+ ):
36
+ """
37
+ Mount all Flet FastAPI handlers in one call.
38
+
39
+ Parameters:
40
+ * `session_handler` (function or coroutine) - application entry point - a method called for newly connected user. Handler must have 1 parameter: `page` - `Page` instance.
41
+ * `assets_dir` (str, optional) - an absolute path to app's assets directory.
42
+ * `app_name` (str, optional) - PWA application name.
43
+ * `app_short_name` (str, optional) - PWA application short name.
44
+ * `app_description` (str, optional) - PWA application description.
45
+ * `web_renderer` (WebRenderer) - web renderer defaulting to `WebRenderer.CANVAS_KIT`.
46
+ * `use_color_emoji` (bool) - whether to load a font with color emoji. Default is `False`.
47
+ * `route_url_strategy` (str) - routing URL strategy: `path` (default) or `hash`.
48
+ * `upload_dir` (str) - an absolute path to a directory with uploaded files.
49
+ * `upload_endpoint_path` (str, optional) - absolute URL of upload endpoint, e.g. `/upload`.
50
+ * `max_upload_size` (str, int) - maximum size of a single upload, bytes. Unlimited if `None`.
51
+ * `secret_key` (str, optional) - secret key to sign and verify upload requests.
52
+ * `session_timeout_seconds` (int, optional)- session lifetime, in seconds, after user disconnected.
53
+ * `oauth_state_timeout_seconds` (int, optional) - OAuth state lifetime, in seconds, which is a maximum allowed time between starting OAuth flow and redirecting to OAuth callback URL.
54
+ """
55
+
56
+ env_upload_dir = os.getenv("FLET_UPLOAD_DIR")
57
+ if env_upload_dir:
58
+ upload_dir = env_upload_dir
59
+
60
+ env_websocket_endpoint = os.getenv("FLET_WEBSOCKET_HANDLER_ENDPOINT")
61
+ websocket_endpoint = (
62
+ "ws" if not env_websocket_endpoint else env_websocket_endpoint.strip("/")
63
+ )
64
+
65
+ env_upload_endpoint = os.getenv("FLET_UPLOAD_HANDLER_ENDPOINT")
66
+ upload_endpoint = (
67
+ "upload" if not env_upload_endpoint else env_upload_endpoint.strip("/")
68
+ )
69
+
70
+ env_oauth_callback_endpoint = os.getenv("FLET_OAUTH_CALLBACK_HANDLER_ENDPOINT")
71
+ oauth_callback_endpoint = (
72
+ "oauth_callback"
73
+ if not env_oauth_callback_endpoint
74
+ else env_oauth_callback_endpoint.strip("/")
75
+ )
76
+
77
+ fastapi_app = FastAPI()
78
+
79
+ @fastapi_app.websocket(f"/{websocket_endpoint}")
80
+ async def app_handler(websocket: WebSocket):
81
+ await FletApp(
82
+ asyncio.get_running_loop(),
83
+ session_handler,
84
+ session_timeout_seconds=session_timeout_seconds,
85
+ oauth_state_timeout_seconds=oauth_state_timeout_seconds,
86
+ upload_endpoint_path=upload_endpoint_path,
87
+ secret_key=secret_key,
88
+ ).handle(websocket)
89
+
90
+ if upload_dir:
91
+
92
+ @fastapi_app.put(
93
+ f"/{upload_endpoint_path if upload_endpoint_path else upload_endpoint}"
94
+ )
95
+ async def upload_handler(request: Request):
96
+ await FletUpload(
97
+ upload_dir=upload_dir,
98
+ max_upload_size=max_upload_size,
99
+ secret_key=secret_key,
100
+ ).handle(request)
101
+
102
+ @fastapi_app.get(f"/{oauth_callback_endpoint}")
103
+ async def oauth_redirect_handler(request: Request):
104
+ return await FletOAuth().handle(request)
105
+
106
+ fastapi_app.mount(
107
+ path="/",
108
+ app=FletStaticFiles(
109
+ proxy_path=proxy_path,
110
+ assets_dir=assets_dir,
111
+ app_name=app_name,
112
+ app_short_name=app_short_name,
113
+ app_description=app_description,
114
+ web_renderer=web_renderer,
115
+ use_color_emoji=use_color_emoji,
116
+ route_url_strategy=route_url_strategy,
117
+ ),
118
+ )
119
+
120
+ return fastapi_app