Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to embed Python for web version Pyxel #412

Closed
kitao opened this issue Sep 4, 2022 · 12 comments
Closed

How to embed Python for web version Pyxel #412

kitao opened this issue Sep 4, 2022 · 12 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@kitao
Copy link
Owner

kitao commented Sep 4, 2022

The initial web version of Pyxel is built as wheel and worked with (patched) Pyodide.
But I'd also like to consider embedding-Python-version like PyGame WASM.

The difference between Pyxel and PyGame is Pyxel uses Rust, PyO3, and Maturin.
I'd like to know how to modify the way to use them for embedding Python WASM.

I'm not familiar with Emscripten-related area, so any information would be appreciated!

@kitao kitao added the enhancement New feature or request label Sep 4, 2022
@kitao kitao added the help wanted Extra attention is needed label Sep 4, 2022
@km19809
Copy link
Contributor

km19809 commented Sep 5, 2022

PyO3 can statically embed the python interpreter, but it is complicated. Also, as I know, no one succeeds to link it to the wasm target.
Another option is RustPython. An abandoned engine, pyckitup embedded RustPython.
The problem is that it needs wasm-bindgen. wasm-bindgen does not support wasm32-unknown-emscripten. Instead, it uses wasm32-unknown-unknown. So it cannot be used with SDL2.

In summary:

Options PyO3 RustPython
Python CPython RustPython
Backend SDL2 Rust backend, such as miniquad
Tragets wasm32-unknown-emscripten wasm32-unknown-unknown
Challanges There is no prior work We have to change the backend and wrapper*.

*Unfortunately, PyO3 does not support PyO3.

See also: michaelwooley/pybros#32

@kitao
Copy link
Owner Author

kitao commented Sep 5, 2022

Thank you for the information.
In the case of dynamic link instead of static link, do you think it is easy to use Python WASM with PyO3?
Pyodide may have some limitations because it is not designed for Pyxel and SDL2, so I'm also interested in using self-build Python WASM.

@kitao
Copy link
Owner Author

kitao commented Sep 5, 2022

I am also investigating here to understand how PyGame realizes WASM feature.

@kitao
Copy link
Owner Author

kitao commented Sep 5, 2022

Another possibility.
If Pyxel is added as an embedded package for Pyodide. Specifically put under pyodide/packages directory.
Will Pyxel be linked to Pyodide as a static library? (Pyodide may also need to be compiled with SDL flag)

I'm wondering whether it will be linked statically and Pyodide support Maturin to build an embedded package.

@pmp-p
Copy link

pmp-p commented Sep 7, 2022

Would you prefer something like pyxel-script ( based on pygame-script the newest addition to pygbag ) ?
i just tested locally a few minutes ago with @km19809's wheel for pyodide it just need to remove a bigint u64 call with bynarien and everything seems to go well in stock cpython 3.11. That may be easier to maintain than a full fork of pyodide ( at least until they switch to 3.11 in ~ 3 months ) and you gain compatibility with older browsers ( eg android kitkat 4.4 and chrome 81 )

a pygame-script example : https://pygame-web.github.io/showroom/pygame-scripts/org.pygame.touchpong.html

i don't think that loading the wheel dynamically will loose much performance vs a static build but i would need a benchmark code to be sure.

I am also investigating here to understand how PyGame realizes WASM feature.

That is only the normal python build + emsdk packaged for CI, pygame uses a static build, and the process is here https://github.com/pygame-web/pygame-wasm-plus, ** the static initializer is here https://github.com/pmp-p/pygame-wasm/blob/pygame-wasm/src_c/static.c and handle multiphase modules (cython)

i also apply the same to Panda3D or Harfang3D but it may not be necessary to add that complication for Pyxel thanks to the abi3

** edit i merged pygame and loader build into pygbag repo

@kitao
Copy link
Owner Author

kitao commented Sep 7, 2022

I cleaned up the Pyodide-related code in Pyxel.
Now if Pyodide only enables SDL2 flags without other changes, Pyxel can work with it.
And I also wrote a simple wrapper for Pyodide and Pyxel (pyxel/wasm/pyxel.js).
Though there are several errors which should be addressed, but it can be said that the support for Pyodide is relatively stable now.
And regarding its performance, as far as I have confirmed with Pyxel users, it seems that there is no particular problem.
Anyway I'll keep investigating.

@kitao
Copy link
Owner Author

kitao commented Sep 7, 2022

@pmp-p Thank you for your suggestion. Pyxel-script with very simple tags sounds attractive.
I'm wondering how to handle assets like image files. Is there some easy way?

@pmp-p
Copy link

pmp-p commented Sep 7, 2022

There's the easy way : letting pygbag do what it does for pygame games and just open() the assets after waiting they are mounted and browser preloaded them ( that's the green progress bar you can see on some games on demos/itch )

Or the async way and get assets one by one from server asynchronously ( like pyodide fetch ) and preload manually each new asset . Preloading is annoying unless you use a SDL2_image > 2.6 (pygbag does) which uses stbimage and nanosvg internally.

or just mix the two methods and everyone will pick for their needs ! ( that's the default in pygbag once .apk is mounted in filesystem and asyncio.run(main()) has started running but for that i rely on two builtins modules that are NOT part of cpython or pyodide see https://discuss.python.org/t/status-of-wasm-in-cpythons-main-branch/15542/12?u=pmp-p )
sadly these modules cannot be imported in pyodide or stock cpython-wasm they are included directly in pymain and linked to static lib of stock cpython-wasm

i really hope theses modules get considered for inclusion in 3.12, instead of having to slap around thousands lines of typescript and js glue each time you want to do a fetch, network/webrtc or just query battery/accelerometer/webusb/web audio etc ... => if you happen to think the same, just make your voice heard

@kitao
Copy link
Owner Author

kitao commented Sep 9, 2022

@pmp-p Thank you for your response. In that case, Pyxel already has "pyxapp" format which includes scripts and assets as single zip. And Pyxel can play it from JavaScript with its JavaScript utility function now. So I did the most of what I could, I think.

@pmp-p
Copy link

pmp-p commented Sep 10, 2022

Pyxel already has "pyxapp" format which includes scripts and assets as single zip.

perfect ! you could use pygame-script to mount them directly like here https://github.com/pygame-web/pygbag/blob/2aae0ac269aeeb9c377d91ca0b9f82ca165ad0e6/static/default.tmpl#L87

after that they are synchronously available ( and writeable : editors may like that ! ) from python via normal filesystems files.

@kitao
Copy link
Owner Author

kitao commented Sep 13, 2022

Does anyone know whether it is possible to embed libpython for WASM on PyO3?
I would like to know if there are actual cases.

@kitao
Copy link
Owner Author

kitao commented Oct 2, 2022

Now Pyxel Web works stably with its custom HTML elements. And I never heard performance issue from users.
So let me close this issue because it is no longer necessary to embed Python. Thank you.

@kitao kitao closed this as completed Oct 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants