Compare commits

...

311 Commits

Author SHA1 Message Date
Ted Patrick
25809660ef 2022.12.1 (#1044)
* 2022.12.1

* release level

* fix tests for release
2022-12-13 08:06:38 -06:00
pre-commit-ci[bot]
6b9eff45bb [pre-commit.ci] pre-commit autoupdate (#1042)
updates:
- [github.com/psf/black: 22.10.0 → 22.12.0](https://github.com/psf/black/compare/22.10.0...22.12.0)
- [github.com/pycqa/isort: 5.10.1 → 5.11.1](https://github.com/pycqa/isort/compare/5.10.1...5.11.1)
- [github.com/asottile/pyupgrade: v3.3.0 → v3.3.1](https://github.com/asottile/pyupgrade/compare/v3.3.0...v3.3.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-13 10:12:34 +05:30
Madhur Tandon
08e83feaf5 getPySrc should return source code (#1041)
* getPySrc should return source code

* fix lint

* add test

* fix dynamic tag test

* address feedback
2022-12-13 02:41:21 +05:30
Madhur Tandon
4f05b5afc6 remove fetching of pyscript.py from tutorial (#1036)
* remove fetching of pyscript.py from tutorial

* fix indentation
2022-12-10 01:04:04 +05:30
Fabio Pliger
9a5bf9918e Fix py-markdown plugin (#1008)
* fix wrong console method and unescape the tag content before running markdown on it

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add markdown plugin example test

* add PyMarkdown minimal test

* remove commented code

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove import of console from pyscript

* remove unused imports

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2022-12-08 10:09:31 -08:00
Jeff Glass
1c7cf0ba7d Bump bokeh, panel versions (#1032)
Bump panel version 13.1 -> 14.1 ; bump bokeh version 2.4.2 -> 2.4.3
2022-12-08 11:40:48 -06:00
Ted Patrick
ce2d1a4513 Release 2022.12.1.RC1 (#1030)
* Release 2022.12.1

* RC1
2022-12-08 07:49:22 -06:00
Madhur Tandon
7d50d7eea0 add docs for using display with matplotlib (#1029) 2022-12-08 07:38:45 -06:00
Fábio Rosado
e9411dc796 Fix the toga example (#1028) 2022-12-08 10:52:09 +00:00
Fábio Rosado
5cf2de16d1 Remove freedom units from examples (#1026) 2022-12-07 12:53:03 +00:00
Ted Patrick
e53bcf15a9 Fix for D3 and 3JS demos (#1025)
* fix for d3 example

* fix webgl +upgrade 3js
2022-12-06 13:36:03 -06:00
Madhur Tandon
bec70b60b8 add reference to Jeff's blog (#1024)
* add reference to Jeff's blog

* fix url
2022-12-06 23:08:12 +05:30
Fábio Rosado
8b7fb89c68 Update docs examples so they don't use deprecated features, styling tweaks (#982)
* Deprecate pyscript output attribute

* Update code blocks so they work

* Small tweaks to styling and use html to warning

* Fix broken test from bad conflict resolution

* lowercase pyodide
2022-12-06 14:36:17 +00:00
Madhur Tandon
b2bbdda73d updated docs for fetch (#1019) 2022-12-06 19:36:23 +05:30
Madhur Tandon
ee2f46cfb9 split py-config into sections (#1022)
* split into sections

* new section about custom keys

* link to fetch section

* add example for using runtime
2022-12-06 19:26:19 +05:30
Fábio Rosado
4337e6833a Rewrite the get started tutorial using the ice cream demo (#985)
* Rewrite the get started tutorial using the ice cream demo

* Update docs/tutorials/getting-started.md

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

* Address Antonio's comments

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-12-06 13:47:08 +00:00
Jeff Glass
a73c73b814 Fix antigravity (#1017)
* Fix antigravity

* Add test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-06 19:09:58 +05:30
Antonio Cuni
e8318a98f0 Introduce DeprecatedGlobal and show proper warnings (#1014)
* kill the PyScript class and the weird pyscript instance; from the user point of view its functionalities are still available as pyscript.*, but pyscript is not the module, not the instance of PyScript

* simplify the code in _set_version_info, while I'm at it

* start to implement DeprecatedGlobal

* DeprecatedGlobal.__getattr__

* don't show the same warning twice

* DeprecatedGlobal.__call__

* make it possible to specify a different warning message for every global

* WIP: carefully use DeprecatedGlobal to show reasonable warning messages depending on which name you are accessing to. More names to follow

* deprecate more names

* deprecate private names

* depreacte direct usage of console and document

* deprecate the PyScript class

* use a better error message

* fix test_pyscript.py

* introduce a __repr__ for DeprecatedGlobal

* add an helper to ensure that we don't show any error or warning on the page

* WIP: ensure that examples don't use depreacted features. Many tests are failing

* don't deprecate Element

* don't use the global micropip to install packages, else we trigger a warning

* use a better error message for micropip

* fix test_todo_pylist to avoid using deprecated globals

* fix test_webgl_raycaster

* fix tests

* make HTML globally available

* add MIME_RENDERERS and MIME_METHODS

* fix the typing of Micropip, thanks to @FabioRosado
2022-12-06 19:01:57 +05:30
Ted Patrick
94f2ac6204 Fake server 404 support (#994)
* Fake server 404 support

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* 404 test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-05 21:26:11 -06:00
pre-commit-ci[bot]
cc6cb4ded0 [pre-commit.ci] pre-commit autoupdate (#1021)
updates:
- [github.com/macisamuele/language-formatters-pre-commit-hooks: v2.4.0 → v2.5.0](https://github.com/macisamuele/language-formatters-pre-commit-hooks/compare/v2.4.0...v2.5.0)
- [github.com/asottile/pyupgrade: v3.2.2 → v3.3.0](https://github.com/asottile/pyupgrade/compare/v3.2.2...v3.3.0)
- [github.com/pre-commit/mirrors-eslint: v8.28.0 → v8.29.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.28.0...v8.29.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-05 21:07:16 -06:00
Fábio Rosado
c61d4191c3 Convert image bytes to base64 in pyscript's render_image (#1020)
* Convert bytes to b64 if needed

* Move test and check for pattern
2022-12-05 21:37:03 +00:00
Madhur Tandon
e284da7c09 Fix clashing test names (#1018)
* rename tests

* rename tests for element
2022-12-06 00:43:02 +05:30
Fábio Rosado
9992096654 Add Element to the API reference (#998) 2022-12-05 15:14:34 +00:00
Mariana Meireles
c696d92f40 Rm MIME types that we don't offer support to (#1013) 2022-12-05 16:09:34 +01:00
Fábio Rosado
af60299324 Improve UX when we can't install a package (#1000) 2022-12-05 14:35:15 +00:00
Fábio Rosado
5aa9135a34 Remove comments from github actions (#1011) 2022-12-02 14:11:59 +00:00
Mariana Meireles
72e23ac86f Rm id use (#912)
* rm unecessary code on output rendering on pyscript.py

* Remove all ids from repl

* Fix problems on rendering outside repl

* fixing tests

* Fixes repl and tes_py_repl

* Fix zz tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test 864now works consistently

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-02 00:59:21 +01:00
Madhur Tandon
33d49ad87d add docstrings for loadFromFile (#997)
* add docstrings for loadFromFile

* address feedback

* add example usage

* fix typo
2022-11-30 20:54:10 +05:30
pre-commit-ci[bot]
aa2335ca2e [pre-commit.ci] pre-commit autoupdate (#990)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.3.0 → v4.4.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.3.0...v4.4.0)
- [github.com/PyCQA/flake8: 5.0.4 → 6.0.0](https://github.com/PyCQA/flake8/compare/5.0.4...6.0.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-30 09:05:26 -06:00
Fábio Rosado
b31428006c Use response.ok instead of just status 200 (#999) 2022-11-30 13:17:48 +00:00
Madhur Tandon
dc1d583791 remove unneeded imports (#991) 2022-11-30 15:16:16 +05:30
Jeff Glass
4299a74e40 Invalidate Importlib's Module Cache on Writes to FS (#996)
* Add runtime.invalidate_module_path_cache() to clear importlib's cache of modules

* Clear cache after [[fetch]], after plugin files download, after plugins setup, and prior to py-script tag execution.
2022-11-29 15:36:23 -06:00
Fabio Pliger
3e408b7baa Python Plugins (#961)
* add test and example files

* update config to include python plugins in build

* add markdown plugin

* remove full pyscript execution from pyodide

* move loading of pyscript.py from pyodide loagInterpreter to main setupVirtualEnv and add function to create python CE plugins

* add plugin class to pyscript.py

* add missing import

* fix plugin path

* add fetchPythonPlugins to PyScriptApp

* remove old comments

* fix test

* add support for python plugins beyond custom elements and add app to python namespace in main

* inject reference to PyScript app onto python plugins

* add example hook onto markdown plugin

* change plugin events logs

* remove unused PyPlugin

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix type import

* add docstring to fetchPythonPlugins

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* rename addPythonPlugin method

* address PR comment

* call python plugins on hooks after the interpreted is ready

* add test for event hooks and split the test in 2 separate plugins to isolte type of plugins tests

* change python plugins initialization and registration, to inject the app from app itself instead of on the plugins themselves

* handle case when plugin cannot load due to missing plugin attribute

* add test for fail scenario when a plugin module does not have a plugin attribute

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add deprecation warning for pyscript objects loaded in global namespace

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove all from global scope

* remove create_custom_element from global scope

* rename create_custom_element to define_custom_element

* rename attributes in define_custom_element and add docstrings

* better handle connect event output

* add warning to py_markdown plugin

* remove debugging logs

* improve tests

* remove debugging log

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove unused import

* add executable shebang

* add pyodide mock module

* fmt and lint

* Update to pyodide.ffi.create_proxy per pyodide v21 api change

* Mock pyodide as package instead of mdoule

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add __init__ to pyodide package

* Update pyscriptjs/src/plugin.ts

fix logger name

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

* fix pyodide import but handling the diff in their API change

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* oops, conflict resolution blooper

* Fix failing integration tests

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Jeff Glass <glass.jeffrey@gmail.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
Co-authored-by: FabioRosado <fabiorosado@outlook.com>
2022-11-28 12:39:31 -06:00
Fábio Rosado
446c131ccb Deprecate pyscript output attribute (#981)
* Deprecate pyscript output attribute

* Update pyscriptjs/src/components/pyscript.ts

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-11-25 18:04:27 +00:00
Fábio Rosado
b062efcf17 Add error codes to our custom errors (#959) 2022-11-25 17:04:10 +00:00
Mariana Meireles
30e31a86ef Fix test and add new ones to close 878 (#971)
* Fix test and add new ones to close 887

* lint
2022-11-25 17:40:36 +01:00
Fábio Rosado
182272e8c7 Add tests for changes to examples/ (#980) 2022-11-24 11:17:52 +00:00
Fábio Rosado
06df21e8e3 Add three new tutorials and small tweaks to docs (#972) 2022-11-24 10:53:22 +00:00
Fábio Rosado
cafebd68f2 Fix failing tests (#978) 2022-11-24 09:46:06 +00:00
woxtu
061d4b3f72 Use a more precise type (#976) 2022-11-23 19:16:26 +00:00
Jason Washburn
6586e79d5e remove deprecated ref in getting started doc (#974) 2022-11-23 16:52:26 +00:00
Fábio Rosado
cda6c6bc7e Update docs GitHub actions to deploy to unstable or latest (#977) 2022-11-23 16:51:11 +00:00
Fábio Rosado
a628026838 Restyle examples and add button to show code on all examples (#968) 2022-11-22 15:46:54 +00:00
pre-commit-ci[bot]
6700856b9f [pre-commit.ci] pre-commit autoupdate (#970)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.27.0 → v8.28.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.27.0...v8.28.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-22 12:21:36 +05:30
Lukas Schönmann
411aa0bbed Remove hardcoded cursor for <input> (#967) 2022-11-21 21:10:24 +00:00
woxtu
0d79d31b96 Specify the unknown type (#965) 2022-11-21 23:43:57 +05:30
Jeff Glass
cb05a9b067 Export Version from JS Module (#963)
* Export PyScript version from js module

* Add docs and test
2022-11-20 09:58:09 -06:00
woxtu
536f359fb9 Fix a typo (#964) 2022-11-20 13:51:09 +00:00
Jeff Glass
56e888ed33 Fix stray capitalization in file name (#960) 2022-11-19 03:39:54 +05:30
Jeff Glass
687b93d148 Import PyScript Version into Python Runtime (#958)
* Import current version as PyScript.__version__ and PyScript.version_info

* Add integration, python unit tests
 
* Mock pyscript.py with __mocks__/pyscript.js to make jest tests happy
2022-11-18 11:49:45 -06:00
Fábio Rosado
0e1c396d7c Add div id to target in the display so examples get displayed in the right tag (#955)
* Add target to display

* Remove output from examples
2022-11-17 14:51:16 +00:00
Jeff Glass
7e24289703 Unwind async/await chains (#957)
*Cleanup several spots where runtime.run() no longer needs to be awaited, now that #928 is merged.
2022-11-16 13:42:40 -06:00
Jeff Glass
0b23310a06 Remove 'Implicit Async', Don't Await runtime.run() (#928)
* Revert to runPython instead of await runPythonAsync

* "Implicit Coroutines" are no longer permitted in py-script tags

* Tests added for the above

* xfail test_importmap (See #938)
2022-11-16 13:11:40 -06:00
Antonio Cuni
41ebaaf366 More plugins: splashscreen and importmap (#938)
This PR move codes from main.ts into two new plugins:

- splashscreen (formerly known as py-loader)
- importmap

The old setting config.autoclose_loader is still supported but deprecated; the new setting is config.splashscreen.autoclose.

Moreover, it does a small refactoring around UserError: now UserErrors are correctly caught even if they are raised from within afterRuntimeLoad.
2022-11-16 18:08:17 +01:00
Ted Patrick
b79ceea7a8 version number in build (#953) 2022-11-15 15:50:25 -06:00
Fábio Rosado
b990bcb67a Add basic docs for py-terminal (#933)
* Add basic docs for py-terminal

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add Antonio's suggestions

* Remove terminal = true

* fix typo

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-11-15 15:35:50 +00:00
pre-commit-ci[bot]
3f0f2d9910 [pre-commit.ci] pre-commit autoupdate (#951)
updates:
- [github.com/asottile/pyupgrade: v3.2.0 → v3.2.2](https://github.com/asottile/pyupgrade/compare/v3.2.0...v3.2.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-15 18:25:18 +05:30
Fábio Rosado
4333f5f979 Zip the build folder and add it to release (#949) 2022-11-14 20:32:11 +00:00
Madhur Tandon
07e75293b8 use a const for run button svg (#948)
* use a const for run button svg

* remove id

* remove consts.ts file
2022-11-15 01:47:36 +05:30
Fábio Rosado
a9ca7106cb Fix deprecated message (#950) 2022-11-15 01:36:21 +05:30
Fábio Rosado
da2728e6df Add flag to send HTML or plain Text to banner (#947) 2022-11-14 18:36:54 +00:00
Fábio Rosado
adfa9a9b05 Deprecate py-button, py-inputbox, py-box and py-title (#931) 2022-11-14 16:29:28 +00:00
Madhur Tandon
be9b9f66d3 remove one more unneeded import (#946) 2022-11-14 19:09:03 +05:30
Madhur Tandon
9521bc7175 remove unneeded import (#945) 2022-11-14 17:07:33 +05:30
Fábio Rosado
b445f8a834 Handle non-200 code when fetch py-script src (#940) 2022-11-12 10:07:51 +00:00
Fábio Rosado
3c3dffd5ed Raise error if we get a non 200 status from fetch (#935)
* Raise error if we get a non 200 status from fetch

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add custom exception

* Add check for TypeError as well

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-10 15:00:41 +00:00
Antonio Cuni
4c8443fd00 Make HTTP cache persisten across sessions (#936)
* use pytest-cache to cache HTTP requests, so that it survives across multiple runs

* add an option to clear the HTTP cache

* add some docs about pytest
2022-11-10 15:01:27 +01:00
Fábio Rosado
06a5a54103 Fix banner width (#930) 2022-11-09 16:42:10 +00:00
Antonio Cuni
0d3c3eef4e Introduce a Plugin system, implement <py-terminal> as a plugin (#917)
This PR does two things:

1. introduce the first minimal version of a Plugin system. Plugins are subclasses of the Plugin class, and pyscript will call the relevant methods/hooks at the right time. Currently, I have added only the minimal sets of hooks which were needed for this PR.

2. Implement <py-terminal> as a plugin.
2022-11-09 16:17:21 +01:00
Madhur Tandon
f0a6fb913f add test for not escaping characters in pyconfig (#929) 2022-11-09 12:18:02 +05:30
Madhur Tandon
5f0c508fed use user error for paths calculation (#927) 2022-11-09 03:13:18 +05:30
pre-commit-ci[bot]
16d9657982 [pre-commit.ci] pre-commit autoupdate (#922)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.26.0 → v8.27.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.26.0...v8.27.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-09 03:01:19 +05:30
Madhur Tandon
40d098310e decode innerhtml for pyconfig (#926) 2022-11-09 03:00:37 +05:30
Fábio Rosado
1345449d57 Create error or warning level banners and allow users to close it (#909) 2022-11-08 17:19:01 +00:00
Madhur Tandon
515858f313 implement proposal for fetching paths and retaining structure of dirs and packages (#914)
* implement proposal

* update docs and replace py-env

* more docs

* suggested proposal

* update docs

* add to_file parameter

* remove comment from Makefile

* suggested improvements

* move tests from basic to py_config

* retain leading slash from the first path
2022-11-08 17:26:45 +05:30
Fábio Rosado
2f452e9dc7 Add development section to our docs (#920) 2022-11-07 15:36:05 +00:00
Antonio Cuni
66119157a7 display() should escape by default (#915)
- display(some_str) escapes the string by default. This is almost always what you want

- display(some_obj) calls repr(obj) and escapes the result. Again, it's a very sensible default

- if you want to inject some raw HTML in the output, you can use the new HTML class: display(HTML("<p>hello</p>")).
2022-11-03 09:20:10 +01:00
pre-commit-ci[bot]
5b671dd1d0 [pre-commit.ci] pre-commit autoupdate (#913)
updates:
- [github.com/asottile/pyupgrade: v3.1.0 → v3.2.0](https://github.com/asottile/pyupgrade/compare/v3.1.0...v3.2.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-11-01 14:05:10 +05:30
woxtu
1017362eec Use globalThis (#908) 2022-10-31 15:25:36 +01:00
Antonio Cuni
f67b8e0285 Fix py-repl auto-generate=true (#910)
What is not tested is broken man_facepalming
Test&fix <py-repl auto-generate=true> which was broken by PR #884
2022-10-31 12:55:20 +01:00
woxtu
4c635fe84c Add syntax highlighting (#903) 2022-10-31 14:55:11 +05:30
Mariana Meireles
68e463493e Address to Jeff's review on output docs + Ted's remodeling of docs (#866) 2022-10-29 16:24:18 +01:00
Ted Patrick
f1979d60b7 Add Fabio Rosado (#899) 2022-10-28 10:41:34 -05:00
Ted Patrick
9150ebafec Fix py-repl docs (#896) 2022-10-28 07:21:48 -05:00
woxtu
9543019336 Format the TypeScript files (#877) 2022-10-28 14:18:27 +05:30
Fábio Rosado
1c53d91c6b Add more type definitions (#882)
* More typing to base.ts

* Add more types

* More types
2022-10-27 17:48:28 -05:00
Jeff Glass
4850f39b5a Upgrade to Pyodide 0.21.3 (#887)
* Upgrade to Pyodide 21.3

* During the PyodideRuntime test, set the indexURL parameter of loadPyodide to allow Jest to find pyodide-adjacent files.
2022-10-27 15:16:17 -05:00
Madhur Tandon
ab085c2d92 Retain path structure for loading paths (#845)
* update retain dir structure logic to use emscripten FS APIs

* remove unused import

* replace error message
2022-10-27 20:08:58 +05:30
Madhur Tandon
bf4d835948 remove duplicate pytest_configure (#894) 2022-10-27 16:57:12 +05:30
Antonio Cuni
214e39537b Simplify pyrepl.ts and kill base.ts (#884)
Major highlights:

1. Merge&simplify base.ts and pyrepl.ts; kill base.ts
2. improve and extente the py-repl integration tests
3. Reorder the code in pyrepl.ts. This part of the PR doesn't change much of the concrete logic: it's just a sequence of renaming variables, moving code around, group code into functions, killing code which is no longer needed. But the end result is much better and nicer to read, IMHO.

Minor highlights:

1. py-repl now uses the new logic in pyexec.ts to run the code

2. after PR Add display impl, rm outputManage, print and console.log default to browser console #749 py-repl no longer displayed the result of the last evaluated expression (e.g. if you typed 42 and run it, it displayed nothing). This PR re-introduces this behavior, which is what you would expect by a REPL.

3. improve the pytest --dev option: now it implies --no-fake-server so that sourcemaps works automatically

4. improve the names of the CSS classes to be more consistent

5. kill pyrepl.test.ts: the old tests didn't check anything useful,  this style of unit test doesn't really add much value if you have good integration tests (which now we have) and trying to revive them was not worth the hassle
2022-10-27 10:10:57 +02:00
Antonio Cuni
2d33afc195 try to display a reasonable message if you run a bare 'pytest' command (#890) 2022-10-26 18:05:12 +02:00
Ted Patrick
87ea24ebd4 header for pyrepl table (#889) 2022-10-25 19:34:27 -05:00
Ted Patrick
5380f8b9b3 Reference Docs (#888)
* Reference Docs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* py-repl

* pyrepl

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-25 17:42:30 -05:00
Fábio Rosado
00121ff8ba Remove svelte (#886) 2022-10-25 14:49:53 -05:00
pre-commit-ci[bot]
80e5d20e37 [pre-commit.ci] pre-commit autoupdate (#885)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.25.0 → v8.26.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.25.0...v8.26.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-24 17:48:54 -05:00
Antonio Cuni
58f7c2137d Introduce/improve check_js_errors and improve test_no_implicit_target (#874)
Until now, we didn't have a nice way to check that we expect a specific JS error in the web page.
This PR improves check_js_errors() so that now you can pass a list of error messages that you expect.
It is tricky because we need to handle (and test!) all various combinations of cases:

- errors expected and found / expected but not found
- unexpected errors found / not found

Moreover, JS exceptions now are logged in the special category console.js_error, which means that the printed text is also available using e.g. self.console.js_error.text or self.console.all.text. However, this should never be required and it's preferred to use self.check_js_errors to check for exceptions. This fixes #795 .

Finally, use the new logic to improve test_no_implicit_target.
2022-10-24 16:24:52 +02:00
Antonio Cuni
f9194cc833 Refactor how py-script are executed, kill scriptQueue store, introduce pyExec (#881)
Yet another refactoring to untangle the old mess.
Highlights:

base.ts, pyscript.ts and pyrepl.ts were a tangled mess of code, in which each of them interacted with the others in non-obvious ways. Now PyScript is no longer a subclass of BaseEvalElement and it is much simpler. I removed code for handling the attributes std-out and std-err because they are no longer needed with the new display() logic.

The logic for executing python code is now in pyexec.ts: so we are decoupling the process of "finding" the python code (handled by the py-script web component) and the logic to actually execute it. This has many advantages, including the fact that it will be more easily usable by other components (e.g. pyrepl). Also, note that it's called pyexec and not pyeval: in the vast majority of cases in Python you have statements to execute, and almost never expressions to evaluate.

I killed the last remaining global store, scriptQueue tada. As a bonus effect, now we automatically do the correct thing when a <py-script> tag is dynamically added to the DOM (I added a test for it). I did not remove svelte from packages.json, because I don't fully understand the implications: there are various options which mention svelte in rollup.js and tsconfig.json, so it's probably better to kill it in its own PR.

pyexec.ts is also responsible of handling the default target for display() and correct handling/visualization of exceptions. I fixed/improved/added display/output tests in the process.
I also found a problem though, see issue #878, so I improved the test and marked it as xfail.

I removed BaseEvalElement as the superclass of most components. Now the only class which inherits from it is PyRepl. In a follow-up PR, I plan to merge them into a single class and do more cleanup.

During the refactoring, I killed guidGenerator: now instead of generating random py-* IDs which are very hard to read for humans, we generated py-internal-X IDs, where X is 0, 1, 2, 3, etc. This makes writing tests and debugging much easier.

I improved a lot our test machinery: it turns out that PR #829 broke the ability to use/view sourcemaps inside the playwright browser (at least on my machine).
For some reason chromium is unable to find sourcemaps if you use playwrights internal routing. So I reintroduced the http_server fixture which was removed by that PR, and added a pytest option --no-fake-server to use it instead, useful for debugging. By default we are still using the fakeserver though (which is faster and parallelizable).

Similarly, I added --dev which implies --headed and also automatically open chrome dev tools.
2022-10-23 23:31:50 +02:00
Jeff Glass
d9b8b48972 Export Runtime from PyScript Module (#868)
* export 'pyscript' JS module with runtime attribute, to allow accessing (Pyodide) runtime and globals from JS.
* add docs to explain the js module
* add integration tests for the js module

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-23 13:46:19 -05:00
woxtu
aa85f5f596 Migrate the Jest config (#873)
* Migrate the Jest config

* Run Prettier
2022-10-21 19:35:14 +05:30
woxtu
5341a0be4a Add type annotations (#869)
* Add a type declaration

* Add a missing type annotation
2022-10-21 09:03:54 -05:00
Madhur Tandon
0cfe20ca65 use emscripten virtual FS directly to load paths (#870)
* use emscripten virtual FS directly to load paths

* use more low level APIs

* use await instead of then

* remove try...catch from loadFromFile since it's being handled externally

* add test for an invalid path

* test checks for error shown to the user too

* add comment about a missing case
2022-10-21 18:43:03 +05:30
Ted Patrick
c352b502c4 ts strict - getAttribute (#863)
* ts strict getAttribute

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* mark xfail

* fix to string

* Remove

* use getAttribute for theme

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-21 07:47:44 -05:00
Antonio Cuni
58b4df6b3d skip test_repl as it's flaky (#875) 2022-10-21 14:31:54 +02:00
Jeff Glass
29ba9436c8 Fix 'no unncessary type assertion' (#871) 2022-10-20 16:18:27 +02:00
pre-commit-ci[bot]
2a044e88ad [pre-commit.ci] pre-commit autoupdate (#862)
updates:
- [github.com/codespell-project/codespell: v2.2.1 → v2.2.2](https://github.com/codespell-project/codespell/compare/v2.2.1...v2.2.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-17 19:09:20 -05:00
Ted Patrick
63092f9d72 Add note on [[runtimes]] TOML table in docs (#861)
* Note on pyconfig. Fixes #859

* spell

* grammar

* mor grammar

* goes to go
2022-10-17 17:45:24 -05:00
woxtu
0209324d57 Pin dependencies for pre-commit (#860)
* Remove an unused dependency

* Pin dependencies
2022-10-17 15:12:53 -05:00
Mariana Meireles
1587273868 Add display impl, rm outputManage, print and console.log default to browser console (#749)
* Add display impl, remove outputManage, print and console.log defaults to terminal

* Fixing tests

* Lint

* Erase unecessary code, add cuter CSS formating for errors, fix problems around REPL output

* Add fix to repl2 and lint

* lint

* Allow for list of display, fix elif to else

* Add better global option

* test work

* xfails

* (antocuni, mariana): let's try to start again with TDD methodology: write the minimum test and code for a simple display()

* (antocuni, mariana): this test works out of the box

* WIP: this test is broken, mariana is going to fix it

* add a failing test

* Add ability to deal with targets

* Add append arg and append tests

* Add multiple values to display

* Small adjustments to tests. I noticed I wasn;t running all at some point

* add display test

* Add console tests

* Add async tests

* Fix repl tests

* Fixing merging issues

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Address antocuni's review

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fixing more tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* linting

* Improve repl tests

* Change my test so codespell is hapy with it

* Test: change test_runtime_config to use json instead of toml to see if stops failing on CI

* kill this file: it is a merge artifact since it was renamed into test_py_config.py on the main branch

* Change test execution order and add async tests to async test file

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-17 16:28:40 +02:00
Antonio Cuni
beb3aa1574 kill stores.runtimeLoaded and many other stores (#850)
As the title stays, the main goal of the branch is to kill the infamous runtimeLoaded global store and all the complications, problems and bugs caused by the fact that in many places we needed to ensure/wait that the global runtime was properly set before being able to execute code.

The core idea is that runtime is never a global object and that it's passed around explicitly, which means that when a function receives it, it is guaranteed to be initialized&ready.

This caused a bit of complications in pybutton.ts, pyinputbox.ts and pyrepl.ts, because they indirectly want to call runtime.run from connectedCallback, which is the only place where we cannot explicitly pass the runtime because it's automatically called by the browser.
But also, it is also a sign of a bad design, because it were entirely possible that connectedCallback was called before the runtime was ready, which probably caused many bugs, see e.g. #673 and #747.

The solution to is use dependency injection and create the class later on: so instead of having a global PyButton class which relies on a global runtime (whose state is uncertain) we have a make_PyButton function which takes a runtime and make a PyButton class which is tied to that specific runtime (whose state is certainly ready, because we call make_PyButton only when we know that the runtime is ready).
Similar for PyInputBox and PyRepl.

Other highlights: thanks to this, I could kill the also infamous runAfterRuntimeInitialized and a couple of smelly lines which used setTimeout to "wait" for the runtime.

While I was at it, I also called a lot of other stores which were completely unused and where probably leftovers from a past universe.
2022-10-17 10:31:57 +02:00
woxtu
fe708c9fb4 Remove an unused import (#858) 2022-10-17 00:38:52 +05:30
John Franey
e45d8bf973 Fix typo in passing-objects.md (#856)
Fixes typo in HTML example: `do-mmath` -> `do-math`
2022-10-15 14:56:29 -04:00
Jeff Glass
b184c92f01 Use only single rollup-plugin-copy() to avoid race condition (#843)
* Use only single copy() plugin to avoid race condition

* clean production def, better copy_target structure

* Restore '!process.env.ROLLUP_WATCH to production definition

Co-authored-by: Ted Patrick <tpatrick@anaconda.com>
2022-10-12 12:05:14 -05:00
Ted Patrick
6c8afb05a7 Don't hide undefined elements in the CSS (#837)
* Hide py-config element

* display:none for all web components

* docs

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add style tests for raw html and pyscript enabled html

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test naming

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-11 12:27:22 -05:00
pre-commit-ci[bot]
d3dd4573cf [pre-commit.ci] pre-commit autoupdate (#844)
updates:
- [github.com/psf/black: 22.8.0 → 22.10.0](https://github.com/psf/black/compare/22.8.0...22.10.0)
- [github.com/asottile/pyupgrade: v2.38.2 → v3.1.0](https://github.com/asottile/pyupgrade/compare/v2.38.2...v3.1.0)
- [github.com/pre-commit/mirrors-eslint: v8.23.1 → v8.25.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.23.1...v8.25.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-11 08:21:23 -05:00
Ted Patrick
d5cf68391a Upgrade and pin dependencies (#840)
* Upgrade and Pin Dependencies

* Removal all unused deps

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* lock

* remove svelte-fa reference from the svg style.

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-11 07:20:31 -05:00
Ted Patrick
4e54e93450 Correct the url in the example (#841) 2022-10-09 10:24:00 +05:30
Ted Patrick
e4f6387f18 Remove fa reference in py-repl 2022-10-08 20:13:25 -05:00
Ted Patrick
54cb35b60a Add directly listing for releases (fix error) (#839)
* move copy index.html out of !production to run every time

* format

* dir syntax

* file order in dir listing

* Example title
2022-10-09 05:04:28 +05:30
Ted Patrick
18ede2b729 Add directly listing for releases (#838)
* Add directly listing for releases

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-08 16:05:03 -05:00
Ted Patrick
f138b5a4f4 Add cache, fetch, retry logic to tests (#829)
* Add cache, fetch, retry logic to tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* run in parallel

* add pytest-xdist

* undo parallelism. Need to remove http server to enable.

* woops a extra space

* Pass flake8

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* spell fulfill

* use decorator for fetch if not in cache

* Fix --headed and limit to PlaywrightRequestError

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* docs on cache

* CICD caching of conda on unstable builds

* fix config issues

* empty commit to trigger gh-actions

* restore build-unstable

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Remove http server, add parallel

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* temp: Bypass zip runtime test and point to v0.21.3 on CDN

* suport for files in zip under /pyodide

* remove test-one

* self.http_server and remove content_type

* domcontentloaded w no timeout on base url + longer timeout on wait_for_pyscript

* Fixed #678

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* set default timeout to 60000

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* seamless --headed support

* add test-integration-parallel and default for GHActions

* simplify the code. Use http://fakeserver instead of localhost:8080 so that it's clearer that the browser is NOT hitting a real server, and use urllib to parse the url. Moreover, the special case for pyodide is no longer needed, it's automatically handled by the normal 'fakeserver' logic

* The page-routing logic is becoming too much complicated to stay as an inner function. Move it to its own class, and add some logic to workaround a limitation of playwright which just hangs if a Python exception is raised inside it

* no need to use a hash, we can use the url as the key

* re-implement the retry logic. The old @retry decorator was nice but a bit too over-engineered and most importantly failed silently in case of exceptions. This new approach is less powerful but since we want to retry only two times, simple is better than complex -- and in case of exception, the exception is actually raised

* improve logging

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Madhur Tandon <madhurtandon23@gmail.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-10-07 10:31:26 -05:00
Antonio Cuni
11a517bba4 Make the life-cycle more linear and kill some svelte stores (#830)
This is a follow-up of PR #806 and it's a big step forward towards solving issue #763.

The basic idea is that at this stage I want to streamline the execution logic
and make it as linear and easy to read/understand as possible. The diff is
relatively big, but for the most part is just "shuffling code around".


Svelte stores:
the idea is to eventually kill of them, so that we can remove the dependency
on svelte but also to avoid relying on so much global state, which makes
things more complicated and error-prone (e.g., we have several issues related
to using runtime when it's not ready yet).

I killed addInitializer, addPostInitializer and the corresponding svelte
stores tada. They are no longer needed since the relevant code is called
directly from main.ts.

I started to kill the usage of the runtimeLoaded svelte store: instead of
relying on a global variable, I want to arrive at the point in which the
runtime is passed as a parameter in all places where it's needed: pyscript.ts
is now free of global state, but I couldn't kill it yet because it's used
heavily by base.ts and pyrepl.ts. I will do it in another PR.

Other misc changes:
I added sanity checks (and corresponding tests!) which complain if you specify
0 or multiple runtimes. Currently we support having one and only one, so there
is no point to pretend otherwise

I modified the messages displayed by the loader, to be more informative from
the user point of view.
2022-10-07 17:13:12 +02:00
Jeff Glass
66b57bf812 Remove fortawesome/free-solid-svg-icons (#831) 2022-10-06 22:54:10 +05:30
Ted Patrick
a9357bd97e SVG Docs logo (#832)
* SVG Docs logo. Fixes https://github.com/pyscript/pyscript/issues/818

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-06 20:48:08 +05:30
Madhur Tandon
d7c6d42c3d remove warning (#828) 2022-10-05 01:24:51 +05:30
Madhur Tandon
4dd1dc28b1 move py-config between body tags (#827) 2022-10-05 01:13:34 +05:30
Antonio Cuni
1e05ff7c95 detect the case in which multiple <py-config> are listed
Ideally I would like it to be a fatal error, but it's too hard to do it with the current state of the code, will refactor it later (#826)
2022-10-04 19:59:59 +02:00
Mariana Meireles
e8e2e65584 Update CONTRIBUTING.md (#822)
To add that we need to have a test for every feature :)
closes https://github.com/pyscript/pyscript/issues/615
2022-10-04 17:16:48 +02:00
Ted Patrick
3727e60152 Maintainers Update (#823) 2022-10-04 09:23:47 -05:00
Ted Patrick
0254012db6 Add epic to exempt labels (#821) 2022-10-04 08:55:55 -05:00
Jeff Glass
8b97e4757f Update to Codemirror 6 (py-repl) (#814)
* Upgrade to codemirror v6

* Increase indentation to 4 spaces by default
2022-10-04 08:49:42 -05:00
Madhur Tandon
c70e121078 eliminate py-env altogether (#775)
* examples use toml now

* use 0.21.2 for now

* change config in docs

* fix pre-commit
2022-10-04 19:00:39 +05:30
Ted Patrick
a4f97e6e46 Add Github Stale to PyScript repo (#791)
* Add stale to pyscript repo

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add tags: backlog, needs-triage, needs-work

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-10-04 08:08:26 -05:00
Antonio Cuni
800145a83c Add a link to docs in the README (#817) 2022-10-04 18:14:12 +05:30
Antonio Cuni
c75f885cb4 Refactor py-config and the general initialization logic of the page (#806)
This PR is the first step to improve and rationalize the life-cycle of a pyscript app along the lines of what I described in #763 .
It is not a complete solution, more PRs will follow.
Highlights:

- py-config is no longer a web component: the old code relied on PyConfig.connectedCallback to do some logic, but then if no <py-config> tag was present, we had to introduce a dummy one with the sole goal of activating the callback. Now the logic is much more linear.

- the new pyconfig.ts only contains the code which is needed to parse the config; I also moved some relevant code from utils.ts because it didn't really belong to it

- the old PyConfig class did much more than dealing with the config: in particular, it contained the code to initialize the env and the runtime. Now this logic has been moved directly into main.ts, inside the new PyScriptApp class. I plan to refactor the initialization code in further PRs

- the current code relies too much on global state and global variables, they are everywhere. This PR is a first step to solve the problem by introducing a PyScriptApp class, which will hold all the mutable state of the page. Currently only config is stored there, but eventually I will migrate more state to it, until we will have only one global singleton, globalApp

- thanks to what I described above, I could kill the appConfig svelte store: one less store to kill :).
2022-10-04 14:26:12 +02:00
Ted Patrick
4011a51013 add tsc as a build step with noEmit (#816) 2022-10-04 04:51:56 -05:00
Ted Patrick
f4165dabcf TOML Error Cases (#815)
* TOML Error Cases

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove traceback

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* any is a ts feature

* full eslint

* format and disable eslint for toml.js

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Madhur Tandon <madhurtandon23@gmail.com>
2022-10-04 13:13:24 +05:30
djchou
de6c26eb05 Add discord channel (#811)
from Ted Patrick --
tedpatrick — 09/19/2022
Hello and Good Morning (CST in Austin TX)
Key: We want the dialog about Pyscript OSS to be transparent and centered in the community. Rather than add another communication platform, using this Discord meets the community where they are.
2022-10-01 20:44:58 +05:30
Ted Patrick
5f319452d5 simplify OutputCtxManager logging (#809)
* simplify OutputCtxManager logging

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-30 09:41:53 -05:00
Madhur Tandon
60d505d2d1 update docs for the minimal config (#807) 2022-09-30 19:35:16 +05:30
Ted Patrick
f64cc4dcae Minimum viable py-config default schema (#803)
* Minimium viable py-config default schema

* Add packages and paths to default

* Add in default for plugins

* Remove tests for values no longer in the default config
2022-09-29 18:54:56 -05:00
Madhur Tandon
60e6f4293a new docs for py-config without removing py-env (#802)
* new docs for py-config without removing py-env

* fix table

* fix table

* fix message for local modules

* fix src
2022-09-29 20:50:33 +05:30
Jeff Glass
00ab9a8d02 Update MAINTAINERS.md (#797) 2022-09-28 18:34:41 -05:00
Ted Patrick
7d5f6c9ead Loading and void script.evaluate() (#796)
* Loading and Script evaluate with Promise.all

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Move to 'void script.evaluate();'

* chmod files to 644

* Add a test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-28 17:38:21 -05:00
pre-commit-ci[bot]
a295edf19d [pre-commit.ci] pre-commit autoupdate (#794)
updates:
- [github.com/asottile/pyupgrade: v2.38.0 → v2.38.2](https://github.com/asottile/pyupgrade/compare/v2.38.0...v2.38.2)
- [github.com/pre-commit/mirrors-eslint: v8.23.1 → v8.24.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.23.1...v8.24.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-28 18:52:34 +02:00
Fábio Rosado
b674515d06 Add more unit and integration tests (#773)
* Add unit tests for pyloader and pytitle

* Add more unit tests for pyrepl, pybox and pyinputbox

* Add more tests for pyscript and pyconfig

* White space

* Fix d3 tests and improve more examples test

* Update matplotlib test

* Add numpy to dependencies

* Address Madhur comments

* Update test name
2022-09-27 03:47:32 +05:30
Ted Patrick
d033ab04da Credit Pyodide within readme.md (#792)
* Credit pyodide within readme

* Use pyscript.net definition
2022-09-26 07:03:01 -05:00
Ted Patrick
304d76d088 Enable snapshot publishing by removing --dryrun (#790) 2022-09-26 05:41:13 -05:00
Ted Patrick
978afdad97 Snapshot releases (#789)
* A workflow that enables snapshot releases by manual github action

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* typo in comment

* match naming and add name to workflow

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-25 12:24:41 -05:00
Ted Patrick
d4e41e679d examples: py-env to py-config (#784)
* examples: py-env to py-config

* 1 example as JSON with type

* Fix todo event attribute
2022-09-23 11:04:31 -05:00
Madhur Tandon
146264ff12 add toml support for configs with fast-toml (#783)
* add toml support for configs with fast-toml

* fix package-lock.json and pin pyodide to 0.21.2

* use browser version of fast-toml

* disable eslint and add credits

* fix jest issues

* use type attribute for py-config
2022-09-23 20:11:22 +05:30
Emir
dcb107ae65 add pure-python (async) HTTP request how to (#778)
* add HTTP request how to

First draft.
Proof read http-requests.md


Formatting


Reword intro


modify fetch API docs links


Conclusion

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add http-request howto into toctree, index

* implement review

By @madhur-tandon
Implement review

and fix formatting mistake in request function docstring.

* add # HTTP requests section, add fetch_kwargs to helper function

Add a section in the explanation discussing HTTP Requests

* add API reference

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* specify docs for `pyodide.http` members

* address review

By @marimeireles

* Change code [Python] to Python

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-09-23 14:14:00 +02:00
Ted Patrick
c236269d13 Update MAINTAINERS.md (#782) 2022-09-22 02:23:39 +05:30
Subramanian Mahadevan
8f658e6d85 fixed Makefile to always clean and recopy the examples build folder (located under examples) (#772) 2022-09-21 16:25:13 +02:00
Fábio Rosado
d203b60f44 Update contributing docs and remove lint from makefile (#779) 2022-09-21 16:22:12 +02:00
pre-commit-ci[bot]
a1a16aba74 [pre-commit.ci] pre-commit autoupdate (#780)
updates:
- [github.com/asottile/pyupgrade: v2.37.3 → v2.38.0](https://github.com/asottile/pyupgrade/compare/v2.37.3...v2.38.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-21 13:56:20 +02:00
Valerio Maggio
6ded003447 Fixed typo in logger message (#774) 2022-09-19 09:31:59 +02:00
Madhur Tandon
4841e29fc6 refactor py-config to use json (#754)
* refactor py-config to use toml

* switch from toml to json and add unit tests

* fix test for py-config

* fix integration test

* use flat structure for JSON

* allow merging configs

* replace arrays instead of concatenating them

* remove extra keys from inline config of integration test

* simplify array replacement logic

* allow config from src to be partial as well

* add comments to unit tests

* add unit test for setting config from both inline and src

* handle parse errors + validate config supplied

* separate functions for src and inline

* suggested improvements

* show error message in red on parser error

* fix eslint

* use resolveJsonModule as true

* use default config defined as a variable without import

* remove disable eslint comment

* remove import for covfefe.json as well

* metadata injection

* add support for schema + extra keys

* use schema_version
2022-09-16 02:07:00 +05:30
Jeff Glass
0b014eea56 Execute pys-on* events when triggered, not at load (#686)
* Execute pys-on* events when triggered, not at load

Mimicing the behavior of Javascripts 'onLoad' event, we should
not be executing the use code at page-load time, only when
the event is triggered.

* Update examples to new syntax

* Fix merge issue

* Await running event handler code

* Restore pys-on* events with original behavior, deprecation warning

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* xfail toga example

* Add missing { (typo)

* Adjust callback chandling to make linter happy

* Change alpha to latest (#760)

* Don't create custom elements in main and fix various small issues on tests (#747)

* Create custom elements when the runtime finishes loading

* Remove xfails and fix repl integration test

* Fix commented ignore

* Address Antonio's comments

* Fix bad rebase

* Make ure to wait for repl to be in attached state before asserting content

* Move createCustomeElement up so it runs before we close the loader, xfail flaky d3 test

* Fix xfail

* [pre-commit.ci] pre-commit autoupdate (#762)

updates:
- [github.com/pre-commit/mirrors-eslint: v8.23.0 → v8.23.1](https://github.com/pre-commit/mirrors-eslint/compare/v8.23.0...v8.23.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* change documentation to point to latest instead of frozen alpha (#764)

* Toga example is xpass

* Correct 'xpass' to 'xfail' mark

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Peter W <34256109+pww217@users.noreply.github.com>
Co-authored-by: Fábio Rosado <fabiorosado@outlook.com>
2022-09-14 20:33:42 -05:00
Peter W
1c0be16f30 change documentation to point to latest instead of frozen alpha (#764) 2022-09-13 12:02:05 -04:00
pre-commit-ci[bot]
27ba8bea2f [pre-commit.ci] pre-commit autoupdate (#762)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.23.0 → v8.23.1](https://github.com/pre-commit/mirrors-eslint/compare/v8.23.0...v8.23.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-13 10:34:24 -05:00
Fábio Rosado
c566977749 Don't create custom elements in main and fix various small issues on tests (#747)
* Create custom elements when the runtime finishes loading

* Remove xfails and fix repl integration test

* Fix commented ignore

* Address Antonio's comments

* Fix bad rebase

* Make ure to wait for repl to be in attached state before asserting content

* Move createCustomeElement up so it runs before we close the loader, xfail flaky d3 test

* Fix xfail
2022-09-13 16:59:33 +02:00
Peter W
5c1b785b4b Change alpha to latest (#760) 2022-09-12 12:07:44 -04:00
Jeff Glass
8657dfb5da Docs: How To Pass Objects between JavaScript and PyScript (#753)
* Begin writeup

* Draft full howto

* Correct code errors in writeup, swap sections

* Add introduction, clarification

* Add link to howto:js in index

* Copyedit, update examples to Pyodide 21

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add toc tree context

* Use print instead of js console in python examples

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-09-12 04:29:25 -04:00
Neil Stoker
dfa837754e Remove line numbers from example (#745)
As per #565 the current best fix is to simply remove the line numbers from the output
2022-09-12 04:28:19 -04:00
Ted Patrick
0a7df78770 Add space before/after secrets value (#757)
Co-authored-by: Ted Patrick <tpatrick@anaconda.com>
2022-09-08 07:54:33 -05:00
Mariana Meireles
066ecbe022 Add docs on how to contribute to docs (#720)
* Add docs on how to contribute to docs

* Reword some phrases
2022-09-08 07:38:31 -04:00
Ted Patrick
6c80db810f pyon-dragover to py-dragover (#755)
typo in events
2022-09-07 16:31:59 -05:00
Mariana Meireles
6023c413ab Update CONTRIBUTING.md (#728)
* Update CONTRIBUTING.md

Adding docs on how to make a pr

* Rewording so ideas are clearer
2022-09-07 03:05:20 +05:30
Peter W
7910d040b6 fix ci file sync (#752) 2022-09-06 19:30:01 +02:00
pre-commit-ci[bot]
5bd99f5224 [pre-commit.ci] pre-commit autoupdate (#750)
updates:
- [github.com/psf/black: 22.6.0 → 22.8.0](https://github.com/psf/black/compare/22.6.0...22.8.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-09-06 10:12:52 -05:00
Antonio Cuni
f3157b377f Improve JS logging (#743)
This PR tries to improve and rationalize what we log. Key points:
- introduce `logger.ts`: each file/component is encouraged to use the logger instead of writing directly to `console.*`
    * the logger automatically prepend a prefix like `[py-config]`, `[py-env]` which make it easier to understand where a certain message is printed from
    * it provide a central place where to add more features in the future. E.g., I can imagine having a config setting to completely silence the logs (not implemented yet)
- use the new loggers everywhere
- write to `.info()` instead of `.log()`. The idea is to keep `console.log` free, so that for the users it's easier to tell apart their own messages and the pyscript ones
- generally improve what we log. This is an endless exercise, but I tried to print more things which are useful to understand what's going on and in which order the various things are executed, and remove prints which were clearly debugging leftovers
2022-09-06 15:18:41 +02:00
Madhur Tandon
e31e03afde add tests for runtime config inside py-config and remove usage of indexURL (#734)
* add integration test for py-config

* fix bug

* fix test

* remove indexURL altogether

* make jest happy

* fix create_proxy import

* check that py-config loads an older version

* add unit test

* suggested changes

* don't use /tmp because of bandit
2022-09-01 01:02:43 +05:30
Peter W
eddde7c94c [WIP] Actions workflow cleanup/readability (#695)
* discrete steps and artifact passing

* fix small mistakes, prep test

* upload path

* fix path again

* change again

* checkout for test

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* formatting

* artifact paths

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* diagnostics

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* simplify

* small cosemtic changes

* move upload to end

* needs:

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-31 10:01:41 -05:00
pre-commit-ci[bot]
7be72ee4c1 [pre-commit.ci] pre-commit autoupdate (#737)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.22.0 → v8.23.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.22.0...v8.23.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-30 19:49:15 +05:30
woxtu
6731467514 Update TypeScript to 4.8 (#739) 2022-08-30 19:47:14 +05:30
Madhur Tandon
8dd699d235 Remove workaround for sed and upgrade pyodide to 0.21.2 (#738)
* remove sed workaround + upgrade version

* upgrade package.json and package-lock.json
2022-08-30 18:19:00 +05:30
woxtu
6cb81b5c3d Remove the Svelte plugins for ESLint/Prettier (#733)
* Remove the Svelte plugins for Prettier

* Remove the Svelte plugins for ESLint
2022-08-29 01:13:16 +05:30
woxtu
17187ba3ec Remove the Svelte plugins for Rollup (#730) 2022-08-27 02:40:37 +05:30
Madhur Tandon
531ee928b0 fix linting and types related issues (#731) 2022-08-27 02:18:01 +05:30
Madhur Tandon
db806a5df9 make runtime an object of Runtime class when it is just an object (#729)
* make runtime an object of Runtime class when it is just an object

* fix constructor

* remove explicit string type

* define default values out of pyodide runtime and use default config instead of initializing a DEFAULT_RUNTIME instance

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-08-26 15:19:03 -05:00
Fábio Rosado
9de154595a Add more unit tests for PyButton and BaseEvalElement (#711)
* Add more unit tests

* Rebase main and fix failing tests

* xfail flaky test

* Fix import
2022-08-26 08:25:51 -04:00
Fábio Rosado
9e4cb79679 Fix: Examples not importing pyscript from build folder when running locally (#705)
* Copy build to examples if not running prod

* Add rollup-copy as a dev dep

Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-25 18:05:17 -04:00
Bikarna Pokharel
b7834073b8 Remove unwanted code and/or text (#589)
* Remove unwanted class attribute

Multiple attributes with the same name are illegal in html. Nonetheless, the class task-check is not doing anything here.

* Remove to=task_list

The argument to=task_list is not playing any role, since the function works well without it.

Please see comment in pyscript.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Clean comment

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-25 17:30:54 -04:00
woxtu
b0e56577b5 Fix misused promises (#723)
* Remove an unnecessary await

* Add an async IIFE wrapper
2022-08-26 02:17:29 +05:30
tkeech1
ccb0e6b269 585: Add a line to the makefile to run the examples on a python serve… (#689)
* 585: Add a line to the makefile to run the examples on a python server with one line command

* Build exs and run server with previous makefile cmds

Co-authored-by: Todd Keech <tkeech1@hotmail.com>

Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-25 16:43:25 -04:00
Madhur Tandon
edfd4baa1f import create_proxy and to_js from pyodide.ffi (#725) 2022-08-25 22:11:18 +02:00
woxtu
0f50f4a9fd Remove overwriting properties (#724) 2022-08-25 23:27:13 +05:30
Madhur Tandon
47494e62a7 Fix and enable integration tests in CI (#721)
* run jest only inside node + fix indexURL for integration tests

* add integration tests to CI

* use pytest from env
2022-08-25 22:01:05 +05:30
Fábio Rosado
7aa25712d9 Update tsconfig to use es2017 (#704) 2022-08-24 21:01:51 -05:00
Madhur Tandon
1db155570d PyodideRuntime should be one of the runtimes (#698)
* PyodideRuntime should be one of the runtimes

* subsume interpreter into runtime API

* fix eslint

* add comments

* move initializers, postInitializers, scriptsQueue, etc. to initialize() of Runtime Super Class

* modify comment for initialize

* small renaming

* change id to default

* fix pyscript.py import

* try adding tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Add inlineDynamicImports option

* Make jest happy about ESM modules

* Attempt to make jest happy about pyodide

* point to version in accordance with node module being used

* fix base.ts

* fix tests

* fix indexURL path determination

* edit pyodide.asm.js as a part of setup process

* load runtime beforeAll tests

* add test for loading a package

* use only runPythonAsync underneath for pyodide

* import PyodideInterface type directly from pyodide

* add some comments

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Philipp Rudiger <prudiger@anaconda.com>
2022-08-25 02:33:36 +05:30
Dylan
1054e8e644 Add clarification where to place script and stylesheet - README.md (#713)
* Update README.md

UPDATE: Specified to add files to head tag of HTML file

* UPDATE README.md

UPDATE README: Specify to add CSS and JS file to head tag of HTML

* Update README.md

Clean up wording.
2022-08-24 11:10:20 +05:30
Fábio Rosado
aa429f34d8 Add more integration tests for py-components and examples (#709)
* Add more integration tests for py-components and examples

for more information, see https://pre-commit.ci

* remove xfail mark since we merged fix for issue 707

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-08-23 18:22:44 -05:00
Fábio Rosado
e351889811 Set importmaps to an empty array (#708)
Use const instead
2022-08-23 18:03:52 -05:00
Fabio Pliger
24a70a8273 fix error management bug and improve examples automation (#717)
* add build to the make examples cmd so that it automates more to the user

* temporarily improve error managament when executing eval until we properly refactor the whole io and error workflow

* add minimal test for format_mime
2022-08-23 17:12:30 -05:00
Fabio Pliger
3f26657116 update pyodide version (#719) 2022-08-23 17:11:42 -05:00
pre-commit-ci[bot]
d41669af8b [pre-commit.ci] pre-commit autoupdate (#710)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/codespell-project/codespell: v2.1.0 → v2.2.1](https://github.com/codespell-project/codespell/compare/v2.1.0...v2.2.1)

* push

* push

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: pww217 <pwilson@anaconda.com>
2022-08-23 17:07:04 -05:00
Peter W
56466c2a00 fix typo 2022-08-23 17:06:19 -05:00
Fabio Pliger
fa7a97ca30 Bootstrap python tests (#697)
* move current integration tests to the integration folder

* move pyscript.py into its own python folder

* change the path for python unit testing files

* change pyscript.py path

* Update Makefile

* remove echo

* replace conda run with pytest directly

* oops, add python test files I embarrassingly forgot to add

Co-authored-by: Peter W <34256109+pww217@users.noreply.github.com>
2022-08-18 16:59:07 -05:00
Fabio Pliger
8aba271a42 Add TS tests tooling (#661)
* install test dependencies

* change config for tests

* fix linter failing tests

* add basic test file

* add custom element registration to test

* update dependencies

* add jest config file

* fix test calls on makefile and minor fix on test

* update local npm version

* clean testm file
2022-08-16 16:39:42 -05:00
Philipp Rudiger
8275aa2810 Ensure that angle brackets in pyscript tag are escaped before parsing (#684)
* Ensure that angle brackets in pyscript tag are escaped before parsing

* Improve tests

* Update pyscriptjs/tests/test_01_basic.py

Co-authored-by: James A. Bednar <jbednar@users.noreply.github.com>

Co-authored-by: James A. Bednar <jbednar@users.noreply.github.com>
2022-08-16 21:41:09 +05:30
imbev
410ddf314c Correct typo in CONTRIBUTING.md (#692) 2022-08-16 10:12:09 -05:00
pre-commit-ci[bot]
fa217bee20 [pre-commit.ci] pre-commit autoupdate (#691)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.21.0 → v8.22.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.21.0...v8.22.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-16 09:56:13 -05:00
Antonio Cuni
817d0edc69 Use the new testing machinery for test_examples (#676)
* WIP: start to use the PyScriptTests machinery to test the examples

* factor test_hello_world out of test_examples

* B011 forbids 'assert False' in tests because python -O remove asserts. Thank you, I knew that.

* improve test_simple_clock and remove it from test_examples

* test_altair

* test_bokeh

* rename

* kill the parametrized test_example and write individual tests for each of them

* test_kmeans it's slow, increase the timeout

* improve these xfail

* kill wait_for_load, no longer needed

* write the name of the issue

* add issue number

* add a trick which I discovered to run test interactively

* move the docstring inside the class
2022-08-11 19:18:42 -05:00
Antonio Cuni
513dfe0b42 Introduce PyScriptTest, an helper class to write integration tests (#663)
This PR is about integration tests: they use playwright to load HTML pages in the browser and check that PyScript works as intended, as opposed to unit tests like the ones being introduced by #665 and #661.

The main goal of this PR is to introduce some machinery to make such tests easier to write, read and maintain, with some attention to capture enough information to produce useful error messages in case they fail in the CI.

In order to use the machinery, you need to subclass tests.support.PyScriptTest, which provides several useful API calls in the form self.xxx().

See the full description here:
https://github.com/pyscript/pyscript/pull/663

Co-authored-by: Mariana Meireles <marian.meireles@gmail.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-10 12:29:59 +02:00
pre-commit-ci[bot]
bd7a20309b [pre-commit.ci] pre-commit autoupdate (#669)
updates:
- [github.com/PyCQA/flake8: 5.0.2 → 5.0.4](https://github.com/PyCQA/flake8/compare/5.0.2...5.0.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-09 09:13:52 -05:00
woxtu
a726be3c7c Remove unnecessary await (#662) 2022-08-08 23:16:02 +05:30
Mariana Meireles
10f2054e9a Create command to run tests locally (#668) 2022-08-08 10:07:37 +02:00
Fabio Pliger
2fa47f310d remove output manager code injection in repl source (#664) 2022-08-05 18:50:20 +02:00
Antonio Cuni
5b927a70c2 PyItemTemplate.strike() uses the CSS class line-through, which was part of Tailwind. Reintroduce it in our custom CSS. This fixes the todo-pylist example (#638) 2022-08-03 12:29:39 +02:00
Peter W
2a59ff8e68 point examples to /latest instead of /alpha (#624)
* point examples to /unstable instead of /alpha

* Change makefile from alpha to unstable

* unstable -> latest

* Update Makefile

* Update repl.html

Co-authored-by: mariana <marianameireles@protonmail.com>
2022-08-02 13:59:50 -04:00
woxtu
e4d1befcdb Specify the array type (#653) 2022-08-02 21:10:08 +05:30
ic-768
844e04ff96 Minor refactoring (#557)
* checkpoint: added some text

* checkpoint: added setting up the environment, tips for writing good issues

* continuing to fill it out

* added more detailed description of the process of creating a change and some other cleanup.

* added a getting started section and cleaned up the grammar. This ready for the PR now

* forgot to add the new section to the TOC

* Changes

* Minor fixes

* Minor fixes

* Minor fixes

* Minor fixes

* Minor fixes

* Minor fixes

* Fix

Co-authored-by: Kevin Goldsmith <kgoldsmith@anaconda.com>
Co-authored-by: Matt Kramer <mkramer@anaconda.com>
2022-08-02 20:58:21 +05:30
pre-commit-ci[bot]
cc05a98b0e [pre-commit.ci] pre-commit autoupdate (#650)
updates:
- [github.com/PyCQA/flake8: 4.0.1 → 5.0.2](https://github.com/PyCQA/flake8/compare/4.0.1...5.0.2)
- [github.com/asottile/pyupgrade: v2.37.2 → v2.37.3](https://github.com/asottile/pyupgrade/compare/v2.37.2...v2.37.3)
- [github.com/pre-commit/mirrors-eslint: v8.20.0 → v8.21.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.20.0...v8.21.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-02 10:27:46 -05:00
Madhur Tandon
006d161a32 cleanup leftovers such as mode and pyodideReadyPromise (#649)
* remove usage of mode

* clean up pyodideReadyPromise
2022-08-02 20:44:41 +05:30
Madhur Tandon
a4839db79a fix tests by changing serving dir (#652)
* fix tests by changing serving dir

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-08-02 20:35:09 +05:30
Madhur Tandon
87e3b5b1dc remove App.svelte as CSS is already present in pyscript_base.css (#648)
* remove App.svelte as CSS is already present in pyscript_base.css

* remove usage of app
2022-08-02 17:01:23 +02:00
Madhur Tandon
faa900d502 change args for Linux for sed (#651) 2022-08-02 12:27:56 +02:00
woxtu
a5275db3ec Specify the type of store value (#643) 2022-08-01 21:45:20 +05:30
Madhur Tandon
77e017a574 Add myself as maintainer as per discussion (#636) 2022-08-01 21:40:21 +05:30
Madhur Tandon
8ed8ddbf76 use pip (latest) to install playwright (#647) 2022-08-01 20:45:49 +05:30
Philipp Rudiger
eb31978488 Add tests verifying correct example behavior (#625) 2022-07-29 14:42:49 -04:00
woxtu
677d708588 Make the stores simple (#564) 2022-07-28 22:09:21 -04:00
Nicholas Tollervey
ade0dca8f9 Update to latest Pyodide (#631) 2022-07-28 20:52:54 -04:00
Fabio Pliger
8e1cd0b268 minor changes to make linting happier (#598)
* minor changes to make linting happy

* remove cast since linter wasn't happy

* address PR comments
2022-07-28 15:30:03 -05:00
woxtu
9102768366 Improve with string interpolations (#604)
* Use string interpolations

* Fix the key in py-env
2022-07-28 11:07:10 -04:00
pre-commit-ci[bot]
0c722b9164 [pre-commit.ci] pre-commit autoupdate (#630)
updates:
- [github.com/asottile/pyupgrade: v2.37.1 → v2.37.2](https://github.com/asottile/pyupgrade/compare/v2.37.1...v2.37.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-28 11:05:34 -04:00
takahiro ono
b6f514451a fix links in contribution & troubleshooting doc (#632) 2022-07-28 11:04:55 -04:00
Mariana Meireles
c49fdfc56c Re-introduce xPyWidget update on CustomWidget's class (#576)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-07-21 15:13:11 -05:00
Peter W
676e04b28e sync examples on stable releases (#623) 2022-07-21 16:00:02 -04:00
Antonio Cuni
6aa864a351 enable blank issues (#626) 2022-07-20 15:30:28 -04:00
pre-commit-ci[bot]
72acb4826c [pre-commit.ci] pre-commit autoupdate (#620)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.19.0 → v8.20.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.19.0...v8.20.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-19 17:02:10 -05:00
pre-commit-ci[bot]
734be5f355 [pre-commit.ci] pre-commit autoupdate (#594)
updates:
- [github.com/asottile/pyupgrade: v2.34.0 → v2.37.1](https://github.com/asottile/pyupgrade/compare/v2.34.0...v2.37.1)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-18 11:43:38 -04:00
Leonardo Pliger
cede06ae19 Clearer contribution docs & add troubleshooting page (#597)
* Expanded upon the make setup docs

* Fixed formatting & speling, added troubleshooting

* same

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-18 11:42:32 -04:00
Christian Clauss
19491d8010 f-string accelerates examples.utils.format_date() (#591) 2022-07-12 11:26:47 -05:00
pww217
c580aac991 add workflow dispatch to unstable 2022-07-07 14:47:23 -05:00
pww217
032d1aaad7 change path to /build 2022-07-07 14:45:33 -05:00
Mariana Meireles
afa216dc5e Mv build folder from examples/build to build/ (#571)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-07-07 11:29:09 -03:00
Nicholas Tollervey
69339fe3de Add myself to the list of maintainers as per recent discussion. (#573) 2022-07-06 10:36:23 +02:00
pre-commit-ci[bot]
571bb2b294 [pre-commit.ci] pre-commit autoupdate (#570)
updates:
- [github.com/psf/black: 22.3.0 → 22.6.0](https://github.com/psf/black/compare/22.3.0...22.6.0)
- [github.com/macisamuele/language-formatters-pre-commit-hooks: v2.3.0 → v2.4.0](https://github.com/macisamuele/language-formatters-pre-commit-hooks/compare/v2.3.0...v2.4.0)
- [github.com/pre-commit/mirrors-eslint: v8.18.0 → v8.19.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.18.0...v8.19.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-07-04 21:03:35 -03:00
Fabio Pliger
91a09a09f7 Rename examples cmd and add checks (#563)
* add checks for node and npm versions

* rename example cmd to examples
2022-07-04 15:21:17 -03:00
munyoudoum
9b3433f6ae fix: typos in play_mario, handtrack examples (#566) 2022-07-04 15:19:18 -03:00
Leonardo Pliger
ee9b0960f7 Add support to py- events that map all js events available (#561)
* added the  py- events throughout pyscript.ts

* Integrated the py- event throughout the examples

* Fixed spelling error
2022-06-29 19:49:21 -03:00
woxtu
506ac2574f Add type annotations (#562) 2022-06-28 14:17:23 -05:00
ic-768
dc84d7c1b5 Minor improvements (#556)
* checkpoint: added some text

* checkpoint: added setting up the environment, tips for writing good issues

* continuing to fill it out

* added more detailed description of the process of creating a change and some other cleanup.

* added a getting started section and cleaned up the grammar. This ready for the PR now

* forgot to add the new section to the TOC

* Minor fixes

Co-authored-by: Kevin Goldsmith <kgoldsmith@anaconda.com>
Co-authored-by: Matt Kramer <mkramer@anaconda.com>
2022-06-28 14:16:05 -05:00
Fabio Pliger
fcaa57307f See you later tailwind (#452)
* start removing tailwind and rebuilding some css

* add css to pybox and add class to repl

* set output component visibility

* replace tailwind class with single component class

* add styles to css

* replace classes on  button

* replace classes on input

* replace classes in title

* replace classes on list

* replace classes

* add new style file

* add list element style

* remove tailwind classes from todo example

* revert link on examples files

* remove tailwind config files

* remove commented old code

* add missing ;
2022-06-24 18:30:07 -05:00
Mariana Meireles
d25e754beb Move dashboard workflow to worflow dir (#554)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-06-24 17:01:52 -05:00
Peter W
7f6f411ea8 Try new method to keep CI from running on forks (#538) 2022-06-24 16:55:15 -05:00
Fabio Pliger
96a73e31f3 add diataxis info to docs readme (#548)
* add loca build info to htmlserve

* add info about diataxis to the docs/readme

* add diataxis img
2022-06-24 17:06:47 -03:00
woxtu
c7942d7d8f Use the type definition of pyodide (#535)
* Import the type definition

* Add type annotations
2022-06-24 14:25:14 -05:00
Leonardo Pliger
479348eec9 Added section and cleared up documentation in getting started (#547)
* add section and cleared up documentation

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* I fixed the typo in getting-started

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-24 16:14:48 -03:00
Peter W
ebfed27630 release, latest, unstable branches (#550)
* build unstable workflow

* releases are synced to /latest and /releases/YYYY.MM.MICRO/

* slashes
2022-06-24 10:32:00 -05:00
Mariana Meireles
8923485169 Update feature-request.yml (#541)
Fix typo
2022-06-23 17:44:55 -05:00
Brandon High
d62de26683 Fix inconsistencies and reduce verbosity in examples/index.html (#545) 2022-06-23 17:40:36 -05:00
pww217
1dd9c5b009 small renaming 2022-06-23 11:22:33 -05:00
Peter W
01b64e18ab add release.yml, release automation ready for prod (#539)
* add release.yml, release automation ready for prod

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update .github/workflows/build-release.yml

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

* dont overwrite /alpha/ and change unstable to latest

* alpha -> releases

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2022-06-23 11:08:25 -05:00
Mariana Meireles
fa61339a49 Add GHA to push issues directly to dashboard (#534)
* Add GHA to push issues directly to dashboard

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: mariana <marianameireles@protonmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-22 13:40:31 -03:00
Philipp Rudiger
deb2eee3ad Revert output manager after REPR evaluation (#522)
* Revert output manager after repr evaluation

* Fix indentation
2022-06-21 16:42:53 -05:00
Philipp Rudiger
829cc9f6f9 Simplify tests with pytest-playwright (#523)
* Simplify tests with pytest-playwright

* Add pytest-playwright to pip

* Fix simple_clock example

* Attempt to make example tests more robust

* Make pre-commit happy

* Revert accidental change to simple_clock pyscript resources

* Another attempt at reducing flakeyness

* Do not wait until page load event is fired

* Remove pointless py-config

Co-authored-by: mariana <marianameireles@protonmail.com>
2022-06-21 14:28:05 -03:00
pww217
1c7ef6622b test release automation 2022-06-21 10:26:39 -05:00
pww217
f54ae52b2a test publishing 2022-06-21 10:10:10 -05:00
pww217
171ae3cabe skip test for now 2022-06-21 09:57:30 -05:00
Peter W
f3888df88c Release automation (#521)
* workflow updates

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* build release

* remove if

* test on main

* update docs release workflow

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-21 09:42:56 -05:00
pre-commit-ci[bot]
9274f9ec08 [pre-commit.ci] pre-commit autoupdate (#516)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.2.0 → v4.3.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.2.0...v4.3.0)
- [github.com/asottile/pyupgrade: v2.32.1 → v2.34.0](https://github.com/asottile/pyupgrade/compare/v2.32.1...v2.34.0)
- [github.com/pre-commit/mirrors-eslint: v8.17.0 → v8.18.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.17.0...v8.18.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-21 09:11:00 -05:00
woxtu
6822105c70 Add type annotations (#488) 2022-06-20 13:22:03 -03:00
Gabriel Silvério
d5d855e4c3 Improved user interface of the examples page (#504)
* Added card components for basic examples

* Added card components for mime rendering

* fix anchor tag inside anchor tag

* Added card components for js interaction

* Added card components for visualizations e dashboards

* Refactor card components responsive

* Fix href Fractals with NumPy and canvas

* Refactor quote format

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Added css files

* Refactor card components for basic examples

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Rename global file to main

* Add css variables

* Refactor card components

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Refactor move css files into css folder

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-15 16:20:20 -05:00
idanenglander
1e09ac4fd3 Adding FAQ topic and link from main index (#513)
* Adding FAQ topic and link from main index

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Adding periods

* fix typo

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-15 15:37:03 -05:00
LandonTheCoder
bc513400c5 Fix URL source reference. (#517)
The old version erroneously referenced "./build/" instead of "https://pyscript.net/alpha/".
2022-06-14 14:21:08 -05:00
Ryan Russell
715ceb9ed4 Improve WebGL Raycaster example (#478)
Signed-off-by: Ryan Russell <ryanrussell@users.noreply.github.com>
2022-06-10 11:02:02 -05:00
pre-commit-ci[bot]
0115b152a8 [pre-commit.ci] pre-commit autoupdate (#497)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.16.0 → v8.17.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.16.0...v8.17.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-10 10:48:14 -05:00
andre-dietrich
e1622a56fa fix: < & > are parsed with HTML escape symbols (#481)
Adds utils.htmlDecode arround innerHTML to read the code for <py-repl> and
<py-script>, which preserves all newlines, tabs, and < & > characters.

Fix bug #480
2022-06-09 16:01:31 -05:00
WrigglySplash
03fee56a54 Added example code block to py-repl tag section (#455) 2022-06-02 16:10:21 -03:00
J.I. Cruz
d00171a629 Fix typo/reformat GETTING-STARTED.md (#460)
* Fix conflict

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: mariana <marianameireles@protonmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-02 16:09:29 -03:00
Nuhman Pk
fa28b218ec Added link to Readme file (#487)
https://github.com/pyscript/pyscript/blob/main/README.md
2022-06-02 14:29:05 -03:00
Mariana Meireles
eb882170d5 Fix all favicon issues (#483)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-06-01 15:41:52 -05:00
Mariana Meireles
48a565a51d Fix all favicon issues (#483)
Co-authored-by: mariana <marianameireles@protonmail.com>
2022-06-01 15:41:31 -05:00
Fabio Pliger
f60dd6a788 Fix extensions regression bug (#489)
* add output div visibility rule and make sure CustomWidget is being registered

* add new runAfterRuntimeInitialized method that classes can use to run code only after runtime actually initialized

* replace setTimout with proper event to wait for runtime to be completed

* replace setTimout on pyinpytbox with proper event to wait for runtime to be completed
2022-06-01 15:39:05 -05:00
Jannis Leidel
d6a88d4c9e Only run docs review workflow on non-forks. (#490)
* Only run docs review workflow on non-forks.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-06-01 21:23:42 +02:00
woxtu
4b4ff08131 Change the metadata format (#457)
* Chnage the metadata format

* Add syntax highlighting

* have simple_clock example run from local build to test change

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-06-01 15:49:41 -03:00
Michael Mayer
698478ef95 added a link to the Contributing Guidelines (#477)
The Contributing Guidelines are referenced in the PyScript Documentation readme. Added a quick link to get there
2022-05-30 14:18:30 -03:00
Ifihanagbara Olusheye
4ab9ab51f6 Fixed typo in getting-started.md (#466)
* Fixed little typo

* Fixed extra typo
2022-05-27 17:02:52 -05:00
Jaynarayan vaishnav
bf3995d45c update README.md and CONTRIBUTING.md (#254)
* update README.md

Corrected the grammatical mistakes to make the documents easier to read and understand.

* update README.md

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update README.md

made required changes

* update CONTRIBUTING.md

made necessary changes.

* fixed a typo in CONTRIBUTING.md

* removed unnecessary file

* removed unnecessary file

* removed unnecessary words

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-27 01:09:56 -05:00
Mariana Meireles
4fe603bf96 Fix import link (#339)
Co-authored-by: mariana <marianameireles@protonmail.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-27 01:05:53 -05:00
Fabio Pliger
0639827d00 fix examples indent (#454) 2022-05-27 00:36:37 -05:00
marianoweber
eaacd45672 [FIX] output management cleanups (#464)
* return on \n before empty div is appended

* use appendOutput with out.write

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: Mariano Weber <info@uiremotely.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-27 00:21:47 -05:00
Dan Meador
5d733ab915 Add issue forms (#264)
* Added bug report and feature request issue forms

* Update bug-report.yml

Added browsers dropdown to bugs

* Added misc issue type

* Add keypress event to todo example (#241)

* add enter keypress event in todo example

* fix linting

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* Changed variable names to snake_case for PEP8 formatting (#211)

* Changed variable names to snakecase for PEP8 formatting.

* Changed variable names to snakecase for PEP8 formatting.

* fix indentation

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>

* Add issue templates (#252)

* add issue templates

* incorporate @fpliger suggestions

* Removed mardown files. Added link for questions

* Updated browser dev console info

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Minor typo

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix issue with labels that should be strings, ignore pretty-format of ISSUE_TEMPLATE yaml files

* Removed old md. Updated label

* add the needs-triage label to all new issues

Co-authored-by: Allan Lago <35788148+alago1@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Jason Barnwell <master.j1994@gmail.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
Co-authored-by: Matt Kramer <mkramer@anaconda.com>
2022-05-26 23:59:42 +02:00
Peter W
1bf6cc0e72 Fix examples Ci, Makefile, some doc references (#469)
* fix examples ci, makefile, and update docs

* getting started reference
2022-05-26 16:56:54 -05:00
Mariana Meireles
a9470ed9c1 Move tests, create makefile action to run tests on examples (#433)
* Move tests, create makefile action to run tests on examples

* Correct import file for html files

* Build environment for tests

* Fix the CI

* rearrange CI

* fix find cmd and make sure we don't delete the folder implicitly

* more rearranging

* fix folder permissions and custom sed for subfolders

* add toga wheels files

* re-add missing file

* mirror latest changes in alpha ci

* fix find cmd

* try different fix for find

* remove redundant build

Co-authored-by: mariana <marianameireles@protonmail.com>
Co-authored-by: pww217 <pwilson@anaconda.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-26 16:31:38 -05:00
Philipp Rudiger
2c5ef95027 Update panel examples to panel 0.13.1 (#458)
* Update panel examples to panel 0.13.1

* More indent
2022-05-24 18:01:45 -05:00
marianoweber
f712b1369a [PROPOSAL] REPL output replacement (#439)
* fix OutputManager _append setter

* fix OutputManager change parameters

* fix OutputCtxManager __init__ and change methods

* replacing OutputManager pyscript.write with write function

* add optional output-append attribute to py-repl

* add appendOutput(default: true) to base component

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update pyscriptjs/src/components/pyrepl.ts

Co-authored-by: woxtu <woxtup@gmail.com>

* change from output-append flag to output-mode attribute

* removed type annotation

* repositioned setOutputMode call for auto-generated REPLs to work

* fixed indentation error for indented input

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* added preEvaluate method

* moved output-mode logic to preEvaluate

* remove static write method from PyScript, add write method to Element

* removed err parameter from OutputCtxManager

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add PyScript.write back with a deprecation warning

* fix wrong input name

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: woxtu <woxtup@gmail.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-24 17:58:48 -05:00
Iftikhar #100Devs
2f03b18619 updated-README-files-Contributing-Section (#438) 2022-05-23 18:18:30 -05:00
ic-768
8cd5ba6361 Minor refactoring (#437) 2022-05-23 18:15:37 -05:00
pre-commit-ci[bot]
c951961a92 [pre-commit.ci] pre-commit autoupdate (#450)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.15.0 → v8.16.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.15.0...v8.16.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-23 15:11:44 -05:00
woxtu
3b68e1b27d Bundle the Python files into the output file (#441)
* Bundle the Python files into the output file

* Remove unused functions
2022-05-22 16:30:19 -05:00
weensy
48e6b1a84e Fix typo in getting-started.md (#443)
- place holders => placeholders
- can by used by => can be used by
2022-05-22 11:09:34 -05:00
Peter W
ee46b46234 Add testing to CI flow (#418)
* new testing ci flow

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* install conda

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test conda

* pre-commit fix

* remove if

* makefile fix

* fix pytest install

* argument for test

* restructure

* fix sync

* full path filter

* use setup-condav2

* syntax

* test path

* add binary argument

* remove which

* Update Makefile

* remove arguments

* trigger CI

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-20 13:45:49 -05:00
Furkan Doğan
db49fd498a fixed the logging of initializers (#431) 2022-05-19 19:44:55 -03:00
woxtu
e95b90363e Add event listeners properly (#424) 2022-05-19 17:56:53 -03:00
woxtu
82c0d741e4 Add type annotations (#396)
* Add type annotations

* Replace `StateCommand` with `Command`

* Revert "Replace `StateCommand` with `Command`"

This reverts commit 2dfc2d34e4.

* Fix the return value
2022-05-19 16:59:39 -03:00
Peter W
87b150d539 Update build-alpha.yml 2022-05-19 12:16:41 -05:00
ic-768
508a7d8605 Add labels for pyrepl component (#322)
* Add labels for pyrepl component

* Add id to editor box instead of main div

Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-19 09:23:08 -05:00
Fabio Pliger
9119939c3d add components description in getting started (#417)
* add missing tags in getting started

* add py-config tag to getting started

* Edits to Fabio's tags/definitions

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update getting-started.md

Co-authored-by: Idan <ienglander@anaconda.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: idanenglander <60263976+idanenglander@users.noreply.github.com>
2022-05-18 16:47:56 -05:00
cleonard
59fc667651 Basic tests (#355)
* Added microsoft channel and playwright as dependency

* Added test-setup to run

* Basic tests for each example in examples/index.html

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update test_webgl_raycaster_index.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update test_folium.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update test_folium.py

* Update test_folium.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update test_bokeh.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Whitelisting assertion statements in test files

* Updated bare execept statements with ImportError

* Flake8 compliance

* Updated  message

* Removed 'make test-setup'

* Removed @echo from make test

* Uncommented Toga test

* Removed __test_all__.py file

* Removing unnecessary files

* Removed individual test files

* conftest.py with all data for running tests

* Consolidated test file

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fixed pre-commit flake8 issues

* flake8 issue

* add playwright installation to setup

* Testing parameterization and webserver to serve examples locally

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Flake8 compliance

* More flake8

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Michael Verhulst <michael@terminallabs.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-18 13:08:15 -05:00
idanenglander
0d946f853f Embedding video, adding PS tag definitions (#403)
* Embedding video, adding PS tag definitions

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* html -> HTML; add sphinxcontrib.youtube to env.yml

* change place of sphinxcontrib.youtube in env.yml

* one more sphinxcontrib-youtube change

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-18 09:03:46 -05:00
Jeff Glass
b767a78b05 Provide Visible Error if <py-env> paths is used in a local HTML file (#311)
* Add onscreen error when using py-env paths in local HTTP files without file server

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Remove redundant code, fix error handling, add 404 error

* Lint and Format

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* manage errors loading files

* use handleFetchError for handling fetch errors in env

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Fabio Pliger <fabio.pliger@gmail.com>
2022-05-17 23:48:02 -05:00
woxtu
39774a83c5 Use a recommended method (#363) 2022-05-17 22:24:33 -05:00
marianoweber
c04015899b fixed REPL bugs (#372)
* fixed REPL play button alignment

* fixed REPL auto-generate

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* changed nextExecId selector

* added removeClasses to utils.ts

* fixed visual bug after error output

* changed play button alignment

Co-authored-by: Mariano Weber <info@uiremotely.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-05-17 16:20:00 -05:00
Jannis Leidel
6898daf0ce Documentation infrastructure. (#262)
* Initial setup.

This does a few things:

- Adds some placeholders following the Diátaxis framework (https://diataxis.fr)
- Sets up Sphinx with MyST parser for Markdown in addition to rST.
- Uses the well-known PyData Sphinx theme.
- Moves some already existing Markdown files into the docs directory.
- Sets up the initial doc review GitHub action to auto-deploy to GitHub pages.

* Activate conda env.

* Remove custom action.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Make the dir.

* Push directly

* Add readthedocs config.

* Disable GitHub pages deployment for now.

* Add release and latest workflows as well.

* Make clear that this is work in progress.

* Made docs merge ready, added What is PyScript section with example.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Replace `on:tags:` with `on:create:`

The existing trigger is apparently not in the GHA spec

* Pretty format YAML

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add s3 sync and permissions

* Leave status message in PR.

* Redirect from docs.pyscript.net/ to docs.pyscript.net/latest/

* Delete latest directory before deployment.

* Update review and release workflows, too.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Allow access to S3 for review and release doc workflow.

* Fix name of workflow.

* Bump up Python version.

* Because YAML.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Revert move to 3.10.

* Fix sitemap.

* Remove status settgin from release and latest build.

* Comment out cleanup.

* Add write permissions for statuses.

* More permissions?

* Fix artifact name.

* Use appropriate concurrency.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* .zip not needed

* Align name of workflows with CI workflows.

* Add checks permission.

* Set a notice instead.

* Move to sphinx-design.

* Add sphinx-autobuild.

* Use frontmatter more.

* Add section for mdformat but disable it for now.

See https://github.com/executablebooks/mdformat-myst/pull/9 for more details.

* Fix fencing.

* Actually using html renderer.

* Revert moving governance files.

* Use full URLs for governance docs.

* Added warning.

* Fix copyright and author.

* Another minor fix.

* Use GitHub Action summary instead of notice.

* Fix variable name.

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Matt Kramer <mkramer@anaconda.com>
Co-authored-by: ximena9201 <ximenandrea.ro@gmail.com>
2022-05-17 12:08:06 -05:00
hoge1e3
eb3a31a698 fixed the bug std-err attribute cannot set stderr properly (#371) 2022-05-16 21:30:57 -05:00
Fabio Pliger
0476627f34 fix autogenerated element (#397)
* use static string in checkId to simplify behaviour and ensure ids always start with alpha char

* re-enable terser on minify

* fix example local path
2022-05-16 16:08:28 -05:00
Yannick Funk
eba42ad9b4 Add checkId() for PyButton and PyInputBox, add id check for tags with pys- Event handlers (#400)
* Add id generation to PyButton and PyInputBox components

* Refactor init handlers and add check for id
2022-05-16 16:05:11 -05:00
Javadz
ca909b4f6b Create readme.md (#374) 2022-05-16 11:13:39 -05:00
308 changed files with 26651 additions and 7254 deletions

63
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@@ -0,0 +1,63 @@
name: Bug Report
description: Create a report to help us improve
labels: ["type: bug", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Thanks for helping PyScript! 🐍
Going through bugs and issues takes up a lot of time, so please be so kind and take a few minutes to fill out all the areas to the best of your ability.
There will always be more issues than there is time to do them, and so we will need to selectively close issues that don't provide enough information, so we can focus our time on helping people like you who fill out the issue form completely. Thank you for your collaboration!
There are also already a lot of open issues, so please take 2 minutes and search through existing ones to see if what you are experiencing already exists
Thanks for helping PyScript be amazing. We are nothing without people like you helping build a better community 💐!
- type: checkboxes
id: checks
attributes:
label: Checklist
description: Please confirm and check all the following options.
options:
- label: I added a descriptive title
required: true
- label: I searched for other issues and couldn't find a solution or duplication
required: true
- label: I already searched in Google and didn't find any good information or help
required: true
- type: textarea
id: what-happened
attributes:
label: What happened?
description: And what should have happened instead? This really helps everyone review quicker and greatly increases the chance that someone can get around to solve your issue
placeholder: Tell us what you see!
validations:
required: true
- type: dropdown
id: browsers
attributes:
label: What browsers are you seeing the problem on? (if applicable)
multiple: true
options:
- Firefox
- Chrome
- Safari
- Microsoft Edge
- Other
validations:
required: false
- type: textarea
id: list
attributes:
label: Console info
description: |
If there are errors in your browser console then its helpful to be able to troubleshoot.
- Chrome , Firefox, and Edge: Right-click on the page and select *Inspect*. Alternatively you can press F12 on your keyboard.
- Safari: Find instructions [here](https://support.apple.com/guide/safari/use-the-developer-tools-in-the-develop-menu-sfri20948/mac).
render: shell
- type: textarea
id: context
attributes:
label: Additional Context
description: Add any additional context information or screenshots you think are useful.

View File

@@ -1,23 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG]"
labels: needs-triage
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior: either a code snippet or a link to an HTML page which shows the bug.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Question
url: https://community.anaconda.cloud/c/tech-topics/pyscript
about: For questions or discussions about pyscript

View File

@@ -0,0 +1,67 @@
name: Feature Request
description: Create a feature request to make PyScript even better
labels: ["type: enhancement", "needs-triage"]
body:
- type: markdown
attributes:
value: |
### Thanks for helping PyScript! 🐍
Going through feature requests and issues takes up a lot of time, so please be so kind and take a few minutes to fill out all the areas to the best of your ability.
There will always be more great ideas than there is time to do them, and so we will need to selectively close issues that don't provide enough information, so everyone can focus our time on helping people like you who fill out the form completely. Thank you for your collaboration!
There are also already a lot of open requests, so please take 2 minutes and search through existing ones to see if your idea already exists. If you find something close, please upvote that request and comment.
Thanks for helping PyScript be amazing. We are nothing without people like you helping build a better community 💐!
### Lets make sure you are in the right place. If you have an idea/request for:
- #### A specific package/library (such as pandas or scikit learn):
Search for that respective library on github repo or website. You will have much more success there.
- #### A general Python question/feature request:
Try out a forum post [here](https://discuss.python.org/c/users/7)
- type: checkboxes
id: checks
attributes:
label: Checklist
description: Please confirm and check all the following options
options:
- label: I added a descriptive title
required: true
- label: I searched for other feature requests and couldn't find a duplicate (including also the ``type-feature`` tag)
required: true
- label: I confirmed that it's not related to another project area (see the above section)
required: true
- type: textarea
id: request-idea
attributes:
label: What is the idea?
description: Describe what the feature is and the desired state
placeholder: This feature would allow any user of PyScript to type in a simple command in the console and show all variables currently in use
validations:
required: true
- type: textarea
id: why
attributes:
label: Why is this needed
description: |
Who would benefit from this and why would this add value to them? What problem does this solve?
placeholder: This would benefit users who would like to see what is being used so they can learn and debug faster
- type: textarea
id: what
attributes:
label: What should happen?
description: |
What should be the user experience with the feature? Describe from a user perpective what they would do and see
placeholder: A user would type in ``PyScript debug`` in the browser console and see a list of all variables created.
- type: textarea
id: context
attributes:
label: Additional Context
description: |
Is there any other information that you think would be valuable for the team to know?

View File

@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[FEATURE]"
labels: needs-triage
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. As a user, I'd like to [...]
**Describe the solution you'd like**
A clear and concise description of what you expect to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

37
.github/ISSUE_TEMPLATE/misc.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Miscellaneous
description: For issues that don't belong in other categories
labels: ["type: misc", "needs-triage"]
body:
- type: markdown
attributes:
value: |
Thanks for helping PyScript! 🐍
This issue is for things that doesn't make sense to put into the other issue categories and we don't want it to get lost.
Going through issues takes up a lot of time, so please be so kind and take a few minutes to fill out all the areas to the best of your ability.
There will always be more issues than there is time to do them, and so we will need to selectively close issues that don't provide enough information, so we can focus our time on helping people like you who fill out the issue form completely. Thank you for your collaboration!
There are also already a lot of open issues, so please take 2 minutes and search through existing ones to see if what you are experiencing already exists
Thanks for helping PyScript be amazing. We are nothing without people like you helping build a better community 💐!
- type: checkboxes
id: checks
attributes:
label: Checklist
description: Please confirm and check all the following options.
options:
- label: I added a descriptive title
required: true
- label: I searched for other issues and couldn't find a duplication
required: true
- label: I already searched in Google and didn't find any good information or help
required: true
- type: textarea
id: what
attributes:
label: What is the issue/comment/problem?
description: This is a miscellaneous issue so this could be just about anything. We simply ask that you provide as many details as you can to help spur discussion or the outcome you want.
validations:
required: true

5
.github/release.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
changelog:
categories:
- title: New Features
- title: Breaking Changes
- title: Known Issues

26
.github/stale.yaml vendored Normal file
View File

@@ -0,0 +1,26 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- backlog
- needs-triage
- needs-work
- epic
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
This issue has been automatically closed because it has not had
recent activity. Thank you for your contributions.

View File

@@ -1,37 +1,42 @@
name: '[CI] Build Latest' name: '[CI] Build Unstable'
on: on:
push: # Only run on merges into main that modify files under pyscriptjs/ push: # Only run on merges into main that modify files under pyscriptjs/ and examples/
branches: branches:
- main - main
paths: paths:
- pyscriptjs/** - pyscriptjs/**
- examples/**
- .github/workflows/build-latest.yml # Test that workflow works when changed - .github/workflows/build-latest.yml # Test that workflow works when changed
pull_request: # Run on any PR that modifies files in pyscriptjs/ pull_request: # Run on any PR that modifies files under pyscriptjs/ and examples/
branches: branches:
- main - main
paths: paths:
- pyscriptjs/** - pyscriptjs/**
- .github/workflows/build-latest.yml # Test that workflow works when changed - examples/**
- .github/workflows/build-unstable.yml # Test that workflow works when changed
workflow_dispatch:
jobs: jobs:
build: BuildAndTest:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
defaults: defaults:
run: run:
working-directory: pyscriptjs working-directory: pyscriptjs
env:
MINICONDA_PYTHON_VERSION: py38
MINICONDA_VERSION: 4.11.0
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Install node - name: Install node
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 18.x node-version: 18.x
- name: Cache node modules - name: Cache node modules
uses: actions/cache@v3 uses: actions/cache@v3
env: env:
@@ -44,20 +49,53 @@ jobs:
${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build- ${{ runner.os }}-build-
${{ runner.os }}- ${{ runner.os }}-
- name: Install dependencies
run: | - name: setup Miniconda
npm install uses: conda-incubator/setup-miniconda@v2
- name: Build pyscript
run: | - name: Setup Environment
npm run build run: make setup
- name: Build
run: make build
- name: TypeScript Tests
run: make test-ts
- name: Python Tests
run: make test-py
- name: Integration Tests
run: make test-integration-parallel
- uses: actions/upload-artifact@v3
with:
name: pyscript
path: |
pyscriptjs/build/
if-no-files-found: error
retention-days: 7
Deploy:
runs-on: ubuntu-latest
needs: BuildAndTest
if: github.ref == 'refs/heads/main' # Only deploy on merge into main
permissions:
contents: read
id-token: write
steps:
- uses: actions/download-artifact@v3
with:
name: pyscript
path: ./build/
# Deploy to S3 # Deploy to S3
- name: Configure AWS credentials - name: Configure AWS credentials
if: github.ref == 'refs/heads/main' # Only deploy on merge into main
uses: aws-actions/configure-aws-credentials@v1.6.1 uses: aws-actions/configure-aws-credentials@v1.6.1
with: with:
aws-region: ${{ secrets.AWS_REGION }} aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }} role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3 - name: Sync to S3
if: github.ref == 'refs/heads/main' run: aws s3 sync --quiet ./build/ s3://pyscript.net/unstable/
run: aws s3 sync --quiet ./examples/build/ s3://pyscript.net/unstable

66
.github/workflows/docs-release.yml vendored Normal file
View File

@@ -0,0 +1,66 @@
name: '[Docs] Build Release'
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
env:
SPHINX_HTML_BASE_URL: https://docs.pyscript.net/
steps:
- name: Checkout
uses: actions/checkout@v3
with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- name: Setup
uses: conda-incubator/setup-miniconda@v2
with:
auto-update-conda: true
activate-environment: docs
environment-file: docs/environment.yml
python-version: '3.9'
- name: Build
shell: bash -l {0}
run: |
cd docs/
make html
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: pyscript-docs-${{ github.ref_name }}
path: docs/_build/html/
# Deploy to S3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1.6.1
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Copy redirect file
run: aws s3 cp --quiet ./docs/_build/html/_static/redirect.html s3://docs.pyscript.net/index.html
# - name: Delete release directory
# run: aws s3 rm --recursive s3://docs.pyscript.net/${{ github.ref_name }}/
- name: Sync to S3
run: aws s3 sync --quiet ./docs/_build/html/ s3://docs.pyscript.net/${{ github.ref_name }}/
# Make sure to remove the latest folder so we sync the full docs upon release
- name: Delete latest directory
run: aws s3 rm --recursive s3://docs.pyscript.net/latest/
# Note that the files are the same as above, but we want to have folders with
# /<tag name>/ AND /latest/ which latest will always point to the latest release
- name: Sync to /latest
run: aws s3 sync --quiet ./docs/_build/html/ s3://docs.pyscript.net/latest/

74
.github/workflows/docs-review.yml vendored Normal file
View File

@@ -0,0 +1,74 @@
name: '[Docs] Build Review'
on:
pull_request:
branches:
- '*'
paths:
- docs/**
concurrency:
# Concurrency group that uses the workflow name and PR number if available
# or commit SHA as a fallback. If a new build is triggered under that
# concurrency group while a previous build is running it will be canceled.
# Repeated pushes to a PR will cancel all previous builds, while multiple
# merges to main will not cancel.
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
build:
if: github.repository_owner == 'pyscript'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
env:
SPHINX_HTML_BASE_URL: https://docs.pyscript.net/
steps:
- name: Checkout
uses: actions/checkout@v3
with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- name: Setup
uses: conda-incubator/setup-miniconda@v2
with:
auto-update-conda: true
activate-environment: docs
environment-file: docs/environment.yml
python-version: '3.9'
- name: Build
shell: bash -l {0}
run: |
cd docs/
make html
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: pyscript-docs-review-${{ github.event.number }}
path: docs/_build/html/
# Deploy to S3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1.6.1
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Copy redirect file
run: aws s3 cp --quiet ./docs/_build/html/_static/redirect.html s3://docs.pyscript.net/index.html
- name: Sync to S3
run: aws s3 sync --quiet ./docs/_build/html/ s3://docs.pyscript.net/review/${{ github.event.number }}/
- name: Adding step summary
run: |
echo "### Review documentation" >> $GITHUB_STEP_SUMMARY
echo "As with any pull request, you can find the rendered documentation version for pull request ${{ github.event.number }} here:"
echo "" >> $GITHUB_STEP_SUMMARY # this is a blank line
echo "https://docs.pyscript.net/review/${{ github.event.number }}/" >> $GITHUB_STEP_SUMMARY

55
.github/workflows/docs-unstable.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
name: '[Docs] Build Latest'
on:
push:
branches:
- main
paths:
- docs/**
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
env:
SPHINX_HTML_BASE_URL: https://docs.pyscript.net/
steps:
- name: Checkout
uses: actions/checkout@v3
with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- name: Setup
uses: conda-incubator/setup-miniconda@v2
with:
auto-update-conda: true
activate-environment: docs
environment-file: docs/environment.yml
python-version: '3.9'
- name: Build
shell: bash -l {0}
run: |
cd docs/
make html
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: pyscript-docs-latest
path: docs/_build/html/
# Deploy to S3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1.6.1
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
# Sync will only copy changed files
- name: Sync to S3
run: aws s3 sync --quiet ./docs/_build/html/ s3://docs.pyscript.net/unstable/

60
.github/workflows/prepare-release.yml vendored Normal file
View File

@@ -0,0 +1,60 @@
name: '[CI] Prepare Release'
on:
push:
tags:
- '[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9]+' # YYYY.MM.MICRO
env:
MINICONDA_PYTHON_VERSION: py38
MINICONDA_VERSION: 4.11.0
defaults:
run:
working-directory: pyscriptjs
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v3
env:
cache-name: cache-node-modules
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: setup Miniconda
uses: conda-incubator/setup-miniconda@v2
- name: Setup Environment
run: make setup
- name: Build and Test
run: make test
- name: Zip build folder
run: zip -r -q ./build.zip ./build
- name: Prepare Release
uses: softprops/action-gh-release@v1
with:
draft: true
prerelease: true
generate_release_notes: true
files: ./build.zip

View File

@@ -1,14 +1,16 @@
name: '[CI] Build Alpha' name: '[CI] Publish Release'
on: on:
push: release:
branches: types: [published]
- main
tags: env:
- '**' # Currently any tag, need to slim down MINICONDA_PYTHON_VERSION: py38
paths: MINICONDA_VERSION: 4.11.0
- pyscriptjs/**
- .github/workflows/build-alpha.yml # Test that workflow works when changed defaults:
run:
working-directory: pyscriptjs
jobs: jobs:
build: build:
@@ -16,17 +18,15 @@ jobs:
permissions: permissions:
contents: read contents: read
id-token: write id-token: write
defaults:
run:
working-directory: pyscriptjs
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Install node - name: Install node
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: 18.x node-version: 18.x
- name: Cache node modules - name: Cache node modules
uses: actions/cache@v3 uses: actions/cache@v3
env: env:
@@ -39,18 +39,24 @@ jobs:
${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build- ${{ runner.os }}-build-
${{ runner.os }}- ${{ runner.os }}-
- name: Install dependencies
run: |
npm install
- name: Build pyscript
run: |
npm run build
# Deploy to S3 - name: setup Miniconda
uses: conda-incubator/setup-miniconda@v2
- name: Setup Environment
run: make setup
- name: Build and Test
run: make test
# Upload to S3
- name: Configure AWS credentials - name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1.6.1 uses: aws-actions/configure-aws-credentials@v1.6.1
with: with:
aws-region: ${{ secrets.AWS_REGION }} aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }} role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3 - name: Sync to S3
run: aws s3 sync --quiet ./examples/build/ s3://pyscript.net/alpha/ run: | # Update /latest and create an explicitly versioned directory under releases/YYYY.MM.MICRO/
aws s3 sync --quiet ./build/ s3://pyscript.net/latest/
aws s3 sync --quiet ./build/ s3://pyscript.net/releases/${{ github.ref_name }}/

26
.github/workflows/publish-snapshot.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: '[CI] Publish Snapshot'
# Copy /unstable/ to /snapshots/2022.09.1.RC1/
on:
workflow_dispatch:
inputs:
snapshot_version:
description: 'The calver version of this snapshot: 2022.09.1 or 2022.09.1.RC1'
type: string
required: true
jobs:
snapshot:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1.6.1
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3
run: >
aws s3 sync s3://pyscript.net/unstable/ s3://pyscript.net/snapshots/${{ inputs.snapshot_version }}/

View File

@@ -1,12 +1,8 @@
name: '[CI] Sync Examples' name: '[CI] Sync Examples'
on: on:
push: # Only run on merges into main that modify files under pyscriptjs/examples/ release:
branches: types: [published]
- main
paths:
- pyscriptjs/examples/**
- .github/workflows/sync-examples.yml # Test that workflow works when changed
jobs: jobs:
build: build:
@@ -16,7 +12,7 @@ jobs:
id-token: write id-token: write
defaults: defaults:
run: run:
working-directory: pyscriptjs/examples working-directory: examples
steps: steps:

4
.gitignore vendored
View File

@@ -51,6 +51,7 @@ coverage.xml
*.py,cover *.py,cover
.hypothesis/ .hypothesis/
.pytest_cache/ .pytest_cache/
pyscriptjs/examples
# Translations # Translations
*.mo *.mo
@@ -71,6 +72,7 @@ instance/
# Sphinx documentation # Sphinx documentation
docs/_build/ docs/_build/
docs/_env/
# PyBuilder # PyBuilder
target/ target/
@@ -134,3 +136,5 @@ dmypy.json
.pyre/ .pyre/
node_modules/ node_modules/
coverage/

View File

@@ -4,7 +4,7 @@
default_stages: [commit] default_stages: [commit]
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.2.0 rev: v4.4.0
hooks: hooks:
- id: check-builtin-literals - id: check-builtin-literals
- id: check-case-conflict - id: check-case-conflict
@@ -25,53 +25,65 @@ repos:
hooks: hooks:
- id: bandit - id: bandit
args: args:
- --skip=B201 - --skip=B101,B201
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 22.3.0 rev: 22.12.0
hooks: hooks:
- id: black - id: black
- repo: https://github.com/codespell-project/codespell - repo: https://github.com/codespell-project/codespell
rev: v2.1.0 rev: v2.2.2
hooks: hooks:
- id: codespell # See 'setup.cfg' for args - id: codespell # See 'setup.cfg' for args
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
rev: 4.0.1 rev: 6.0.0
hooks: hooks:
- id: flake8 # See 'setup.cfg' for args - id: flake8 # See 'setup.cfg' for args
additional_dependencies: [flake8-bugbear, flake8-comprehensions] additional_dependencies: [flake8-bugbear, flake8-comprehensions]
- repo: https://github.com/pycqa/isort - repo: https://github.com/pycqa/isort
rev: 5.10.1 rev: 5.11.1
hooks: hooks:
- id: isort - id: isort
name: isort (python) name: isort (python)
args: [--profile, black] args: [--profile, black]
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.3.0 rev: v2.5.0
hooks: hooks:
- id: pretty-format-yaml - id: pretty-format-yaml
args: [--autofix, --indent, '4'] args: [--autofix, --indent, '4']
exclude: .github/ISSUE_TEMPLATE/.*\.yml$
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v2.32.1 rev: v3.3.1
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: args:
- --py310-plus - --py310-plus
- repo: https://github.com/pre-commit/mirrors-eslint - repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.15.0 rev: v8.29.0
hooks: hooks:
- id: eslint - id: eslint
files: pyscriptjs/src/.*\.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx files: pyscriptjs/src/.*\.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx
types: [file] types: [file]
additional_dependencies: additional_dependencies:
- eslint - eslint@8.25.0
- eslint-plugin-svelte3 - typescript@4.8.4
- typescript - '@typescript-eslint/eslint-plugin@5.39.0'
- '@typescript-eslint/eslint-plugin' - '@typescript-eslint/parser@5.39.0'
- '@typescript-eslint/parser'
# Commented out until mdformat-myst supports custom extensions
# See https://github.com/executablebooks/mdformat-myst/pull/9
# - repo: https://github.com/executablebooks/mdformat
# rev: 0.7.14 # Use the ref you want to point at
# hooks:
# - id: mdformat
# additional_dependencies:
# - mdformat-gfm
# - mdformat-myst
# - mdformat-black

28
.readthedocs.yml Normal file
View File

@@ -0,0 +1,28 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: miniconda3-4.7
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
conda:
environment: docs/environment.yml
# If using Sphinx, optionally build your docs in additional formats such as PDF
# formats:
# - pdf
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt

View File

@@ -1,4 +1,4 @@
# Code of Conduct # Code of Conduct
The Code of Conduct is available in the pyscript Governance repo. The Code of Conduct is available in the PyScript Governance repo.
See https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md See https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md

View File

@@ -9,58 +9,39 @@ Thank you for wanting to contribute to the PyScript project!
* [Reporting bugs](#reporting-bugs) * [Reporting bugs](#reporting-bugs)
* [Reporting security issues](#reporting-security-issues) * [Reporting security issues](#reporting-security-issues)
* [Asking questions](#asking-questions) * [Asking questions](#asking-questions)
* [Setting up your environment](#setting-up-your-environment) * [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
* [Places to start](#places-to-start) * [Places to start](#places-to-start)
* [Submitting a change](#submitting-a-change) * [Submitting a change](#submitting-a-change)
* [License terms for contributions](#license-terms-for-contributions) * [License terms for contributions](#license-terms-for-contributions)
* [Becoming a maintainer](#becoming-a-maintainer) * [Becoming a maintainer](#becoming-a-maintainer)
* [Trademarks](#trademarks) * [Trademarks](#trademarks)
## Code of Conduct # Code of Conduct
The [PyScript Code of Conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md) governs the project and everyone participating in it. By participating, you are expected to uphold this code. Please report unacceptable behavior to the maintainers or administrators as described in that document. The [PyScript Code of Conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md) governs the project and everyone participating in it. By participating, you are expected to uphold this code. Please report unacceptable behavior to the maintainers or administrators as described in that document.
## Contributing # Contributing
### Reporting bugs ## Reporting bugs
Bugs are tracked on the [project issues page](https://github.com/pyscript/pyscript/issues). Please check if your issue has already been filed by someone else by searching the existing issues before filing a new one. Once your issue is filed, it will be triaged by another contributor or maintainer. If there are questions raised about your issue, please respond promptly. Bugs are tracked on the [project issues page](https://github.com/pyscript/pyscript/issues). Please check if your issue has already been filed by someone else by searching the existing issues before filing a new one. Once your issue is filed, it will be triaged by another contributor or maintainer. If there are questions raised about your issue, please respond promptly.
#### Creating useful issues ## Creating useful issues
* Use a clear and descriptive title. * Use a clear and descriptive title.
* Describe the specific steps that reproduce the problem with as many details as possible so that someone can verify the issue. * Describe the specific steps that reproduce the problem with as many details as possible so that someone can verify the issue.
* Describe the behavior you observed, and the behavior you had expected. * Describe the behavior you observed, and the behavior you had expected.
* Include screenshots if they help make the issue clear. * Include screenshots if they help make the issue clear.
### Reporting security issues ## Reporting security issues
If you aren't confident that it is appropriate to submit a security issue using the above process, you can e-mail it to security@pyscript.net If you aren't confident that it is appropriate to submit a security issue using the above process, you can e-mail it to security@pyscript.net
### Asking questions ## Asking questions
If you have questions about the project, using PyScript, or anything else, please ask in the [PyScript forum](https://community.anaconda.cloud/c/tech-topics/pyscript). If you have questions about the project, using PyScript, or anything else, please ask in the [PyScript forum](https://community.anaconda.cloud/c/tech-topics/pyscript).
### Setting up your environment ## Places to start
* clone the repo
```
git clone https://github.com/pyscript/pyscript
```
* cd into the main project folder
```
cd pyscript/pyscriptjs
```
* install the dependencies with npm install - make sure to use nodejs version >= 16
```
npm install
```
* run npm run dev to build and run the dev server. This will also watch for changes and rebuild when a file is saved.
```
npm run dev
```
### Places to start
If you would like to contribute to PyScript, but you aren't sure where to begin, here are some suggestions. If you would like to contribute to PyScript, but you aren't sure where to begin, here are some suggestions.
@@ -69,16 +50,11 @@ If you would like to contribute to PyScript, but you aren't sure where to begin,
* **Look over the open pull requests.** Do you have comments or suggestions for the proposed changes? Add them. * **Look over the open pull requests.** Do you have comments or suggestions for the proposed changes? Add them.
* **Check out the examples.** Is there a use case that would be good to have sample code for? Create an example for it. * **Check out the examples.** Is there a use case that would be good to have sample code for? Create an example for it.
### Submitting a change ## Setting up your local environment and developing
All contributions must be licensed Apache 2.0, and all files must have a copy of the boilerplate license comment (can be copied from an existing file). If you would like to contribute to PyScript, you will need to set up a local development environment. The [following instructions](https://docs.pyscript.net/latest/development/setting-up-environment.html) will help you get started.
To create a change for PyScript, you can follow the process described [here](https://docs.github.com/en/get-started/quickstart/contributing-to-projects). You can also read the [developing process](https://docs.pyscript.net/latest/development/developing.html) and how to rebase your branch with the latest changes.
* Fork a personal copy of the PyScript project.
* Make the changes you would like (don't forget to test them!)
* Please squash all commits for a change into a single commit (this can be done using "git rebase -i"). Do your best to have a well-formed commit message for the change.
* Open a pull request back to the PyScript project and address any comments/questions from the maintainers and other contributors.
## License terms for contributions ## License terms for contributions
@@ -86,7 +62,7 @@ This Project welcomes contributions, suggestions, and feedback. All contribution
## Becoming a maintainer ## Becoming a maintainer
Contributors are invited to be maintainers to the project by demonstrating good decision making in their contributions, a commitment to the goals of the project, and consistent adherence to the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md). New maintainers are invited by a 3/4 vote of the existing maintainers. Contributors are invited to be maintainers of the project by demonstrating good decision making in their contributions, a commitment to the goals of the project, and consistent adherence to the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md). New maintainers are invited by a 3/4 vote of the existing maintainers.
## Trademarks ## Trademarks

View File

@@ -1,210 +0,0 @@
# Getting started with PyScript
This page will guide you through getting started with PyScript.
## Development setup
PyScript does not require any development environment other
than a web browser. We recommend using [Chrome](https://www.google.com/chrome/).
If you're using [VSCode](https://code.visualstudio.com/), the
[Live Server extension](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)
can be used to reload the page as you edit the HTML file.
## Installation
There is no installation required. In this document we'll use
the PyScript assets served on https://pyscript.net.
If you want to download the source and build it yourself, follow
the instructions in the README.md file.
## Your first PyScript HTML file
Here's a "Hello, world!" example using PyScript.
Using your favorite editor create a new file called `hello.html` in
the same directory as your PyScript, JavaScript, and CSS files with the
following content, and open the file in your web browser. You can typically
open an HTML by double clicking it in your file explorer.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body> <py-script> print('Hello, World!') </py-script> </body>
</html>
```
Notice the use of the `<py-script>` tag in the HTML body. This
is where you'll write your Python code. In the following sections we'll
introduce the 8 tags provided by PyScript.
## The py-script tag
The `<py-script>` tag lets you execute multi-line Python scripts and
print back onto the page. For
example, we can compute π.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
</head>
<body>
<py-script>
print("Let's compute π:")
def compute_pi(n):
pi = 2
for i in range(1,n):
pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
return pi
pi = compute_pi(100000)
s = f"π is approximately {pi:.3f}"
print(s)
</py-script>
</body>
</html>
```
### Writing into labeled elements
In the example above we had a single `<py-script>` tag and it printed
one or more lines onto the page in order. Within the `<py-script>` you
have access to the `pyscript` module, which provides a `.write()` method
to send strings into labeled elements on the page.
For example we'll add some style elements and provide place holders for
the `<py-script>` tag write to.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
</head>
<body>
<b><p>Today is <u><label id='today'></label></u></p></b>
<br>
<div id="pi" class="alert alert-primary"></div>
<py-script>
import datetime as dt
pyscript.write('today', dt.date.today().strftime('%A %B %d, %Y'))
def compute_pi(n):
pi = 2
for i in range(1,n):
pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
return pi
pi = compute_pi(100000)
pyscript.write('pi', f'π is approximately {pi:.3f}')
</py-script>
</body>
</html>
```
## Packages and modules
In addition to the [Python Standard Library](https://docs.python.org/3/library/) and
the `pyscript` module, many 3rd-party OSS packages will work out-of-the-box with PyScript.
In order to use them you will need to declare the dependencies using the `<py-env>` in the
HTML head. You can also link to `.whl` files directly on disk like in our [toga example](https://github.com/pyscript/pyscript/blob/main/pyscriptjs/examples/toga/freedom.html)
```
<py-env>
- './static/wheels/travertino-0.1.3-py3-none-any.whl'
</py-env>
```
If your `.whl` is not a pure Python wheel, then open a PR or issue with [pyodide](https://github.com/pyodide/pyodide) to get it added [here](https://github.com/pyodide/pyodide/tree/main/packages).
If there's enough popular demand the pyodide team will likely work on supporting your package, regardless things will likely move faster if you make the PR and consult with the team to get unblocked.
For example, NumPy and Matplotlib are available. Notice here we're using `<py-script output="plot">`
as a shortcut, which takes the expression on the last line of the script and runs `pyscript.write('plot', fig)`.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- numpy
- matplotlib
</py-env>
</head>
<body>
<h1>Let's plot random numbers</h1>
<div id="plot"></div>
<py-script output="plot">
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(1000)
y = np.random.randn(1000)
fig, ax = plt.subplots()
ax.scatter(x, y)
fig
</py-script>
</body>
</html>
```
### Local modules
In addition to packages you can declare local Python modules that will
be imported in the `<py-script>` tag. For example, we can place the random
number generation steps in a function in the file `data.py`.
```python
# data.py
import numpy as np
def make_x_and_y(n):
x = np.random.randn(n)
y = np.random.randn(n)
return x, y
```
In the HTML tag `<py-env>` paths to local modules are provided in the
`paths:` key.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
<script defer src="https://pyscript.net/alpha/pyscript.js"></script>
<py-env>
- numpy
- matplotlib
- paths:
- /data.py
</py-env>
</head>
<body>
<h1>Let's plot random numbers</h1>
<div id="plot"></div>
<py-script output="plot">
import matplotlib.pyplot as plt
from data import make_x_and_y
x, y = make_x_and_y(n=1000)
fig, ax = plt.subplots()
ax.scatter(x, y)
fig
</py-script>
</body>
</html>
```

View File

@@ -1,6 +1,6 @@
# Governance Policy # Governance Policy
This document provides the governance policy for the Project. Maintainers agree to this policy and to abide by all Project polices, including the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md), [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md), and [antitrust policy](https://github.com/pyscript/governance/blob/main/ANTITRUST.md) by adding their name to the [maintainers.md file](./MAINTAINERS.md). This document provides the governance policy for the Project. Maintainers agree to this policy and to abide by all Project policies, including the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md), [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md), and [antitrust policy](https://github.com/pyscript/governance/blob/main/ANTITRUST.md) by adding their name to the [maintainers.md file](https://github.com/pyscript/pyscript/blob/main/MAINTAINERS.md).
## 1. Roles. ## 1. Roles.

View File

@@ -1,17 +1,23 @@
# Maintainers # Maintainers
This document lists the Maintainers of the Project. Maintainers may be added once approved by the existing maintainers as described in the [Governance document](./GOVERNANCE.md). By adding your name to this list you are agreeing to abide by the Project governance documents and to abide by all of the Organization's polices, including the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md), [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md), and [antitrust policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md). If you are participating because of your affiliation with another organization (designated below), you represent that you have the authority to bind that organization to these policies. This document lists the Maintainers of the Project. Maintainers may be added once approved by the existing maintainers as described in the [Governance document](https://github.com/pyscript/pyscript/blob/main/GOVERNANCE.md). By adding your name to this list you are agreeing to abide by the Project governance documents and to abide by all of the Organization's polices, including the [code of conduct](https://github.com/pyscript/governance/blob/main/CODE-OF-CONDUCT.md), [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md), and [antitrust policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md). If you are participating because of your affiliation with another organization (designated below), you represent that you have the authority to bind that organization to these policies.
| **NAME** | **Organization** | | **NAME** | **Organization** |
| --- | --- | | -------------------- | ---------------- |
| Fabio Pliger | Anaconda, Inc | | Fabio Pliger | Anaconda, Inc |
| Antonio Cuni | Anaconda, Inc | | Antonio Cuni | Anaconda, Inc |
| Philipp Rudiger | Anaconda, Inc | | Philipp Rudiger | Anaconda, Inc |
| Peter Wang | Anaconda, Inc | | Peter Wang | Anaconda, Inc |
| Kevin Goldsmith | Anaconda, Inc | | Kevin Goldsmith | Anaconda, Inc |
| Mariana Meireles | Anaconda, Inc | | Mariana Meireles | Anaconda, Inc |
| --- | --- | | Nicholas H.Tollervey | Anaconda, Inc |
| Madhur Tandon | Anaconda, Inc |
| Ted Patrick | Anaconda, Inc |
| Jeff Glass | --- |
| Paul Everitt | --- |
| Fabio Rosado | --- |
______________________________________________________________________
---
Part of MVG-0.1-beta. Part of MVG-0.1-beta.
Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/). Made with love by GitHub. Licensed under the [CC-BY 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/).

View File

@@ -3,38 +3,43 @@
## What is PyScript ## What is PyScript
### Summary ### Summary
PyScript is a Pythonic alternative to Scratch, JSFiddle, and other "easy to use" programming frameworks, with the goal of making the web a friendly, hackable place where anyone can author interesting and interactive applications.
To get started see [GETTING-STARTED](GETTING-STARTED.md). PyScript is a framework that allows users to create rich Python applications in the browser using HTML's interface and the power of [Pyodide](https://pyodide.org/en/stable/), [WASM](https://webassembly.org/), and modern web technologies.
For examples see [the pyscript folder](pyscriptjs). To get started see the [getting started tutorial](docs/tutorials/getting-started.md).
For examples see [here](examples).
### Longer Version ### Longer Version
PyScript is a meta project that aims to combine multiple open technologies into a framework that allows users to create sophisticated browser applications with Python. It integrates seamlessly with the way the DOM works in the browser and allows users to add Python logic in a way that feels natural both to web and Python developers. PyScript is a meta project that aims to combine multiple open technologies into a framework that allows users to create sophisticated browser applications with Python. It integrates seamlessly with the way the DOM works in the browser and allows users to add Python logic in a way that feels natural both to web and Python developers.
## Try PyScript ## Try PyScript
To try PyScript, import the appropriate pyscript files to your html page with: To try PyScript, import the appropriate pyscript files into the ```<head>``` tag of your html page with:
```html ```html
<link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" /> <head>
<script defer src="https://pyscript.net/alpha/pyscript.js"></script> <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
``` ```
You can then use PyScript components in your html page. PyScript currently implements the following elements: You can then use PyScript components in your html page. PyScript currently implements the following elements:
* `<py-script>`: can be used to define python code that is executable within the web page. The element itself is not rendered to the page and is only used to add logic * `<py-script>`: can be used to define python code that is executable within the web page. The element itself is not rendered to the page and is only used to add logic
* `<py-repl>`: creates a REPL component that is rendered to the page as a code editor and allows users to write executable code * `<py-repl>`: creates a REPL component that is rendered to the page as a code editor and allows users to write executable code
Check out the [pyscriptjs/examples](pyscriptjs/examples) folder for more examples on how to use it, all you need to do is open them in Chrome. Check out the [the examples directory](examples) folder for more examples on how to use it, all you need to do is open them in Chrome.
## How to Contribute ## How to Contribute
To contribute see the [CONTRIBUTING](CONTRIBUTING.md) document. Read the [contributing guide](CONTRIBUTING.md) to learn about our development process, reporting bugs and improvements, creating issues and asking questions.
## Resources ## Resources
* [Official docs](https://docs.pyscript.net)
* [Discussion board](https://community.anaconda.cloud/c/tech-topics/pyscript) * [Discussion board](https://community.anaconda.cloud/c/tech-topics/pyscript)
* [Home Page](https://pyscript.net/) * [Home Page](https://pyscript.net/)
* [Blog Post](https://engineering.anaconda.com/2022/04/welcome-pyscript.html) * [Blog Post](https://engineering.anaconda.com/2022/04/welcome-pyscript.html)
* [Discord Channel](https://discord.gg/BYB2kvyFwm)
## Notes ## Notes

18
TROUBLESHOOTING.md Normal file
View File

@@ -0,0 +1,18 @@
# Troubleshooting
This page is meant for troubleshooting common problems with PyScript.
## Table of contents:
* [Make Setup](#make-setup)
## Make setup
A lot of problems related to `make setup` are related to node and npm being outdated. Once npm and node are updated, `make setup` should work. You can follow the steps on the [npm documentation](https://docs.npmjs.com/try-the-latest-stable-version-of-npm) to update npm (the update command for Linux should work for Mac as well). Once npm has been updated you can continue to the instructions to update node below.
To update Node run the following commands in order (Most likely you'll be prompted for your user password, this is normal):
```
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
```

46
docs/Makefile Normal file
View File

@@ -0,0 +1,46 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
CONDA_ENV ?= _env
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
env := $(CONDA_ENV)
conda_run := conda run -p $(env)
setup:
@if [ -z "$${CONDA_SHLVL:+x}" ]; then echo "Conda is not installed." && exit 1; fi
$(CONDA_EXE) env $(shell [ -d $(env) ] && echo update || echo create) -p $(env) --file environment.yml
clean:
rm -rf $(BUILDDIR)
clean-all: clean
rm -rf $(env) *.egg-info
shell:
@export CONDA_ENV_PROMPT='<{name}>'
@echo 'conda activate $(env)'
htmlserve:
@echo 'visit docs at http://localhost:8080'
python -m http.server -d "$(BUILDDIR)/html/" 8080
livehtml:
sphinx-autobuild "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile setup clean clean-all shell
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

31
docs/README.md Normal file
View File

@@ -0,0 +1,31 @@
# PyScript documentation
Welcome to the PyScript documentation directory, where you can find
and contribute to discussions around PyScript and related topics.
## Getting started
Before you start contributing to the documentation, it's worthwhile to
take a look at the general contributing guidelines for the PyScript project. You can find these guidelines here
[Contributing Guidelines](https://github.com/pyscript/pyscript/blob/main/CONTRIBUTING.md)
## Documentation Principles
The PyScript documentation is based on a documentation framework called [Diátaxis](https://diataxis.fr/). This framework helps to solve the problem of structure in technical documentation and identifies four modes of documentation - **tutorials, how-to guides, technical reference and explanation**. Each one of these modes answers to a different user need, fulfills a different purpose and requires a different approach to its creation.
The picture below gives a good visual representation of that separation of concerns:
![pyodide-pyscript](./img/diataxis.png)
So, please keep that in mind when contributing to the project documentation. For more information on, make sure to check [their website](https://diataxis.fr/).
### Setup
The `docs` directory in the pyscript repository contains a
[Sphinx](https://www.sphinx-doc.org/) documentation project. Sphinx is a system
that takes plaintext files containing documentation written in Markdown, along with
static files like templates and themes, to build the static end result.
### Build
To learn how to build the docs, head over the [CONTRIBUTING](../CONTRIBUTING.md) page.

View File

@@ -0,0 +1,48 @@
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<style>
.pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: .2;
}
}
</style>
</head>
<body>
<h1>Let's plot random numbers</h1>
<div id="plot">
<div class="pulse" >
<p style='font-family: monospace sans-serif;'><big><big><big><big>&#10096;py&#10097;</big></big></big></big></p>
</div>
</div>
<py-config>
packages = [
"numpy",
"matplotlib"
]
</py-config>
<py-script>
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(1000)
y = np.random.randn(1000)
fig, ax = plt.subplots()
ax.scatter(x, y)
pyscript.write('plot', fig)
</py-script>
</body>
</html>

BIN
docs/_static/fonts/Hack-Bold.woff vendored Normal file

Binary file not shown.

BIN
docs/_static/fonts/Hack-BoldItalic.woff vendored Normal file

Binary file not shown.

BIN
docs/_static/fonts/Hack-Italic.woff vendored Normal file

Binary file not shown.

BIN
docs/_static/fonts/Hack-Regular.woff vendored Normal file

Binary file not shown.

16
docs/_static/images/pyscript.svg vendored Normal file
View File

@@ -0,0 +1,16 @@
<svg width="100%" viewBox="0 0 2057 974" xmlns="http://www.w3.org/2000/svg">
<g fill="#fda703" stroke="none" transform="translate(0 100)">
<path
d="M 1092.534 158.364 C 1095.764 169.589 1102.374 179.795 1107.224 190.364 C 1119.104 216.243 1131.874 241.728 1144.274 267.364 C 1179.204 339.56 1214.064 411.844 1248.314 484.364 C 1260.474 510.112 1273.154 535.617 1285.314 561.364 C 1290.014 571.319 1299.154 583.378 1300.684 594.364 C 1301.444 599.785 1296.944 606.478 1294.984 611.364 C 1289.004 626.289 1282.004 640.557 1273.734 654.364 C 1265.284 668.483 1256.704 683.257 1245.444 695.364 C 1237.304 704.123 1228.664 712.851 1218.534 719.31 C 1176.654 746.023 1130.104 739.811 1084.534 729.364 L 1084.534 796.364 C 1137.744 803.235 1191.744 806.988 1241.534 782.094 C 1291.224 757.25 1321.144 708.125 1345.794 660.364 C 1391.424 571.949 1425.474 477.074 1463.954 385.364 C 1484.774 335.759 1505.144 285.968 1525.954 236.364 C 1532.804 220.048 1539.454 203.643 1546.384 187.364 C 1550.314 178.14 1555.824 168.274 1557.534 158.364 L 1503.534 158.364 C 1498.104 158.364 1487.624 156.363 1482.924 159.392 C 1477.284 163.031 1474.824 176.375 1472.254 182.364 C 1463.294 203.198 1455.174 224.401 1446.524 245.364 C 1422.624 303.289 1398.764 361.248 1375.334 419.364 C 1365.024 444.923 1349.894 471.569 1343.534 498.364 L 1341.534 498.364 L 1326.784 467.364 L 1300.794 414.364 L 1219.784 248.364 L 1188.284 184.364 L 1174.894 159.392 L 1152.534 158.364 L 1092.534 158.364 Z">
</path>
<path
d="M 100.534 391.364 C 109.625 398.897 122.97 403.329 133.534 408.611 L 197.534 440.611 L 405.534 544.611 C 436.606 560.147 467.458 576.073 498.534 591.611 C 511.98 598.334 527.713 609.722 542.534 612.364 L 542.534 563.364 L 541.506 543.754 L 518.534 531.117 L 460.534 502.117 L 307.534 425.117 L 240.534 391.364 L 307.534 358.117 L 459.534 282.611 L 518.534 253.117 L 541.506 240.727 L 542.534 221.364 L 542.534 171.364 C 527.073 174.12 510.565 186.102 496.534 193.117 L 398.534 242.117 L 200.534 341.117 C 167.367 357.701 132.553 372.676 100.534 391.364 Z">
</path>
<path
d="M 1600.534 171.364 L 1600.534 220.364 C 1600.534 225.605 1598.654 235.422 1601.564 239.974 C 1605.194 245.662 1617.614 249.159 1623.534 252.117 L 1680.534 280.611 C 1730.924 305.806 1781.134 331.41 1831.534 356.611 C 1853.974 367.829 1877.404 384.412 1901.534 391.364 L 1901.534 393.364 C 1875.624 400.829 1849.674 418.049 1825.534 430.117 L 1679.534 503.117 C 1661.964 511.903 1644.564 521.567 1626.534 529.364 C 1619.964 532.203 1605.494 536.596 1601.564 542.754 C 1598.654 547.306 1600.534 557.122 1600.534 562.364 L 1600.534 612.364 L 1655.534 585.611 L 1763.534 531.611 L 1947.534 439.611 L 2041.534 392.364 C 2031.474 382.202 2012.324 376.511 1999.534 370.117 L 1907.534 324.117 L 1701.534 221.117 L 1635.534 188.117 C 1624.294 182.495 1612.624 174.847 1600.534 171.364 Z">
</path>
<path
d="M 704.534 384.364 C 704.534 374.13 702.051 360.064 705.503 350.364 C 710.589 336.071 722.183 321.459 731.164 309.364 C 737.516 300.809 743.992 292.429 750.959 284.364 C 786.81 242.863 854.576 189.488 905.519 239.403 C 931.848 265.201 939.204 301.065 941.623 336.364 C 946.631 409.413 926.04 491.22 860.534 532.928 C 811.862 563.917 757.912 556.382 704.534 545.364 Z M 705.534 259.364 L 704.534 259.364 L 704.534 158.364 L 628.534 158.364 L 628.534 789.364 L 704.534 789.364 L 704.534 613.364 C 728.157 613.38 751.915 618.29 775.534 619.325 C 816.206 621.106 857.009 614.508 893.534 596.116 C 989.069 548.011 1025.008 434.77 1024.535 335.364 C 1024.298 285.5 1013.766 232.452 979.364 194.364 C 968.209 182.013 954.851 171.287 940.534 162.816 C 875.388 124.27 794.704 158.21 745.534 207.364 C 730.887 222.007 713.84 240.114 705.534 259.364 Z">
</path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

1
docs/_static/redirect.html vendored Normal file
View File

@@ -0,0 +1 @@
<html><head><meta http-equiv="refresh" content="0; URL='/latest/'" /></head><body></body></html>

View File

@@ -0,0 +1 @@
../../../MAINTAINERS.md

View File

@@ -0,0 +1 @@
../../../GOVERNANCE.md

12
docs/concepts/index.md Normal file
View File

@@ -0,0 +1,12 @@
# Concepts
This section contains various topics that are higher-level and useful to know.
```{toctree}
---
maxdepth: 2
glob:
---
what-is-pyscript
governance/*
```

View File

@@ -0,0 +1,33 @@
# What is PyScript?
The PyScript library provides HTML tags for embedding and executing Python code in your browser. PyScript is built using [Pyodide](https://pyodide.org/en/stable/), the WebAssembly port of CPython, which is compiled using [Emscripten](https://emscripten.org/).
PyScript turns the browser into a code deployment tool that anyone can learn to use.
## Example
In this example, we are using the `<py-script>` HTML tag to generate a Matplotlib figure and display it as an image.
Click **Preview** to see the rendered HTML.
To try it in your browser, copy the code below into an online HTML editor like W3School's [Tryit Editor](https://www.w3schools.com/html/tryit.asp?filename=tryhtml_default_default), which allows you to modify, run, and even save your code. Watch the video below to see it in action!
```{youtube} ZtC7TCt_LhU
```
::::{tab-set}
:::{tab-item} HTML Source
```{literalinclude} ../_static/examples/what-is-pyscript.html
---
```
:::
:::{tab-item} Preview
```{raw} html
<iframe height="600px" width="100%" scrolling="auto" frameborder="0" src="../_static/examples/what-is-pyscript.html"></iframe>
```
:::
::::

103
docs/conf.py Normal file
View File

@@ -0,0 +1,103 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = "PyScript"
copyright = "(c) 2022, Anaconda, Inc."
author = "Anaconda, Inc."
language = "en"
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"myst_parser",
"sphinx_copybutton",
"sphinx_design",
"sphinx_togglebutton",
"sphinx_sitemap",
"sphinxemoji.sphinxemoji",
"sphinxcontrib.youtube",
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "_env", "README.md"]
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "pydata_sphinx_theme"
html_logo = "_static/images/pyscript.svg"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
# html_css_files = ["styles/custom.css"]
html_baseurl = os.environ.get("SPHINX_HTML_BASE_URL", "http://127.0.0.1:8000/")
sitemap_locales = [None]
sitemap_url_scheme = "{link}"
html_extra_path = ["robots.txt"]
html_theme_options = {
"github_url": "https://github.com/pyscript/pyscript",
"twitter_url": "https://twitter.com/pyscript_dev",
"icon_links_label": "Quick Links",
# "google_analytics_id": "G-XXXXXXXXXX",
"use_edit_page_button": True,
"show_nav_level": 2,
"external_links": [
# {"name": "GitHub repo", "url": "https://github.com/pyscript/pyscript"},
],
}
html_context = {
"default_mode": "dark",
"pygment_light_style": "tango",
"pygment_dark_style": "native",
"github_user": "pyscript",
"github_repo": "pyscript",
"github_version": "main",
"doc_path": "docs",
}
myst_enable_extensions = [
"dollarmath",
"amsmath",
"deflist",
"html_admonition",
"html_image",
"colon_fence",
"smartquotes",
"replacements",
]

View File

@@ -0,0 +1,30 @@
# Deprecation Cycle
Pyscript is under heavy development, which means that some things may change, and some features might need to be deprecated so you can use different alternative implementations.
This page describes the deprecation cycle for pyscript.
## Deprecation Steps
1. Remove usage of deprecated features from all examples.
2. Add warnings to all elements/features marked for deprecation.
3. Release a new version of pyscript with the deprecation warnings.
4. Next release, remove the deprecated features.
## Deprecation Warnings
Deprecation warnings are added to the codebase using the `showWarning` function from the `pyscriptjs.utils` module.
This function creates a warning banner on the page if any of the deprecated features was used. You can use HTML to write the message; ideally, you should provide an alternative to the deprecated feature.
### Example
```js
import {showWarning} from './utils'
showWarning(`
<p>
The <code>py-deprecated</code> tag is deprecated. Please use the <code>py-actual</code> tag instead. Please refer to <a href="#">this documentation page</a> for more information.
</p>
`, "html")
```

View File

@@ -0,0 +1,203 @@
# Developing Process
This document is intended to help you get started developing for pyscript, it assumes that you have [setup your development environment](setting-up-environment.md).
* First, make sure you are using the latest version of the pyscript main branch
```
git pull upstream main
```
* Update your fork with the latest changes
```
git push origin main
```
* Activate the conda environment (this environment will contain all the necessary dependencies)
```
conda activate pyscriptjs/env/
```
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **NOTE**: We are assuming you are in the root folder. If you are in the pyscriptjs you can run `conda activate env/` instead.
* Install pre-commit (you only need to do this once)
```
pre-commit install
```
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **NOTE**: On first run, pre-commit installs a bunch of hooks that will be run when you commit changes to your branch - this will make sure that your code is following our style (it will also lint your code automatically).
* Create a branch for the issue that you want to work on
```
git checkout -b <your branch name>
```
* Work on your change
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **NOTE**: If you are working on a python file, you may encounter linting issues when pre-commit runs. Pyscript uses [black](https://black.readthedocs.io/en/stable/) to fix any linting problems automatically. All you need to do is add the changes again and commit using your previous commit message (the previous one that failed didn't complete due to black formatting files).
* Run tests before pushing the changes
```
make tests
```
* When you make changes locally, double check that your contribution follows the PyScript formatting rules by running `npm run lint`. Note that in this case you're looking for the errors, <u>**NOT**</u> the warnings (Unless the warning is created by a local change). If an error is found by lint you should fix it <u>**before**</u> creating a pull request
## Rebasing changes
Sometimes you might be asked to rebase main into your branch. Please refer to this [section on git rebase from GitHub docs](https://docs.github.com/en/get-started/using-git/about-git-rebase).
If you need help with anything, feel free to reach out and ask for help!
## pytest quick guide
We make a heavy usage of `pytest`. Here is a quick guide and collection of
useful options:
- To run all tests in the current directory and subdirectories: `pytest`
- To run tests in a specific directory or file: `pytest path/to/dir/test_foo.py`
- `-s`: disables output capturing
- `--pdb`: in case of exception, enter a `(Pdb)` prompt so that you can
inspect what went wrong.
- `-v`: verbose mode
- `-x`: stop the execution as soon as one test fails
- `-k foo`: run only the tests whose full name contains `foo`
- `-k 'foo and bar'`
- `-k 'foo and not bar'`
## Running integration tests under pytest
`make test` is useful to run all the tests, but during the development is
useful to have more control on how tests are run. The following guide assumes
that you are in the directory `pyscriptjs/tests/integration/`.
#### To run all the integration tests, single or multi core
```
$ pytest -xv
...
test_00_support.py::TestSupport::test_basic[chromium] PASSED [ 0%]
test_00_support.py::TestSupport::test_console[chromium] PASSED [ 1%]
test_00_support.py::TestSupport::test_check_js_errors_simple[chromium] PASSED [ 2%]
test_00_support.py::TestSupport::test_check_js_errors_expected[chromium] PASSED [ 3%]
test_00_support.py::TestSupport::test_check_js_errors_expected_but_didnt_raise[chromium] PASSED [ 4%]
test_00_support.py::TestSupport::test_check_js_errors_multiple[chromium] PASSED [ 5%]
...
```
`-x` means "stop at the first failure". `-v` means "verbose", so that you can
see all the test names one by one. We try to keep tests in a reasonable order,
from most basic to most complex. This way, if you introduced some bug in very
basic things, you will notice immediately.
If you have the `pytest-xdist` plugin installed, you can run all the
integration tests on 4 cores in parallel:
```
$ pytest -n 4
```
#### To run a single test, headless
```
$ pytest test_01_basic.py -k test_pyscript_hello -s
...
[ 0.00 page.goto ] pyscript_hello.html
[ 0.01 request ] 200 - fake_server - http://fake_server/pyscript_hello.html
...
[ 0.17 console.info ] [py-loader] Downloading pyodide-0.21.3...
[ 0.18 request ] 200 - CACHED - https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.js
...
[ 3.59 console.info ] [pyscript/main] PyScript page fully initialized
[ 3.60 console.log ] hello pyscript
```
`-k` selects tests by pattern matching as described above. `-s` instructs
`pytest` to show the output to the terminal instead of capturing it. In the
output you can see various useful things, including network requests and JS
console messages.
#### To run a single test, headed
```
$ pytest test_01_basic.py -k test_pyscript_hello -s --headed
...
```
Same as above, but with `--headed` the browser is shown in a window, and you
can interact with it. The browser uses a fake server, which means that HTTP
requests are cached.
Unfortunately, in this mode source maps does not seem to work, and you cannot
debug the original typescript source code. This seems to be a bug in
playwright, for which we have a workaround:
```
$ pytest test_01_basic.py -k test_pyscript_hello -s --headed --no-fake-server
...
```
As the name implies, `-no-fake-server` disables the fake server: HTTP requests
are not cached, but source-level debugging works.
Finally:
```
$ pytest test_01_basic.py -k test_pyscript_hello -s --dev
...
```
`--dev` implies `--headed --no-fake-server`. In addition, it also
automatically open chrome dev tools.
#### Fake server, HTTP cache
By default, our test machinery uses a playwright router which intercepts and
cache HTTP requests, so that for example you don't have to download pyodide
again and again. This also enables the possibility of running tests in
parallel on multiple cores.
The cache is stored using the `pytest-cache` plugin, which means that it
survives across sessions.
If you want to temporarily disable the cache, the easiest thing is to use
`--no-fake-server`, which bypasses it completely.
If you want to clear the cache, you can use the special option
`--clear-http-cache`:
```
$ pytest --clear-http-cache
...
-------------------- SmartRouter HTTP cache --------------------
Requests found in the cache:
https://raw.githubusercontent.com/pyscript/pyscript/main/README.md
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/repodata.json
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.asm.js
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/micropip-0.1-py3-none-any.whl
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.asm.data
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.js
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide.asm.wasm
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyodide_py.tar
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/pyparsing-3.0.9-py3-none-any.whl
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/distutils.tar
https://cdn.jsdelivr.net/pyodide/v0.21.3/full/packaging-21.3-py3-none-any.whl
Cache cleared
```
**NOTE**: this works only if you are inside `tests/integration`, or if you
explicitly specify `tests/integration` from the command line. This is due to
how `pytest` decides to search for and load the various `conftest.py`.

12
docs/development/index.md Normal file
View File

@@ -0,0 +1,12 @@
# Development
This section contains various topics related to pyscript development.
```{toctree}
---
maxdepth: 1
---
setting-up-environment
deprecation-cycle
developing
```

View File

@@ -0,0 +1,69 @@
# Setting up your development environment
* Fork the repository - [quicklink](https://github.com/pyscript/pyscript/fork)
* Clone your fork of the project
```
git clone https://github.com/<your username>/pyscript
```
* Add the original project as your upstream (this will allow you to pull the latest changes)
```sh
git remote add upstream git@github.com:pyscript/pyscript.git
```
* cd into the `pyscriptjs` folder using the line below in your terminal (if your terminal is already in pyscript then use **cd pyscriptjs** instead)
```
cd pyscript/pyscriptjs
```
* Install the dependencies with the command below (you must have node >=16)
```
make setup
```
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **NOTE**: If `make setup` gives a node/npm version required error then go to [troubleshooting](https://github.com/pyscript/pyscript/blob/main/TROUBLESHOOTING.md)
* You can also run the examples locally by running the command below in your terminal
```
make examples
```
* Run ***npm run dev*** to build and run the dev server. This will also watch for changes and rebuild when a file is saved.
```
npm run dev
```
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; **NOTE**: To access your local build paste `http://localhost:8080` into your browser
Now that node and npm have both been updated `make setup` should work, and you can continue [setting up your local environment](setting-up-environment.md) without problems (hopefully).
## Setting up and building the docs
To build the documentation locally first make sure you are in the `docs` directory.
You'll need `make` and `conda` installed in your machine. The rest of the environment should be automatically download and created for you once you use the command:
```
make setup
```
Use `conda activate $environment_name` to activate your environment.
To add new information to the documentation make sure you conform with PyScript's code of conduct and with the general principles of Diataxis. Don't worry about reading too much on it, just do your best to keep your contributions on the correct axis.
Write your documentation files using [Markedly Structured Text](https://myst-parser.readthedocs.io/en/latest/syntax/optional.html), which is very similar to vanilla Markdown but with some addons to create the documentation infrastructure.
Once done, initialize a server to check your work:
```
make livehtml
```
Visible here: [http://127.0.0.1:8000](http://127.0.0.1:8000)

18
docs/environment.yml Normal file
View File

@@ -0,0 +1,18 @@
channels:
- conda-forge
- defaults
dependencies:
- python=3.9
- pip=20.2.2
- Sphinx=4.5.0
- myst-parser=0.17.2
- pydata-sphinx-theme
- sphinx-copybutton
- sphinx-design
- sphinx-togglebutton
- pip:
- sphinxemoji
- sphinx-sitemap
- sphinx-autobuild
- sphinxcontrib-youtube

3
docs/error.md Normal file
View File

@@ -0,0 +1,3 @@
# Not found!
The page that you looked for could not be found. If you think this is a mistake, please [open an issue](https://github.com/pyscript/pyscript/issues/new/)

35
docs/guides/asyncio.md Normal file
View File

@@ -0,0 +1,35 @@
# Using Async/Await and Asyncio
## {bdg-warning-line}`Deprecated` Implicit Coroutine Scheduling / Top-Level Await
In PyScript versions 2022.09.1 and earlier, \<py-script\> tags could be written in a way that enabled "Implicit Coroutine Scheduling." The keywords `await`, `async for` and `await with` were permitted to be used outside of `async` functions. Any \<py-script\> tags with these keywords at the top level were compiled into coroutines and automatically scheuled to run in the browser's event loop. This functionality was deprecated, and these keywords are no longer allowed outside of `async` functions.
To transition code from using top-level await statements to the currently-acceptable syntax, wrap the code into a coroutine using `async def()` and schedule it to run in the browser's event looping using `asyncio.ensure_future()` or `asyncio.create_task()`.
The following two pieces of code are functionally equivalent - the first only works in versions 2022.09.1, the latter is the currently acceptable equivalent.
```python
# This version is deprecated, since
# it uses 'await' outside an async function
<py-script>
import asyncio
for i in range(3):
print(i)
await asyncio.sleep(1)
</py-script>
```
```python
# This version is acceptable
<py-script>
import asyncio
async def main():
for i in range(3):
print(i)
await asyncio.sleep(1)
asyncio.ensure_future(main())
</py-script>
```

View File

@@ -0,0 +1,213 @@
# How to make HTTP requests using `PyScript`, in pure Python
[Pyodide](https://pyodide.org), the runtime that underlies `PyScript`, does not have the `requests` module
(or other similar modules) available by default, which are traditionally used to make HTTP requests in Python.
However, it is possible to make HTTP requests in Pyodide using the modern `JavaScript` `fetch` API
([docs](https://developer.mozilla.org/en-US/docs/Web/API/fetch)). This example shows how to make common HTTP request
(GET, POST, PUT, DELETE) to an API, using only Python code! We will use asynchronous functions with
async/await syntax, as concurrent code is preferred for HTTP requests.
The purpose of this guide is not to teach the basics of HTTP requests, but to show how to make them
from `PyScript` using Python, since currently, the common tools such as `requests` and `httpx` are not available.
## Fetch
The `fetch` API is a modern way to make HTTP requests. It is available in all modern browsers, and in Pyodide.
Although there are two ways to use `fetch`:
1) using `JavaScript` from `PyScript`
2) using Pyodide's Python wrapper,
`pyodide.http.pyfetch`
This example will only show how to use the Python wrapper. Still, the
[fetch documentation](https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters) is a useful reference, as its
parameters can be called from Python using the `pyfetch` wrapper.
## Pyodide.http, pyfetch, and FetchResponse
The [pyodide.http module](https://pyodide.org/en/stable/usage/api/python-api/http.html#module-pyodide.http) is a Python API
for dealing with HTTP requests. It provides the `pyfetch` function as a wrapper for the `fetch` API,
which returns a `FetchResponse` object whenever a request is made. Extra keyword arguments can be passed to `pyfetch`
which will be passed to the `fetch` API.
The returned object `FetchResponse` has familiar methods and properties
for dealing with the response, such as `json()` or `status`. See the
[FetchResponse documentation](https://pyodide.org/en/stable/usage/api/python-api/http.html#pyodide.http.FetchResponse)
for more information.
# Example
We will make async HTTP requests to [JSONPlaceholder](https://jsonplaceholder.typicode.com/)'s fake API using `pyfetch`.
First we write a helper function in pure Python that makes a request and returns the response. This function
makes it easier to make specific types of requests with the most common parameters.
## Python convenience function
```python
from pyodide.http import pyfetch, FetchResponse
from typing import Optional, Any
async def request(url: str, method: str = "GET", body: Optional[str] = None,
headers: Optional[dict[str, str]] = None, **fetch_kwargs: Any) -> FetchResponse:
"""
Async request function. Pass in Method and make sure to await!
Parameters:
url: str = URL to make request to
method: str = {"GET", "POST", "PUT", "DELETE"} from `JavaScript` global fetch())
body: str = body as json string. Example, body=json.dumps(my_dict)
headers: dict[str, str] = header as dict, will be converted to string...
Example, headers=json.dumps({"Content-Type": "application/json"})
fetch_kwargs: Any = any other keyword arguments to pass to `pyfetch` (will be passed to `fetch`)
Return:
response: pyodide.http.FetchResponse = use with .status or await.json(), etc.
"""
kwargs = {"method": method, "mode": "cors"} # CORS: https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
if body and method not in ["GET", "HEAD"]:
kwargs["body"] = body
if headers:
kwargs["headers"] = headers
kwargs.update(fetch_kwargs)
response = await pyfetch(url, **kwargs)
return response
```
This function is a wrapper for `pyfetch`, which is a wrapper for the `fetch` API. It is a coroutine function,
so it must be awaited. It also has type hints, which are not required, but are useful for IDEs and other tools.
The basic idea is that the `PyScript` will import and call this function, then await the response. Therefore,
the script containing this function must be importable by `PyScript`.
For this example, we will name the file containing the Python code `request.py` and place it in the same directory as the file
containing the html code, which is described below.
## `PyScript` HTML code
In this How-to, the HTML code is split into separate code blocks to enable context highlighting (coloring of the Python
code inside the html code block), but in reality it is all in the same file. The first part is a bare bones `PyScript`
html page, using the [community examples](https://github.com/pyscript/pyscript-collective/) set-up. The second part is
the actual Python code for HTTP requests, which is wrapped in `<py-script>` tags, while the third block has the
concluding html code.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>GET, POST, PUT, DELETE example</title>
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<py-config>
[[fetch]]
files = ["/request.py"]
</py-config>
</head>
<body><p>
Hello world request example! <br>
Here is the output of your request:
</p>
<py-script>
import asyncio
import json
from request import request # import our request function.
async def main():
baseurl = "https://jsonplaceholder.typicode.com"
# GET
headers = {"Content-type": "application/json"}
response = await request(f"{baseurl}/posts/2", method="GET", headers=headers)
print(f"GET request=> status:{response.status}, json:{await response.json()}")
# POST
body = json.dumps({"title": "test_title", "body": "test body", "userId": 1})
new_post = await request(f"{baseurl}/posts", body=body, method="POST", headers=headers)
print(f"POST request=> status:{new_post.status}, json:{await new_post.json()}")
# PUT
body = json.dumps({"id": 1, "title": "test_title", "body": "test body", "userId": 2})
new_post = await request(f"{baseurl}/posts/1", body=body, method="PUT", headers=headers)
print(f"PUT request=> status:{new_post.status}, json:{await new_post.json()}")
# DELETE
new_post = await request(f"{baseurl}/posts/1", method="DELETE", headers=headers)
print(f"DELETE request=> status:{new_post.status}, json:{await new_post.json()}")
asyncio.ensure_future(main())
</py-script>
<div>
<p>
You can also use other methods. See fetch documentation: <br>
https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters
</p>
</div>
<div>
<p>
See pyodide documentation for what to do with a FetchResponse object: <br>
https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.FetchResponse
</p>
</div>
</body>
</html>
```
## Explanation
### `py-config` tag for importing our Python code
The very first thing to notice is the `py-config` tag. This tag is used to import Python files into the `PyScript`.
In this case, we are importing the `request.py` file, which contains the `request` function we wrote above.
### `py-script` tag for making async HTTP requests.
Next, the `py-script` tag contains the actual Python code where we import `asyncio` and `json`,
which are required or helpful for the `request` function.
The `# GET`, `# POST`, `# PUT`, `# DELETE` blocks show examples of how to use the `request` function to make basic
HTTP requests. The `await` keyword is required not only for the `request` function, but also for certain methods of the
`FetchResponse` object, such as `json()`, meaning that the code is asynchronous and slower requests will not block the
faster ones.
### HTTP Requests
HTTP requests are a very common way to communicate with a server. They are used for everything from getting data from
a database, to sending emails, to authorization, and more. Due to safety concerns, files loaded from the
local file system are not accessible by `PyScript`. Therefore, the proper way to load data into `PyScript` is also
through HTTP requests.
In our example, we show how to pass in a request `body`, `headers`, and specify the request `method`, in order to make
`GET`, `POST`, `PUT`, and `DELETE` requests, although methods such as `PATCH` are also available. Additional
parameters for the `fetch` API are also available, which can be specified as keyword arguments passed to our helper
function or to `pyfetch`. See the
[fetch documentation](https://developer.mozilla.org/en-US/docs/Web/API/fetch#parameters) for more information.
HTTP requests are defined by standards-setting bodies in [RFC 1945](https://www.rfc-editor.org/info/rfc1945) and
[RFC 9110](https://www.rfc-editor.org/info/rfc9110).
# Conclusion
This tutorial demonstrates how to make HTTP requests using `pyfetch` and the `FetchResponse` objects. Importing Python
code/files into the `PyScript` using the `py-config` tag is also covered.
Although a simple example, the principals here can be used to create complex web applications inside of `PyScript`,
or load data into `PyScript` for use by an application, all served as a static HTML page, which is pretty amazing!
# API Quick Reference
## pyodide.http.pyfetch
### Usage
```python
await pyodide.http.pyfetch(url: str, **kwargs: Any) -> FetchResponse
```
Use `pyfetch` to make HTTP requests in `PyScript`. This is a wrapper around the `fetch` API. Returns a `FetchResponse`.
- [`pyfetch` Docs.](https://pyodide.org/en/stable/usage/api/python-api/http.html#pyodide.http.pyfetch)
## pyodide.http.FetchResponse
### Usage
```python
response: pyodide.http.FetchResponse = await <pyfetch call>
status = response.status
json = await response.json()
```
Class for handling HTTP responses. This is a wrapper around the `JavaScript` fetch `Response`. Contains common (async)
methods and properties for handling HTTP responses, such as `json()`, `url`, `status`, `headers`, etc.
- [`FetchResponse` Docs.](https://pyodide.org/en/stable/usage/api/python-api/http.html#pyodide.http.FetchResponse)

20
docs/guides/index.md Normal file
View File

@@ -0,0 +1,20 @@
# Guides
Welcome to the how-to documentation section for PyScript. If you've already
gained some experience with PyScript before and just need practical guides
to get your ideas realized, you can learn step by step how to use PyScript here.
```{note}
Please head over to the [tutorials](../tutorials/index.md) section if you're only getting started.
```
```{toctree}
---
maxdepth: 2
glob:
caption: 'Contents:'
---
passing-objects
http-requests
asyncio
```

View File

@@ -0,0 +1,295 @@
# How to Pass Objects from PyScript to Javascript (and Vice Versa)
[Pyodide](https://pyodide.org), the runtime that underlies PyScript, does a lot of work under the hood to translate objects between Python and JavaScript. This allows code in one language to access objects defined in the other.
This guide discusses how to pass objects between JavaScript and Python within PyScript. For more details on how Pyodide handles translating and proxying objects between the two languages, see the [Pyodide Type Translations Page](https://pyodide.org/en/stable/usage/type-conversions.html).
For our purposes, an 'object' is anything that can be bound to a variable (a number, string, object, [function](https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function), etc).
## JavaScript to PyScript
We can use the syntax `from js import ...` to import JavaScript objects directly into PyScript. Simple JavaScript objects are converted to equivalent Python types; these are called [implicit conversions](https://pyodide.org/en/stable/usage/type-conversions.html#implicit-conversions). More complicated objects are wrapped in [JSProxy](https://pyodide.org/en/stable/usage/type-conversions.html) objects to make them behave like Python objects.
`import js` and `from js import ...` [in Pyodide](https://pyodide.org/en/stable/usage/type-conversions.html#type-translations-using-js-obj-from-py) get objects from the [JavaScript globalThis scope](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis), so keep the[ rules of JavaScript variable scoping](https://www.freecodecamp.org/news/var-let-and-const-whats-the-difference/) in mind.
```html
<script>
name = "Guido" //A JS variable
// Define a JS Function
function addTwoNumbers(x, y){
return x + y;
}
</script>
```
```python
<py-script>
# Import and use JS function and variable into Python
from js import name, addTwoNumbers
print(f"Hello {name}")
print("Adding 1 and 2 in Javascript: " + str(addTwoNumbers(1, 2)))
</py-script>
```
## PyScript to JavaScript
### Using Pyodide's globals access
The [PyScript JavaScript module](../reference/modules/pyscript.md) exposes its underlying Pyodide runtime as `PyScript.runtime`, and maintains a reference to the [globals()](https://docs.python.org/3/library/functions.html#globals) dictionary of the Python namespace. Thus, any global variables in python are accessible in JavaScript at `PyScript.runtime.globals.get('my_variable_name')`
```html
<body>
<py-script>x = 42</py-script>
<button onclick="showX()">Click Me to Get 'x' from Python</button>
<script>
function showX(){
console.log(`In Python right now, x = ${pyscript.runtime.globals.get('x')}`)
}
</script>
</body>
```
Since [everything is an object](https://docs.python.org/3/reference/datamodel.html) in Python, this applies not only to user created variables, but also to classes, functions, built-ins, etc. If we want, we can even apply Python functions to JavaScript data and variables:
```html
<body>
<!-- Click this button to log 'Apple', 'Banana', 'Candy', 'Donut' by sorting in Python-->
<button onclick="sortInPython(['Candy', 'Donut', 'Apple', 'Banana'])">Sort In Python And Log</button>
<script>
function sortInPython(data){
js_sorted = pyscript.runtime.globals.get('sorted') //grab python's 'sorted' function
const sorted_data = js_sorted(data) //apply the function to the 'data' argument
for (const item of sorted_data){
console.log(item)
}
}
</script>
</body>
```
### Using JavaScript's eval()
There may be some situations where it isn't possible or ideal to use `PyScript.runtime.globals.get()` to retrieve a variable from the Pyodide global dictionary. For example, some JavaScript frameworks may take a function/Callable as an html attribute in a context where code execution isn't allowed (i.e. `get()` fails). In these cases, you can create JavaScript proxies of Python objects more or less "manually" using [JavaScript's eval() function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval), which executes a string as code much like [Python's eval()](https://docs.python.org/3/library/functions.html#eval).
First, we create a JS function `createObject` which takes an object and a string, then uses `eval()` to create a variable named after the string and bind it to that object. By calling this function from PyScript (where we have access to the Pyodide global namespace), we can bind JavaScript variables to Python objects without having direct access to that global namespace.
Include the following script tag anywhere in your html document:
```html
<script>
function createObject(object, variableName){
//Bind a variable whose name is the string variableName
// to the object called 'object'
let execString = variableName + " = object"
console.log("Running '" + execString + "'");
eval(execString)
}
</script>
```
This function takes a Python Object and creates a variable pointing to it in the JavaScript global scope.
### Exporting all Global Python Objects
We can use our new `createObject` function to "export" the entire Python global object dictionary as a JavaScript object:
```python
<py-script>
from js import createObject
from pyodide.ffi import create_proxy
createObject(create_proxy(globals()), "pyodideGlobals")
</py-script>
```
This will make all Python global variables available in JavaScript with `pyodideGlobals.get('my_variable_name')`.
(Since PyScript tags evaluate _after_ all JavaScript on the page, we can't just dump a `console.log(...)` into a `<script>` tag, since that tag will evaluate before any PyScript has a chance to. We need to delay accessing the Python variable in JavaScript until after the Python code has a chance to run. The following example uses a button with `id="do-math"` to achieve this, but any method would be valid.)
```python
<py-script>
# create some Python objects:
symbols = {'pi': 3.1415926, 'e': 2.7182818}
def rough_exponential(x):
return symbols['e']**x
class Circle():
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return symbols['pi'] * self.radius**2
</py-script>
```
```html
<input type="button" value="Log Python Variables" id="do-math">
<script>
document.getElementById("do-math").addEventListener("click", () => {
const exp = pyodideGlobals.get('rough_exponential');
console.log(`e squared is about ${exp(2)}`);
const c = pyodideGlobals.get('Circle')(4);
console.log(`The area of c is ${c.area}`);
});
</script>
```
#### Full example
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Exporting all Global Python Objects</title>
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<input type="button" value="Log Python Variables" id="do-math">
<py-script>
from js import createObject
from pyodide.ffi import create_proxy
createObject(create_proxy(globals()), "pyodideGlobals")
# create some Python objects:
symbols = {'pi': 3.1415926, 'e': 2.7182818}
def rough_exponential(x):
return symbols['e']**x
class Circle():
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return symbols['pi'] * self.radius**2
</py-script>
<script>
function createObject(object, variableName){
//Bind a variable whose name is the string variableName
// to the object called 'object'
let execString = variableName + " = object"
console.log("Running '" + execString + "'");
eval(execString)
}
document.getElementById("do-math").addEventListener("click", () => {
const exp = pyodideGlobals.get('rough_exponential');
console.log(`e squared is about ${exp(2)}`);
const c = pyodideGlobals.get('Circle')(4);
console.log(`The area of c is ${c.area}`);
});
</script>
</body>
</html>
```
### Exporting Individual Python Objects
We can also export individual Python objects to the JavaScript global scope if we wish.
(As above, the following example uses a button to delay the execution of the `<script>` until after the PyScript has run.)
```python
<py-script>
import js
from pyodide.ffi import create_proxy
# Create 3 python objects
language = "Python 3"
animals = ['dog', 'cat', 'bird']
multiply3 = lambda a, b, c: a * b * c
# js object can be named the same as Python objects...
js.createObject(language, "language")
# ...but don't have to be
js.createObject(create_proxy(animals), "animals_from_py")
# functions are objects too, in both Python and Javascript
js.createObject(create_proxy(multiply3), "multiply")
</py-script>
```
```html
<input type="button" value="Log Python Variables" id="log-python-variables">
<script>
document.getElementById("log-python-variables").addEventListener("click", () => {
console.log(`Nice job using ${language}`);
for (const animal of animals_from_py){
console.log(`Do you like ${animal}s? `);
}
console.log(`2 times 3 times 4 is ${multiply(2,3,4)}`);
});
</script>
```
#### Full example
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Exporting Individual Python Objects</title>
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
import js
from pyodide.ffi import create_proxy
# Create 3 python objects
language = "Python 3"
animals = ['dog', 'cat', 'bird']
multiply3 = lambda a, b, c: a * b * c
# js object can be named the same as Python objects...
js.createObject(language, "language")
# ...but don't have to be
js.createObject(create_proxy(animals), "animals_from_py")
# functions are objects too, in both Python and Javascript
js.createObject(create_proxy(multiply3), "multiply")
</py-script>
<input type="button" value="Log Python Variables" id="log-python-variables">
<script>
function createObject(object, variableName){
//Bind a variable whose name is the string variableName
// to the object called 'object'
let execString = variableName + " = object"
console.log("Running '" + execString + "'");
eval(execString)
}
document.getElementById("log-python-variables").addEventListener("click", () => {
console.log(`Nice job using ${language}`);
for (const animal of animals_from_py){
console.log(`Do you like ${animal}s? `);
}
console.log(`2 times 3 times 4 is ${multiply(2,3,4)}`);
});
</script>
</body>
</html>
```

BIN
docs/img/diataxis.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

57
docs/index.md Normal file
View File

@@ -0,0 +1,57 @@
# PyScript
Welcome to the PyScript documentation!
PyScript provides a way for you to run Python code directly in your browser, giving
anyone the ability to program without infrastructure barriers. Add an interactive
Python REPL directly to your website, share an interactive dashboard with a colleague
as an HTML file, or create a client-side Python-powered web application. This documentation
will show you how.
::::{grid} 2
:gutter: 3
:::{grid-item-card} [Tutorials](tutorials/index.md)
Just getting started with PyScript?
Check out our [getting started guide](tutorials/getting-started.md)!
:::
:::{grid-item-card} [Guides](guides/index.md)
You already know the basics and want to learn specifics!
[Passing Objects between JavaScript and Python](guides/passing-objects.md)
[Making async HTTP requests in pure Python](guides/http-requests.md)
[Async/Await and Asyncio](guides/asyncio.md)
:::
:::{grid-item-card} [Concepts](concepts/index.md)
[What is PyScript?](concepts/what-is-pyscript.md)
:::
:::{grid-item-card} [Reference](reference/index.md)
[Frequently asked questions](reference/faq.md)
[The PyScript JS Module](reference/modules/pyscript.md)
:::{toctree}
:maxdepth: 1
:::
::::
```{toctree}
---
maxdepth: 1
hidden:
---
tutorials/index
guides/index
concepts/index
reference/index
```

35
docs/make.bat Normal file
View File

@@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)
if "%1" == "" goto help
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd

View File

@@ -0,0 +1,8 @@
# `__version__`
`PyScript.__version__` is a `str` representing the current version of PyScript in a human-readable form. For a structured version more suitable to comparisons, and for details of what each part of the version number represents, see [`version_info`](version_info.md)
```shell
>>> pyscript.__version__
'2023.02.1.dev'
```

View File

@@ -0,0 +1,87 @@
# `display(*values, target=None, append=True)`
## Parameters
`*values` - the objects to be displayed. String objects are output as-written. For non-string objects, the default content to display is the the object's `repr()`. Objects may implement the following methods to indicate that they should be displayed as a different MIME type. MIME types with a * indicate that the content will be wrapped in the appropriate html tags and attributes before output:
| Method | Inferred MIME type |
|---------------------|------------------------|
| `__repr__` | text/plain |
| `_repr_html_` | text/html |
| `_repr_svg_` | image/svg+xml |
| `_repr_png_` | image/png* |
| `_repr_pdf_` | application/pdf |
| `_repr_jpeg_` | image/jpeg* |
| `_repr_json_` | application/json |
| `_repr_javascript_` | application/javascript*|
| `savefig` | image/png |
| | |
`target` - Element's ID. The default value for `target` is the current `py-script` tag ID, it's possible to specify different IDs for this parameter
`append` - `boolean` if the output is going to be appended or not to the `target`ed element. It creates a `<div>` tag if `True` and a `<py-script>` tag with a random ID if `False`. The default value for `append` is `True`.
### Description
Display is the default function to display objects on the screen. Functions like the Python `print()` or JavaScript `console.log()` are now defaulted to only appear on the terminal.
Display will throw an exception if the target is not clear. E.g. the following code is invalid:
```html
<py-script>
def display_hello():
# this fails because we don't have any implicit target
# from event handlers
display('hello')
</py-script>
<button id="my-button" py-onClick="display_hello()">Click me</button>
```
Because it's considered unclear if the `hello` string should be displayed underneath the `<py-script>` tag or the `<button>` tag.
To write compliant code, make sure to specify the target using the `target` parameter, for example:
```html
<py-script>
def display_hello():
# this fails because we don't have any implicit target
# from event handlers
display('hello', target="helloDiv")
</py-script>
<div id="helloDiv"></div>
<button id="my-button" py-onClick="display_hello()">Click me</button>
```
#### Using matplotlib with display
`matplotlib` has two ways of plotting things as mentioned [here](https://matplotlib.org/matplotblog/posts/pyplot-vs-object-oriented-interface/)
- In case of using the `pyplot` interface, the graph can be shown using `display(plt)`.
```python
import matplotlib.pyplot as plt
import numpy as np
# Data for plotting
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
plt.plot(t,s)
display(plt)
```
- In case of using the `object oriented` interface, the graph can be shown using `display(fig)` or `display(plt)` both.
```python
import matplotlib.pyplot as plt
import numpy as np
# Data for plotting
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
fig, ax = plt.subplots()
ax.plot(t, s)
display(fig) # but even display(plt) would have worked!
```

View File

@@ -0,0 +1,309 @@
# `Element`
The `Element` API is a helpful way to create and manipulate elements in the DOM. It is a wrapper around the native DOM API, and is designed to be as intuitive as possible.
## Methods and Properties
| Property | Description |
|----------|-----------------------------------------|
| `element` | Returns the element with the given ID. |
| `id` | Returns the element's ID. |
| `value` | Returns the element's value. |
| `innerHtml` | Returns the element's inner HTML. |
| Method | Description |
|----------------------|--------------------------------------------------------------|
| `write` | Writes `value` to element and handles various mime types. `append` defaults to `False`, if set to true, it will create a child element. |
| `clear` | Clears the element's value or content. |
| `select` | Select element from `query` which uses [Document.querySelector()](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector). |
| `clone` | Clones the with `new_id` if provided and `to` element if provided. |
| `remove_class` | Removes one or more class name from the element. |
| `add_class` | Adds one or more class name to the element. |
## Element.element
| Parameter | Default | Type |
|-----------|---------|------|
| | | |
The `element` property returns the DOM element with the given ID.
```html
from pyscript import Element
my_div = Element('my-div')
print(my_div.element)
```
## Element.id
| Parameter | Default | Type |
|-----------|---------|------|
| | | |
Return the element's ID.
```html
<div id="my-div"></div>
<py-script>
from pyscript import Element
my_div = Element('my-div')
print(my_div.id) # prints 'my-div'
</py-script>
```
## Element.value
| Parameter | Default | Type |
|-----------|---------|------|
| | | |
Return the element's value.
```html
<input id="my-input" value="hello world"></input>
<py-script>
from pyscript import Element
my_input = Element('my-input')
print(my_input.value) # prints 'hello world'
</py-script>
```
## Element.innerHtml
| Parameter | Default | Type |
|-----------|---------|------|
| | | |
Return the element's inner HTML.
```html
<div id="my-innerHtml">
<b>hello world</b>
</div>
<py-script>
from pyscript import Element
my_innerHtml = Element('my-innerHtml')
print(my_innerHtml.innerHtml) # prints <b> hello world </b>
</py-script>
```
## Element.write
| Parameter | Default | Type |
|-------------|---------|-----------------------------|
| `value` | | `str` or `__mime_type__` |
| `append` | False | `bool` |
Writes `value` to element and handles various mime types. This method also contains a `append` parameter, which defaults to `False`.
Currently, these are the MIME types that are supported when rendering content using this method
| Method | Inferred MIME type |
|---------------------|------------------------|
| `__repr__` | text/plain |
| `_repr_html_` | text/html |
| `_repr_svg_` | image/svg+xml |
| `_repr_png_` | image/png* |
| `_repr_pdf_` | application/pdf |
| `_repr_jpeg_` | image/jpeg* |
| `_repr_json_` | application/json |
| `_repr_javascript_` | application/javascript*|
| `savefig` | image/png |
```html
<div id="foo"></div>
<py-script>
from pyscript import Element
el = Element("foo")
el.write("Hello!")
el.write("World!") # will replace the previous content
</py-script>
```
If we set `append` to `True`, it will create a child element using a `div`.
```html
<div id="foo"></div>
<py-script>
from pyscript import Element
el = Element("foo")
el.write("Hello!", append=True)
# This will create a child div with the id "foo-1"
el.write("World!", append=True)
</py-script>
```
## Element.clear
| Parameter | Default | Type |
|-----------|---------|------|
| | | |
Clears the element's value or content. For example, we can clear the value of an input element.
```html
<input id="foo" value="Hello!"></input>
<py-script>
from pyscript import Element
el = Element("foo")
el.clear() # Removes value from input
</py-script>
```
Or we can clear the content of a div element.
```html
<div id="foo">Hello!</div>
<py-script>
from pyscript import Element
el = Element("foo")
el.clear() # Removes Hello from div content
</py-script>
```
## Element.select
Select element from `query`, it will look into the main Element if `from_content` is `True`. This method is a wrapper of [Document.querySelector()](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector).
```html
<div id="foo">
<div id="bar"></div>
</div>
<py-script>
from pyscript import Element
el = Element("foo")
bar = el.select("#bar")
print(bar.id) # prints 'bar'
</py-script>
```
## Element.clone
| Parameter | Default | Type |
|-------------|---------|-----------|
| `new_id` | None | `str` |
| `to` | None | `Element` |
Clones the element to a new element. You can provide `new_id` to set a different id to the cloned element. You can also use a `to` element to append the cloned element to.
```html
<div id="foo">
HI!
</div>
<py-script>
from pyscript import Element
el = Element("foo")
# Creates two divs with the id "foo" and content "HI!"
el.clone()
</py-script>
```
It's always a good idea to pass a new id to the element you are cloning to avoid confusion if you need to reference the element by id again.
```html
<div id="foo">Hello!</div>
<py-script>
from pyscript import Element
el = Element("foo")
# Clones foo and its contents, but uses the id 'bar'
el.clone(new_id="bar")
</py-script>
```
You can also clone an element into another element.
```html
<div id="bond">
Bond
</div>
<div id="james">
James
</div>
<py-script>
from pyscript import Element
bond_div = Element("bond")
james_div = Element("james")
bond_div.clone(new_id="bond-2", to=james_div)
</py-script>
```
## Element.remove_class
| Parameter | Default | Type |
|-------------|---------|-----------------------|
| `classname` | None | `str` or `List[str]` |
Removes one or more class names from the element.
```html
<div id="foo" class="bar baz"></div>
<py-script>
from pyscript import Element
el = Element("foo")
el.remove_class("bar")
</py-script>
```
You can also remove multiple classes by passing a list of strings.
```html
<div id="foo" class="bar baz"></div>
<py-script>
from pyscript import Element
el = Element("foo")
el.remove_class(["bar", "baz"]) # Remove all classes from element
</py-script>
```
## Element.add_class
| Parameter | Default | Type |
|-------------|---------|-----------------------|
| `classname` | None | `str` or `List[str]` |
Adds one or more class names to the element.
```html
<style> .red { color: red; } </style>
<div id="foo">Hi!</div>
<py-script>
from pyscript import Element
el = Element("foo")
el.add_class("red")
</py-script>
```
You can also add multiple classes at once by passing a list of strings.
```html
<style> .red { color: red; } .bold { font-weight: bold; } </style>
<div id="foo">Hi!</div>
<py-script>
from pyscript import Element
el = Element("foo")
el.add_class(["red", "bold"])
</py-script>
```

View File

@@ -0,0 +1,16 @@
# `version_info`
`PyScript.version_info` is a `namedtuple` representing the current version of PyScript. It can be used to compare whether current version precedes or follows a desired version. For a human-readable version of the same info, see [`__version__`](__version__.md)
```sh
>>> pyscript.version_info
version_info(year=2023, month=2, minor=1, releaselevel='dev')
```
## Version Fields
| **parameter** | **CalVer equivalent field** | **example value** | **description** |
|-----------------|-----------------------------|---------------|------------------------------------------------------------------------------------------------------------------------------------------|
| `year` | Full year (YYYY) | 2023 | The year of the release; when printed or represented as a string, always written with 4 digits |
| `month` | Short Month (MM) | 2 | The month of the release; when printed or represented as a string, written with 1 or 2 digits as necessary |
| `minor` | | 1 | The incremental number of the release for this month; when printed or represented as a string, written with 1 or two digits as necessary |
| `releaselevel` | | 'dev' | A string representing the qualifications of this build |

View File

@@ -0,0 +1,487 @@
# &lt;py-config&gt;
Use the `<py-config>` tag to set and configure general metadata along with declaring dependencies for your PyScript application. The configuration has to be set in either [TOML](https://toml.io/)(default) or [JSON](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON) format.
If you are unfamiliar with TOML, consider [reading about it](https://learnxinyminutes.com/docs/toml/) or if you are unfamiliar with JSON, consider reading [freecodecamp's JSON for beginners](https://www.freecodecamp.org/news/what-is-json-a-json-file-example/) guide for more information.
The `<py-config>` element should be placed within the `<body>` element.
## Attributes
| attribute | type | default | description |
|-----------|--------|---------|---------------------------------------------------------------------------------------------------------|
| **type** | string | "toml" | Syntax type of the `<py-config>`. Value can be `json` or `toml`. Default: "toml" if type is unspecifed. |
| **src** | url | | Source url to an external configuration file. |
## Examples
### Defining an inline config
- `<py-config>` using TOML (default)
```{note}
Reminder: when using TOML, any Arrays of Tables defined with double-brackets (like `[[runtimes]]` and `[[fetch]]` must come after individual keys (like `plugins = ...` and `packages=...`)
```
```html
<py-config>
[splashscreen]
autoclose = true
[[runtimes]]
src = "https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js"
name = "pyodide-0.21.2"
lang = "python"
</py-config>
```
- `<py-config>` using JSON via `type` attribute
```html
<py-config type="json">
{
"splashscreen": {
"autoclose": true
},
"runtimes": [{
"src": "https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js",
"name": "pyodide-0.21.2",
"lang": "python"
}]
}
</py-config>
```
### Defining a file based config
- Use of the `src` attribute
```html
<py-config src="./custom.toml"></py-config>
```
where `custom.toml` contains
```toml
[splashscreen]
autoclose = true
[[runtimes]]
src = "https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js"
name = "pyodide-0.21.2"
lang = "python"
```
- JSON using the `type` and `src` attribute
```html
<py-config type="json" src="./custom.json"></py-config>
```
where `custom.json` contains
```json
{
"splashscreen": {
"autoclose": true,
},
"runtimes": [{
"src": "https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js",
"name": "pyodide-0.21.2",
"lang": "python"
}]
}
```
### Mixing inline and file based configs
One can also use both i.e pass the config from `src` attribute as well as specify it as `inline`. So the following snippet is also valid:
```html
<py-config src="./custom.toml">
[[fetch]]
files = ["./utils.py"]
</py-config>
```
This can also be done via JSON using the `type` attribute.
```html
<py-config type="json" src="./custom.json">
{
"fetch": [{
"files": ["./utils.py"]
}]
}
</py-config>
```
Note: While the `<py-config>` tag supports both TOML and JSON, one cannot mix the type of config passed from 2 different sources i.e. the case when inline config is in TOML format while config from src is in JSON format is NOT allowed. Similarly for the opposite case.
---
This is helpful in cases where a number of applications share a common configuration (which can be supplied via `src`), but their specific keys need to be customised and overridden.
The keys supplied through `inline` override the values present in config supplied via `src`.
## Dependencies and Packages
One can also declare dependencies so as to get access to many 3rd party OSS packages that are supported by PyScript.
You can also link to `.whl` files directly on disk like in our [toga example](https://github.com/pyscript/pyscript/blob/main/examples/toga/freedom.html).
Package dependencies in the `<py-config>` can be declared by using the direct link to the package URL (whl or any other format supported by the chosen runtime) or by just providing the package name [and version]. If only the name [and version] are provided, packages will be installed directly from what's provided by your runtime or from PyPI.
NOTICE that only pure python packages from PyPI will work and packages with C dependencies will not. These need to be built specifically for WASM (please, consult the Pyodide project for more information about what's supported and on how to build packages with C dependencies)
```html
<py-config>
packages = ["./static/wheels/travertino-0.1.3-py3-none-any.whl"]
</py-config>
```
OR in JSON like
```html
<py-config type="json">
{
"packages": ["./static/wheels/travertino-0.1.3-py3-none-any.whl"]
}
</py-config>
```
If your `.whl` is not a pure Python wheel, then open a PR or issue with [pyodide](https://github.com/pyodide/pyodide) to get it added [here](https://github.com/pyodide/pyodide/tree/main/packages).
If there's enough popular demand, the pyodide team will likely work on supporting your package. Regardless, things will likely move faster if you make the PR and consult with the team to get unblocked.
For example, NumPy and Matplotlib are available. Notice here we're using `display(fig, target="plot")`, which takes the graph and displays it in the element with the id `plot`.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<h1>Let's plot random numbers</h1>
<div id="plot"></div>
<py-config type="json">
{
"packages": ["numpy", "matplotlib"]
}
</py-config>
<py-script>
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(1000)
y = np.random.randn(1000)
fig, ax = plt.subplots()
ax.scatter(x, y)
display(fig, target="plot")
</py-script>
</body>
</html>
```
## Local modules
In addition to packages, you can declare local Python modules that will
be imported in the `<py-script>` tag. For example, we can place the random
number generation steps in a function in the file `data.py`.
```python
# data.py
import numpy as np
def make_x_and_y(n):
x = np.random.randn(n)
y = np.random.randn(n)
return x, y
```
In the HTML tag `<py-config>`, paths to local modules are provided in the
`files` key within the `fetch` section. Refer to the [fetch](#fetch) section for
more details.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<h1>Let's plot random numbers</h1>
<div id="plot"></div>
<py-config type="toml">
packages = ["numpy", "matplotlib"]
[[fetch]]
files = ["./data.py"]
</py-config>
<py-script>
import matplotlib.pyplot as plt
from data import make_x_and_y
x, y = make_x_and_y(n=1000)
fig, ax = plt.subplots()
ax.scatter(x, y)
display(fig, target="plot")
</py-script>
</body>
</html>
```
## Supported configuration values
The following optional values are supported by `<py-config>`:
| Value | Type | Description |
| ------ | ---- | ----------- |
| `name` | string | Name of the user application. This field can be any string and is to be used by the application author for their own customization purposes. |
| `description` | string | Description of the user application. This field can be any string and is to be used by the application author for their own customization purposes. |
| `version` | string | Version of the user application. This field can be any string and is to be used by the application author for their own customization purposes. It is not related to the PyScript version. |
| `schema_version` | number | The version of the config schema which determines what all keys are supported. This can be supplied by the user so PyScript knows what to expect in the config. If not supplied, the latest version for the schema is automatically used. |
| `type` | string | Type of the project. The default is an "app" i.e. a user application |
| `author_name` | string | Name of the author. |
| `author_email` | string | Email of the author. |
| `license` | string | License to be used for the user application. |
| `autoclose_loader` | boolean | If false, PyScript will not close the loading splash screen when the startup operations finish. |
| `packages` | List of Packages | Dependencies on 3rd party OSS packages are specified here. The default value is an empty list. |
| `fetch` | List of Stuff to fetch | Local Python modules OR resources from the internet are to be specified here using a Fetch Configuration, described below. The default value is an empty list. |
| `plugins` | List of Plugins | List of Plugins are to be specified here. The default value is an empty list. |
| `runtimes` | List of Runtimes | List of runtime configurations, described below. The default value contains a single Pyodide based runtime. |
### <a name="fetch">Fetch</a>
A fetch configuration consists of the following:
| Value | Type | Description |
|--------------|-----------------|-------------------------------------------------|
| `from` | string | Base URL for the resource to be fetched. |
| `to_folder` | string | Name of the folder to create in the filesystem. |
| `to_file` | string | Name of the target to create in the filesystem. |
| `files` | List of strings | List of files to be downloaded. |
The parameters `to_file` and `files` shouldn't be supplied together.
#### Mechanism
The `fetch` mechanism works in the following manner:
- If both `files` and `to_file` parameters are supplied: Error!
- `from` defaults to an empty string i.e. `""` to denote relative URLs of the serving directory
- `to_folder` defaults to `.` i.e. the current working directory of the filesystem
- If `files` is specified
- for each `file` present in the `files` array
- the `sourcePath` is calculated as `from + file`
- the `destination` is calculated as `to_folder + file`
- thus, the object is downloaded from `sourcePath` to `destination`
- Else i.e. `files` is NOT specified
- If `to_file` is specified
- the object is downloaded from `from` to `to_folder + to_file`
- Otherwise, calculate the `filename` at the end of `from` i.e. the part after last `/`
- the object is downloaded from `from` to `to_folder + filename at the end of 'from'`
Learn more about `fetch` on PyScript [here](https://jeff.glass/post/whats-new-pyscript-2022-12-1)
#### Use-Cases
Assumptions:
The directory being served has the following tree structure:
```
content/
├─ index.html <<< File with <py-config>
├─ info.txt
├─ data/
│ ├─ sensordata.csv
├─ packages/
│ ├─ my_package/
│ │ ├─ __init__.py
│ │ ├─ helloworld/
│ │ │ ├─ __init__.py
│ │ │ ├─ greetings.py
```
1. Fetching a single file
```html
<py-config>
[[fetch]]
files = ['info.txt']
</py-config>
```
```html
<py-script>
with open('info.txt', 'r') as fp:
print(fp.read())
</py-script>
```
2. Single File with Renaming
```html
<py-config>
[[fetch]]
from = 'info.txt'
to_file = 'info_loaded_from_web.txt'
</py-config>
```
```html
<py-script>
with open('info_loaded_from_web.txt', 'r') as fp:
print(fp.read())
</py-script>
```
3. Single File to another Directory
```html
<py-config>
[[fetch]]
files = ['info.txt']
to_folder = 'infofiles/loaded_info'
</py-config>
```
```html
<py-script>
with open('infofiles/loaded_info/info.txt', 'r') as fp:
print(fp.read())
</py-script>
```
4. Single File to another Directory with Renaming
```html
<py-config>
[[fetch]]
from = 'info.txt'
to_folder = 'infofiles/loaded_info'
to_file = 'info_loaded_from_web.txt'
</py-config>
```
```html
<py-script>
with open('infofiles/loaded_info/info_loaded_from_web.txt', 'r') as fp:
print(fp.read())
</py-script>
```
5. Single file from a folder to the current working directory
```html
<py-config>
[[fetch]]
from = 'data/'
files = ['sensordata.csv']
</py-config>
```
```html
<py-script>
with open('./sensordata.csv', 'r') as fp:
print(fp.read())
</py-script>
```
6. Single file from a folder to another folder (i.e. not the current working directory)
```html
<py-config>
[[fetch]]
from = 'data/'
to_folder = './local_data'
files = ['sensordata.csv']
</py-config>
```
```html
<py-script>
with open('./local_data/sensordata.csv', 'r') as fp:
print(fp.read())
</py-script>
```
7. Multiple files preserving directory structure
```html
<py-config>
[[fetch]]
from = 'packages/my_package/'
files = ['__init__.py', 'helloworld/greetings.py', 'helloworld/__init__.py']
to_folder = 'custom_pkg'
</py-config>
```
```html
<py-script>
from custom_pkg.helloworld.greetings import say_hi
print(say_hi())
</py-script>
```
8. From an API endpoint which doesn't end in a filename
```html
<py-config>
[[fetch]]
from = 'https://catfact.ninja/fact'
to_file = './cat_fact.json'
</py-config>
```
```html
<py-script>
import json
with open("cat_fact.json", "r") as fp:
data = json.load(fp)
</py-script>
```
### Runtime
A runtime configuration consists of the following:
| Value | Type | Description |
|--------|-------------------|-------------|
| `src` | string (Required) | URL to the runtime source. |
| `name` | string | Name of the runtime. This field can be any string and is to be used by the application author for their own customization purposes |
| `lang` | string | Programming language supported by the runtime. This field can be used by the application author to provide clarification. It currently has no implications on how PyScript behaves. |
#### Example
- The default runtime is `pyodide`, another version of which can be specified as following
```html
<py-config>
[[runtimes]]
src = "https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js"
name = "pyodide-0.20.0"
lang = "python"
</py-config>
```
## Supplying extra information (or metadata)
Besides the above schema, a user can also supply any extra keys and values that are relevant as metadata information or perhaps are being used within the application.
For example, a valid config could also be with the snippet below:
```html
<py-config type="toml">
magic = "unicorn"
</py-config>
```
OR in JSON like
```html
<py-config type="json">
{
"magic": "unicorn"
}
</py-config>
```
If this `"magic"` key is present in config supplied via `src` and also present in config supplied via `inline`, then the value in the inline config is given priority i.e. the overriding process also works for custom keys.

View File

@@ -0,0 +1,30 @@
# &lt;py-repl&gt;
The `<py-repl>` element provides a REPL(Read Eval Print Loop) to evaluate multi-line Python and display output.
## Attributes
| attribute | type | default | description |
|-------------------|---------|---------|---------------------------------------|
| **auto-generate** | boolean | | Auto-generates REPL after evaluation |
| **output** | string | | The element to write output into |
### Examples
#### `<py-repl>` element set to auto-generate
```html
<py-repl auto-generate="true"> </py-repl>
```
#### `<py-repl>` element with output
```html
<div id="replOutput"></div>
<py-repl output="replOutput">
hello = "Hello world!"
hello
</py-repl>
```
Note that if we `print` any element in the repl, the output will be printed in the [`py-terminal`](../plugins/py-terminal.md) if is enabled.

View File

@@ -0,0 +1,111 @@
# &lt;py-script&gt;
The `<py-script>` element lets you execute multi-line Python scripts both inline and via a src attribute.
## Attributes
| attribute | type | default | description |
|-----------|------|---------|------------------------------|
| **src** | url | | Url of a python source file. |
## Examples
### Inline `<py-script>` element
Let's execute this multi-line Python script to compute π and print it back onto the page
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
print("Let's compute π:")
def compute_pi(n):
pi = 2
for i in range(1,n):
pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
return pi
pi = compute_pi(100000)
s = f"π is approximately {pi:.3f}"
print(s)
</py-script>
</body>
</html>
```
### Using `<py-script>` element with `src` attribute
we can also move our python code to its own file and reference it via the `src` attribute.
```python
# compute_pi.py
print("Let's compute π:")
def compute_pi(n):
pi = 2
for i in range(1,n):
pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
return pi
pi = compute_pi(100000)
s = f"π is approximately {pi:.3f}"
print(s)
```
Since both compute_pi.py and index.html are in the same directory, we can reference the python file with a relative path.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script src="compute_pi.py"></py-script>
</body>
</html>
```
### Writing into labeled elements
In the example above, we had a single `<py-script>` tag printing
one or more lines onto the page in order. Within the `<py-script>`, you can
use the `Element` class to create a python object for interacting with
page elements. Objects created from the `Element` class provide the `.write()` method
which enables you to send strings into the page elements referenced by those objects.
For example, we'll add some style elements and provide placeholders for
the `<py-script>` tag to write to.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
</head>
<body>
<b><p>Today is <u><label id='today'></label></u></p></b>
<br>
<div id="pi" class="alert alert-primary"></div>
<py-script>
import datetime as dt
Element('today').write(dt.date.today().strftime('%A %B %d, %Y'))
def compute_pi(n):
pi = 2
for i in range(1,n):
pi *= 4 * i ** 2 / (4 * i ** 2 - 1)
return pi
pi = compute_pi(100000)
Element('pi').write(f'π is approximately {pi:.3f}')
</py-script>
</body>
</html>
```

View File

@@ -0,0 +1,39 @@
# Exceptions and error codes
When creating pages with PyScript, you may encounter exceptions. Each handled exception will contain a specific code which will give you more information about it.
This reference guide contains the error codes you might find and a description of each of them.
## User Errors
| Error code | Description | Recommendation |
|------------|--------------------------------|--------------------|
| PY1000 | Invalid configuration supplied | Confirm that your `py-config` tag is using a valid `TOML` or `JSON` syntax and is using the correct configuration type. |
| PY1001 | Unable to install package(s) | Confirm that the package contains a pure Python 3 wheel or the name of the package is correct. |
| PY9000 | Top level await is deprecated | Create a coroutine with your code and schedule it with `asyncio.ensure_future` or similar |
## Fetch Errors
These error codes are related to any exception raised when trying to fetch a resource. If, while trying to fetch a resource, we encounter a status code that is not 200, the error code will contain the HTTP status code and the `PY0` prefix. For example, if we encounter a 404 error, the error code will be `P02404`.
| Error Code | Description |
|------------|--------------------------------------------------------------|
| PY0001 | Generic fetch error, failed to fetch page from the server |
| PY0002 | Name supplied when trying to fetch resource is invalid |
| PY0401 | You are not authorized to access this resource. |
| PY0403 | You are not allowed to access this resource. |
| PY0404 | The page you are trying to fetch does not exist. |
| PY0500 | The server encountered an internal error. |
| PY0503 | The server is currently unavailable. |
## PY1001
Pyscript cannot install the package(s) you specified in your `py-config` tag. This can happen for a few reasons:
- The package does not exist
- The package does not contain a pure Python 3 wheel
- An error occurred while trying to install the package
An error banner should appear on your page with the error code and a description of the error or a traceback. You can also check the developer console for more information.

160
docs/reference/faq.md Normal file
View File

@@ -0,0 +1,160 @@
# Frequently asked questions
As the worlds most popular programming language, Python is powerful in its capabilities and comparatively easy to learn, yet the limitations cannot be ignored: its hard to install Python and all necessary dependencies; its glued to the backend without the ability to make apps or websites; and its difficult to share your work.
What if we could remove those limitations, making the power of Python accessible to the masses? The makers of PyScript set out to do just that by enabling Python in the browser for frontend web and application development. No more complicated installs. Projects can be shared with anyone, anywhere—all you need is a browser.
We are fully leaning into the idea that the browser is the most ubiquitous VM by using Python to build a graphical, programmable OS on top to make and share applications. Harness the full power of canvas, webGL, WASI, and even in-browser support for P2P and CRDTs for serverless data sharing and collaboration.
> “This is the exciting beginning for supporting new ways of programming, building, sharing, and deploying applications. Ultimately, we should be spending our time thinking and writing applications to solve the real problems we have, not dealing with mundane, hardware-induced challenges. Let's make programming more fun and simple.” - Fabio Pliger
## Why PyScript?
Exponentially expand accessibility and use cases for Python by enabling Python in the browser for building UIs. Reproduce environments without having to download Python or conda or install other packages. Projects can be shared with anyone and deployed anywhere—all you need is a browser and a web-accessible device (computer, tablet, or mobile).
We are fully leaning into the idea that the browser is the most ubiquitous VM by using Python to build a graphical, programmable operating system on top of the browser to make and share applications. Harness the full power of canvas, webGL, WASI, and even in-browser support for P2P and CRDTs for serverless data sharing and collaboration.
- [PyCon US 2022 Keynote with Peter Wang](https://anaconda.cloud/pyscript-pycon2022-peter-wang-keynote)
- [Example demos from Keynote](https://pyscript.net/examples/index.html)
## What is PyScript?
PyScript is a framework that allows users to create rich Python applications in the browser using HTML's interface and the power of [Pyodide — Version 0.20.0](https://pyodide.org/en/stable/), [WebAssembly](https://webassembly.org/), and modern web technologies. The PyScript framework provides users at every experience level with access to an expressive, easy-to-learn programming language with countless applications.
What is PyScript? Well, here are some of the core components:
- Python in the browser: Enable drop-in content, external file hosting, and application hosting without the reliance on server-side configuration
- Python ecosystem: Run many popular packages of Python and the scientific stack (such as numpy, pandas, scikit-learn, and more)
- Python with JavaScript: Bi-directional communication between Python and Javascript objects and namespaces
- Environment management: Allow users to define what packages and files to include for the page code to run
- Visual application development: Use readily available curated UI components, such as buttons, containers, text boxes, and more
- Flexible framework: A flexible framework that can be leveraged to create and share new pluggable and extensible components directly in Python
All that to say... PyScript is just HTML, only a bit (okay, maybe a lot) more powerful, thanks to the rich and accessible ecosystem of Python libraries.
In short, our mission is to enable programming for the 99%.
## How can a user get started?
Leveraging Python in HTML is literally as simple as adding a few lines of code to your page. The best place to learn more, get started, and stay updated on all things PyScript is [Pyscript.net](http://pyscript.net/). Additional shareable resources below:
- [PyScript Repo](https://github.com/pyscript/pyscript)
- [PyScript Announcement Blog](https://www.anaconda.com/blog/pyscript-python-in-the-browser)
- [PyScript Technical Blog](https://engineering.anaconda.com/2022/04/welcome-pyscript.html)
- [PyScript Nucleus Project](https://anaconda.cloud/s/pyscript)
- [PyScript Documentation](https://docs.pyscript.net/)
## Why isn't this going to be as terrible as PHP?
This comparison is based on both PHP and PyScript having a similar way of declaring things: put a tag on the page and the interpreter handles it. PHP works on the server side and is itself a whole different programming language that has its own directives and semantics.
The choice of using tags to allow people to execute Python is explicit; even if this functionality is similar to PHP, it works differently. First of all, everything runs in the browser itself rather than going to the server side. Secondly, PyScript lives close to the text and allows changes to be made to the visual elements. The PyScript REPL can generate output, plus it provides additional visual elements like buttons, titles, and input boxes. PyScript functions as a framework that generates UIs that makes sense as a tag in the html code.
Currently, both PHP and PyScript operate with only one namespace. However, PyScript will soon support multiple namespaces and different types of isolation of code (scope), along with support for languages beyond Python.
## Why not just learn JavaScript?
JavaScript is not only a different language from python, but a challenging language at that. With PyScript, you now have two languages to choose from, with even more on the roadmap. PyScript allows you to use both libraries and makes JavaScript and Python compatible with one another.
Python is incredibly powerful, super intuitive, and easy to learn. By adding Python to your toolkit, you can use Numpy, SciPy, Pandas, and more, seamlessly. One tradeoff is longer download times, so it isnt the right tool for everything—but where it is the right tool, its almost irreplaceable.
Ultimately, PyScript will enable the use of a variety of languages, offer a standard set of components that is well linked to the REPLs, and allow you to do an introspection on the code base—you can have, for example, a *modifiable* chart as a python object.
## Will PyScript replace JavaScript?
No. PyScript allows Python to leverage HTML, CSS, and JavaScript conventions to build elegant UIs and address general web application building, packaging, distribution, and deployment challenges (a huge pain). We expect the popularity and adoption of HTML, CSS, and JavaScript to rise alongside Python, ultimately making the web a more friendly and hackable place for everyone. That said, we do believe:
- PyScript will displace some use cases that people have to rely on Javascript for now
- PyScript will heavily leverage and interface with existing powerful, feature-full JS libraries, as appropriate
- PyScript will open up web programming to tens of millions of people who would otherwise not have touched JavaScript; so in this way, it will outpace JavaScript
But none of these above scenarios lead to a situation where "PyScript replaces all existing JavaScript." Just as Python itself didn't replace C, C++, or Java. But, it did take a LOT of market share for new use cases where those languages would otherwise have been used.
## What is the difference between PyScript and Pyodide?
![pyodide-pyscript](../img/pyodide-pyscript.png)
PyScript provides HTML tags for embedding and executing Python code in your browser. As a glue framework, it sits on top of a variety of tools and provides users access to Pyodide, the WebAssembly port of CPython, which is compiled using Emscripten. In other words, Pyodide enables PyScript users to take advantage of real CPython on the browser.
Together, PyScript and Pyodide allow users to author applications by turning the browser into a code deployment tool that anyone can learn to use.
With respect to the UI, PyScript is opinionated and purposeful, while Pyodide is agnostic, unopinionated, and intended for more general use.
## What packages can I use? Can I use anything from PyPI?
You can use anything within the Pyodide library, and pure python packages from PyPi that do not contain C dependencies should be supported by Pyodide.
There is a list of packages built in Pyodide in [Packages built in Pyodide — Version 0.20.0](https://pyodide.org/en/stable/usage/packages-in-pyodide.html) (these are mostly packages with C extensions). You can also install pure Python packages from PyPI or custom URLs, assuming they have a wheel.
In general, Pyodide doesnt support all Python features—not because of Pyodide itself, but because some concepts just work differently on the browser (think of sockets/websockets, IO, threading, etc.). If its a pure python package that doesnt have any non-supported features, you should expect it to work. If it has C dependencies, etc., dont expect it to work unless someone builds/ports them. A lot of the features that dont work can be made to work, but it will take human power to fix. For example, the PyTorch community wanted those features to work, so they rallied around it to make it happen. Expect the set of libraries that work to grow quickly given the volume of package builds coming from the community.
## This package XXX is not supported because it has C dependencies. How can I make it work?
See [Creating a Pyodide package — Version 0.20.0](https://pyodide.org/en/stable/development/new-packages.html).
## Why is PyScript loading so slowly? Why cant we put things behind a CDN?
Packages are already served from the JsDelivr CDN. This is not a downloading speed problem—it's WASM assembly time. PyScript loads slowly because the Python standard library and packages are large and WebAssembly code needs to be compiled and run by the browser after they are loaded for the first time.
Currently, there are efforts to mitigate the problem, and Pyodide is currently working on a bundler, for instance.
## Is PyScript owned by Anaconda?
Anaconda doesnt own PyScript. It is an open source project developed by Anaconda internally, and Anaconda team members are currently the main contributors, but the repo itself is public. We are working on a steering council to ensure the project stays public and owned by the community.
See [Maintainers](../concepts/governance/maintainers.md).
See [Governance Policy](../concepts/governance/policy.md).
## What is the governing model for PyScript?
See [Governance Policy](../concepts/governance/policy.md).
## What is the license?
PyScript uses the Apache-2.0 license.
Pyodide uses MPL-2.0 license. Various packages are distributed under their corresponding license.
## Is Pyodide a replacement for CPython? How does PyScript and Pyodide compare to CPython on WASM?
No. They have different elements that do different things, both of which are additive.
PyScript sits on top of everything. Pyodide came before the work on CPython and WASM. Patches were created in order for it to work, but now that CPython/WASM are progressing, Pyodide is able to remove a few of those patches. Additionally, CPython doesnt deal with building Python packages for WASM. WASM related work on upstream CPython will integrate into Pyodide in the near future.
For a list of differences from “standard” CPython, see [Pyodide Python compatibility — Version 0.20.0](https://pyodide.org/en/stable/usage/wasm-constraints.html).
## Hasnt this already been done before by Brython/skulpt?
No. Brython and Skulpt accomplish different things than PyScript and Pyodide.
Brython is client-side and functions as syntax on top of Javascript—it is a reimplementation of Python on top of Javascript, without support for packages or a file system. The extraction of a package in normal Python has been replaced completely by something else. You should be able to run code with minimal changes; however, that isnt possible with Brython.
Skulpt is a cross compiler from Python to Javascript, leveraged for compatibility with the Python ecosystem. If you want to do any more Python, you would have to send it over.
Fairly similar syntax to normal Python, but not exactly the same. If Brython was an interpreter and a full Python implementation, it could be used with PyScript to leverage packages like Numpy, but that isnt possible as it stands today. They do have the Python script tag, but it is a smaller API and not as feature rich—which is why PyScript is built on Pyodide, Emscripten, and WebAssembly.
## How can I contribute/help?
**PyScript** - we are currently working on building documentation and a contributing guide. In the meantime, just ask to help on the PyScript [discussions page](https://anaconda.cloud/s/pyscript) or in the [repo](http://github.com/pyscript/pyscript).
**Pyodide** - refer to [Pyodide docs](https://pyodide.org/en/stable/development/contributing.html).
## WebAssembly Security
See [WebAssembly docs](https://webassembly.org/docs/security/).
## Why dont Requests and Black work?
Requests and Black do not work out of the box because they werent meant for the browser. On the browser, sockets multiprocessing works differently, so there is work to be done to actually match things.
For Black, its a design choice that can be patched. This is currently being addressed by the team at Pyodide.
Requests do not work because of the sockets issue (sockets and websockets are two different things) and requests are blocking—which you dont want in the browser. Itll require putting the runtime on a webworker and utilizing an assistant, but on the main thread its unlikely that itll work.
There are options as a path forward. For example, Requests can be leveraged using javascript libraries, or building a python async version of Requests API or a python wrapper for fetch (pyfetch), etc. The websockets library has a client side that could be made to work—given that it has all asynchronous APIs, theres nothing fundamentally difficult about getting it to work.

54
docs/reference/index.md Normal file
View File

@@ -0,0 +1,54 @@
# Reference
```{toctree}
---
maxdepth: 1
glob:
caption: Elements
---
elements/*
```
```{toctree}
---
maxdepth: 1
glob:
caption: Modules
---
modules/*
```
```{toctree}
---
maxdepth: 1
glob:
caption: Plugins
---
plugins/*
```
```{toctree}
---
maxdepth: 1
glob:
caption: API
---
API/*
```
```{toctree}
---
maxdepth: 2
glob:
caption: Exceptions
---
exceptions
```
```{toctree}
---
maxdepth: 1
caption: Miscellaneous
---
faq
```

View File

@@ -0,0 +1,77 @@
# pyscript
The code underlying PyScript is a TypeScript/JavaScript module, which is loaded and executed by the browser. This is what loads when you include, for example, `<script defer src="https://pyscript.net/latest/pyscript.js">` in your HTML.
The module is exported to the browser as `pyscript`. The exports from this module are:
## pyscript.version
Once `pyscript.js` has loaded, the version of PyScript that is currently running can be accessed via `pyscript.version`.
```html
<script defer onload="console.log(`${pyscript.version}`)" src="https://pyscript.net/latest/pyscript.js"></script>
```
```js
//example result
Object { year: 2022, month: 11, patch: 1, releaselevel: "dev" }
```
## pyscript.runtime
The RunTime object which is responsible for executing Python code in the Browser. Currently, all runtimes are assumed to be Pyodide runtimes, but there is flexibility to expand this to other web-based Python runtimes in future versions.
The RunTime object has the following attributes
| attribute | type | description |
|---------------------|---------------------|-----------------------------------------------------------------------------|
| **src** | string | The URL from which the current runtime was fetched |
| **interpreter** | RuntimeInterpreter | A reference to the runtime object itself |
| **globals** | any | The globals dictionary of the runtime, if applicable/accessible |
| **name (optional)** | string | A user-designated name for the runtime |
| **lang (optional)** | string | A user-designation for the language the runtime runs ('Python', 'C++', etc) |
### pyscript.runtime.src
The URL from which the current runtime was fetched.
### pyscript.runtime.interpreter
A reference to the Runtime wrapper that PyScript uses to execute code. object itself. This allows other frameworks, modules etc to interact with the same [(Pyodide) runtime instance](https://pyodide.org/en/stable/usage/api/js-api.html) that PyScript uses.
For example, assuming we've loaded Pyodide, we can access the methods of the Pyodide runtime as follows:
```html
<button onclick="logFromPython()">Click Me to Run Some Python</button>
<script>
function logFromPython(){
pyscript.runtime.interpreter.runPython(`
animal = "Python"
sound = "sss"
console.warn(f"{animal}s go " + sound * 5)
`)
}
</script>
```
### pyscript.runtime.globals
A proxy for the runtime's `globals()` dictionary. For example:
```html
<body>
<py-script>x = 42</py-script>
<button onclick="showX()">Click Me to Get 'x' from Python</button>
<script>
function showX(){
console.log(`In Python right now, x = ${pyscript.runtime.globals.get('x')}`)
}
</script>
</body>
```
### pyscript.runtime.name
A user-supplied string for the runtime given at its creation. For user reference only - does not affect the operation of the runtime or PyScript.
### PyScript.runtime.lang
A user-supplied string for the language the runtime uses given at its creation. For user reference only - does not affect the operation of the runtime or PyScript.

View File

@@ -0,0 +1,41 @@
# &lt;py-terminal&gt;
This is one of the core plugins in PyScript, which is active by default. With it, you can print to `stdout` and `stderr` from your python code, and the output will be displayed on the page in `<py-terminal>`.
## Configuration
You can control how `<py-terminal>` behaves by setting the value of the `terminal` configuration in your `<py-config>`.
| value | description |
|-------|-------------|
| `false` | Don't add `<py-terminal>` to the page |
| `true` | Automatically add a `<py-terminal>` to the page |
| `"auto"` | This is the default. Automatically add a `<py-terminal auto>`, to the page. The terminal is initially hidden and automatically shown as soon as something writes to `stdout` and/or `stderr` |
### Examples
```html
<py-config>
terminal = true
</py-config>
<py-script>
print("Hello, world!")
</py-script>
```
This example will create a new `<py-terminal>`, the value "Hello, world!" that was printed will show in it.
You can also add one (or more) `<py-terminal>` to the page manually.
```html
<py-script>
print("Hello, world!")
</py-script>
<py-terminal></py-terminal>
```
```{note}
If you include a `<py-terminal>` in the page, you can skip `terminal` from your `<py-config>`.
```

5
docs/robots.txt Normal file
View File

@@ -0,0 +1,5 @@
User-agent: *
Disallow: /review/
Sitemap: https://docs.pyscript.net/sitemap.xml
Host: docs.pyscript.net

View File

@@ -0,0 +1,268 @@
# Getting started with PyScript
This page will guide you through getting started with PyScript.
## Development setup
PyScript does not require any development environment other
then a web browser (we recommend using [Chrome](https://www.google.com/chrome/)) and a text editor, even though using your [IDE](https://en.wikipedia.org/wiki/Integrated_development_environment) of choice might be convenient.
If you're using [VSCode](https://code.visualstudio.com/), the
[Live Server extension](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)
can be used to reload the page as you edit the HTML file.
## Installation
There is no installation required. In this document, we'll use
the PyScript assets served on [https://pyscript.net](https://pyscript.net).
If you want to download the source and build it yourself, follow
the instructions in the [README.md](https://github.com/pyscript/pyscript/blob/main/README.md) file.
## Your first PyScript HTML file
Here's a "Hello, world!" example using PyScript.
Using your favorite editor, create a new file called `hello.html` in
the same directory as your PyScript, JavaScript, and CSS files with the
following content, and open the file in your web browser. You can typically
open an HTML by double-clicking it in your file explorer.
```html
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
print('Hello, World!')
</py-script>
</body>
</html>
```
## A more complex example
Now that we know how you can create a simple 'Hello, World!' example, let's see a more complex example. This example will use the Demo created by [Cheuk Ting Ho](https://github.com/Cheukting). In this example, we will use more features from PyScript.
### Setting up the base index file
Let's create a new file called `index.html` and add the following content:
```html
<html>
<head>
<title>Ice Cream Picker</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
</body>
</html>
```
In this first step, we have created the index file, imported `pyscript.css` and `pyscript.js`. We are ready to start adding the elements we need for our application.
### Importing the needed libraries
For this example, we will need to install `pandas` and `matplotlib`. We can install libraries using the `<py-config>` tag so we can import them later. Please refer to the [`<py-config>`](../reference/elements/py-config.md) documentation for more information.
```html
<html>
<head>
<title>Ice Cream Picker</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-config>
packages = ["matplotlib", "pandas"]
</py-config>
</body>
</html>
```
### Importing the data and exploring
Now that we have installed the needed libraries, we can import and explore the data. In this step, we need to create a `<py-script>` tag to import our dependencies, read the data with pandas and then use `py-repl` to explore the data.
You may want to read the [`<py-script>`](../reference/elements/py-script.md) and [`<py-repl>`](../reference/elements/py-repl.md) documentation for more information about these elements.
```html
<html>
<head>
<title>Ice Cream Picker</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-config>
packages = ["matplotlib", "pandas"]
</py-config>
<py-script>
import pandas as pd
from pyodide.http import open_url
url = (
"https://raw.githubusercontent.com/Cheukting/pyscript-ice-cream/main/bj-products.csv"
)
ice_data = pd.read_csv(open_url(url))
</py-script>
<py-repl>
ice_data
</py-repl>
</body>
</html>
```
Note that we are adding `ice_data` to `py-repl` to pre-populate the REPL with this variable, so you don't have to type it yourself.
### Creating the plot
Now that we have the data, we can create the plot. We will use the `matplotlib` library to make the plot. We will use the `display` API to display the plot on the page. You may want to read the [`display`](../reference/API/display.md) documentation for more information.
```html
<html>
<head>
<title>Ice Cream Picker</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-config>
packages = ["matplotlib", "pandas"]
</py-config>
<py-script>
import pandas as pd
import matplotlib.pyplot as plt
from pyodide.http import open_url
url = (
"https://raw.githubusercontent.com/Cheukting/pyscript-ice-cream/main/bj-products.csv"
)
ice_data = pd.read_csv(open_url(url))
def plot(data):
plt.rcParams["figure.figsize"] = (22,20)
fig, ax = plt.subplots()
bars = ax.barh(data["name"], data["rating"], height=0.7)
ax.bar_label(bars)
plt.title("Rating of ice cream flavours of your choice")
display(fig, target="graph-area", append=False)
plot(ice_data)
</py-script>
<py-repl>
ice_data
</py-repl>
<div id="graph-area"></div>
</body>
</html>
```
### Select specific flavours
Now that we have a way to explore the data using `py-repl` and a way to create the plot using all of the data, it's time for us to add a way to select specific flavours.
```html
<html>
<head>
<title>Ice Cream Picker</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-config>
packages = ["matplotlib", "pandas"]
</py-config>
<py-script>
import pandas as pd
import matplotlib.pyplot as plt
from pyodide.http import open_url
from pyodide.ffi import create_proxy
url = (
"https://raw.githubusercontent.com/Cheukting/pyscript-ice-cream/main/bj-products.csv"
)
ice_data = pd.read_csv(open_url(url))
current_selected = []
flavour_elements = document.getElementsByName("flavour")
def plot(data):
plt.rcParams["figure.figsize"] = (22,20)
fig, ax = plt.subplots()
bars = ax.barh(data["name"], data["rating"], height=0.7)
ax.bar_label(bars)
plt.title("Rating of ice cream flavours of your choice")
display(fig, target="graph-area", append=False)
def select_flavour(event):
for ele in flavour_elements:
if ele.checked:
current_selected = ele.value
break
if current_selected == "ALL":
plot(ice_data)
else:
filter = ice_data.apply(lambda x: ele.value in x["ingredients"], axis=1)
plot(ice_data[filter])
ele_proxy = create_proxy(select_flavour)
for ele in flavour_elements:
if ele.value == "ALL":
ele.checked = True
current_selected = ele.value
ele.addEventListener("change", ele_proxy)
plot(ice_data)
</py-script>
<div id="input" style="margin: 20px;">
Select your 🍨 flavour: <br/>
<input type="radio" id="all" name="flavour" value="ALL">
<label for="all"> All 🍧</label>
<input type="radio" id="chocolate" name="flavour" value="COCOA">
<label for="chocolate"> Chocolate 🍫</label>
<input type="radio" id="cherrie" name="flavour" value="CHERRIES">
<label for="cherrie"> Cherries 🍒</label>
<input type="radio" id="berries" name="flavour" value="BERRY">
<label for="berries"> Berries 🍓</label>
<input type="radio" id="cheese" name="flavour" value="CHEESE">
<label for="cheese"> Cheese 🧀</label>
<input type="radio" id="peanut" name="flavour" value="PEANUT">
<label for="peanut"> Peanut 🥜</label>
</div>
<py-repl>
ice_data
</py-repl>
<div id="graph-area"></div>
</body>
</html>
```

13
docs/tutorials/index.md Normal file
View File

@@ -0,0 +1,13 @@
# Tutorials
This is the tutorials section for beginners.
```{toctree}
---
maxdepth: 2
---
getting-started
py-config-fetch
py-config-runtime
writing-to-page
```

View File

@@ -0,0 +1,188 @@
# Using the fetch from py-config
This tutorial shows how to use the fetch configuration from `py-config` to fetch two files from a remote server, store them in a local directory, and verify their contents.
## Development setup
We will create a todo list application similar to the one in the [examples](https://pyscript.net/examples/todo.html). To do this, we need three things:
* An `index.html` file containing the HTML for the application.
* A `todo.py` file containing the Python code for the application.
* A `utils.py` file containing some utility functions for the application.
We will use the `fetch` configuration from `py-config` to fetch these files from a remote server and store them in a local directory.
### Creating the html file
In this first step, we will create the `index.html` file and import both `pyscript.css` and `pyscript.js`. These are needed to run our Python code in the browser and style the application.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>My Todo</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
</body>
</html>
```
## Fetching the files
### Using `fetch` to get the python files
Now we will use the `fetch` configuration from `py-config` to fetch the `todo.py` and `utils.py` files from a remote server and store them in a local directory called `todo`. Here we will fetch files from different URLs, using a `fetch` per item.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>My Todo</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-config>
[[fetch]]
from = "https://pyscript.net/examples/"
files = ["utils.py"]
[[fetch]]
from = "https://gist.githubusercontent.com/FabioRosado/faba0b7f6ad4438b07c9ac567c73b864/raw/37603b76dc7ef7997bf36781ea0116150f727f44/"
files = ["todo.py"]
</py-config>
</body>
</html>
```
## Creating a todo application
### Creating the todo elements
Now we will create the todo elements in the `body` of the `index.html` file.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>My Todo</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-config>
[[fetch]]
from = "https://pyscript.net/examples/"
files = ["utils.py"]
[[fetch]]
from = "https://gist.githubusercontent.com/FabioRosado/faba0b7f6ad4438b07c9ac567c73b864/raw/37603b76dc7ef7997bf36781ea0116150f727f44/"
files = ["todo.py"]
</py-config>
<section>
<div class="text-center w-full mb-8">
<h1 class="text-3xl font-bold text-gray-800 uppercase tracking-tight">To Do List</h1>
</div>
<div>
<input id="new-task-content" class="py-input" type="text">
<button id="new-task-btn" class="py-button" type="submit" py-click="add_task()">
Add task
</button>
</div>
<div id="list-tasks-container" class="flex flex-col-reverse mt-4"></div>
<template id="task-template">
<section class="task py-li-element">
<label for="flex items-center p-2 ">
<input class="mr-2" type="checkbox">
<p class="m-0 inline"></p>
</label>
</section>
</template>
</section>
</body>
</html>
```
Our todo application is starting to shape up, although if you try to add any tasks, you will notice that nothing happens. This is because we have not yet imported the `todo.py` file.
### Importing the needed functions from `todo.py`
This is where the magic happens. We can import the `todo.py` file by adding it as a source to the `py-script` tag. By specifying the file, pyscript will automatically import the file and run the code in it.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>My Todo</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-config>
[[fetch]]
from = "https://pyscript.net/examples/"
files = ["utils.py"]
[[fetch]]
from = "https://gist.githubusercontent.com/FabioRosado/faba0b7f6ad4438b07c9ac567c73b864/raw/37603b76dc7ef7997bf36781ea0116150f727f44/"
files = ["todo.py"]
</py-config>
<py-script>
from todo import add_task, add_task_event
</py-script>
<section>
<div class="text-center w-full mb-8">
<h1 class="text-3xl font-bold text-gray-800 uppercase tracking-tight">To Do List</h1>
</div>
<div>
<input id="new-task-content" class="py-input" type="text">
<button id="new-task-btn" class="py-button" type="submit" py-click="add_task()">
Add task
</button>
</div>
<div id="list-tasks-container" class="flex flex-col-reverse mt-4"></div>
<template id="task-template">
<section class="task py-li-element">
<label for="flex items-center p-2 ">
<input class="mr-2" type="checkbox">
<p class="m-0 inline"></p>
</label>
</section>
</template>
</section>
</body>
</html>
```
You can now save the file and refresh the page. You should now be able to add tasks to your todo list.
## That's it!
You have now created a todo application using pyscript. You can add tasks and mark them as done. Let's take a recap of what we have achieved:
* We have imported three separate files into our `index.html` file using the `py-config` tag.
* We have created the necessary HTML code to create our todo's
* We have imported functions from the `todo.py` file, using the `py-script` tag.
For reference, the code from [the gist](https://gist.githubusercontent.com/FabioRosado/faba0b7f6ad4438b07c9ac567c73b864/raw/37603b76dc7ef7997bf36781ea0116150f727f44/todo.py) is the same code that our [todo example](https://pyscript.net/examples/todo.html) uses with a slight change of importing `Element` from `pyscript`.

View File

@@ -0,0 +1,88 @@
# Setting a pyodide runtime
Pyscript will automatically set the runtime for you, but you can also set it manually. This is useful if you want to use a different version than the one set by default.
## Development setup
To get started, let's create a new `index.html` file and import `pyscript.js`.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Runtime</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
</body>
</html>
```
We are using the pyodide CDN to setup our runtime, but you can also download the files from [the pyodide GitHub release](https://github.com/pyodide/pyodide/releases/tag/0.22.0a3), unzip them and use the `pyodide.js` file as your runtime.
## Setting the runtime
To set the runtime, you can use the `runtime` configuration in the `py-config` element. In this tutorial, we will use the default `TOML` format, but know that you can also use `json` if you prefer by changing the `type` attribute of the `py-config` element.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Runtime</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-config>
[[runtimes]]
src = "https://cdn.jsdelivr.net/pyodide/v0.22.0a3/full/pyodide.js"
name = "pyodide-0.22.0a3"
lang = "python"
</py-config>
</body>
</html>
```
## Confirming the runtime version
To confirm that the runtime is set correctly, you can open the DevTools and check the version from the console. But for the sake of this tutorial, let's create a `py-script` tag and print pyodide's version.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Runtime</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-config>
[[runtimes]]
src = "https://cdn.jsdelivr.net/pyodide/v0.22.0a3/full/pyodide.js"
name = "pyodide-0.22.0a3"
lang = "python"
</py-config>
<py-script>
import pyodide
print(pyodide.__version__)
</py-script>
</body>
</html>
```

View File

@@ -0,0 +1,212 @@
# How to write content to the page
When creating your PyScript application, you will want to write content to the page. This tutorial will explore the different methods you can use to write content to the page and their differences.
## Development setup
To get started, we will create an `index.html` file, import PyScript and start building on top of it.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Writing to the page</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
</body>
</html>
```
## Writing content to an element
Let's first see how we can write content to an element on the page. We will start by creating a `div` element with an `id` of `manual-write`, then create a `py-script` tag that, upon a click of a button, will write 'Hello World' to the `div` element.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Writing to the page</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div id="manual-write"></div>
<button py-click="write_to_page()" id="manual">Say Hello</button>
<py-script>
def write_to_page():
manual_div = Element("manual-write")
manual_div.element.innerText = "Hello World"
</py-script>
</body>
</html>
```
```{note}
When using `py-click` you must supply an `id` to the element you want to use as the trigger.
```
We can now open our `index.html` file and click the button. You will see that "Hello World" will appear in the `div` element. You could also write HTML using `manual_div.element.innerHTML` instead of `innerText`. For example:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Writing to the page</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div id="manual-write"></div>
<button py-click="write_to_page()" id="manual">Say Hello</button>
<py-script>
def write_to_page():
manual_div = Element("manual-write")
manual_div.element.innerHTML = "<p><b>Hello World</b></p>"
</py-script>
</body>
</html>
```
## Writing content with the `display` API
The `display` API is a simple way to write content to the page. Not only does it allow you to write content to the page, but it also allows you to display a range of different content types such as images, markdown, svgs, json, etc.
Using the' display' API, let's reuse our previous example and write "Hello World" to the page.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Writing to the page</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div id="manual-write"></div>
<button py-click="write_to_page()" id="manual">Say Hello</button>
<div id="display-write"></div>
<button py-click="display_to_div()" id="display">Say Things!</button>
<py-script>
def write_to_page():
manual_div = Element("manual-write")
manual_div.element.innerHTML = "<p><b>Hello World</b></p>"
def display_to_div():
display("I display things!", target="display-write")
</py-script>
</body>
</html>
```
```{note}
When using the `display` API, you must specify the `target` parameter to tell PyScript where to write the content. If you do not use this parameter, an error will be thrown.
```
You may be interested in reading more about the `display` API in the [Display API](../reference/api/display) section of the documentation.
## Printing to the page
We couldn't have a tutorial on writing to the page without mentioning the `print` function. The `print` function is a simple way to write content to the page, that any Python developer will be familiar with. When you use the `print` function, the content will be written to the page in a `py-terminal` element.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Writing to the page</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div id="manual-write"></div>
<button py-click="write_to_page()" id="manual">Say Hello</button>
<div id="display-write"></div>
<button py-click="display_to_div()" id="display">Say Things!</button>
<button py-click="print_to_page()" id="print">Print Things!</button>
<py-script>
def write_to_page():
manual_div = Element("manual-write")
manual_div.element.innerHTML = "<p><b>Hello World</b></p>"
def display_to_div():
display("I display things!", target="display-write")
def print_to_page():
print("I print things!")
</py-script>
</body>
</html>
```
You may be surprised to see that when you click the "Print Things!" button, the content is written below the rest of the elements on the page in a black canvas. This is because the `print` function writes content to the page in a `py-terminal` element. You can read more about the `py-terminal` element in the [Terminal Element](../reference/plugins/py-terminal) section of the documentation.
PyScript comes with the `py-terminal` plugin by default and any `stdout` or `stderr` content will be shown in this element. We can be explicit about where we want the terminal to be shown by adding the `<py-terminal>` tag to our HTML.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Writing to the page</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div id="manual-write"></div>
<button py-click="write_to_page()" id="manual">Say Hello</button>
<div id="display-write"></div>
<button py-click="display_to_div()" id="display">Say Things!</button>
<div>
<py-terminal>
</div>
<button py-click="print_to_page()" id="print">Print Things!</button>
<py-script>
def write_to_page():
manual_div = Element("manual-write")
manual_div.element.innerHTML = "<p><b>Hello World</b></p>"
def display_to_div():
display("I display things!", target="display-write")
def print_to_page():
print("I print things!")
</py-script>
</body>
</html>
```

154
examples/altair.html Normal file
View File

@@ -0,0 +1,154 @@
<html>
<head>
<title>Altair</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<link rel="stylesheet" href="./assets/css/examples.css" />
<link rel="stylesheet" href="./assets/prism/prism.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<script defer src="./assets/prism/prism.js"></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000;">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo">
</a>
<a class="title" href="" style="color: #f0ab3c;">Altair</a>
</div>
</nav>
<section class="pyscript">
<div id="altair"></div>
<py-config>
packages = [
"altair",
"pandas",
"vega_datasets"
]
</py-config>
<py-script>
import altair as alt
from vega_datasets import data
source = data.movies.url
pts = alt.selection(type="single", encodings=['x'])
rect = alt.Chart(data.movies.url).mark_rect().encode(
alt.X('IMDB_Rating:Q', bin=True),
alt.Y('Rotten_Tomatoes_Rating:Q', bin=True),
alt.Color('count()',
scale=alt.Scale(scheme='greenblue'),
legend=alt.Legend(title='Total Records')
)
)
circ = rect.mark_point().encode(
alt.ColorValue('grey'),
alt.Size('count()',
legend=alt.Legend(title='Records in Selection')
)
).transform_filter(
pts
)
bar = alt.Chart(source).mark_bar().encode(
x='Major_Genre:N',
y='count()',
color=alt.condition(pts, alt.ColorValue("steelblue"), alt.ColorValue("grey"))
).properties(
width=550,
height=200
).add_selection(pts)
display(alt.vconcat(
rect + circ,
bar
).resolve_legend(
color="independent",
size="independent"
), target="altair")
</py-script>
</section>
<section class="code">
<div id="view-code-button" role="button" aria-pressed="false" tabindex="0">View Code</div>
<div id="code-section" class="code-section-hidden">
<p>index.html</p>
<pre class="prism-code language-html">
<code class="language-html">
&lt;py-config&gt;
packages = [
"altair",
"pandas",
"vega_datasets"
]
&lt;/py-config&gt;
&lt;py-script&gt;
import altair as alt
from vega_datasets import data
source = data.movies.url
pts = alt.selection(type="single", encodings=['x'])
rect = alt.Chart(data.movies.url).mark_rect().encode(
alt.X('IMDB_Rating:Q', bin=True),
alt.Y('Rotten_Tomatoes_Rating:Q', bin=True),
alt.Color('count()',
scale=alt.Scale(scheme='greenblue'),
legend=alt.Legend(title='Total Records')
)
)
circ = rect.mark_point().encode(
alt.ColorValue('grey'),
alt.Size('count()',
legend=alt.Legend(title='Records in Selection')
)
).transform_filter(
pts
)
bar = alt.Chart(source).mark_bar().encode(
x='Major_Genre:N',
y='count()',
color=alt.condition(pts, alt.ColorValue("steelblue"), alt.ColorValue("grey"))
).properties(
width=550,
height=200
).add_selection(pts)
display(alt.vconcat(
rect + circ,
bar
).resolve_legend(
color="independent",
size="independent"
), target="altair")
&lt;/py-script&gt;
</code>
</pre>
</div>
</section>
</body>
<script>
const viewCodeButton = document.getElementById("view-code-button");
const codeSection = document.getElementById("code-section");
const handleClick = () => {
if (codeSection.classList.contains("code-section-hidden")) {
codeSection.classList.remove("code-section-hidden");
codeSection.classList.add("code-section-visible");
} else {
codeSection.classList.remove("code-section-visible");
codeSection.classList.add("code-section-hidden");
}
}
viewCodeButton.addEventListener("click", handleClick)
viewCodeButton.addEventListener("keydown", (e) => {
if (e.key === " " || e.key === "Enter" || e.key === "Spacebar") {
handleClick();
}
})
</script>
</html>

118
examples/antigravity.html Normal file
View File

@@ -0,0 +1,118 @@
<html>
<head>
<title>Antigravity</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<link rel="stylesheet" href="./assets/css/examples.css" />
<link rel="stylesheet" href="./assets/prism/prism.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<script defer src="./assets/prism/prism.js"></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000;">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo">
</a>
<a class="title" href="" style="color: #f0ab3c;">Antigravity</a>
</div>
</nav>
<section class="pyscript">
<py-config>
[[fetch]]
files = ["./antigravity.py"]
</py-config>
<b>Based on xkcd: antigravity https://xkcd.com/353/.</b>
<py-script>
import antigravity
antigravity.fly()
</py-script>
</section>
<section class="code">
<div id="view-code-button" role="button" aria-pressed="false" tabindex="0">View Code</div>
<div id="code-section" class="code-section-hidden">
<p>index.html</p>
<pre class="prism-code language-html">
<code class="language-html">
&lt;py-config&gt;
[[fetch]]
files = ["./antigravity.py"]
&lt;/py-config&gt;
&lt;py-script&gt;
import antigravity
antigravity.fly()
&lt;/py-script&gt;
</code>
</pre>
<p>antigravity.py</p>
<pre class="prism-code language-python">
<code class="language-python">
import random
import sys
from js import DOMParser, document, setInterval
from pyodide.ffi import create_proxy
from pyodide.http import open_url
class Antigravity:
url = "./antigravity.svg"
def __init__(self, target=None, interval=10, append=True, fly=False):
target = target or sys.stdout._out
self.target = (
document.getElementById(target) if isinstance(target, str) else target
)
doc = DOMParser.new().parseFromString(
open_url(self.url).read(), "image/svg+xml"
)
self.node = doc.documentElement
if append:
self.target.append(self.node)
else:
self.target.replaceChildren(self.node)
self.xoffset, self.yoffset = 0, 0
self.interval = interval
if fly:
self.fly()
def fly(self):
setInterval(create_proxy(self.move), self.interval)
def move(self):
char = self.node.getElementsByTagName("g")[1]
char.setAttribute("transform", f"translate({self.xoffset}, {-self.yoffset})")
self.xoffset += random.normalvariate(0, 1) / 20
if self.yoffset < 50:
self.yoffset += 0.1
else:
self.yoffset += random.normalvariate(0, 1) / 20
_auto = Antigravity(append=True)
fly = _auto.fly
</code>
</div>
</section>
</body>
<script>
const viewCodeButton = document.getElementById("view-code-button");
const codeSection = document.getElementById("code-section");
const handleClick = () => {
if (codeSection.classList.contains("code-section-hidden")) {
codeSection.classList.remove("code-section-hidden");
codeSection.classList.add("code-section-visible");
} else {
codeSection.classList.remove("code-section-visible");
codeSection.classList.add("code-section-hidden");
}
}
viewCodeButton.addEventListener("click", handleClick)
viewCodeButton.addEventListener("keydown", (e) => {
if (e.key === " " || e.key === "Enter" || e.key === "Spacebar") {
handleClick();
}
})
</script>
</html>

View File

@@ -1,8 +1,7 @@
import random import random
import sys
from js import DOMParser, document, setInterval from js import DOMParser, document, setInterval
from pyodide import create_proxy from pyodide.ffi import create_proxy
from pyodide.http import open_url from pyodide.http import open_url
@@ -11,9 +10,10 @@ class Antigravity:
url = "./antigravity.svg" url = "./antigravity.svg"
def __init__(self, target=None, interval=10, append=True, fly=False): def __init__(self, target=None, interval=10, append=True, fly=False):
target = target or sys.stdout._out
self.target = ( self.target = (
document.getElementById(target) if isinstance(target, str) else target document.getElementById(target)
if isinstance(target, str)
else document.body
) )
doc = DOMParser.new().parseFromString( doc = DOMParser.new().parseFromString(
open_url(self.url).read(), "image/svg+xml" open_url(self.url).read(), "image/svg+xml"

View File

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 212 KiB

View File

@@ -0,0 +1,90 @@
body {
margin: 0;
}
.pyscript {
margin: 0.5rem;
}
.code {
display: flex;
position: absolute;
right: 0px;
z-index: 9998;
top: 7rem;
}
@media (max-width: 1300px) {
.code:has(> .code-section-visible) {
width: 90%;
/* Absolute position is messing up the layout on small screens */
right: 70px;
}
}
.code-section-hidden {
width: 0px;
display: none;
}
.code-section-visible {
display: flex;
flex-direction: column;
width: 100%;
background-color: rgb(45 46 53 / 90%);
padding: 1rem;
border-radius: 10px 0px 0px 10px;
color: #c6c6c8;
}
.code-section-visible p{
margin: 0;
font-style: italic;
font-size: small;
}
.language-html, .language-python {
float: left;
}
#view-code-button {
writing-mode: tb-rl;
text-orientation: sideways-right;
background-color: #1D1D22;
color: white;
padding: 0.5rem;
border-radius: 5px;
cursor: pointer;
height: 81px;
}
nav {
position: sticky;
width: 100%;
top: 0;
left: 0;
z-index: 9999;
}
.logo {
padding-right: 10px;
font-size: 28px;
height: 30px;
max-width: inherit;
}
.title {
text-decoration: none;
text-decoration-line: none;
text-decoration-style: initial;
text-decoration-color: initial;
font-weight: 400;
font-size: 1.5em;
line-height: 2em;
white-space: nowrap;
}
.app-header {
display: flex;
align-items: center;
padding: 0.5rem 1rem;
}

View File

@@ -0,0 +1,70 @@
.example {
margin-bottom: 5rem;
}
.example h2{
/* color: #000000; */
font-family: "Inconsolata", monospace;
font-size: 2.25rem;
margin-bottom: 1rem;
}
.card {
height: 15rem;
background-color: var(--color-secondary);
padding: 1rem;
border-radius: 10px;
}
.card:hover, .card:hover a, .card:hover a:visited, .card:hover h2 {
background-color: var(--color-primary);
color: #1D1D22
}
.card a h2 {
color: var(--color-primary);
margin: 0;
font-family: "Inconsolata", monospace;
font-size: 2.25rem;
}
.card a p {
color: var(--text-color);
}
a .card {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.card-content {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.card-content a, .card-content a:visited {
color: var(--color-primary);
}
.container-card {
max-width: 1500px;
margin: 0 auto;
display: grid;
gap: 1rem;
}
@media (min-width: 600px) {
.container-card {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 900px) {
.container-card {
grid-template-columns: repeat(4, 1fr);
}
}

View File

@@ -0,0 +1,24 @@
@import url("https://fonts.googleapis.com/css2?family=Inconsolata:wght@400;700&display=swap");
@import "./variables.css";
@import "./reset.css";
body {
background: #2D2E35 url('https://assets.anaconda.com/production/Content/1650828148240.png?w=3240&auto=compress%2Cformat&fit=crop&dm=1650828161&s=c558dc55e0ed1f8419a892e842a5728f') repeat-x center bottom / 250px;
background-attachment: fixed;
overflow-x: hidden;
color: var(--text-color)
}
.container {
max-width: 1510px;
margin: auto;
padding: 0 2rem;
}
.title-main {
font-size: 4.25rem;
font-family: "Inconsolata", monospace;
text-align: center;
margin: 2rem 0;
}

View File

@@ -0,0 +1,22 @@
*,
*:after,
*:before {
margin: 0;
padding: 0;
box-sizing: border-box;
text-decoration: none;
}
body {
font-size: 100%;
list-style-type: none;
}
p {
font-family: "Inconsolata", monospace;
font-weight: 400;
}
a {
text-decoration: none;
}

View File

@@ -0,0 +1,6 @@
:root {
--color-primary: #FDA703;
--color-secondary: #1D1D22;
--text-color: white;
--card-shadow: 0px 5px 11px 0px rgb(0 0 0 / 15%);
}

View File

@@ -0,0 +1,3 @@
/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism-okaidia&languages=markup+clike+javascript+python */
code[class*=language-],pre[class*=language-]{color:#f8f8f2;background:0 0;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border-radius:.3em}:not(pre)>code[class*=language-],pre[class*=language-]{background:#272822}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#8292a2}.token.punctuation{color:#f8f8f2}.token.namespace{opacity:.7}.token.constant,.token.deleted,.token.property,.token.symbol,.token.tag{color:#f92672}.token.boolean,.token.number{color:#ae81ff}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#a6e22e}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f8f8f2}.token.atrule,.token.attr-value,.token.class-name,.token.function{color:#e6db74}.token.keyword{color:#66d9ef}.token.important,.token.regex{color:#fd971f}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('A', i)
await asyncio.sleep(0.1)
</py-script>
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('B', i)
await asyncio.sleep(0.1)
</py-script>
</body>
</html>

View File

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div>
Pyscript - FIRST ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCallLoop1():
for i in range(3):
js.console.log('A', i)
await asyncio.sleep(2)
asyncCallLoop1()
</py-script>
</div>
<div>
Pyscript - SECOND ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCallLoop2():
for i in range(3):
js.console.log('B', i)
await asyncio.sleep(2)
asyncCallLoop2()
</py-script>
</div>
</body>
</html>

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div>
Pyscript - FIRST ASYNC WITH INVOKED LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCallLoop1():
for i in range(3):
js.console.log('A', i)
await asyncio.sleep(2)
asyncCallLoop1()
</py-script>
</div>
<div>
Pyscript - SECOND ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('B', i)
await asyncio.sleep(2)
</py-script>
</div>
</body>
</html>

View File

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await NON-BLOCKING Pyscript Twice</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div>
Pyscript - FIRST ASYNC WITH NON-BLOCKING AWAIT AT ONE LEVEL LOWER THAN LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCall1():
await asyncio.sleep(2)
for i in range(3):
js.console.log('A', i)
asyncCall1()
</py-script>
</div>
<div>
Pyscript - SECOND ASYNC WITH NON-BLOCKING AWAIT AT ONE LEVEL LOWER THAN LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
async def asyncCall2():
await asyncio.sleep(2)
for i in range(3):
js.console.log('B', i)
asyncCall2()
</py-script>
</div>
</body>
</html>

View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<div>
Pyscript - FIRST ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('A', i)
await asyncio.sleep(2)
</py-script>
</div>
<div>
Pyscript - SECOND ASYNC WITH TOP-LEVEL LOOP BLOCKING AWAIT AT SAME LEVEL AS LOOP Pyscript writing to console.log:
<py-script>
import js
import asyncio
for i in range(3):
js.console.log('B', i)
await asyncio.sleep(2)
</py-script>
</div>
</body>
</html>

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Async Await BLOCKING LOOP Pyscript Twice</title>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<py-script>
import asyncio
from itertools import count
for i in count():
print(f"Count: {i}")
await asyncio.sleep(1)
</py-script>
</body>
</html>

115
examples/bokeh.html Normal file
View File

@@ -0,0 +1,115 @@
<html><head>
<title>Bokeh Example</title>
<meta charset="iso-8859-1">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.2.min.js"></script>
<script type="text/javascript">
Bokeh.set_log_level("info");
</script>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link rel="stylesheet" href="./assets/css/examples.css" />
<link rel="stylesheet" href="./assets/prism/prism.css" />
<script defer src="./assets/prism/prism.js"></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000;">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo">
</a>
<a class="title" href="" style="color: #f0ab3c;">Bokeh Example</a>
</div>
</nav>
<section class="pyscript">
<div id="myplot"></div>
<py-config>
packages = [
"bokeh",
"numpy"
]
</py-config>
<py-script id="main">
import json
import pyodide
from js import Bokeh, console, JSON
from bokeh.embed import json_item
from bokeh.plotting import figure
from bokeh.resources import CDN
# create a new plot with default tools, using figure
p = figure(plot_width=400, plot_height=400)
# add a circle renderer with x and y coordinates, size, color, and alpha
p.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=15, line_color="navy", fill_color="orange", fill_alpha=0.5)
p_json = json.dumps(json_item(p, "myplot"))
Bokeh.embed.embed_item(JSON.parse(p_json))
</py-script>
</section>
<section class="code">
<div id="view-code-button" role="button" aria-pressed="false" tabindex="0">View Code</div>
<div id="code-section" class="code-section-hidden">
<p>index.html</p>
<pre class="prism-code language-html">
<code class="language-html">
&lt;py-config&gt;
packages = [
"bokeh",
"numpy"
]
&lt;/py-config&gt;
&lt;py-script id="main"&gt;
import json
import pyodide
from js import Bokeh, console, JSON
from bokeh.embed import json_item
from bokeh.plotting import figure
from bokeh.resources import CDN
# create a new plot with default tools, using figure
p = figure(plot_width=400, plot_height=400)
# add a circle renderer with x and y coordinates, size, color, and alpha
p.circle([1, 2, 3, 4, 5], [6, 7, 2, 4, 5], size=15, line_color="navy", fill_color="orange", fill_alpha=0.5)
p_json = json.dumps(json_item(p, "myplot"))
Bokeh.embed.embed_item(JSON.parse(p_json))
&lt;/py-script&gt;
</code>
</pre>
</div>
</section>
</body>
<script>
const viewCodeButton = document.getElementById("view-code-button");
const codeSection = document.getElementById("code-section");
const handleClick = () => {
if (codeSection.classList.contains("code-section-hidden")) {
codeSection.classList.remove("code-section-hidden");
codeSection.classList.add("code-section-visible");
} else {
codeSection.classList.remove("code-section-visible");
codeSection.classList.add("code-section-hidden");
}
}
viewCodeButton.addEventListener("click", handleClick)
viewCodeButton.addEventListener("keydown", (e) => {
if (e.key === " " || e.key === "Enter" || e.key === "Spacebar") {
handleClick();
}
})
</script>
</html>

View File

@@ -0,0 +1,216 @@
<html><head>
<title>Bokeh Example</title>
<meta charset="iso-8859-1">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-2.4.2.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-gl-2.4.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.4.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.4.2.min.js"></script>
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-2.4.2.min.js"></script>
<link rel="stylesheet" href="./assets/css/examples.css" />
<link rel="stylesheet" href="./assets/prism/prism.css" />
<script defer src="./assets/prism/prism.js"></script>
<script type="text/javascript">
Bokeh.set_log_level("info");
</script>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000;">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo">
</a>
<a class="title" href="" style="color: #f0ab3c;">Bokeh Example</a>
</div>
</nav>
<section class="pyscript">
<h1>Bokeh Example</h1>
<div id="myplot"></div>
<py-config>
packages = [
"bokeh",
"numpy"
]
</py-config>
<py-script id="main">
import asyncio
import json
import pyodide
from js import Bokeh, console, JSON
from bokeh import __version__
from bokeh.document import Document
from bokeh.embed.util import OutputDocumentFor, standalone_docs_json_and_render_items
from bokeh.models import Slider, Div
from bokeh.layouts import Row
from bokeh.protocol.messages.patch_doc import process_document_events
# create a new plot with default tools, using figure
p = Slider(start=0.1, end=10, value=1, step=.1, title="Amplitude")
div = Div(text=f'Amplitude is: {p.value}')
def callback(attr, old, new):
div.text = f'Amplitude is: {new}'
p.on_change('value', callback)
row = Row(children=[p, div])
def doc_json(model, target):
with OutputDocumentFor([model]) as doc:
doc.title = ""
docs_json, _ = standalone_docs_json_and_render_items(
[model], suppress_callback_warning=True
)
doc_json = list(docs_json.values())[0]
root_id = doc_json['roots']['root_ids'][0]
return doc, json.dumps(dict(
target_id = target,
root_id = root_id,
doc = doc_json,
version = __version__,
))
def _link_docs(pydoc, jsdoc):
def jssync(event):
if getattr(event, 'setter_id', None) is not None:
return
events = [event]
json_patch = jsdoc.create_json_patch_string(pyodide.ffi.to_js(events))
pydoc.apply_json_patch(json.loads(json_patch))
jsdoc.on_change(pyodide.ffi.create_proxy(jssync), pyodide.ffi.to_js(False))
def pysync(event):
json_patch, buffers = process_document_events([event], use_buffers=True)
buffer_map = {}
for (ref, buffer) in buffers:
buffer_map[ref['id']] = buffer
jsdoc.apply_json_patch(JSON.parse(json_patch), pyodide.ffi.to_js(buffer_map), setter_id='js')
pydoc.on_change(pysync)
async def show(plot, target):
pydoc, model_json = doc_json(plot, target)
views = await Bokeh.embed.embed_item(JSON.parse(model_json))
jsdoc = views[0].model.document
_link_docs(pydoc, jsdoc)
asyncio.ensure_future(show(row, 'myplot'))
</py-script>
</section>
<section class="code">
<div id="view-code-button" role="button" aria-pressed="false" tabindex="0">View Code</div>
<div id="code-section" class="code-section-hidden">
<p>index.html</p>
<pre class="prism-code language-html">
<code class="language-html">
&lt;py-config&gt;
packages = [
"bokeh",
"numpy"
]
&lt;/py-config&gt;
&lt;py-script id="main"&gt;
import asyncio
import json
import pyodide
from js import Bokeh, console, JSON
from bokeh import __version__
from bokeh.document import Document
from bokeh.embed.util import OutputDocumentFor, standalone_docs_json_and_render_items
from bokeh.models import Slider, Div
from bokeh.layouts import Row
from bokeh.protocol.messages.patch_doc import process_document_events
# create a new plot with default tools, using figure
p = Slider(start=0.1, end=10, value=1, step=.1, title="Amplitude")
div = Div(text=f'Amplitude is: {p.value}')
def callback(attr, old, new):
div.text = f'Amplitude is: {new}'
p.on_change('value', callback)
row = Row(children=[p, div])
def doc_json(model, target):
with OutputDocumentFor([model]) as doc:
doc.title = ""
docs_json, _ = standalone_docs_json_and_render_items(
[model], suppress_callback_warning=True
)
doc_json = list(docs_json.values())[0]
root_id = doc_json['roots']['root_ids'][0]
return doc, json.dumps(dict(
target_id = target,
root_id = root_id,
doc = doc_json,
version = __version__,
))
def _link_docs(pydoc, jsdoc):
def jssync(event):
if getattr(event, 'setter_id', None) is not None:
return
events = [event]
json_patch = jsdoc.create_json_patch_string(pyodide.ffi.to_js(events))
pydoc.apply_json_patch(json.loads(json_patch))
jsdoc.on_change(pyodide.ffi.create_proxy(jssync), pyodide.ffi.to_js(False))
def pysync(event):
json_patch, buffers = process_document_events([event], use_buffers=True)
buffer_map = {}
for (ref, buffer) in buffers:
buffer_map[ref['id']] = buffer
jsdoc.apply_json_patch(JSON.parse(json_patch), pyodide.ffi.to_js(buffer_map), setter_id='js')
pydoc.on_change(pysync)
async def show(plot, target):
pydoc, model_json = doc_json(plot, target)
views = await Bokeh.embed.embed_item(JSON.parse(model_json))
jsdoc = views[0].model.document
_link_docs(pydoc, jsdoc)
asyncio.ensure_future(show(row, 'myplot'))
&lt;/py-script&gt;
</code>
</pre>
</div>
</section>
</body>
<script>
const viewCodeButton = document.getElementById("view-code-button");
const codeSection = document.getElementById("code-section");
const handleClick = () => {
if (codeSection.classList.contains("code-section-hidden")) {
codeSection.classList.remove("code-section-hidden");
codeSection.classList.add("code-section-visible");
} else {
codeSection.classList.remove("code-section-visible");
codeSection.classList.add("code-section-hidden");
}
}
viewCodeButton.addEventListener("click", handleClick)
viewCodeButton.addEventListener("keydown", (e) => {
if (e.key === " " || e.key === "Enter" || e.key === "Spacebar") {
handleClick();
}
})
</script>
</html>

314
examples/d3.html Normal file
View File

@@ -0,0 +1,314 @@
<html>
<head>
<title>d3: JavaScript & PyScript visualizations side-by-side</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link rel="stylesheet" href="./assets/css/examples.css" />
<link rel="stylesheet" href="./assets/prism/prism.css" />
<script defer src="./assets/prism/prism.js"></script>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
.loading {
display: inline-block;
width: 50px;
height: 50px;
border: 3px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: black;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<nav class="navbar" style="background-color: #000000;">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo">
</a>
<a class="title" href="" style="color: #f0ab3c;">Simple d3 visualization</a>
</div>
</nav>
<section class="pyscript">
<b>
Based on <i><a href="https://observablehq.com/@d3/learn-d3-shapes?collection=@d3/learn-d3>">Learn D3: Shapes</a></i> tutorial.
</b>
<div style="display: flex; flex-direction: row">
<div>
<div style="text-align: center">JavaScript version</div>
<div id="js" style="width: 400px; height: 400px">
<div class="loading"></div>
</div>
</div>
<div>
<div style="text-align: center">PyScript version</div>
<div id="py" style="width: 400px; height: 400px">
<div class="loading"></div>
</div>
</div>
</div>
<script type="module">
const fruits = [
{name: "🍊", count: 21},
{name: "🍇", count: 13},
{name: "🍏", count: 8},
{name: "🍌", count: 5},
{name: "🍐", count: 3},
{name: "🍋", count: 2},
{name: "🍎", count: 1},
{name: "🍉", count: 1},
]
const fn = (d) => d.count
const data = d3.pie().value(fn)(fruits)
const arc = d3.arc()
.innerRadius(210)
.outerRadius(310)
.padRadius(300)
.padAngle(2 / 300)
.cornerRadius(8)
const js = d3.select("#js")
js.select(".loading").remove()
const svg = js
.append("svg")
.attr("viewBox", "-320 -320 640 640")
.attr("width", "400")
.attr("height", "400")
for (const d of data) {
svg.append("path")
.style("fill", "steelblue")
.attr("d", arc(d))
const text = svg.append("text")
.style("fill", "white")
.attr("transform", `translate(${arc.centroid(d).join(",")})`)
.attr("text-anchor", "middle")
text.append("tspan")
.style("font-size", "24")
.attr("x", "0").text(d.data.name)
text.append("tspan")
.style("font-size", "18")
.attr("x", "0")
.attr("dy", "1.3em")
.text(d.value)
}
</script>
<py-script>
import js
from pyodide.ffi import create_proxy, to_js
d3 = js.d3
fruits = [
dict(name="🍊", count=21),
dict(name="🍇", count=13),
dict(name="🍏", count=8),
dict(name="🍌", count=5),
dict(name="🍐", count=3),
dict(name="🍋", count=2),
dict(name="🍎", count=1),
dict(name="🍉", count=1),
]
fn = create_proxy(lambda d, *_: d["count"])
data = d3.pie().value(fn)(to_js(fruits))
arc = (d3.arc()
.innerRadius(210)
.outerRadius(310)
.padRadius(300)
.padAngle(2 / 300)
.cornerRadius(8))
py = d3.select("#py")
py.select(".loading").remove()
svg = (py
.append("svg")
.attr("viewBox", "-320 -320 640 640")
.attr("width", "400")
.attr("height", "400"))
for d in data:
d_py = d.to_py()
(svg.append("path")
.style("fill", "steelblue")
.attr("d", arc(d)))
text = (svg.append("text")
.style("fill", "white")
.attr("transform", f"translate({arc.centroid(d).join(',')})")
.attr("text-anchor", "middle"))
(text.append("tspan")
.style("font-size", "24")
.attr("x", "0")
.text(d_py["data"]["name"]))
(text.append("tspan")
.style("font-size", "18")
.attr("x", "0")
.attr("dy", "1.3em")
.text(d_py["value"]))
</py-script>
</section>
<section class="code">
<div id="view-code-button" role="button" aria-pressed="false" tabindex="0">View Code</div>
<div id="code-section" class="code-section-hidden">
<p>index.html</p>
<pre class="prism-code language-html">
<code class="language-html">
&lt;script&gt;
import * as d3 from "https://cdn.skypack.dev/pin/d3@v7.6.1-1Q0NZ0WZnbYeSjDusJT3/mode=imports,min/optimized/d3.js";
const fruits = [
{name: "🍊", count: 21},
{name: "🍇", count: 13},
{name: "🍏", count: 8},
{name: "🍌", count: 5},
{name: "🍐", count: 3},
{name: "🍋", count: 2},
{name: "🍎", count: 1},
{name: "🍉", count: 1},
]
const fn = (d) => d.count
const data = d3.pie().value(fn)(fruits)
const arc = d3.arc()
.innerRadius(210)
.outerRadius(310)
.padRadius(300)
.padAngle(2 / 300)
.cornerRadius(8)
const js = d3.select("#js")
js.select(".loading").remove()
const svg = js
.append("svg")
.attr("viewBox", "-320 -320 640 640")
.attr("width", "400")
.attr("height", "400")
for (const d of data) {
svg.append("path")
.style("fill", "steelblue")
.attr("d", arc(d))
const text = svg.append("text")
.style("fill", "white")
.attr("transform", `translate(${arc.centroid(d).join(",")})`)
.attr("text-anchor", "middle")
text.append("tspan")
.style("font-size", "24")
.attr("x", "0").text(d.data.name)
text.append("tspan")
.style("font-size", "18")
.attr("x", "0")
.attr("dy", "1.3em")
.text(d.value)
}
&lt;/script&gt;
&lt;py-script&gt;
from pyodide.ffi import create_proxy, to_js
import d3
fruits = [
dict(name="🍊", count=21),
dict(name="🍇", count=13),
dict(name="🍏", count=8),
dict(name="🍌", count=5),
dict(name="🍐", count=3),
dict(name="🍋", count=2),
dict(name="🍎", count=1),
dict(name="🍉", count=1),
]
fn = create_proxy(lambda d, *_: d["count"])
data = d3.pie().value(fn)(to_js(fruits))
arc = (d3.arc()
.innerRadius(210)
.outerRadius(310)
.padRadius(300)
.padAngle(2 / 300)
.cornerRadius(8))
py = d3.select("#py")
py.select(".loading").remove()
svg = (py
.append("svg")
.attr("viewBox", "-320 -320 640 640")
.attr("width", "400")
.attr("height", "400"))
for d in data:
d_py = d.to_py()
(svg.append("path")
.style("fill", "steelblue")
.attr("d", arc(d)))
text = (svg.append("text")
.style("fill", "white")
.attr("transform", f"translate({arc.centroid(d).join(',')})")
.attr("text-anchor", "middle"))
(text.append("tspan")
.style("font-size", "24")
.attr("x", "0")
.text(d_py["data"]["name"]))
(text.append("tspan")
.style("font-size", "18")
.attr("x", "0")
.attr("dy", "1.3em")
.text(d_py["value"]))
&lt;/py-script&gt;
</code>
</pre>
</div>
</section>
</body>
<script>
const viewCodeButton = document.getElementById("view-code-button");
const codeSection = document.getElementById("code-section");
const handleClick = () => {
if (codeSection.classList.contains("code-section-hidden")) {
codeSection.classList.remove("code-section-hidden");
codeSection.classList.add("code-section-visible");
} else {
codeSection.classList.remove("code-section-visible");
codeSection.classList.add("code-section-hidden");
}
}
viewCodeButton.addEventListener("click", handleClick)
viewCodeButton.addEventListener("keydown", (e) => {
if (e.key === " " || e.key === "Enter" || e.key === "Spacebar") {
handleClick();
}
})
</script>
</html>

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

136
examples/folium.html Normal file
View File

@@ -0,0 +1,136 @@
<html>
<head>
<title>Folium</title>
<meta charset="utf-8">
<link rel="icon" type="image/x-icon" href="./favicon.png">
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link rel="stylesheet" href="./assets/css/examples.css" />
<link rel="stylesheet" href="./assets/prism/prism.css" />
<script defer src="./assets/prism/prism.js"></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000;">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo">
</a>
<a class="title" href="" style="color: #f0ab3c;">Folium</a>
</div>
</nav>
<section class="pyscript">
<div id="folium"></div>
<py-config>
packages = [
"folium",
"pandas"
]
</py-config>
<py-script>
import folium
import json
import pandas as pd
from pyodide.http import open_url
url = (
"https://raw.githubusercontent.com/python-visualization/folium/master/examples/data"
)
state_geo = f"{url}/us-states.json"
state_unemployment = f"{url}/US_Unemployment_Oct2012.csv"
state_data = pd.read_csv(open_url(state_unemployment))
geo_json = json.loads(open_url(state_geo).read())
m = folium.Map(location=[48, -102], zoom_start=3)
folium.Choropleth(
geo_data=geo_json,
name="choropleth",
data=state_data,
columns=["State", "Unemployment"],
key_on="feature.id",
fill_color="YlGn",
fill_opacity=0.7,
line_opacity=0.2,
legend_name="Unemployment Rate (%)",
).add_to(m)
folium.LayerControl().add_to(m)
display(m, target="folium")
</py-script>
</section>
<section class="code">
<div id="view-code-button" role="button" aria-pressed="false" tabindex="0">View Code</div>
<div id="code-section" class="code-section-hidden">
<p>index.html</p>
<pre class="prism-code language-html">
<code class="language-html">
&lt;div id="folium"&gt;&lt;/div&gt;
&lt;py-config&gt;
packages = [
"folium",
"pandas"
]
&lt;/py-config&gt;
&lt;py-script&gt;
import folium
import json
import pandas as pd
from pyodide.http import open_url
url = (
"https://raw.githubusercontent.com/python-visualization/folium/master/examples/data"
)
state_geo = f"{url}/us-states.json"
state_unemployment = f"{url}/US_Unemployment_Oct2012.csv"
state_data = pd.read_csv(open_url(state_unemployment))
geo_json = json.loads(open_url(state_geo).read())
m = folium.Map(location=[48, -102], zoom_start=3)
folium.Choropleth(
geo_data=geo_json,
name="choropleth",
data=state_data,
columns=["State", "Unemployment"],
key_on="feature.id",
fill_color="YlGn",
fill_opacity=0.7,
line_opacity=0.2,
legend_name="Unemployment Rate (%)",
).add_to(m)
folium.LayerControl().add_to(m)
display(m, target="folium")
&lt;/py-script&gt;
</code>
</pre>
</div>
</section>
</body>
<script>
const viewCodeButton = document.getElementById("view-code-button");
const codeSection = document.getElementById("code-section");
const handleClick = () => {
if (codeSection.classList.contains("code-section-hidden")) {
codeSection.classList.remove("code-section-hidden");
codeSection.classList.add("code-section-visible");
} else {
codeSection.classList.remove("code-section-visible");
codeSection.classList.add("code-section-hidden");
}
}
viewCodeButton.addEventListener("click", handleClick)
viewCodeButton.addEventListener("keydown", (e) => {
if (e.key === " " || e.key === "Enter" || e.key === "Spacebar") {
handleClick();
}
})
</script>
</html>

View File

@@ -4,12 +4,12 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" /> <meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Svelte app</title> <title>Say Hello</title>
<link rel="icon" type="image/png" href="favicon.png" /> <link rel="icon" type="image/png" href="../favicon.png" />
<link rel="stylesheet" href="../https://pyscript.net/alpha/pyscript.css" /> <link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="../https://pyscript.net/alpha/pyscript.js"></script> <script defer src="https://pyscript.net/latest/pyscript.js"></script>
</head> </head>
<body> <body>
@@ -106,7 +106,7 @@ pyscript.run_until_complete(start())
</py-script> </py-script>
<div class="mb10"> <div class="mb10">
<button id="trackbutton" class="bx--btn bx--btn--secondary" type="button" pys-onClick="toggle_video"> <button id="trackbutton" class="bx--btn bx--btn--secondary" type="button" py-onClick="toggle_video()">
Toggle Video Toggle Video
</button> </button>
<button id="nextimagebutton" class="mt10 bx--btn bx--btn--secondary" type="button" disabled> <button id="nextimagebutton" class="mt10 bx--btn bx--btn--secondary" type="button" disabled>

71
examples/hello_world.html Normal file
View File

@@ -0,0 +1,71 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>PyScript Hello World</title>
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<link rel="stylesheet" href="./assets/css/examples.css" />
<link rel="stylesheet" href="./assets/prism/prism.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<script defer src="./assets/prism/prism.js"></script>
</head>
<body>
<nav class="navbar" style="background-color: #000000;">
<div class="app-header">
<a href="/">
<img src="./logo.png" class="logo">
</a>
<a class="title" href="" style="color: #f0ab3c;">Hello World</a>
</div>
</nav>
<section class="pyscript">
Hello world! <br>
This is the current date and time, as computed by Python:
<py-script>
from datetime import datetime
now = datetime.now()
display(now.strftime("%m/%d/%Y, %H:%M:%S"))
</py-script>
</section>
<section class="code">
<div id="view-code-button" role="button" aria-pressed="false" tabindex="0">View Code</div>
<div id="code-section" class="code-section-hidden">
<p>index.html</p>
<pre class="prism-code language-html">
<code class="language-html">
&lt;py-script&gt;
from datetime import datetime
now = datetime.now()
display(now.strftime("%m/%d/%Y, %H:%M:%S"))
&lt;/py-script&gt;
</code>
</pre>
</div>
</section>
</body>
<script>
const viewCodeButton = document.getElementById("view-code-button");
const codeSection = document.getElementById("code-section");
const handleClick = () => {
if (codeSection.classList.contains("code-section-hidden")) {
codeSection.classList.remove("code-section-hidden");
codeSection.classList.add("code-section-visible");
} else {
codeSection.classList.remove("code-section-visible");
codeSection.classList.add("code-section-hidden");
}
}
viewCodeButton.addEventListener("click", handleClick)
viewCodeButton.addEventListener("keydown", (e) => {
if (e.key === " " || e.key === "Enter" || e.key === "Spacebar") {
handleClick();
}
})
</script>
</html>

276
examples/index.html Normal file
View File

@@ -0,0 +1,276 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>PyScript demo</title>
<link rel="icon" type="image/png" href="favicon.png" />
<link rel="stylesheet" href="./assets/css/main.css" />
<link rel="stylesheet" href="./assets/css/index.css" />
</head>
<body class="container">
<h1 class="title-main">PyScript demos</h1>
<section class="example">
<h2>Basic examples</h2>
<div class="container-card">
<div class="card">
<div class="card-content">
<a href="./hello_world.html" target="_blank">
<h2>Hello world</h2>
</a>
<p>
A static demo of the <code>&lt;py-script&gt;</code> tag
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./simple_clock.html" target="_blank">
<h2>Simple clock</h2>
</a>
<p>
A dynamic demo of the <code>&lt;py-script&gt;</code> tag
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./repl.html" target="_blank">
<h2>REPL</h2>
</a>
<p>
A Python REPL (Read Eval Print Loop)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./repl2.html" target="_blank">
<h2>REPL2</h2>
</a>
<p>
A Python REPL (Read Eval Print Loop) with slightly better formatting
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./todo.html" target="_blank">
<h2>TODO App</h2>
</a>
<p>
Simple TODO App
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./todo-pylist.html" target="_blank">
<h2>PyScript Native TODO App</h2>
</a>
<p>
Simple TODO App using <code>&lt;py-list&gt;</code>
</p>
</div>
</div>
</div>
</section>
<section class="example">
<h2>MIME Rendering</h2>
<div class="container-card">
<div class="card">
<div class="card-content">
<a href="./matplotlib.html" target="_blank">
<h2>Matplotlib</h2>
</a>
<p>
Demonstrates rendering a <a href="https://matplotlib.org/" target="_blank">Matplotlib</a> figure as output of the py-script tag
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./altair.html" target="_blank">
<h2>
Altair
</h2>
</a>
<p>
Demonstrates rendering a <a href="https://altair-viz.github.io/" target="_blank">Altair</a> plot as output of the py-script tag
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./folium.html" target="_blank">
<h2>
Folium
</h2>
</a>
<p>
Demonstrates rendering a
<a href="https://python-visualization.github.io/folium/" target="_blank">Folium</a>
map as output of the py-script tag
</p>
</div>
</div>
</div>
</section>
<section class="example">
<h2>JS Interaction</h2>
<div class="container-card">
<div class="card">
<div class="card-content">
<a href="./d3.html" target="_blank">
<h2>
Simple d3 visualization
</h2>
</a>
<p>
Minimal <a href="https://d3js.org/" target="_blank">D3</a>
demo demonstrating how to create a visualization
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./webgl/raycaster/index.html" target="_blank">
<h2>
Webgl Icosahedron Example
</h2>
</a>
<p>
Demo showing how a Simple <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API" target="_blank">WebGL</a>
scene would work in PyScript</code> tag
</p>
</div>
</div>
</div>
</section>
<section class="example">
<h2>Visualizations & Dashboards</h2>
<div class="container-card">
<div class="card">
<div class="card-content">
<a href="./bokeh.html" target="_blank">
<h2>
Simple Static Bokeh Plot
</h2>
</a>
<p>
Minimal Bokeh demo demonstrating how to create a simple
<a href="https://bokeh.org/" target="_blank">Bokeh</a>
plot from code
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./bokeh_interactive.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
Bokeh Interactive
</h2>
</a>
<p>
Interactive demo using a
<a href="https://bokeh.org/" target="_blank">Bokeh</a>
slider widget to dynamically change a value in the page
WARNING: This examples takes a little longer to load. So be patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./panel_kmeans.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
KMeans Demo in Panel
</h2>
</a>
<p>
Interactive KMeans Chart using
<a href="https://panel.holoviz.org/" target="_blank">Panel</a>
WARNING: This examples takes a little longer to load. So be patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./panel_stream.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
Streaming Demo in Panel
</h2>
</a>
<p>
Interactive Streaming Table and Bokeh plot using
<a href="https://panel.holoviz.org/" target="_blank">Panel</a>
WARNING: This examples takes a little longer to load. So be patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./panel.html" target="_blank">
<h2 class="text-3xl font-bold text-blue-600">
Simple Panel Demo
</h2>
</a>
<p>
Simple demo showing
<a href="https://panel.holoviz.org/" target="_blank">Panel</a>
widgets interacting with parts of the page
WARNING: This examples takes a little longer to load. So be patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./panel_deckgl.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
NYC Taxi Data Panel DeckGL Demo
</h2>
</a>
<p>
Interactive application exploring the NYC Taxi dataset using
<a href="https://panel.holoviz.org/" target="_blank">Panel</a> and <a href="https://deck.gl/" target="_blank">DeckGL</a>
WARNING: This examples takes a little longer to load. So be patient :)
</p>
</div>
</div>
<div class="card">
<div class="card-content">
<a href="./numpy_canvas_fractals.html" target="_blank">
<h2 class="text-2xl font-bold text-blue-600">
Fractals with NumPy and canvas
</h2>
</a>
<p>
Visualization of Mandelbrot and Julia sets with
<a href="https://numpy.org/" target="_blank">Numpy</a> and
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API" target="_blank">
HTML5 canvas
</a>
</p>
</div>
</div>
</div>
</section>
</body>
</html>

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Some files were not shown because too many files have changed in this diff Show More