Skip to content

Commit 88ac763

Browse files
refactor(build): rename web build platform from Pyodide to Emscripten (#6492)
* refactor: rename web build platform identifier from `Pyodide` to `Emscripten` Aligns the value with `platform.system()` inside Pyodide, so PEP 508 markers on `flet`'s deps (`oauthlib`, `httpx`) work both via `flet build web` (through serious_python's sitecustomize) and when `flet` is installed directly via micropip in a Pyodide runtime. Requires the matching rename in serious_python. * chore: bump `serious_python` to 1.0.0 in build template Required for the `Pyodide` → `Emscripten` platform-argument rename to take effect on `flet build` runs. * Add CHANGELOG entry for `Pyodide` → `Emscripten` rename (#6492) * python-worker: load msgpack explicitly so prints from flet-less scripts reach the host Console msgpack was only ever imported if the user's deps pulled it in (typically via flet). Apps with no flet dependency — or no pyproject.toml at all — left the python_output bridge unregistered, and their prints fell through to the browser dev console silently. Load msgpack from Pyodide's prebuilt repodata when it isn't already importable; the bridge install is now unconditional. * Restore main(page) wrapper in use_dialog_* examples Integration test packages/flet/integration_tests/examples/apps/test_use_dialog.py imports `main` from each example expecting a `main(page)` callable. The wrapper was inadvertently removed in #6489, breaking pytest collection.
1 parent a3ba9cb commit 88ac763

9 files changed

Lines changed: 55 additions & 34 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
* Fix `TooltipTheme.decoration` so it applies to controls using `ft.Tooltip(...)` when the tooltip does not explicitly set `decoration` or `bgcolor` ([#6432](https://github.com/flet-dev/flet/issues/6432), [#6482](https://github.com/flet-dev/flet/pull/6482)) by @ndonkoHenri.
66
* Fix `flet-geolocator.Geolocator` reliability on web and desktop: `get_last_known_position()` no longer crashes with `TypeError: argument after ** must be a mapping, not NoneType` and now returns `Optional[GeolocatorPosition]`; `get_current_position()` no longer hangs forever on web (Dart-side workaround for the upstream [`geolocator_web` 4.1.3](https://pub.dev/packages/geolocator_web) `inMicroseconds`/`inMilliseconds` timeout typo) and uses sensible web defaults (`time_limit: 30s`, `maximum_age: 5m`); the previously-dropped `configuration` argument now actually reaches `getCurrentPosition` on the Dart side; the position stream is gated behind a registered `on_position_change`/`on_error` handler (with cancel-on-update to prevent leaks); and platform exceptions (`LocationServiceDisabledException`, `PermissionDeniedException`, `PermissionDefinitionsNotFoundException`, `PermissionRequestInProgressException`, `PositionUpdateException`, `TimeoutException`) are now translated into actionable error messages and surfaced to Python as `RuntimeError` without the default `Exception:` prefix ([#6487](https://github.com/flet-dev/flet/pull/6487)) by @FeodorFitsner.
7+
* Fix PEP 508 markers on `flet`'s `oauthlib`/`httpx` deps not actually excluding those packages under Pyodide: the `flet build web` package platform has been renamed from `Pyodide` to `Emscripten` to match `platform.system()` inside the Pyodide runtime, and the markers now use `platform_system != 'Emscripten'`, so the exclusion works both via `flet build` and a direct `micropip.install("flet")` in a Pyodide REPL. Requires `serious_python` `>= 1.0.0`, which is now pinned in the `flet build` template ([#6492](https://github.com/flet-dev/flet/pull/6492)) by @FeodorFitsner.
78

89
## 0.85.0
910

client/web/python-worker.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,23 +149,27 @@ self.initPyodide = async function () {
149149
micropip = await ensure_micropip()
150150
await micropip.install(py_args["dependencies"], pre=micropip_include_pre)
151151
152-
# Install the python_output bridge using msgpack from the
153-
# already-loaded user deps (typically pulled in via flet). If
154-
# msgpack isn't around — apps that don't depend on flet — skip
155-
# silently; stdout/stderr just stays in the dev console.
152+
# Install the python_output bridge. msgpack normally rides in
153+
# with the user's flet dependency, but apps without a flet dep
154+
# (or without a pyproject.toml at all) would otherwise leave the
155+
# bridge unregistered and their prints stranded in the dev
156+
# console. Pyodide ships msgpack as a prebuilt package, so we
157+
# load it explicitly when it isn't already importable.
156158
try:
157159
import msgpack as _msgpack
160+
except ImportError:
161+
import pyodide_js
162+
await pyodide_js.loadPackage("msgpack")
163+
import msgpack as _msgpack
158164
159-
def _send_python_output(text, is_stderr):
160-
flet_js.receive_callback(
161-
_msgpack.packb(
162-
[7, {"text": text, "is_stderr": bool(is_stderr)}]
163-
)
165+
def _send_python_output(text, is_stderr):
166+
flet_js.receive_callback(
167+
_msgpack.packb(
168+
[7, {"text": text, "is_stderr": bool(is_stderr)}]
164169
)
170+
)
165171
166-
flet_js.send_python_output = _send_python_output
167-
except ImportError:
168-
pass
172+
flet_js.send_python_output = _send_python_output
169173
170174
# Flip the worker into "user code" mode so stdout/stderr starts
171175
# flowing to the host page's Console pane instead of dev console.

sdk/python/examples/apps/declarative/use_dialog_basic/main.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,9 @@ async def handle_delete():
5353
)
5454

5555

56+
def main(page: ft.Page):
57+
page.render(App)
58+
59+
5660
if __name__ == "__main__":
57-
ft.run(lambda page: page.render(App))
61+
ft.run(main)

sdk/python/examples/apps/declarative/use_dialog_chained/main.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,9 @@ def on_confirm_dismiss():
7878
)
7979

8080

81+
def main(page: ft.Page):
82+
page.render(App)
83+
84+
8185
if __name__ == "__main__":
82-
ft.run(lambda page: page.render(App))
86+
ft.run(main)

sdk/python/examples/apps/declarative/use_dialog_multiple/main.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,5 +145,9 @@ def handler():
145145
)
146146

147147

148+
def main(page: ft.Page):
149+
page.render(App)
150+
151+
148152
if __name__ == "__main__":
149-
ft.run(lambda page: page.render(App))
153+
ft.run(main)

sdk/python/packages/flet-cli/src/flet_cli/commands/build_base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def __init__(self, parser: argparse.ArgumentParser) -> None:
9595
"can_be_run_on": ["Linux"],
9696
},
9797
"web": {
98-
"package_platform": "Pyodide",
98+
"package_platform": "Emscripten",
9999
"config_platform": "web",
100100
"flutter_build_command": "web",
101101
"status_text": "web app",
@@ -1833,7 +1833,7 @@ def package_python_app(self):
18331833
package_args.extend(["-r", f"flet=={flet.version.flet_version}"])
18341834

18351835
# site-packages variable
1836-
if self.package_platform != "Pyodide":
1836+
if self.package_platform != "Emscripten":
18371837
package_env["SERIOUS_PYTHON_SITE_PACKAGES"] = str(
18381838
self.build_dir / "site-packages"
18391839
)
@@ -2043,12 +2043,12 @@ def _run_flutter_command(self):
20432043
build_env = {}
20442044

20452045
# site-packages variable
2046-
if self.package_platform != "Pyodide":
2046+
if self.package_platform != "Emscripten":
20472047
build_env["SERIOUS_PYTHON_SITE_PACKAGES"] = str(
20482048
self.build_dir / "site-packages"
20492049
)
20502050

2051-
if self.package_platform == "Pyodide" and not self.template_data["no_wasm"]:
2051+
if self.package_platform == "Emscripten" and not self.template_data["no_wasm"]:
20522052
build_args.append("--wasm")
20532053

20542054
android_signing_key_store = (

sdk/python/packages/flet/pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ requires-python = ">=3.10"
99
dependencies = [
1010
"flet-cli; extra == 'cli'",
1111
"flet-web; extra == 'web'",
12-
"oauthlib >=3.2.2; platform_system != 'Pyodide'",
13-
"httpx >=0.28.1; platform_system != 'Pyodide'",
12+
"oauthlib >=3.2.2; platform_system != 'Emscripten'",
13+
"httpx >=0.28.1; platform_system != 'Emscripten'",
1414
"repath >=0.9.0",
1515
"msgpack >=1.1.0",
1616
"typing-extensions; python_version < '3.11'"

sdk/python/templates/build/{{cookiecutter.out_dir}}/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ dependencies:
1717

1818
flet:
1919
path: ../../../../../packages/flet
20-
serious_python: 0.9.12
20+
serious_python: 1.0.0
2121

2222
package_info_plus: ^9.0.0
2323
path_provider: ^2.1.4

sdk/python/templates/build/{{cookiecutter.out_dir}}/web/python-worker.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,23 +149,27 @@ self.initPyodide = async function () {
149149
micropip = await ensure_micropip()
150150
await micropip.install(py_args["dependencies"], pre=micropip_include_pre)
151151
152-
# Install the python_output bridge using msgpack from the
153-
# already-loaded user deps (typically pulled in via flet). If
154-
# msgpack isn't around — apps that don't depend on flet — skip
155-
# silently; stdout/stderr just stays in the dev console.
152+
# Install the python_output bridge. msgpack normally rides in
153+
# with the user's flet dependency, but apps without a flet dep
154+
# (or without a pyproject.toml at all) would otherwise leave the
155+
# bridge unregistered and their prints stranded in the dev
156+
# console. Pyodide ships msgpack as a prebuilt package, so we
157+
# load it explicitly when it isn't already importable.
156158
try:
157159
import msgpack as _msgpack
160+
except ImportError:
161+
import pyodide_js
162+
await pyodide_js.loadPackage("msgpack")
163+
import msgpack as _msgpack
158164
159-
def _send_python_output(text, is_stderr):
160-
flet_js.receive_callback(
161-
_msgpack.packb(
162-
[7, {"text": text, "is_stderr": bool(is_stderr)}]
163-
)
165+
def _send_python_output(text, is_stderr):
166+
flet_js.receive_callback(
167+
_msgpack.packb(
168+
[7, {"text": text, "is_stderr": bool(is_stderr)}]
164169
)
170+
)
165171
166-
flet_js.send_python_output = _send_python_output
167-
except ImportError:
168-
pass
172+
flet_js.send_python_output = _send_python_output
169173
170174
# Flip the worker into "user code" mode so stdout/stderr starts
171175
# flowing to the host page's Console pane instead of dev console.

0 commit comments

Comments
 (0)