flet-web 0.70.0.dev6516__py3-none-any.whl → 0.70.0.dev6619__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.
@@ -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
- print(
171
+ logger.error(
172
172
  "Unhandled error processing page session: "
173
173
  f"{self.__session.id if self.__session else ''}",
174
- traceback.format_exc(),
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
- 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)
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 Exception(f'Unknown message "{action}": {body}')
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 Exception(f"Session has expired or not found: {session_id}")
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 Exception(f"Web root path not found: {web_dir}")
123
+ raise RuntimeError(f"Web root path not found: {web_dir}")
124
124
 
125
125
  # user-defined assets
126
126
  if self.__assets_dir:
@@ -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. Unlimited if `None`.
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
- file_name = request.query_params["f"]
54
- expire_str = request.query_params["e"]
55
- signature = request.query_params["s"]
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 Exception("Invalid request")
61
+ raise HTTPException(
62
+ status_code=status.HTTP_400_BAD_REQUEST,
63
+ detail="Missing upload parameters",
64
+ )
59
65
 
60
- expire_date = datetime.fromisoformat(expire_str)
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 Exception("Invalid request")
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 Exception("Invalid request")
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 Exception("Invalid request")
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 Exception(
93
- f"Max upload size reached: {self.__max_upload_size}"
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 Exception(
43
- "Specify secret_key parameter or set FLET_SECRET_KEY environment variable to enable uploads."
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("utf-8"),
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.dev6516"
1
+ version = "0.70.0.dev6619"
@@ -55,7 +55,7 @@ if (flet.noCdn) {
55
55
  _flutter.loader.load({
56
56
  config: flutterConfig,
57
57
  serviceWorkerSettings: {
58
- serviceWorkerVersion: "159190134",
58
+ serviceWorkerVersion: "1035925904",
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": "35e35486894562464bdcd966aa0c9447",
47
- "flutter_bootstrap.js": "5910c8294fd646b00b542ffadf74f08d",
46
+ "main.dart.wasm": "460194227412855c3876ca2cf805e68c",
47
+ "flutter_bootstrap.js": "b98d3bef832c3c0e6950227b02d0f1c3",
48
48
  "version.json": "3fea9d9c7b4ca6955aa03e762e0d2e13",
49
- "main.dart.js": "3c75fba92d0cdd27d1538d499b46adf5"};
49
+ "main.dart.js": "3ba09333ec4547e85ad8c23f2a01ce95"};
50
50
  // The application shell files that are downloaded before a service worker can
51
51
  // start.
52
52
  const CORE = ["main.dart.js",