flet-web 0.70.0.dev6516__py3-none-any.whl → 0.70.0.dev6616__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.
- flet_web/fastapi/flet_app.py +20 -11
- flet_web/fastapi/flet_app_manager.py +2 -3
- flet_web/fastapi/flet_static_files.py +3 -3
- flet_web/fastapi/flet_upload.py +36 -13
- flet_web/uploads.py +4 -3
- flet_web/version.py +1 -1
- flet_web/web/flutter_bootstrap.js +1 -1
- flet_web/web/flutter_service_worker.js +3 -3
- flet_web/web/main.dart.js +112209 -111397
- flet_web/web/main.dart.wasm +0 -0
- flet_web/web/pyodide/micropip-0.8.0-py3-none-any.whl +2 -2
- {flet_web-0.70.0.dev6516.dist-info → flet_web-0.70.0.dev6616.dist-info}/METADATA +1 -1
- {flet_web-0.70.0.dev6516.dist-info → flet_web-0.70.0.dev6616.dist-info}/RECORD +15 -15
- {flet_web-0.70.0.dev6516.dist-info → flet_web-0.70.0.dev6616.dist-info}/WHEEL +0 -0
- {flet_web-0.70.0.dev6516.dist-info → flet_web-0.70.0.dev6616.dist-info}/top_level.txt +0 -0
flet_web/fastapi/flet_app.py
CHANGED
|
@@ -168,15 +168,13 @@ class FletApp(Connection):
|
|
|
168
168
|
f"{self.__session.id if self.__session else ''}"
|
|
169
169
|
)
|
|
170
170
|
except Exception as e:
|
|
171
|
-
|
|
171
|
+
logger.error(
|
|
172
172
|
"Unhandled error processing page session: "
|
|
173
173
|
f"{self.__session.id if self.__session else ''}",
|
|
174
|
-
|
|
174
|
+
exc_info=True,
|
|
175
175
|
)
|
|
176
176
|
if self.__session:
|
|
177
|
-
self.__session.error(
|
|
178
|
-
f"There was an error while processing your request: {e}"
|
|
179
|
-
)
|
|
177
|
+
self.__session.error(str(e))
|
|
180
178
|
|
|
181
179
|
async def __send_loop(self):
|
|
182
180
|
assert self.__websocket
|
|
@@ -254,16 +252,23 @@ class FletApp(Connection):
|
|
|
254
252
|
# apply page patch
|
|
255
253
|
self.__session.apply_page_patch(req.page)
|
|
256
254
|
|
|
255
|
+
register_error = ""
|
|
257
256
|
if new_session:
|
|
258
257
|
# update IP and user-agent
|
|
259
258
|
self.__session.page.client_ip = self.__client_ip
|
|
260
259
|
self.__session.page.client_user_agent = self.__client_user_agent
|
|
261
260
|
|
|
262
261
|
# run before_main
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
self.__before_main
|
|
262
|
+
try:
|
|
263
|
+
if asyncio.iscoroutinefunction(self.__before_main):
|
|
264
|
+
await self.__before_main(self.__session.page)
|
|
265
|
+
elif callable(self.__before_main):
|
|
266
|
+
self.__before_main(self.__session.page)
|
|
267
|
+
except Exception as e:
|
|
268
|
+
register_error = f"{e}\n{traceback.format_exc()}"
|
|
269
|
+
logger.error(
|
|
270
|
+
"Unhandled error in before_main() handler", exc_info=True
|
|
271
|
+
)
|
|
267
272
|
|
|
268
273
|
# register response
|
|
269
274
|
self.send_message(
|
|
@@ -274,11 +279,15 @@ class FletApp(Connection):
|
|
|
274
279
|
page_patch=self.__session.get_page_patch()
|
|
275
280
|
if new_session
|
|
276
281
|
else self.__session.page,
|
|
277
|
-
error=
|
|
282
|
+
error=register_error,
|
|
278
283
|
),
|
|
279
284
|
)
|
|
280
285
|
)
|
|
281
286
|
|
|
287
|
+
if register_error:
|
|
288
|
+
self.__session.error(register_error)
|
|
289
|
+
return
|
|
290
|
+
|
|
282
291
|
# start session
|
|
283
292
|
if new_session:
|
|
284
293
|
asyncio.create_task(self.__on_session_created())
|
|
@@ -325,7 +334,7 @@ class FletApp(Connection):
|
|
|
325
334
|
|
|
326
335
|
else:
|
|
327
336
|
# it's something else
|
|
328
|
-
raise
|
|
337
|
+
raise RuntimeError(f'Unknown message "{action}": {body}')
|
|
329
338
|
|
|
330
339
|
if task:
|
|
331
340
|
self.__running_tasks.add(task)
|
|
@@ -6,11 +6,10 @@ from concurrent.futures import ThreadPoolExecutor
|
|
|
6
6
|
from datetime import datetime, timezone
|
|
7
7
|
from typing import Optional
|
|
8
8
|
|
|
9
|
+
import flet_web.fastapi as flet_fastapi
|
|
9
10
|
from flet.messaging.connection import Connection
|
|
10
11
|
from flet.messaging.session import Session
|
|
11
12
|
from flet.pubsub.pubsub_hub import PubSubHub
|
|
12
|
-
|
|
13
|
-
import flet_web.fastapi as flet_fastapi
|
|
14
13
|
from flet_web.fastapi.oauth_state import OAuthState
|
|
15
14
|
|
|
16
15
|
logger = logging.getLogger(flet_fastapi.__name__)
|
|
@@ -84,7 +83,7 @@ class FletAppManager:
|
|
|
84
83
|
session = self.__sessions[session_id]
|
|
85
84
|
await session.connect(conn)
|
|
86
85
|
else:
|
|
87
|
-
raise
|
|
86
|
+
raise RuntimeError(f"Session has expired or not found: {session_id}")
|
|
88
87
|
|
|
89
88
|
async def disconnect_session(self, session_id: str, session_timeout_seconds: int):
|
|
90
89
|
logger.info(f"Session disconnected: {session_id}")
|
|
@@ -6,11 +6,11 @@ from pathlib import Path
|
|
|
6
6
|
from typing import Optional
|
|
7
7
|
|
|
8
8
|
from fastapi.staticfiles import StaticFiles
|
|
9
|
-
from flet.controls.types import RouteUrlStrategy, WebRenderer
|
|
10
|
-
from flet.utils import Once, get_bool_env_var
|
|
11
9
|
from starlette.types import Receive, Scope, Send
|
|
12
10
|
|
|
13
11
|
import flet_web.fastapi as flet_fastapi
|
|
12
|
+
from flet.controls.types import RouteUrlStrategy, WebRenderer
|
|
13
|
+
from flet.utils import Once, get_bool_env_var
|
|
14
14
|
from flet_web import (
|
|
15
15
|
get_package_web_dir,
|
|
16
16
|
patch_font_manifest_json,
|
|
@@ -120,7 +120,7 @@ class FletStaticFiles(StaticFiles):
|
|
|
120
120
|
logger.info(f"Web root: {web_dir}")
|
|
121
121
|
|
|
122
122
|
if not os.path.exists(web_dir):
|
|
123
|
-
raise
|
|
123
|
+
raise RuntimeError(f"Web root path not found: {web_dir}")
|
|
124
124
|
|
|
125
125
|
# user-defined assets
|
|
126
126
|
if self.__assets_dir:
|
flet_web/fastapi/flet_upload.py
CHANGED
|
@@ -3,9 +3,10 @@ import os
|
|
|
3
3
|
from datetime import datetime, timezone
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
|
-
import flet_web.fastapi as flet_fastapi
|
|
7
6
|
from anyio import open_file
|
|
8
|
-
from fastapi import Request
|
|
7
|
+
from fastapi import HTTPException, Request, status
|
|
8
|
+
|
|
9
|
+
import flet_web.fastapi as flet_fastapi
|
|
9
10
|
from flet_web.uploads import build_upload_query_string, get_upload_signature
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger(flet_fastapi.__name__)
|
|
@@ -18,7 +19,8 @@ class FletUpload:
|
|
|
18
19
|
Parameters:
|
|
19
20
|
|
|
20
21
|
* `upload_dir` (str) - an absolute path to a directory with uploaded files.
|
|
21
|
-
* `max_upload_size` (str, int) - maximum size of a single upload, bytes.
|
|
22
|
+
* `max_upload_size` (str, int) - maximum size of a single upload, bytes.
|
|
23
|
+
Unlimited if `None`.
|
|
22
24
|
* `secret_key` (str, optional) - secret key to sign and verify upload requests.
|
|
23
25
|
"""
|
|
24
26
|
|
|
@@ -50,14 +52,24 @@ class FletUpload:
|
|
|
50
52
|
"""
|
|
51
53
|
|
|
52
54
|
async def handle(self, request: Request):
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
query_params = request.query_params
|
|
56
|
+
file_name = query_params.get("f")
|
|
57
|
+
expire_str = query_params.get("e")
|
|
58
|
+
signature = query_params.get("s")
|
|
56
59
|
|
|
57
60
|
if not file_name or not expire_str or not signature:
|
|
58
|
-
raise
|
|
61
|
+
raise HTTPException(
|
|
62
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
63
|
+
detail="Missing upload parameters",
|
|
64
|
+
)
|
|
59
65
|
|
|
60
|
-
|
|
66
|
+
try:
|
|
67
|
+
expire_date = datetime.fromisoformat(expire_str)
|
|
68
|
+
except ValueError as e:
|
|
69
|
+
raise HTTPException(
|
|
70
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
71
|
+
detail="Invalid expiration parameter",
|
|
72
|
+
) from e
|
|
61
73
|
|
|
62
74
|
# verify signature
|
|
63
75
|
query_string = build_upload_query_string(file_name, expire_date)
|
|
@@ -67,17 +79,26 @@ class FletUpload:
|
|
|
67
79
|
)
|
|
68
80
|
!= signature
|
|
69
81
|
):
|
|
70
|
-
raise
|
|
82
|
+
raise HTTPException(
|
|
83
|
+
status_code=status.HTTP_403_FORBIDDEN,
|
|
84
|
+
detail="Invalid upload signature",
|
|
85
|
+
)
|
|
71
86
|
|
|
72
87
|
# check expiration date
|
|
73
88
|
if datetime.now(timezone.utc) >= expire_date:
|
|
74
|
-
raise
|
|
89
|
+
raise HTTPException(
|
|
90
|
+
status_code=status.HTTP_410_GONE,
|
|
91
|
+
detail="Upload URL has expired",
|
|
92
|
+
)
|
|
75
93
|
|
|
76
94
|
# build/validate dest path
|
|
77
95
|
joined_path = os.path.join(self.__upload_dir, file_name)
|
|
78
96
|
full_path = os.path.realpath(joined_path)
|
|
79
97
|
if os.path.commonpath([full_path, self.__upload_dir]) != self.__upload_dir:
|
|
80
|
-
raise
|
|
98
|
+
raise HTTPException(
|
|
99
|
+
status_code=status.HTTP_400_BAD_REQUEST,
|
|
100
|
+
detail="Invalid upload destination",
|
|
101
|
+
)
|
|
81
102
|
|
|
82
103
|
# create directory if not exists
|
|
83
104
|
dest_dir = os.path.dirname(full_path)
|
|
@@ -89,7 +110,9 @@ class FletUpload:
|
|
|
89
110
|
async for chunk in request.stream():
|
|
90
111
|
size += len(chunk)
|
|
91
112
|
if self.__max_upload_size and size > self.__max_upload_size:
|
|
92
|
-
raise
|
|
93
|
-
|
|
113
|
+
raise HTTPException(
|
|
114
|
+
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
|
|
115
|
+
detail="Max upload size exceeded: "
|
|
116
|
+
f"{self.__max_upload_size} bytes",
|
|
94
117
|
)
|
|
95
118
|
await f.write(chunk)
|
flet_web/uploads.py
CHANGED
|
@@ -39,8 +39,9 @@ def get_upload_signature(
|
|
|
39
39
|
if env_secret_key:
|
|
40
40
|
secret_key = env_secret_key
|
|
41
41
|
if not secret_key:
|
|
42
|
-
raise
|
|
43
|
-
"Specify secret_key parameter or set FLET_SECRET_KEY environment
|
|
42
|
+
raise RuntimeError(
|
|
43
|
+
"Specify secret_key parameter or set FLET_SECRET_KEY environment "
|
|
44
|
+
"variable to enable uploads."
|
|
44
45
|
)
|
|
45
46
|
signing_key = hmac.new(
|
|
46
47
|
secret_key.encode("utf-8"),
|
|
@@ -49,6 +50,6 @@ def get_upload_signature(
|
|
|
49
50
|
).digest()
|
|
50
51
|
return hmac.new(
|
|
51
52
|
signing_key,
|
|
52
|
-
f"{upload_endpoint_path.strip('/')}{query_string}".encode(
|
|
53
|
+
f"{upload_endpoint_path.strip('/')}{query_string}".encode(),
|
|
53
54
|
hashlib.sha256,
|
|
54
55
|
).hexdigest()
|
flet_web/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
version = "0.70.0.
|
|
1
|
+
version = "0.70.0.dev6616"
|
|
@@ -55,7 +55,7 @@ if (flet.noCdn) {
|
|
|
55
55
|
_flutter.loader.load({
|
|
56
56
|
config: flutterConfig,
|
|
57
57
|
serviceWorkerSettings: {
|
|
58
|
-
serviceWorkerVersion: "
|
|
58
|
+
serviceWorkerVersion: "1655580612",
|
|
59
59
|
},
|
|
60
60
|
onEntrypointLoaded: async function (engineInitializer) {
|
|
61
61
|
loading.classList.add('main_done');
|
|
@@ -43,10 +43,10 @@ const RESOURCES = {"flutter.js": "888483df48293866f9f41d3d9274a779",
|
|
|
43
43
|
"canvaskit/skwasm.js.symbols": "0088242d10d7e7d6d2649d1fe1bda7c1",
|
|
44
44
|
"python-worker.js": "26eb131f3acb5ce232fea72da957e8ce",
|
|
45
45
|
"favicon.png": "302ac04c14db027d016d1fe74c6a80a0",
|
|
46
|
-
"main.dart.wasm": "
|
|
47
|
-
"flutter_bootstrap.js": "
|
|
46
|
+
"main.dart.wasm": "235be5bad710db8c4e2d34e13c332438",
|
|
47
|
+
"flutter_bootstrap.js": "666833912535cd573d1cebc76ab4bb32",
|
|
48
48
|
"version.json": "3fea9d9c7b4ca6955aa03e762e0d2e13",
|
|
49
|
-
"main.dart.js": "
|
|
49
|
+
"main.dart.js": "8d6a52f9f0f4b292cc98bfbfc96bb853"};
|
|
50
50
|
// The application shell files that are downloaded before a service worker can
|
|
51
51
|
// start.
|
|
52
52
|
const CORE = ["main.dart.js",
|