flet-web 1.0.4__tar.gz → 1.1.0.dev0__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.
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/PKG-INFO +4 -3
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/pyproject.toml +7 -5
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/app.py +15 -14
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/flet_app.py +20 -3
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/flet_static_files.py +28 -8
- flet_web-1.1.0.dev0/src/flet_web/version.py +1 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web.egg-info/PKG-INFO +4 -3
- flet_web-1.1.0.dev0/src/flet_web.egg-info/requires.txt +10 -0
- flet_web-1.0.4/src/flet_web/version.py +0 -1
- flet_web-1.0.4/src/flet_web.egg-info/requires.txt +0 -7
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/README.md +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/setup.cfg +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/__init__.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/__init__.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/flet_app_manager.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/flet_fastapi.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/flet_oauth.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/flet_upload.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/oauth_state.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/fastapi/serve_fastapi_web_app.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/patch_index.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web/uploads.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web.egg-info/SOURCES.txt +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web.egg-info/dependency_links.txt +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/src/flet_web.egg-info/top_level.txt +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/tests/test_loading_logo.py +0 -0
- {flet_web-1.0.4 → flet_web-1.1.0.dev0}/tests/test_patch_index.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flet-web
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.1.0.dev0
|
|
4
4
|
Summary: Flet web client in Flutter.
|
|
5
5
|
Author-email: "Appveyor Systems Inc." <hello@flet.dev>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -9,11 +9,12 @@ Project-URL: Repository, https://github.com/flet-dev/flet
|
|
|
9
9
|
Project-URL: Documentation, https://flet.dev/docs
|
|
10
10
|
Requires-Python: >=3.10
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
-
Requires-Dist: flet==1.0.
|
|
12
|
+
Requires-Dist: flet==1.1.0.dev0
|
|
13
13
|
Requires-Dist: fastapi>=0.115.12
|
|
14
14
|
Requires-Dist: websockets>=13.0
|
|
15
15
|
Requires-Dist: uvicorn>=0.35.0
|
|
16
|
-
Requires-Dist: uvicorn[standard]>=0.35.0; sys_platform != "win32" or platform_machine != "ARM64"
|
|
16
|
+
Requires-Dist: uvicorn[standard]>=0.35.0; sys_platform != "win32" or platform_machine != "ARM64" or python_version >= "3.12"
|
|
17
|
+
Requires-Dist: httptools>=0.9.0; sys_platform == "win32" and platform_machine == "ARM64" and python_version >= "3.12"
|
|
17
18
|
|
|
18
19
|
# Flet Web client in Flutter
|
|
19
20
|
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "flet-web"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.1.0.dev0"
|
|
4
4
|
description = "Flet web client in Flutter."
|
|
5
5
|
authors = [{ name = "Appveyor Systems Inc.", email = "hello@flet.dev" }]
|
|
6
6
|
license = "Apache-2.0"
|
|
7
7
|
readme = "README.md"
|
|
8
8
|
requires-python = ">=3.10"
|
|
9
9
|
dependencies = [
|
|
10
|
-
"flet==1.0.
|
|
10
|
+
"flet==1.1.0.dev0",
|
|
11
11
|
"fastapi >=0.115.12",
|
|
12
12
|
"websockets >=13.0",
|
|
13
13
|
"uvicorn >=0.35.0",
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
|
|
14
|
+
# On Windows ARM, uvicorn's standard extras install from wheels only on Python 3.12
|
|
15
|
+
# or later (PyYAML has none for 3.10 or 3.11) and with httptools 0.9.0 or later;
|
|
16
|
+
# otherwise they need a C++ compiler. uvicorn falls back to h11 without them.
|
|
17
|
+
"uvicorn[standard] >=0.35.0; sys_platform != 'win32' or platform_machine != 'ARM64' or python_version >= '3.12'",
|
|
18
|
+
"httptools >=0.9.0; sys_platform == 'win32' and platform_machine == 'ARM64' and python_version >= '3.12'"
|
|
17
19
|
]
|
|
18
20
|
|
|
19
21
|
[project.urls]
|
|
@@ -92,6 +92,18 @@ def app(
|
|
|
92
92
|
|
|
93
93
|
fastapi_app = FastAPI()
|
|
94
94
|
|
|
95
|
+
static_files = FletStaticFiles(
|
|
96
|
+
proxy_path=proxy_path,
|
|
97
|
+
assets_dir=assets_dir,
|
|
98
|
+
app_name=app_name,
|
|
99
|
+
app_short_name=app_short_name,
|
|
100
|
+
app_description=app_description,
|
|
101
|
+
web_renderer=web_renderer,
|
|
102
|
+
route_url_strategy=route_url_strategy,
|
|
103
|
+
websocket_endpoint_path=websocket_endpoint,
|
|
104
|
+
no_cdn=no_cdn,
|
|
105
|
+
)
|
|
106
|
+
|
|
95
107
|
@fastapi_app.websocket(f"/{websocket_endpoint}")
|
|
96
108
|
async def app_handler(websocket: WebSocket):
|
|
97
109
|
"""
|
|
@@ -109,6 +121,8 @@ def app(
|
|
|
109
121
|
oauth_state_timeout_seconds=oauth_state_timeout_seconds,
|
|
110
122
|
upload_endpoint_path=upload_endpoint_path,
|
|
111
123
|
secret_key=secret_key,
|
|
124
|
+
route_url_strategy=static_files.route_url_strategy,
|
|
125
|
+
proxy_path=proxy_path,
|
|
112
126
|
).handle(websocket)
|
|
113
127
|
|
|
114
128
|
if upload_dir:
|
|
@@ -133,20 +147,7 @@ def app(
|
|
|
133
147
|
"""
|
|
134
148
|
return await FletOAuth().handle(request)
|
|
135
149
|
|
|
136
|
-
fastapi_app.mount(
|
|
137
|
-
path="/",
|
|
138
|
-
app=FletStaticFiles(
|
|
139
|
-
proxy_path=proxy_path,
|
|
140
|
-
assets_dir=assets_dir,
|
|
141
|
-
app_name=app_name,
|
|
142
|
-
app_short_name=app_short_name,
|
|
143
|
-
app_description=app_description,
|
|
144
|
-
web_renderer=web_renderer,
|
|
145
|
-
route_url_strategy=route_url_strategy,
|
|
146
|
-
websocket_endpoint_path=websocket_endpoint,
|
|
147
|
-
no_cdn=no_cdn,
|
|
148
|
-
),
|
|
149
|
-
)
|
|
150
|
+
fastapi_app.mount(path="/", app=static_files)
|
|
150
151
|
|
|
151
152
|
# Add middleware for custom headers
|
|
152
153
|
class CustomHeadersMiddleware(BaseHTTPMiddleware):
|
|
@@ -16,6 +16,7 @@ from flet.app import AppCallable
|
|
|
16
16
|
from flet.controls.base_control import BaseControl
|
|
17
17
|
from flet.controls.context import _context_page, context
|
|
18
18
|
from flet.controls.exceptions import FletPageDisconnectedException
|
|
19
|
+
from flet.controls.types import RouteUrlStrategy
|
|
19
20
|
from flet.messaging.connection import Connection
|
|
20
21
|
from flet.messaging.protocol import (
|
|
21
22
|
ControlEventBody,
|
|
@@ -59,6 +60,9 @@ class FletApp(Connection):
|
|
|
59
60
|
and redirecting to OAuth callback URL.
|
|
60
61
|
upload_endpoint_path: Absolute URL of upload endpoint, e.g. `/upload`.
|
|
61
62
|
secret_key: Secret key to sign upload requests.
|
|
63
|
+
route_url_strategy: Route URL strategy of the served web client.
|
|
64
|
+
proxy_path: URL prefix that a proxy in front of the app strips, as given
|
|
65
|
+
to `flet_web.fastapi.app()`; part of the page's base path.
|
|
62
66
|
"""
|
|
63
67
|
|
|
64
68
|
def __init__(
|
|
@@ -71,8 +75,12 @@ class FletApp(Connection):
|
|
|
71
75
|
oauth_state_timeout_seconds: int = DEFAULT_FLET_OAUTH_STATE_TIMEOUT,
|
|
72
76
|
upload_endpoint_path: Optional[str] = None,
|
|
73
77
|
secret_key: Optional[str] = None,
|
|
78
|
+
route_url_strategy: RouteUrlStrategy = RouteUrlStrategy.PATH,
|
|
79
|
+
proxy_path: Optional[str] = None,
|
|
74
80
|
):
|
|
75
81
|
super().__init__()
|
|
82
|
+
self.route_url_strategy = route_url_strategy
|
|
83
|
+
self.__proxy_path = proxy_path
|
|
76
84
|
self.__id = random_string(8)
|
|
77
85
|
logger.info(f"New FletApp: {self.__id}")
|
|
78
86
|
|
|
@@ -124,6 +132,10 @@ class FletApp(Connection):
|
|
|
124
132
|
self.pubsubhub = app_manager.get_pubsubhub(self.__main, loop=self.loop)
|
|
125
133
|
self.page_url = str(websocket.url).rsplit("/", 1)[0]
|
|
126
134
|
self.page_name = websocket.url.path.rsplit("/", 1)[0].lstrip("/")
|
|
135
|
+
mount_path = (
|
|
136
|
+
(self.__proxy_path or "") + websocket.scope.get("root_path", "")
|
|
137
|
+
).strip("/")
|
|
138
|
+
self.page_base_path = f"/{mount_path}/" if mount_path else "/"
|
|
127
139
|
|
|
128
140
|
if not self.__upload_endpoint_path:
|
|
129
141
|
self.__upload_endpoint_path = (
|
|
@@ -236,9 +248,14 @@ class FletApp(Connection):
|
|
|
236
248
|
continue
|
|
237
249
|
ptype = data[0]
|
|
238
250
|
if ptype == 0x00:
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
251
|
+
# One bad message must not end the loop: nothing would be
|
|
252
|
+
# received after it and the app would freeze.
|
|
253
|
+
try:
|
|
254
|
+
await self.__on_message(
|
|
255
|
+
msgpack.unpackb(data[1:], ext_hook=decode_ext_from_msgpack)
|
|
256
|
+
)
|
|
257
|
+
except Exception:
|
|
258
|
+
logger.exception("Error handling a message from the client.")
|
|
242
259
|
elif ptype == 0x01:
|
|
243
260
|
if len(data) < 5:
|
|
244
261
|
logger.debug("Dropping malformed data-channel frame.")
|
|
@@ -69,8 +69,10 @@ class FletStaticFiles(StaticFiles):
|
|
|
69
69
|
app_name: PWA application name.
|
|
70
70
|
app_short_name: PWA application short name.
|
|
71
71
|
app_description: PWA application description.
|
|
72
|
-
web_renderer: Type of web renderer.
|
|
73
|
-
|
|
72
|
+
web_renderer: Type of web renderer, as a `WebRenderer` or its value, e.g.
|
|
73
|
+
`"canvaskit"`.
|
|
74
|
+
route_url_strategy: Routing URL strategy, as a `RouteUrlStrategy` or its
|
|
75
|
+
value, e.g. `"hash"`.
|
|
74
76
|
no_cdn: Whether not load CanvasKit, Pyodide, and fonts from CDN.
|
|
75
77
|
websocket_endpoint_path: Path of Flet app WebSocket handler. A path
|
|
76
78
|
without a leading `/` is resolved against the app mount path.
|
|
@@ -97,8 +99,8 @@ class FletStaticFiles(StaticFiles):
|
|
|
97
99
|
self.__app_name = app_name
|
|
98
100
|
self.__app_short_name = app_short_name
|
|
99
101
|
self.__app_description = app_description
|
|
100
|
-
self.__web_renderer = web_renderer
|
|
101
|
-
self.__route_url_strategy = route_url_strategy
|
|
102
|
+
self.__web_renderer = WebRenderer(web_renderer)
|
|
103
|
+
self.__route_url_strategy = RouteUrlStrategy(route_url_strategy)
|
|
102
104
|
self.__no_cdn = no_cdn
|
|
103
105
|
self.__websocket_endpoint_path = websocket_endpoint_path
|
|
104
106
|
self.__once = Once()
|
|
@@ -119,6 +121,14 @@ class FletStaticFiles(StaticFiles):
|
|
|
119
121
|
logger.info(f"Route URL strategy configured: {self.__route_url_strategy}")
|
|
120
122
|
logger.info(f"No CDN configured: {self.__no_cdn}")
|
|
121
123
|
|
|
124
|
+
@property
|
|
125
|
+
def route_url_strategy(self) -> RouteUrlStrategy:
|
|
126
|
+
"""
|
|
127
|
+
The route URL strategy written into the served `index.html`: the
|
|
128
|
+
`route_url_strategy` argument, or `FLET_WEB_ROUTE_URL_STRATEGY` if set.
|
|
129
|
+
"""
|
|
130
|
+
return self.__route_url_strategy
|
|
131
|
+
|
|
122
132
|
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
|
|
123
133
|
await self.__once.do(self.__config, scope["root_path"])
|
|
124
134
|
await super().__call__(scope, receive, send)
|
|
@@ -126,9 +136,16 @@ class FletStaticFiles(StaticFiles):
|
|
|
126
136
|
def lookup_path(self, path: str) -> tuple[str, Optional[os.stat_result]]:
|
|
127
137
|
"""Resolve a static file path, with SPA fallback for client-side routes.
|
|
128
138
|
|
|
129
|
-
|
|
130
|
-
fall back to `index.html` so the
|
|
131
|
-
Asset-like paths (any other
|
|
139
|
+
With the `path` route URL strategy, route-like paths (no extension, or
|
|
140
|
+
`.html`) that don't match a file fall back to `index.html` so the
|
|
141
|
+
Flutter client can handle routing. Asset-like paths (any other
|
|
142
|
+
extension) resolve to a real `404`.
|
|
143
|
+
|
|
144
|
+
With the `hash` strategy, routes live in the URL fragment and never
|
|
145
|
+
reach the server, so there is no fallback: any path that doesn't match
|
|
146
|
+
a file resolves to a real `404` (with a `404.html` from the assets
|
|
147
|
+
directory as its body, if there is one), while the mount root still
|
|
148
|
+
serves `index.html`.
|
|
132
149
|
|
|
133
150
|
Args:
|
|
134
151
|
path: Requested path, relative to the mounted static root
|
|
@@ -141,7 +158,10 @@ class FletStaticFiles(StaticFiles):
|
|
|
141
158
|
logger.debug(f"StaticFiles.lookup_path: {self.__app_mount_path} {path}")
|
|
142
159
|
full_path, stat_result = super().lookup_path(path)
|
|
143
160
|
|
|
144
|
-
if
|
|
161
|
+
if (
|
|
162
|
+
stat_result is not None
|
|
163
|
+
or self.__route_url_strategy == RouteUrlStrategy.HASH
|
|
164
|
+
):
|
|
145
165
|
return full_path, stat_result
|
|
146
166
|
|
|
147
167
|
# Not found: SPA fallback only for route-like paths.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "1.1.0.dev0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flet-web
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.1.0.dev0
|
|
4
4
|
Summary: Flet web client in Flutter.
|
|
5
5
|
Author-email: "Appveyor Systems Inc." <hello@flet.dev>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -9,11 +9,12 @@ Project-URL: Repository, https://github.com/flet-dev/flet
|
|
|
9
9
|
Project-URL: Documentation, https://flet.dev/docs
|
|
10
10
|
Requires-Python: >=3.10
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
|
-
Requires-Dist: flet==1.0.
|
|
12
|
+
Requires-Dist: flet==1.1.0.dev0
|
|
13
13
|
Requires-Dist: fastapi>=0.115.12
|
|
14
14
|
Requires-Dist: websockets>=13.0
|
|
15
15
|
Requires-Dist: uvicorn>=0.35.0
|
|
16
|
-
Requires-Dist: uvicorn[standard]>=0.35.0; sys_platform != "win32" or platform_machine != "ARM64"
|
|
16
|
+
Requires-Dist: uvicorn[standard]>=0.35.0; sys_platform != "win32" or platform_machine != "ARM64" or python_version >= "3.12"
|
|
17
|
+
Requires-Dist: httptools>=0.9.0; sys_platform == "win32" and platform_machine == "ARM64" and python_version >= "3.12"
|
|
17
18
|
|
|
18
19
|
# Flet Web client in Flutter
|
|
19
20
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
flet==1.1.0.dev0
|
|
2
|
+
fastapi>=0.115.12
|
|
3
|
+
websockets>=13.0
|
|
4
|
+
uvicorn>=0.35.0
|
|
5
|
+
|
|
6
|
+
[:sys_platform != "win32" or platform_machine != "ARM64" or python_version >= "3.12"]
|
|
7
|
+
uvicorn[standard]>=0.35.0
|
|
8
|
+
|
|
9
|
+
[:sys_platform == "win32" and platform_machine == "ARM64" and python_version >= "3.12"]
|
|
10
|
+
httptools>=0.9.0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version = "1.0.4"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|