Compare commits

...

435 Commits

Author SHA1 Message Date
Martin
999897df12 The all-new, pyscript.web (ignore the branch name :) ) (#2129)
* Minor cleanups: move all Element classes to bottom of module.

* Commenting.

* Commenting.

* Commenting.

* Group dunder methods.

* Don't cache the element's parent.

* Remove style type check until we decide whether or not to add for classes too.

* Add ability to register/unregister element classes.

* Implement __iter__ for container elements.

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

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

* Minor renaming to make it clear when we have an Element instance vs an actual DOM element.

* remove duplication: added Element.get_tag_name

* Commenting.

* Allow Element.append to 1) use *args, 2) accept iterables

* Remove iterable check - inteferes with js proxies.

* Don't use *args, so it quacks more like a list ;)

* Element.append take 2 :)

* Remove unused code.

* Move to web.py with a page object!

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

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

* Added 'page.title' too :)

* Add __getitem__ as a shortcut for page.find

* Add Element.__getitem__ to be consistent

* Make __getitem__ consistent for Page, Element and ElementCollection.

* Docstringing.

* Docstringing.

* Docstringing/commenting.

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

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

* fix select.add (revert InnerHTML->html)

* Commenting.

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

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

* Hand-edit some of the AI :)

* Rename ElementCollection.children -> ElementCollection.elements

* Remove unnecessary guard.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-08-01 10:36:57 +01:00
Andrea Giammarchi
d47fb58ede Update Pyodide to its 0.26.2 version (#2133) 2024-07-31 20:34:21 +02:00
Andrea Giammarchi
f316341e73 Updated Polyscript and added Panel worker test (#2130)
* Updated Polyscript and added Panel worker 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>
2024-07-31 14:31:35 +02:00
Andrea Giammarchi
8c46fcabf7 Updating polyscript to its latest (#2128)
* Updating polyscript to its latest
2024-07-29 16:59:31 +02:00
Martin
e4ff4d8fab Controversial version where Element just delegates to the underlying DOM element. (#2127)
* Update elements.py

* remove grid which allows simpler class tag mapping.
2024-07-24 13:27:12 -05:00
Martin
f20a0003ed fix: broken methods video.snap and canvas.download (#2126)
* fix: broken methods video.snap and canvas.download

* Allow canvas.draw to use actual image width/height.
2024-07-23 15:35:07 -05:00
Martin
6c938dfe3b Override __getattr__ and __setattr__ on ElementCollection. (#2116)
* Override __getattr__ and __setattr__ on ElementCollection.

* fix: bug when using a string to query an ElementCollection.

* Use Element.find when indexing ElementCollection with a string.

* For consistency also have a find method on ElementCollection.

* ElementCollection.find now returns a collection of collections :)

* fix tests: for textContent

* Revert to extend for ElementCollection.find :)

* Make element_from_dom a classmethod Element.from_dom

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

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

* rename: Element.from_dom -> Element.from_dom_element

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

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

* PyCharm warning sweep.

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

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

* Workaround for mp not allowing setting via __dict__

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-07-22 10:32:37 -05:00
Andrea Giammarchi
d884586a82 Updated Polyscript to its latest (#2124) 2024-07-19 12:21:04 +02:00
Fabio Pliger
f8f7ba89c1 Cleanup pyscript web elements (#2094)
* change pydom example to use new pyscript.web namespace

* change tests to use new pyscript.web namespace

* create new pyscript.web package and move pydom to pyscript.web.dom

* add __init__ to pyscript.web and expose the dom instance instead of the pyscript.web.dom module

* move elements from pyweb.ui to pyscript.web and temp fix pydom import

* moved of elements file completed

* moved media from pyweb to pyscript.web

* RIP pyweb

* move JSProperty from pyscript.web.dom to pyscript.web.elements

* move element classes from pyscript.web.dom to pyscript.web.elements

* first round of fixes while running tests

* fix test typo

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

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

* restore right type type returned for Element.parent. ALL TESTS PASS LOCALLY NOW

* lint

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

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

* clean up dom.py from dead commented code and osbolete comments

* bugfix: dom shouldn't return None when it can't find any element for a specific selector so it now returns an empty collection

* additional cleanup in tests

* lint

* initial cleaning up of unused modules

* change element.append to not consider types anymore and add tests for appending elements.Element or a JsProxy object

* add Element.append tests for append JS elements directly and appending nodeList as well

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

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

* Tag and create the correct subclass of Element.

* Move: Element.snap -> video.snap

* Move: Element.download and draw to canvas.download and draw.

* Minor cleanups.

* Commenting.

* Allow css classes to be passed to Element constructor.

* Commenting.

* Typo fix.

* Make html, id and text JSProperties.

* Commenting.

* Remove unnecessary selected attribute on BaseElement.

* Extract: BaseElement.from_js -> element_from_js

* Pass *args and **kwargs to element_from_js and remove BaseElement.create

* Move value attribute to specific Element subclasses.

* fix: wrapping of existing js elements.

* Add body and head elements so parent and children work everywhere.

* Revert order of HasOptions mixin for the select element.

* Comment out tests that are no longer relevant (see comment).

* Use correct super args in mixin.

* Have to use element_from_js when returning options from OptionsProxy.

* rename: StyleProxy -> Style, OptionsProxy -> Options and added Classes.

* Remove cached_property.

* Remove list-y methods from Classes collection.

* Allow explicit children or *args for containers.

* controversial: fix tests to use find rather than dom

* Add html element so (say) body.parent does what is expected.

* Collapse Element class hierarchy.

* rename: js_element -> dom_element

* rename: element_from_js -> element_from_dom

* replace: JS with DOM

* rename: _js -> _dom_element

* fix dom tests.

* Complete element list with void elements derived from Element.

* Added attributes to the newly added Element subclasses.

* remove dom module, replace with instance.

Also, remove media :)

* fix: typo in test for 'b' element.

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

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

* Remove dom and media modules.

* fix up ts definitions.

* Added missing import (used in content property).

* Added TODO :)

* wip: Add ClassesCollection

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

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

* Attempt to ask black to leave class list alone.

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

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

* Add classes attribute to ElementCollection

* wip: work on classes collection

* Extract code to get set of all class names in ClassesCollection.

* Update elements.py

* Polishing.

* Make children return an ElementCollection

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

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

* wip: Add the ability to set multiple properties.

* Add __getitem__ back to the dom object.

* Put validation when setting DOM properties back in.

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

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

* All tests green.

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

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

* Remove unnecessary comment.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Martin <martin.chilvers@gmail.com>
2024-07-03 14:21:23 -07:00
Andrea Giammarchi
67d47511d5 Fix MicroPython terminal input when no REPL is used/needed (#2113)
* Fix terminal input when no REPL is used/needed
* Fix input backspace too
2024-07-03 13:03:31 +02:00
Andrea Giammarchi
6f49f18937 Updated Polyscript with its workers feature (#2104)
* Updated Polyscript with its workers feature
* Worked around the inconsistent behavior between Pyodide and MicroPython
* Fixed Pyodide greedy access to undesired Proxy fields
2024-06-26 14:01:22 +02:00
Andrea Giammarchi
7b8ef7ebe2 Fix #2109 - Allow inline JSON config attribute in PyEditor (#2110)
Fix #2109 - Allow inline JSON config attribute in PyEditor
2024-06-24 17:04:28 +02:00
Andrea Giammarchi
461ae38763 Updated reference code to grab latest (#2107) 2024-06-21 16:06:18 +02:00
Andrea Giammarchi
4b90ebdef5 Bring back pyweb as it was (#2105) 2024-06-21 14:49:20 +02:00
Andrea Giammarchi
15c19aa708 Updated Polyscript with latest MicroPython (#2103) 2024-06-19 17:56:22 +02:00
Andrea Giammarchi
d0406be84c A persistent IndexedDB store for PyScript (#2101)
A persistent IndexedDB store for PyScript
2024-06-19 14:11:57 +02:00
Andrea Giammarchi
aab015b9b8 Better py editor indentation (#2098)
Better PyEditor Indentation
2024-06-13 11:34:14 +02:00
Andrea Giammarchi
a1e5a05b49 PyEditor cumulative fixes & improvements (#2095)
* PyEditor fixes

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

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

* PyEditor cumulative fixes & improvements

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-06-12 18:55:36 +02:00
Fabio Pliger
f1a787e031 move pydom and elements from pyweb to pyscript.web (#2092)
* change pydom example to use new pyscript.web namespace

* change tests to use new pyscript.web namespace

* create new pyscript.web package and move pydom to pyscript.web.dom

* add __init__ to pyscript.web and expose the dom instance instead of the pyscript.web.dom module

* move elements from pyweb.ui to pyscript.web and temp fix pydom import

* moved of elements file completed

* moved media from pyweb to pyscript.web

* RIP pyweb

* move JSProperty from pyscript.web.dom to pyscript.web.elements

* move element classes from pyscript.web.dom to pyscript.web.elements

* first round of fixes while running tests

* fix test typo

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

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

* restore right type type returned for Element.parent. ALL TESTS PASS LOCALLY NOW

* lint

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

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

* clean up dom.py from dead commented code and osbolete comments

* bugfix: dom shouldn't return None when it can't find any element for a specific selector so it now returns an empty collection

* additional cleanup in tests

* lint

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-06-06 15:42:14 +02:00
Fabio Pliger
b41cfb7b60 UI creation API (#1960)
* add JSProperty to pydom so it can be used to create descriptors mapping to specific JS attributes

* add pyweb.ui

* fix pyweb imports

* fix link and a elements and add a script element

* fix imports and add initialization to load resources to shoelace module

* new pyweb.ui test folder

* remove comments

* add Icon to shoelace components

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

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

* use html property rather than accessing _js directly

* add markdown suppport

* move examples section out of stdlib pyweb to examples.py in the demo itself

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

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

* simplify demo code

* improve docstrings

* precommit fixes

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

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

* simplify code for main page

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

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

* add load_resources to markdown

* add showlace extra style dynamically

* precommit

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

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

* add gallery files

* add global attributes and dynamic property assignment

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

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

* Add shoelace radio component (#1961)

* add shoelace radio component

* [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>

* fix type that lead using the the JSDescriptor directly instead of the factory method

* add missing marked dependency

* refactor gallary to simplify codebase

* precommig lint

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

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

* add text attribute to pydom Elements

* add global JS attributes to elements and improve demos

* lint

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

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

* fix image instantiation on card since the API has changed

* add attributes to all classes in elements

* lint

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

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

* change example creation functions to take the label and the object directly

* fix input name clashing with input keyword

* refactor examples to better simplify and automate

* fix div clashing names

* fix demo left menu width

* simplify base elements demo by moving all the examples to the examples module

* rename Grid to grid to align to other elements

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

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

* reorg classes order in elements.py and add missing elements to examples

* fix issue related to now importing div from pyweb.ui

* improve demo

* link and fix spelling typo

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

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

* Add a bunch more elements (#1966)

* Add copy button

* Add skeleton and spinner

* Add Switch

* Add text area

* Add more elements

* More styling to each component

* [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@users.noreply.github.com>

* Add radio group (#1963)

* add radio group

* [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@users.noreply.github.com>

* Small tweaks to main demo page (#1962)

* Small tweaks to main demo page

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

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

* [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@users.noreply.github.com>

* fix post merge issues

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

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

* fixed issues with renaming Grid to grid, after we merged

* lint

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

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

* add multple HTML elements in alphabetical order from abbr to em

* fix attributes of some of the elements added in the previous commit and add embed

* fix embed attributes and add fieldset

* add figcation, figure and form. Also fix ordering of definitoin of img and input_

* add style and lint

* wrap up adding all major html elements

* fix test failing due to different error message from fake server compared to a real test server

* change default docstring associated with all classes dynamically patched

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

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

* lint

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

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

* add pyweb tests

* lint

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

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

* add global attributes and change abbr test

* fix abbr to inherit from TextElementBase

* add address test and improve error messaging when ElementBase gets a bad input as style

* change test helper function to be more  flexible on attributes and manage content vs non content based elements. Also adds area tests

* add test for more elements up to caption

* fix canvas and caption as elements that have content and fix name typo on figcaption

* fix another typo on figcaption

* minor fixes and complete tests for all elements

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

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

* adapt shoelace to latest upates in ui.elements

* fix issue with example code not showing created button

* move global attributes to base class

* replace all the calls to _add_js_properties with defining attributes directly in the classes

* finish moving all properties manually on each class

* remove _add_js_properties

* replace JSProperty with js_property

* replace JSProperty with js_property

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

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

* fixed merge conflicts

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

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

* remove js_property and just use JSProperty with name and allow_nones as arguments

* fix bug around Element not being able to map global attributes in subclasses

* remove js_property and fix references

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

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

* precommit

* precommit again

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

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

* lint

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

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

* enable pyweb on micropython

* switch examples to micropython

* fix pydom issue with micropython, created by the monkeypatch around JsProxy

* print micropython version on micropython pydom example

* lint and remove of textwrap in stdlib for micropython compatibility

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

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

* added msising attributes on the option Element. Tests are all passing now

* fix tests

* lint

* temp ugly fix for micropython, using the when decorator with a function without arguments

* small fixes and improvements to examples

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

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

* fix examples and broken link from the removal of markdown and shoelace from stdlib

* lint

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

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

* dynamically change the server address in tests

* use the right element in test_a

* lint

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

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

* skipping test_audio in CI due to different behavior of fake_server vs a real server, that runs in local tests

* add conditional expected_missing_file_errors property to manage different behaviour between local tests and CI (due to fake_server)

* lint

* [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: Askat <aaskat@users.noreply.github.com>
Co-authored-by: Fábio Rosado <hello@fabiorosado.dev>
Co-authored-by: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2024-06-04 13:30:34 -07:00
Andrea Giammarchi
1c675307e1 Expose pyscript.py_import and js_import for lazy Python/JS modules (#2091)
* Expose pyscript.py_modules for lazy Python modules

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

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

* [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>
2024-06-04 19:08:52 +02:00
pre-commit-ci[bot]
ac56f82c6d [pre-commit.ci] pre-commit autoupdate (#2089)
updates:
- [github.com/codespell-project/codespell: v2.2.6 → v2.3.0](https://github.com/codespell-project/codespell/compare/v2.2.6...v2.3.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-06-04 09:36:04 +02:00
Andrea Giammarchi
2ac5ca79d7 Expose py-editor code content read/write (#2087)
* Expose py-editor code content read/write

* [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>
2024-06-03 12:32:54 +02:00
Jeff Glass
cb9ee6f7e2 Update README.md, 2023.11.2 -> 2024.5.2 (#2085) 2024-06-03 10:14:27 +02:00
Andrea Giammarchi
9abaef33bd Fix #2067 - Enable .whl packages (#2084) 2024-05-31 11:50:30 +02:00
Brendan
320a537db2 Add step in build process to publish a tarfile (#2077)
Co-authored-by: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2024-05-30 16:25:58 +02:00
Andrea Giammarchi
9b775ce015 Enhance MicroPython Terminal on both Main and Worker (#2083)
* Allow MicroPython Terminal on Main

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

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

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

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

* [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>
2024-05-30 13:36:42 +02:00
jdw170000
66f72eda1e Add spinner to py-editor run buttons (#2078)
* Add spinner to disabled py-editor run buttons

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

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

* css nit suggested by WebReflection

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-29 17:36:06 +02:00
Martin
39ca29749c fix: typo in "isinstance" in Element.snap. (#2071)
Co-authored-by: Fabio Pliger <fpliger@users.noreply.github.com>
Co-authored-by: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2024-05-27 12:08:49 +02:00
Amjith Ramanujam
85da548447 Fix the links to development process. (#2064)
Co-authored-by: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2024-05-27 11:47:25 +02:00
jdw170000
9985787e4b Update dependencies and deprecated linter configuration format (#2076)
* update python dependencies to latest versions

* isort automatic formatting nits

* update eslint config to non-deprecated flat format

* `npm update` to upgrade javascript dependencies

* [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>
2024-05-27 11:44:24 +02:00
Takanori Suzuki
18ec6ce775 refs #2068 fix links on CONTRIBUTING.md (#2072) 2024-05-21 10:36:41 +01:00
Andrea Giammarchi
ed6d0136b8 Updated MicroPython to its latest (#2063)
* Updated MicroPython to its latest

* [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>
2024-05-19 12:10:15 +02:00
Nicholas Tollervey
e7216d26e7 Add release information to README. (#2059)
* Add release information to README.

* [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>
2024-05-13 12:27:24 +01:00
Andrea Giammarchi
d1a0d8ea98 Fix #2056 - Provide a default empty config per editor env (#2058)
* Fix #2056 - Provide a default empty config per editor env

* [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>
2024-05-13 10:36:00 +02:00
Andrea Giammarchi
04222b0d03 PyEditor - process(code) ability (#2053)
* Even better PyEditor offline use case (#2050)

* Even better PyEditor offline use case

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

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

* [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>

* PyEditor - process(code) ability

* [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>
2024-05-08 21:33:07 +02:00
Andrea Giammarchi
8ec3381789 Even better PyEditor offline use case (#2050)
* Even better PyEditor offline use case

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

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

* [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>
2024-05-07 10:02:55 +02:00
pre-commit-ci[bot]
9bd4737708 [pre-commit.ci] pre-commit autoupdate (#2051)
updates:
- [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v4.6.0)
- [github.com/psf/black: 24.3.0 → 24.4.2](https://github.com/psf/black/compare/24.3.0...24.4.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-07 09:42:28 +02:00
Andrea Giammarchi
c49cb9231b Added listeners to the constructing kw options (#2044) 2024-05-03 16:34:21 +02:00
Andrea Giammarchi
d1d1c5740f Fixed py-editor offline use case (#2043) 2024-05-03 12:23:57 +02:00
Andrea Giammarchi
1a05ea5fd2 Fix #2031 - Add pyscript.WebSocket to the mix (#2042)
* Fix #2031 - Add pyscript.WebSocket to the mix

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

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

* Working on a test case anyone can run

* [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>
2024-05-03 11:35:05 +02:00
Andrea Giammarchi
5b4e8527da Fix #2040 - Polyscript update to provide config dictionary (#2041)
* Fix #2040 - Polyscript update to provide config dictionary

* [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>
2024-05-02 11:47:52 +02:00
Andrea Giammarchi
83c2afeaf1 Updated Polyscript to its latest (#2036) 2024-04-24 16:56:47 +02:00
Andrea Giammarchi
643b76479f HTML class in MicroPython (#2033) 2024-04-22 12:43:17 +02:00
Andrea Giammarchi
cf92996071 Avoid PyWeb as part of stdlib on MicroPython (#2030)
* Avoid PyWeb as part of stdlib on MicroPython

* [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>
2024-04-17 17:10:23 +02:00
Andrea Giammarchi
c653296821 Added @xterm/addon-web-links to the terminal (#2027)
* Added @xterm/addon-web-links to the terminal

* [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>
2024-04-12 16:25:12 +02:00
Andrea Giammarchi
44cd6273ba PyTerminal .process(code) utility (#2026)
* PyTerminal .process(code) utility

* [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>
2024-04-12 15:44:20 +02:00
pre-commit-ci[bot]
d7d2dfb383 [pre-commit.ci] pre-commit autoupdate (#2012)
updates:
- [github.com/psf/black: 24.1.1 → 24.3.0](https://github.com/psf/black/compare/24.1.1...24.3.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2024-04-10 16:22:15 +02:00
Andrea Giammarchi
2d5cf096e0 Fix MicroPython badly handling unicode chars (#2018)
## Changes

  * fixed an issue with the **py-editor** related to the new `linebuffer` directive
  * provide in worker hook scope a simple callback that pre-buffers unicode sequences [accordingly to the standard](https://encoding.spec.whatwg.org/#utf-8-bytes-needed) so that the buffer is sent to the terminal only once those sequences are fulfilled
  * test with both `µ` and way more convoluted sequences such as 👩‍❤️‍👨 that the output, if either requested as input or already evaluated from the page works ... in latter case `test = "👩‍❤️‍👨"` completely messes up the program and the resulting string is empty
2024-04-09 14:51:10 +02:00
Andrea Giammarchi
6ee8217593 Updated dev-dependencies w/ ESLint 9 (#2021) 2024-04-09 14:27:06 +02:00
dependabot[bot]
6d45728787 Bump dorny/test-reporter from 1.8.0 to 1.9.0 in the github-actions group (#2019)
Bumps the github-actions group with 1 update: [dorny/test-reporter](https://github.com/dorny/test-reporter).


Updates `dorny/test-reporter` from 1.8.0 to 1.9.0
- [Release notes](https://github.com/dorny/test-reporter/releases)
- [Changelog](https://github.com/dorny/test-reporter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/dorny/test-reporter/compare/v1.8.0...v1.9.0)

---
updated-dependencies:
- dependency-name: dorny/test-reporter
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-08 10:40:53 +02:00
Andrea Giammarchi
65954a627e Allow MicroPython input("...") to work beside the code.interact() (#2017) 2024-04-04 18:13:00 +02:00
Andrea Giammarchi
2f1b764251 Provide input("") and sync output to MicroPython (#2016)
Provide input("") and sync output to MicroPython
2024-04-04 17:34:12 +02:00
Andrea Giammarchi
1fb6cddd70 Forgot to update current npm version (#2015) 2024-04-04 15:53:52 +02:00
Andrea Giammarchi
239add4e20 Better MicroPython Terminal (#2014)
* Better MicroPython Terminal + fixed Pyodide astty value
2024-04-04 15:33:41 +02:00
Andrea Giammarchi
4e4ac56729 Fix #1998 - Allow lazy terminal bootstrap + MicroPython terminal
* Fix #1998 - Allow lazy PyTerminal bootstrap

* Fix #1998 - Allow lazy terminal bootstrap / runtime

* Implemented mpy terminal in both main and worker

* [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>
2024-04-03 15:50:20 +02:00
Andrea Giammarchi
1447cb3094 Fix #1997 - Bring pyscript stdlib to the PyEditor (#2010)
* Fix #1997 - Bring pyscript stdlib to the PyEditor
2024-03-28 10:43:26 +01:00
dependabot[bot]
2f3659b676 Bump the github-actions group with 6 updates (#1995)
Bumps the github-actions group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/setup-node](https://github.com/actions/setup-node) | `3` | `4` |
| [actions/cache](https://github.com/actions/cache) | `3` | `4` |
| [softprops/action-gh-release](https://github.com/softprops/action-gh-release) | `1` | `2` |
| [conda-incubator/setup-miniconda](https://github.com/conda-incubator/setup-miniconda) | `2` | `3` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `3` | `4` |
| [dorny/test-reporter](https://github.com/dorny/test-reporter) | `1.6.0` | `1.8.0` |


Updates `actions/setup-node` from 3 to 4
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v4)

Updates `actions/cache` from 3 to 4
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v3...v4)

Updates `softprops/action-gh-release` from 1 to 2
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

Updates `conda-incubator/setup-miniconda` from 2 to 3
- [Release notes](https://github.com/conda-incubator/setup-miniconda/releases)
- [Changelog](https://github.com/conda-incubator/setup-miniconda/blob/main/CHANGELOG.md)
- [Commits](https://github.com/conda-incubator/setup-miniconda/compare/v2...v3)

Updates `actions/upload-artifact` from 3 to 4
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

Updates `dorny/test-reporter` from 1.6.0 to 1.8.0
- [Release notes](https://github.com/dorny/test-reporter/releases)
- [Changelog](https://github.com/dorny/test-reporter/blob/main/CHANGELOG.md)
- [Commits](https://github.com/dorny/test-reporter/compare/v1.6.0...v1.8.0)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: conda-incubator/setup-miniconda
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: dorny/test-reporter
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-25 11:00:29 +01:00
Andrea Giammarchi
910c666319 pyscript.ffi - expose most essential utilities (#2005)
pyscript.ffi - expose most essential utilities
2024-03-22 17:41:06 +01:00
Andrea Giammarchi
eee2f64c1d Update Polyscript with its latest untar.gz and unzip abilities (#2004) 2024-03-22 10:42:01 +01:00
Andrea Giammarchi
d080246a0f Update MicroPython to its latest (#2003) 2024-03-21 11:47:47 +01:00
Andrea Giammarchi
98c0f5e50d Fix #2000 - Allow advanced users to deal themselves with responses (#2001)
* Fix #2000 - Allow advanced users to deal themselves with responses

* rolled back the direct utility idea

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

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

* Updated to latest MicroPython and latest way to have direct access with fetch

* [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>
2024-03-20 16:40:24 +01:00
Andrea Giammarchi
a1268f1aa2 Fix #1993 - Expose a handy fetch API (#1994) 2024-03-14 19:36:23 +01:00
Christian Clauss
69b8884045 Keep GitHub Actions up to date with GitHub's Dependabot (#1992)
* Keep GitHub Actions up to date with GitHub's Dependabot

Fix the warning like at the bottom right of
https://github.com/pyscript/pyscript/actions/runs/8263920642

# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem

* [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>
2024-03-14 15:36:18 +01:00
Andrea Giammarchi
df1d699fe6 [feature] py-editor setup (#1989) 2024-03-13 12:25:30 +01:00
Andrea Giammarchi
84f197b657 Updated polyscript to its latest (#1982) 2024-02-15 17:49:09 +01:00
Andrea Giammarchi
5bed5ede52 Fix #1974 - Use utf-8 encoding to bootstrap stdlib (#1981) 2024-02-14 09:59:18 +01:00
Fabio Pliger
f6d5cf06c8 Add text to pydom.Element (#1911)
* add missing test for html attribute

* add test for text attribute

* fix text attribute 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>
Co-authored-by: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2024-02-12 11:50:36 -08:00
Andrea Giammarchi
30c6c830ae Fix #1972 - Evaluate users' code a part (#1975) 2024-02-09 15:52:29 +01:00
Shubhal Gupta
d7084f7f55 Fix: Restored the development docs #1783 (#1803)
* Fix: Restored the development docs #1783

* [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: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2024-02-07 11:17:50 +01:00
pre-commit-ci[bot]
a87d2b3fea [pre-commit.ci] pre-commit autoupdate (#1917)
updates:
- [github.com/psf/black: 23.11.0 → 24.1.1](https://github.com/psf/black/compare/23.11.0...24.1.1)
- [github.com/pycqa/isort: 5.12.0 → 5.13.2](https://github.com/pycqa/isort/compare/5.12.0...5.13.2)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2024-02-07 11:13:05 +01:00
Fábio Rosado
81a26363a3 Update bug template to point users to pyscript.com issue tracker (#1971)
* Update bug template to point users to pyscript.com issue tracker

* add bold to make it more visible
2024-02-06 14:23:12 +00:00
Andrea Giammarchi
53e945201d Update polyscript to fix a try/catch issue (#1968) 2024-02-02 15:33:26 +01:00
Andrea Giammarchi
181d276c8b Allow Workers w/out SharedArrayBuffer (#1967)
Allow Workers w/out SharedArrayBuffer
2024-02-02 15:03:30 +01:00
Fabio Pliger
bcaab0eb93 PyDom compatibility with MicroPython (#1954)
* fix pydom example

* fix the pydom test example to use a python syntax that works with MicroPython by replacing datetime

* add note about capturing errors importing when

* patch event_handler to handle compat with micropython

* turn pyweb into a package and remove hack to make pydom a sort of module with an ugly hack

* add pydom example using micropython

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

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

* fix select element test

* change pydom test page to let pytest tests load it properly

* add missing folders to test dev server so it can run examples in the manual tests folder

* add pydom tests to the test suite as integration tests

* lint

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

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

* improve fixes in event_handling

* change when decorator to actually dynamically fail in micropython and support handlers with or without arguments

* simplify when decorator code

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

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

* add type declaration back for the MP use case

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

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

* removed code to access pydom get index as I can't think of any proper use case

* remove old commented hack to replace pydom module with class

* fix examples title

* precommit checks

* [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>
2024-01-30 11:30:16 -08:00
Andrea Giammarchi
3ff0f84391 Update polyscript + coincident to their latest (#1958) 2024-01-30 12:31:44 +01:00
Andrea Giammarchi
2b411fc635 Update Polyscript to its latest w/ experimental (#1955) 2024-01-29 12:00:37 +01:00
Fabio Pliger
2128572ce5 pyweb camera support (#1901)
* add media module

* add Device class to media

* add camera test example

* add snap, download and other convenience methods

* load devices automagically

* add draw method to canvas

* add docstring for download

* add docstrings to draw method

* add docstrings to snap

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

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

* load devices as soon as the page loads

* solve conflict

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

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

* remove display calls listing devices in camera example

* fix typos and other small errors

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

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

* fix typo in docstring

* fix error message typo

* replace setAttribute on JS properties with accessors

* remove debug statement

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

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

* add docstrings

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

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

* add docstrings to camera example

* [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>
2024-01-26 14:33:02 -08:00
Andrea Giammarchi
63f2453091 Fix #1946 - Do not hold while bootstrapping (#1953) 2024-01-26 15:04:02 +01:00
Andrea Giammarchi
f6470dcad5 Multiple Worker based Terminals (#1948)
Multiple Worker based Terminals
2024-01-24 17:33:55 +01:00
Andrea Giammarchi
a9717afeb7 updated Pyodide to 0.25.0 (#1949) 2024-01-24 13:19:33 +01:00
Andrea Giammarchi
cea52b4334 Adding __terminal__ reference on terminal scripts (#1947) 2024-01-22 15:34:36 +01:00
Andrea Giammarchi
7ad7f0abfb Fix #1943 - Updated Polyscript with configURL (#1944) 2024-01-17 16:15:51 +01:00
Andrea Giammarchi
1efd73af8f Instrumented the io.stderr too when terminal exists (#1942) 2024-01-16 19:05:15 +01:00
Andrea Giammarchi
1e7fb9af44 Fix #1940 - Handle Main Xterm as tty too (#1941) 2024-01-15 17:29:28 +01:00
Fabio Pliger
154e00d320 Add correct copyright and attribution to main license file (#1937)
* add correct copyright and attribution to main license file

* [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>
2024-01-13 22:32:21 +01:00
Andrea Giammarchi
0f788fa284 Fix #1899 - Expose pyscript.js_modules as module (#1902)
* Fix #1899 - Expose pyscript.js_modules as module

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

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

* Fix #1899 - Make import as smooth as in polyscript

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-01-03 17:16:51 +01:00
Andrea Giammarchi
355866a1f1 PyTerminal - expose the reference through the element (#1921)
* PyTerminal - expose the reference through the element

* [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>
2024-01-03 16:24:38 +01:00
pre-commit-ci[bot]
6eca06ac0b [pre-commit.ci] pre-commit autoupdate (#1844)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0)
- [github.com/psf/black: 23.1.0 → 23.11.0](https://github.com/psf/black/compare/23.1.0...23.11.0)
- [github.com/codespell-project/codespell: v2.2.4 → v2.2.6](https://github.com/codespell-project/codespell/compare/v2.2.4...v2.2.6)

* fixed typo in comment

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2023-12-19 14:18:27 +01:00
Andrea Giammarchi
a4aef0b530 Fix CI VS local env inconsistencies (#1892)
* Fix make fmt changing Python files

* [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>
2023-12-19 13:52:45 +01:00
Andrea Giammarchi
136e95498f Reduce conflicts on multiple custom scripts (#1897) 2023-12-14 18:32:46 +01:00
Andrea Giammarchi
6a3e2834b6 Fix #1890 - Apply latest patch that was lost (#1891) 2023-12-07 10:29:45 +01:00
Fabio Pliger
c0d45d368b Pydom add better support for select element (#1887)
* add tests for select options

* add classes to support select and options management

* fix add methond and implement clear on options

* fix optionsproxy.add

* fix select.add method

* add test adding a second option to select

* add tests around adding options in multiple flavors

* add test to add an option by passing the option it wants to be added before

* complete test around adding options

* add select to add test on remove

* add tests and support for selected item

* [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: Andrea Giammarchi <andrea.giammarchi@gmail.com>
2023-12-06 15:56:14 -08:00
Nicholas Tollervey
f18ec3d20a Fix broken links, and put community information at the top of our READE (#1889)
* Fix broken links, and put community information at the top of our README.

* [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>
2023-12-06 14:46:39 +00:00
Andrea Giammarchi
b0377cc7ab Fix #1745 - Throw on multiple configs (#1885)
This MR shows errors and exit in these conditions:

  * multiple `<py-config>` or `<mpy-config>` found on the page
  * both `<py-config>` and `<script type="py" config="file.toml">` found on main
  * different `<script type="py" config="a.toml">`  and `<script type="py" config="b.toml">` configs found on main
2023-12-06 14:12:22 +01:00
Andrea Giammarchi
96e671b55f Amend #1880 - Bootstrap pyscript module ASAP (#1888)
* bootstrap *pyscript* module ASAP as stdlib
  * improve the test to be sure `js.document` exists **before** our module is imported
2023-12-06 11:16:05 +01:00
Andrea Giammarchi
40e99abbdf Py editor (#1860)
* added a *py-editor* plugin based on *codemirror*
  * use a `<script type="py-editor">` wrapper to bootstrap code
  * tested that all is good via smoke-test in test/py-editor.html
2023-12-06 09:53:10 +01:00
Fabio Pliger
8b6b055681 remove examples folder (#1884)
* remove examples folder

* remove examples tests
2023-12-05 13:19:11 -08:00
Andrea Giammarchi
8e5605fa42 Patch js.document out of the box (#1880)
* Patch js.document out of the box

* [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>
2023-12-04 17:53:13 +01:00
Peter W
06e1fdecc2 fix more docs urls (#1882) 2023-12-01 14:15:31 -06:00
Peter W
a82e8334d6 Fix README.md broken link and update for GH pages docs (#1881) 2023-12-01 13:17:00 -06:00
Andrea Giammarchi
539bc2ae0e Expose js_modules via pyscript module (#1877)
* Expose js_modules via pyscript module

* [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>
2023-11-30 16:13:47 +01:00
Andrea Giammarchi
0711acd30e Updated Polyscript to its latest (#1876) 2023-11-30 13:49:08 +01:00
Madhur Tandon
1476131ab4 update references (#1874) 2023-11-29 21:03:34 +05:30
Madhur Tandon
89902a440c remove examples from core repository (#1868)
* remove examples from core repository

* remove icosahedron example
2023-11-29 20:01:46 +05:30
Madhur Tandon
156c23d550 Update README.md (#1872) 2023-11-28 15:53:23 +05:30
Andrea Giammarchi
30396ba79a Fix #1861 - Use addon to fit lines instead of truncating (#1867) 2023-11-27 15:05:23 +01:00
Andrea Giammarchi
a4343c62ca Updated dev/dependencies w/ polyscript & coincident (#1864) 2023-11-22 15:21:57 +01:00
Antonio Cuni
4b89c84692 use UTC time (#1859) 2023-11-15 16:00:09 +01:00
Antonio Cuni
df68449b82 Improve README and and mention the community calls (#1858)
Improve the readme in two ways:

- remove the mention to <py-repl>, and shows a quick summary of the various ways of running Python code

- add a link to the google calendar which contains the community calls
2023-11-15 12:10:52 +01:00
Andrea Giammarchi
48e3383f66 Fix #1841 - Provide a better error when input is used (#1857) 2023-11-14 15:25:17 +01:00
Fabio Pliger
e750fa7393 Add Deprecation message when loading from latest (#1848)
* add tests to verify if we show an error banner when users load from latest

* add deprecation manager to take care of showing a notification in case script src is being loaded from latest

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

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

* make sure deprecation warning also register onWorker

* restore tests for banner in worker

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

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

* add a wait selector when testing banner since worker seems to take too long to render in CI

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

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

* Fix test_deprecate_loading_scripts_from_latest: I think that the
previous failure was because we actually TRIED to execute the js from
latest/core.js and it conflicted with our local copy.

But to trigger the warning is enough to have a script pointing to
pyscript.net/latest, there is no need to execute it: modify it with
type="ignore-me" and an URL which doesn't exist.

---------

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>
2023-11-10 08:18:30 -08:00
Fabio Pliger
5a15199a3a Fix Click test example (#1849)
* fix type in div id

* add types
2023-11-08 11:09:15 -08:00
Fabio Pliger
1801472fc4 Remove when from pydom (#1850)
* bye bye when

* fix create to drop parent and actually pass the other arguments through

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

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

* update types

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-11-08 09:28:58 -08:00
Nicholas Tollervey
ab15ac37ff Add playwright to dependency installation steps. (#1852) 2023-11-08 13:31:12 +00:00
Nicholas Tollervey
0955a6be49 Re-add CHANGELOG.md into root of the repository. (#1851)
* Re-add CHANGELOG.md from the tip of "classic" into root of the repository. Tidy
the formatting in CHANGELOG.md. Update the PR template to reflect the new
location of the CHANGELOG.md.

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

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

* Replace with specific version.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-11-08 13:28:12 +00:00
Jeff Glass
d58237ea15 Update link to not use /latest (#1847)
* Update link in README.me to use specific version, not /latest
2023-11-07 16:37:10 -06:00
Andrea Giammarchi
2d50ca86a6 Fix #1840 - Do not bootstrap interactive shell (#1846) 2023-11-07 19:22:08 +01:00
Andrea Giammarchi
f1a46be738 Fix #1838 - Provides all TS from all projects (#1843) 2023-11-07 17:17:40 +01:00
Andrea Giammarchi
3e2a67d434 PyTerminal: use Pyodide instead of Python (#1833) 2023-11-03 17:59:11 +01:00
Andrea Giammarchi
aef028be6e Fix #1834 - Throw an error if more than a terminal exists (#1837) 2023-11-03 15:19:30 +01:00
Andrea Giammarchi
c8ec29a3d8 Improve offline dist content (#1836) 2023-11-03 10:00:52 +01:00
Fabio Pliger
e81830a2ea Value property to PyDom.Element and ElementCollection (#1828)
* add base test for input value field

* add value property to Element

* add test for non supported element

* prevent users to set value attribute on elements that do not support it

* add test for setting value on collections

* add value property to collection and add more tests

* [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>
2023-11-01 08:33:38 -07:00
Nicholas Tollervey
54df7171a2 Update publish-snapshot.yml (#1827)
Ensure playwright is installed when building.
2023-11-01 10:23:33 +00:00
Andrea Giammarchi
b31af823d1 Use <py-terminal> as default target (#1826) 2023-10-31 16:58:20 +01:00
Andrea Giammarchi
72f266532b PyScript Terminal - the latest kind (#1816) 2023-10-31 15:16:15 +01:00
Andrea Giammarchi
d9bf5cae12 Fix #1814 - Basic mpy integration (#1815) 2023-10-27 15:30:21 +02:00
Andrea Giammarchi
cd95a42e5e Fix #1812 - Avoid duplicated pyscript module (#1813) 2023-10-26 19:44:31 +02:00
Andrea Giammarchi
e67eb06d8b Breaking: new Polyscript Hooks mechanism (#1811)
* Breaking: new Polyscript Hooks mechanism

* Added proper smoke test
2023-10-26 17:13:36 +02:00
Andrea Giammarchi
28d37cdead Fix #1775 - Use latest polyscript dev script (#1810) 2023-10-24 15:23:05 +02:00
Nicholas Tollervey
13604e0a47 Simplify Makefile. Remove Conda. Use requirements.txt. Remove pointless type annotations. Update CI tests.yml. (#1793) 2023-10-24 09:53:10 +01:00
Andrea Giammarchi
aeb6f1a755 Create a dist.zip artifact (#1809) 2023-10-24 10:29:29 +02:00
Madhur Tandon
92e6f711b7 fix docs for append as True (#1808) 2023-10-23 19:32:32 +05:30
Andrea Giammarchi
a24113f42b Fix #1799 - Avoid multiple bootstraps when embedded (#1800) 2023-10-23 15:54:51 +02:00
Madhur Tandon
7a6f8ab3ad Update README.md (#1806) 2023-10-23 19:06:29 +05:30
Andrea Giammarchi
6dd242f3ce Allow PyScript to fully run locally (#1805) 2023-10-20 15:02:05 +02:00
shubhalgupta
88fa82c61a Fix contributing link is README file #1782 (#1797) 2023-10-10 13:24:15 -05:00
Andrea Giammarchi
2299ba5f61 Updated npm version (#1796) 2023-10-10 15:23:18 +02:00
Andrea Giammarchi
117df6ca38 Updated to latest polyscript + coincident (#1795) 2023-10-10 12:38:01 +02:00
Antonio Cuni
4256a81653 run pre-commit on all files (#1789)
pre-commit.ci has been disabled for a while.
This PR ensures that all the files has been validated/formatted by pre-commit, to avoid spurious diffs in subsequent PRs.

During the process, ruff broke the code because it removed an "unused" import which was actually used.
A linter which breaks my code is a linter which I cannot trust, so I just removed it. I re-enabled isort instead.
2023-10-05 15:10:31 +02:00
Andrea Giammarchi
d5b6935c0b Wait for plugins before defining the custom type (#1788) 2023-10-05 13:54:55 +02:00
Madhur Tandon
b4503ef729 remove pyscriptjs and synclink (#1787)
* remove pyscriptjs and synclink

* remove chdir fixture
2023-10-04 21:46:34 +05:30
Valerio Maggio
a00a6750b4 FIX to display function handling null element reference, and wrong target parameter values (#1784)
* blacked

* More robust code for display, with tests

Display now includes more robust controls when checking
the input target parameters, with appropriate exception raised
(i.e. ValueError or TypeError) whether target is either
an empty string, or a not-string, not-None type, respectively.

The TypeError aligns with other similar behaviour with other Pyton
functions (e.g. str.split with integer separator).

Also, now display raises a ValueError whether the target element
is not found or not existing.

All changes are supported by tests.

* traceback lines in check_py_error & removed clones

check_py_error function now automatically includes
check of the traceback in console errors.

This way tests in basic and display have been refactored,
and lots of duplicated code removed.

* removed useless console check lines.

If check_py_errors function is running, those
console log lines are useless to check.
2023-10-03 18:23:44 +01:00
Andrea Giammarchi
a08f891b20 Fix #1777 - Export also PyWorker and current_target (#1779) 2023-10-02 16:02:34 +02:00
Andrea Giammarchi
bc1cac9c41 Fix #1780 - Clean up elements before writing (#1781) 2023-10-02 15:39:34 +02:00
Andrea Giammarchi
50f7ab0f34 Improved py:all-done event (#1778) 2023-10-02 13:38:28 +02:00
Andrea Giammarchi
fdc35ce3ed Add a selector to the HTML tag + export config (#1773) 2023-09-29 15:24:20 +02:00
Andrea Giammarchi
5c4e400d32 Fix #1766 - Ensure correct hooks types (#1772) 2023-09-29 14:01:35 +02:00
Andrea Giammarchi
7a23e355b9 Add experimental files config parser (#1770) 2023-09-28 21:15:04 +02:00
Andrea Giammarchi
dffac642a1 Fix #1765 - Pass the optional config interpreter value (#1768) 2023-09-28 17:49:11 +02:00
Andrea Giammarchi
97699eaded Fix #1764 - Unescape innerHTML artifacts (#1767) 2023-09-28 16:05:51 +02:00
Antonio Cuni
c6aaacdbf1 Re-enable CI tests (#1760)
This re-enables CI tests on every PR 🎉.
This uses make test-integration, which runs tests sequentially.

In theory, we also have test-integration-parallel but it seems to be very flaky: many tests randomly timeout. I didn't spend too much time investigating this, it's probably worth its own investigation in a separate PR, but for now it's important to re-enable CI tests, even if they are a bit slower.
2023-09-27 17:02:49 +02:00
Antonio Cuni
abfc68765f Enable worker tests (#1757)
This PR re-enables tests on `worker`s. Highlights:
 
* by default, each test is run twice: the main thread version uses `<script type="py">`, the worker version automatically turn the tags into `<script type="py" worker>`

* you can tweak the settings per-class by using the `@with_execution_thread` decorator. In particular, `@with_execution_thread(None)` is for those tests which don't care about it (e.g., `test_py_config.py`)

* inside each class, there might be some test which should be run only in the main thread (because it doesn't make sense to test it in a worker). For those, I introduced the `@only_main` decorator

* we might introduce `@only_worker` in the future, if needed

* `@skip_worker` is for those tests which currently pass on main but not on workers. These are meant to be temporary, and eventually they should all be fixed
 
During the process, I tweaked/improved/fixed/deleted some of the existing tests. Some of them were at risk of being flaky and I made them more robust, others depended on some very precise implementation detail, and I made them more generic (for example, `test_image_renders_correctly` relied on pillow to render an image with a very specific string of bytes, and it broke due to the recent upgrade to pyodide 0.24.1)
 
I also renamed all the skip messages to start with `NEXT`, so that they are easier to grep.
2023-09-27 10:05:40 +02:00
Andrea Giammarchi
3ac2ac0982 Added py:all-done event (#1756) 2023-09-26 15:56:50 +02:00
Antonio Cuni
b9a1227e47 Unskip some tests, delete others (#1742)
Clean up a bit the testsuite and integration tests.
Highlights:

- Some of the @skipped tests just worked -- I unskipped them
- some worked after some small tweak to adapt to the new pyscript next
- some are still skipped, but I tweaked the skip message to be more precise and descriptive
- Moreover, I killed/removed the ones which no longer make sense in the context of pyscript next; in particular, I removed all the ones which tested Element (which is now gone) and the one which tested py-config features which are no longer needed (e.g., multiple interpreters).

The testsuite passes locally.
2023-09-25 18:14:20 +02:00
Jeff Glass
801c63947a Skip test_interpreter_config (#1752)
* skip test_interpreter_config

*Clarify the skip() comments on a couple other config tests
2023-09-25 07:30:22 -05:00
Jeff Glass
ffee4add4a Fix target attribute lookup on <script type="py"> (#1751)
* queryTarget takes element as first param

* Add test for 'target' attribute on script tags test_tag_target_attribute
2023-09-25 07:27:47 -05:00
Andrea Giammarchi
f0be7ef418 Fixed eslint ignoring global leaks (#1754) 2023-09-25 12:09:47 +02:00
Andrea Giammarchi
e4eedd80bc [RC] Work on the reverted changes (#1753) 2023-09-25 11:41:34 +02:00
Jeff Glass
c9e7fe16e4 Adding JS Types (#1749)
Added types for some exceptions, config objects, and sleep()
2023-09-22 12:19:22 -05:00
Ted Patrick
5079dd19cb Revert "[RC] Ensure dedicated configs per interpreter (#1743)" (#1747)
This reverts commit b4c686f411.
2023-09-21 14:11:22 -05:00
Andrea Giammarchi
b4c686f411 [RC] Ensure dedicated configs per interpreter (#1743) 2023-09-21 19:20:02 +02:00
Ted Patrick
287d0fa1af Prepare and Publish Release (#1741)
* Prepare and Publish Release

* Add prepare release and publish release

* Update AWS Credentials config to v4
2023-09-20 15:37:37 -05:00
Ted Patrick
b78455c4c1 Add permissions section (#1740) 2023-09-20 15:12:15 -05:00
Ted Patrick
312b6b0706 Fix publish unstable (#1739) 2023-09-20 14:53:19 -05:00
Ted Patrick
924e530096 Update pathing in publish-unstable (#1738) 2023-09-20 14:42:49 -05:00
Ted Patrick
ef8918f3a7 Update Build Unstable (#1737) 2023-09-20 14:35:57 -05:00
Ted Patrick
91ae242e49 Build unstable (#1736)
* Add build unstable

* update publish snapshot

* naming action and steps
2023-09-20 14:30:21 -05:00
Ted Patrick
fd307e52ae Update publish snapshot (#1735)
* Update publish snapshot

* naming is hard
2023-09-20 13:40:24 -05:00
Ted Patrick
a68967c773 Add publish snapshot GHA (#1734) 2023-09-20 13:37:02 -05:00
Ted Patrick
52da45bb9c Disable all workflows - mv to / from .github (#1733) 2023-09-20 13:01:08 -05:00
Andrea Giammarchi
ad0dde3f17 [next] Add mpy as custom type with PyScript magic attached (#1728) 2023-09-20 18:06:52 +02:00
Andrea Giammarchi
8f3c36deea [next] Fix #1730 - Make worker an empty attribute only (#1732) 2023-09-20 16:44:00 +02:00
Ted Patrick
23e1ab81b3 Docs to the docs repo (#1731) 2023-09-20 08:02:19 -05:00
Antonio Cuni
77b40aa348 Use <script type="py"> instead of <py-script> in most tests (#1723)
This is mostly a global search&replace, to replace <py-script> with <script type="py">.

The vast majority of tests just works, some needed some tweak.
2023-09-19 18:35:15 +02:00
Andrea Giammarchi
f6decfd93d [next] Errors on ambiguous/conflicting code intents (#1724) 2023-09-19 18:10:46 +02:00
Andrea Giammarchi
e8d5138cfa [next] Fix #1699 - Updated polyscript + added smoke test (#1726) 2023-09-19 18:08:21 +02:00
Jeff Glass
a088fbd6fb Add pexpect to environment.yml(#1725) 2023-09-19 09:38:58 -05:00
Andrea Giammarchi
19214901f9 [next] Fix regressions around config (#1720) 2023-09-18 14:53:50 +02:00
Andrea Giammarchi
c330a623b2 [next] Remove artifacts from GitHub (#1721) 2023-09-18 14:07:03 +02:00
Fabio Pliger
f77241e977 next integration tests (#1712)
* move integration tests pyscriptjs/tests/integration ->pyscript.core/tests/integration

* add information in regards to how to run integration tests to README

* fix fake server build paths

* fix paths to build and run tests. The change of path before integration tests is a glitch maybe due to pytest cache?

* remove test files created by mistake

* update readme with latest changes

---------

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2023-09-15 14:09:07 -07:00
Antonio Cuni
ed6de66c08 emit a clear error message if you try to use pyscript.sync from the (#1715)
main thread or pyscript.PyWorker from a worker
2023-09-15 15:45:40 +02:00
Antonio Cuni
5191c45113 Refactor the pyscript python package. (#1713) 2023-09-15 13:57:06 +02:00
Andrea Giammarchi
840bc803b7 [next] Improve config parsing on bootstrap (#1704) 2023-09-15 12:50:52 +02:00
Fabio Pliger
00fdc73015 [NEXT] Pydom (#1681)
* add pyweb

* build

* add test file

* fix pydom example code

* remove old reference to js

* temporarily comment out query functions on BaseElement while rearranging code to reuse the same underlying logic accross PyDom and other elements

* add temp TODO comment to content as it breaks with template elements

* update pydom example to define code on external file

* fix name type while renaming document -> dom

* add real pydom test files

* add classes to dom scope

* __len__ to ElementCollection

* fix some of the old tests

* rename test from test_query_by_class to test_getitem_by_class

* change test for read and write multiple elements

* add find method to BaseElement

* fix remaining tests

* add Collection Tests

* add equality to Collection

* add test for collection style manipulation

* fix getter for style property and rename style related attribute from pop to remove

* add single element creation test

* remove append on BaseElement and add body and head to dom

* add test_create_element_child to verify child creation

* add children getter property to Element

* remove old code

* remove more old code, change style attribute from visibility to visible and now default getters on collection to return a list with the value of an attribute for every element in the collection

* remove more old code and add possibility to customize test flags via url

* add support to pass Js and pydom.Element elements to when decorator

* remove methods related to input type of elements until we have a better design for it

* rename _element to _js

* add test_when decorator with a ElementCollection input

* when decorator now supporte pydom.ElementCollection as input

* update pyscript.js

* remove useless variable from when decorator

* remove base.py from pyweb

* add nodes for append collection test and add better feedback on successes vs failure

* add tests and fix code for support of append Element and ElementCollection

* manage access to content attribute when tagname is template

* fix comment

---------

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2023-09-14 13:31:23 -07:00
Ted Patrick
9660976d1d Fix to HTML template logic (#1711) 2023-09-14 13:40:57 -05:00
Ted Patrick
7f666dc6a0 Fix HTML template (#1709) 2023-09-14 13:35:57 -05:00
Ted Patrick
e2a2292a6f Add release html template (#1705) 2023-09-14 12:45:22 -05:00
Andrea Giammarchi
4d89cbde01 [next] Terminal smoke-test follow up (#1702) 2023-09-14 18:11:10 +02:00
Andrea Giammarchi
d8e1cb8b0f [next] Testing XTerm (#1696) 2023-09-14 11:26:09 +02:00
Andrea Giammarchi
3aef5a99dc [next] Bootstrap plugins directly (#1698) 2023-09-14 11:11:44 +02:00
Andrea Giammarchi
7994207c78 [next] Dispatch ready event for the custom py type (#1694) 2023-09-13 12:02:04 +02:00
Andrea Giammarchi
f376097a15 [next] Update CDN links to avoid breaking (#1693) 2023-09-13 11:59:52 +02:00
Fabio Pliger
2a2ff4066d Restore the when decorator and HTML (#1691)
* restore HTML code in display module

* restore when decorator code in event_handling module

* add when and HTML at pyscript import level

* add test for display with HTML

* add quick manual test for when

---------

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2023-09-12 06:27:56 -07:00
Andrea Giammarchi
32c3fb72cc [next] try workaround explicit for jsdelivr (#1692) 2023-09-12 12:06:48 +02:00
Andrea Giammarchi
e44e18114d [next] Use all jsdelivr suggested fields for CDN (#1690) 2023-09-11 16:20:06 +02:00
Andrea Giammarchi
7d2df4895e [next] improve integration tests (#1684) 2023-09-08 17:59:50 +02:00
Andrea Giammarchi
59db56feec [next] Add PyScript Developers Team copy (#1685) 2023-09-08 17:43:54 +02:00
Andrea Giammarchi
fd60b4789a [next] Follow up on stderr (#1683) 2023-09-08 09:55:27 +02:00
Andrea Giammarchi
0696e4682d [next] Cumulative pre-release patches (#1682) 2023-09-07 15:17:09 +02:00
Andrea Giammarchi
d56eeb59ed [next] @pyscript/core 0.1.8 (#1679) 2023-09-06 17:34:11 +02:00
Andrea Giammarchi
1d015c7534 [next] Include most basic error plugin (#1677) 2023-09-06 16:49:43 +02:00
Andrea Giammarchi
264675d0c3 [next] Fix #1675 - use async runner in py-script too (#1676) 2023-09-06 11:28:58 +02:00
Jeff Glass
37d4cb7c48 Adjust Comments in target.html test (#1674)
* Adjust comments

* Remove unnecessary styling
2023-09-06 10:20:16 +02:00
Andrea Giammarchi
cabb1c72b6 [next] Provide less magic around the display (#1673) 2023-09-05 18:51:10 +02:00
Andrea Giammarchi
489a2bb20e [next] Avoid conflicts on @pyscript/core npm artifacts (#1672) 2023-09-05 10:57:40 +02:00
Andrea Giammarchi
d5f42e57ce [next] update PyScript Next to v0.1.7 (#1669) 2023-09-04 13:18:06 +02:00
Andrea Giammarchi
94b0bf4131 [next] Updated latest Polyscript bringing in worker attribute (#1667) 2023-09-04 10:04:12 +02:00
Fabio Pliger
12428c0617 Bring tests to next (#1657)
* bring Makefile to root folder

* add back the print to console when pyscript is ready

* fix build path on tests, link to core.js and overall timeout since it now loads faster

* fix and mark some tests accordingly

* change default timeout to 20s

* review tests and skip what is a known regression

* more tests review until pycondif and skip what is a known regression

* fix pyodide version used on tests

* remove display from config test since it's not testing anything more than console already tests and display as its own tests

* disable config tests that rely on the banner

* skip REPL tests since it's not included in pyscript NEXT

* skip PyTerminal tests since it's not included in pyscript NEXT

* skip more tests relying on Element

* Fix wrong script type from py-script to py

* review more tests related to attributes and add test for worker

* skip spashscreen tests

* wrap up reviews on remaining tests

* update core

* update display tests to use import

* fix more tests and skip some that have known issues

* skip other 2 tests that fail because the test framework injects values that cause the config to fail

* fix getPySrc test due to changed interface

* another round of fixes and commenting on specific tests

---------

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
2023-09-01 10:01:09 -07:00
Andrea Giammarchi
ef44df5dda [next] Bring in stdlib as artifact (#1666) 2023-09-01 09:24:49 -07:00
Andrea Giammarchi
da3b43abdd [next] xworker.sync pollution example (#1659) 2023-08-31 15:37:17 +02:00
Andrea Giammarchi
4cc9647dc6 [next] allow document.createElement(py-script) (#1662) 2023-08-31 14:23:01 +02:00
Andrea Giammarchi
74cd7c840a [next] Sanitize <py-script> content + deprecate html content (#1663) 2023-08-31 10:43:28 +02:00
Andrea Giammarchi
0f2deeb71a [next] Place a target in the body (#1658) 2023-08-30 14:43:48 +02:00
Andrea Giammarchi
93539c9b5a Fix #1651 - Avoid leaks from the registered module (#1655) 2023-08-29 22:32:05 +02:00
Andrea Giammarchi
e48e6276e1 [next] PyScript Next basic documentation (#1634) 2023-08-17 08:12:55 -07:00
Andrea Giammarchi
75a57a49f5 [next] Porting most basic examples (#1631) 2023-08-10 22:42:01 +02:00
Andrea Giammarchi
8a1db288fc [next] Updated polyscript to use PyScript custom stderr when running code (#1629) 2023-08-09 19:30:18 +02:00
Andrea Giammarchi
84dcde188b [next] Bring in the good old PyScript display (#1628) 2023-08-09 16:28:06 +02:00
Andrea Giammarchi
27c91e9703 [next] Updated LICENSE & dependencies (#1626) 2023-08-08 17:16:43 +02:00
Andrea Giammarchi
b5a0cd4057 [sw] Added a first version of the PyScript Service Worker (#1621)
* Added a first version of the PyScript Service Worker

* Fix typo as suggested

Co-authored-by: Fabio Pliger <fpliger@users.noreply.github.com>

---------

Co-authored-by: Fabio Pliger <fpliger@users.noreply.github.com>
2023-08-08 10:57:26 +02:00
Andrea Giammarchi
77d8fe3562 [next] Improved worker attribute DX (#1625) 2023-08-07 18:36:33 +02:00
Andrea Giammarchi
a484aff457 Moved back pyscript.core where it belongs (#1622) 2023-08-07 15:15:05 +02:00
Andrea Giammarchi
c96f5912df Prepared for the first publish (#1620) 2023-08-03 11:22:16 +02:00
Andrea Giammarchi
8a01a56e51 Add pyscript module in both Main and Workers (#1619) 2023-08-03 10:44:17 +02:00
Andrea Giammarchi
2774e49ab9 [next] Brought back home PyScript Next (#1616) 2023-08-01 22:28:57 +02:00
Andrea Giammarchi
26e7a54f1f @pyscript/core deprecation (#1607) 2023-07-21 11:07:42 +02:00
Jack Zhao
f0e69cbc36 fix interpreter absoluteURL (#1603) 2023-07-19 13:21:44 +02:00
Andrea Giammarchi
413428f535 [next] Better Errors - Worker (#1602) 2023-07-19 13:20:03 +02:00
Andrea Giammarchi
0c54036466 [next] Add basic integrations tests (#1576)
* [next] WIP: Add basic integrations tests

* fix typos in  README.md

* Update README.md to specify when files are _ files ignored

---------

Co-authored-by: Fabio Pliger <fpliger@users.noreply.github.com>
2023-07-19 10:18:17 +02:00
Andrea Giammarchi
2555833831 [next] FS create folder before writing in it (#1582) 2023-07-17 13:46:17 +02:00
Andrea Giammarchi
7e0aceced1 [next] Updated to latest coincident + MicroPython (#1595) 2023-07-13 17:00:04 +02:00
Andrea Giammarchi
77234f6df3 [next] Updated coincident to fix a MicroPython bug (#1591) 2023-07-12 17:55:39 +02:00
Andrea Giammarchi
45af96aad4 [next] Updated to latest MicroPython (#1590) 2023-07-12 10:45:46 +02:00
Andrea Giammarchi
184d29055e [next] Await events when invoked (#1589) 2023-07-11 13:27:59 +02:00
Andrea Giammarchi
9e73181816 [next] Use the very same source for all Python interpreters (#1588) 2023-07-10 17:54:13 +02:00
Andrea Giammarchi
0b0e03456c [next] Improve the whole events story (#1584) 2023-07-10 15:36:48 +02:00
Andrea Giammarchi
c6b5ce7f55 [next] Drop web like events (#1578)
* Use registerJSModule when available (#1573)

* Updated version to publish latest
2023-07-06 17:56:06 +02:00
Andrea Giammarchi
a14e701be4 Use registerJSModule when available (#1573) 2023-06-29 22:50:35 +02:00
Andrea Giammarchi
7813c3f03f Added npm run dev (#1572) 2023-06-29 12:45:07 +02:00
Andrea Giammarchi
3a3cb7b11d Align npm versioning (#1568) 2023-06-27 22:34:10 +02:00
Andrea Giammarchi
d7b0731385 Added a section dedicated to XWorker required headers (#1567) 2023-06-27 20:56:16 +02:00
Andrea Giammarchi
df8973736f Update latest package.json version + lock (#1565) 2023-06-27 17:11:53 +02:00
Andrea Giammarchi
9121071ba3 PyScript Core Documentation (#1560) 2023-06-27 16:53:19 +02:00
Andrea Giammarchi
bf6470c046 Cleanup and improve the index.html for tests (#1558) 2023-06-22 21:37:11 +02:00
Andrea Giammarchi
3b7099cd3d Fixed issues around XWorker context (#1556) 2023-06-22 19:04:57 +02:00
Andrea Giammarchi
f6dfc5361e Implement PyScript custom <script type> (#1548)
* updated MicroPython to latest in order to have `globals` API available
  * reduced code around helpers for both MicroPython and Pyodide as now these are more aligned
  * updated all dependencies and brought in latest [coincident/window](https://github.com/WebReflection/coincident#coincidentwindow) goodness to any `xworker`, preserving the `sync` previous behavior
  * using [@ungap/structured-clone/json](https://github.com/ungap/structured-clone#tojson) as *coincident* default `parse` and `stringify` utility to allow recursive and more complex data to travel back from the *Worker* (forward data is still fully [structured clone algorithm compatible](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm))
  * renamed all *plugin/s* references to *custom/s* as plugin as a word was too misleading
  * changed *custom types* helpers logic to allow any single node to have its own version of the interpreter wrapper, and all the extra fields it carries with it, including a way to augment every interpreter execution, among as every worker code execution
  * created a `custom` folder where I've landed the very first `pyscript.js` custom type
  * created an exhaustive test page to demonstrate the current abilities of *PyScript Next* among its ability to expose utilities that can be used to create *PyScript* plugins
2023-06-22 17:29:07 +02:00
Andrea Giammarchi
0a7e1ce0d7 Fix #1531 - Remove overall need for globalThis pollution (#1543) 2023-06-19 18:05:45 +02:00
Andrea Giammarchi
d6b1c393f6 MicroPython as CDN (#1521) 2023-06-19 12:06:15 +02:00
Andrea Giammarchi
bccd5e3750 Fix #1538 - use same customElements Registry utilities (#1542) 2023-06-16 15:34:05 +02:00
Andrea Giammarchi
6df5905b2b [next] Ditch handy shortcuts for good (#1537) 2023-06-15 17:08:28 +02:00
Andrea Giammarchi
6284c02032 [next] Rename all runtime(s) references to interpreter(s) (#1536) 2023-06-15 15:34:07 +02:00
Andrea Giammarchi
db27d52352 [next] Update MicroPython and other dependencies (#1535) 2023-06-15 14:04:47 +02:00
Fábio Rosado
8ba28989fb Add ci for next (#1530)
* Add ci for next

* Install deps from the right folder and build the project

* Rename CI job for test next

* Remove all things pyscriptjs

* Remove ESLint job
2023-06-14 16:01:01 +01:00
Andrea Giammarchi
da544929ac [next] Enabled hooks around plugins (#1522) 2023-06-12 22:18:55 +02:00
Andrea Giammarchi
bb364b0524 Shared array buffer missing error (#1518)
Improve error reporting around SharedArrayBuffer
2023-06-09 20:51:51 +02:00
Andrea Giammarchi
818614b798 Improved Promise polyfill for MicroPython only (#1517) 2023-06-09 12:53:31 +02:00
Andrea Giammarchi
50b1a1d7c5 Fix #1512 - Improve worker tests + update Pyodide (#1513)
* Fix #1512 - Improve worker tests + update Pyodide

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

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

* [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>
2023-06-08 17:39:01 +02:00
Andrea Giammarchi
7d3b792a79 Fix #1514 - Provide a better feedback on HTML typos (#1515) 2023-06-08 13:49:49 +02:00
Andrea Giammarchi
af72e232c3 Worker sync utility (#1511)
* patched an issue with wasmoon randomly asking to resolve proxy references
  * simplified pyodide and micropython dance by grouping their common utilities together
  * created an integration test around a worker to main thread input between MicroPython and Lua
  * commented some weird bugs / funny behaviors around both MicroPython and Pyodide
  * other minor clean ups
2023-06-08 11:10:47 +02:00
Andrea Giammarchi
0cdbfbeb30 Updated MicroPython (#1510)
Updated MicroPython
2023-06-06 11:42:23 +02:00
Andrea Giammarchi
339e40063a WIP: Bringing PyScript.next PoC to the main project (#1507)
* kill unwrapped_remote (#1490)

* kill unwrapped_remote

* linting

* don't use callKwargs for python plugins

* fix tests and improve types

* Bringing PyScript.next PoC to the main project

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

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

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

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

---------

Co-authored-by: Madhur Tandon <20173739+madhur-tandon@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-06-05 21:52:28 +02:00
Neon22
4467898473 Update py-click.md (#1499)
Add links to other events so its clear py-click is not a limitation or umbrella term for the only kind of interaction.
2023-06-05 20:42:42 +05:30
Madhur Tandon
17d16b987f kill unwrapped_remote (#1490)
* kill unwrapped_remote

* linting

* don't use callKwargs for python plugins

* fix tests and improve types
2023-06-01 22:52:23 +05:30
Ted Patrick
8e86daac71 Year 2023 (#1496) 2023-05-31 17:13:13 -05:00
Ted Patrick
856720da49 Simple 404 in _static (#1495)
* Simple 404 in _static

* Docs 404 error

* s3_error.html
2023-05-31 16:42:30 -05:00
Ted Patrick
8f2c150d1e Docs correction (#1494) 2023-05-31 16:19:36 -05:00
Ted Patrick
7d8b4c980a Error html to root of docs (#1493)
* Error html to root of docs

* [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>
2023-05-31 16:10:32 -05:00
Jeff Glass
932756c7a0 Add Option to make Py-Terminal and Xterm.js (#1317)
* Add 'xterm' attribute in py-config using new validation

* Use screen reader mode

* Add `xtermReady` promise to allow users to away xterm.js init

* Guard against initializing a tag twice

* Add tests and doc
2023-05-29 10:00:20 -05:00
Andrea Giammarchi
538aac9a28 Fix #1482 - Add utils.py to the list of modules (#1485) 2023-05-25 10:39:07 +02:00
Andrea Giammarchi
856bf8f5fb Fix #1474 - await both JS and Python plugins all at once (#1481) 2023-05-24 18:59:23 +02:00
Jeff Glass
e1758ae2e2 Upgrade to Pyodide 0.23 (#1347)
* Upgrade to Pyodide 0.23.2

* Update changelog

* Use @param decorator to fix kmeans examlpe

* Separate zz_example tests to run sequentially

* Remove pytest.raises from pyscript_src_not_found test, use check_js_errors instead

* Add 'check_js_errors' to wait_for_pyscript
2023-05-24 07:59:19 -05:00
Andrea Giammarchi
61b3154461 [chore] Improve current Error extends (#1467) 2023-05-22 13:22:53 +02:00
Jeff Glass
fb9b30d144 Fix zz_examples tests (pin dependencies) (#1477) 2023-05-18 19:27:47 -05:00
StefanoHiway
b0df96b13f html tag not closed (#1473) 2023-05-17 16:16:35 +05:30
Andrea Giammarchi
a469062a32 Simplified classList within Python code (#1459) 2023-05-15 12:45:11 +02:00
Andrea Giammarchi
89d5d5c7db Fix svg errors on the page caused by <py-script> (#1464) 2023-05-15 12:44:19 +02:00
Madhur Tandon
b8c2d6b05d fix panel kmeans test (#1465) 2023-05-15 15:24:08 +05:30
Madhur Tandon
b247864414 remove PyWidget and py-register-widget + refactor PyList as a Python Plugin (#1452)
* remove PyWidget and py-register-widget

* refactor py-list as Plugin

* add newline

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

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

* fix eslint

* handle case if src not supplied

* move inside if

* - Remove src attribute for py-list
- Re-implement as a Python plugin
- Remove pylist.py from examples directory
- Remove PyListPlugin as one of the default ones

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

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

* move PyItem and PyList classes to the plugin

* clean up PyListTemplate and PyItemTemplate from pyscript module

* fix linting

* use PyList instead of PyListTemplate instead

* fix example for todo-pylist

* re-enable and improve test

* move py-list plugin to examples

* fix py-list plugin link

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-05-10 20:17:07 +05:30
Andrea Giammarchi
d3bcd87cfa Allow nodes in shadow roots to be addressed via Element (#1454) 2023-05-09 17:42:09 +02:00
Antonio Cuni
82e5b64bad Make sure that tests fail in case there is an unhandled Python error (#1456)
Before this PR, the following test passed:

    def test_pyscript_hello(self):
        self.pyscript_run(
            """
            <script type="py">
                raise Exception("hello")
            </script>
            """)

What happens is that we intercept the Python exception and display a nice banner on the DOM, but the test itself passes. This is error prone: if we have Python exceptions on the page, the test should fail by default, and we should have a way to silence it in case those exceptions are expected.

This PR treats Python errors as we treat JS errors: unhandled exceptions cause the test to fail, but you can silence them by calling self.check_py_errors(), exactly as you can call self.check_js_errors().
2023-05-09 15:39:19 +02:00
Andrea Giammarchi
73e0271c23 Fix typo in py-events attributes handling (#1458) 2023-05-09 14:29:00 +02:00
Andrea Giammarchi
a2dabee0e9 Fix element.select tests (#1457) 2023-05-09 13:12:29 +02:00
Andrea Giammarchi
6a27c6d9f2 Cleanup some unnecessary utility (#1453) 2023-05-06 08:20:08 +02:00
woxtu
213ced0c7f Fix an error message when loading local modules failed (#1394)
* Fix an error message when loading local modules failed

* Fix an error message when loading local modules failed
2023-05-05 18:17:35 +05:30
Andrea Giammarchi
5086c23d47 Fix #1445 - Move the EditorView into ShadowDOM (#1449) 2023-05-05 10:41:05 +02:00
Ted Patrick
ee345a5206 Add Andrea Giammarchi as PyScript Maintainer (#1450) 2023-05-04 19:27:50 -05:00
Andrea Giammarchi
f74cddc3b1 Fix #1446 - Move pyscript defer after other dependencies (#1448) 2023-05-04 12:42:35 +02:00
Andrea Giammarchi
5b986b8b26 Fix #1425 - Move scripts within the tutor to make it explicit more files are needed (#1444) 2023-05-03 13:12:06 +02:00
Andrea Giammarchi
14887b9814 Fix #1341 - Use <script type="py"> instead to avoid entities (#1443) 2023-05-03 13:11:27 +02:00
Andrea Giammarchi
ecc40315b3 Fix #1427 - Avoid multiple initialization of the same node (#1433) 2023-05-03 10:00:35 +02:00
Andrea Giammarchi
e7aed7fcf0 Fix #1059 - Observe py-* attributes changes (#1435) 2023-05-03 09:50:21 +02:00
Madhur Tandon
cd1aa948f9 [Worker support] test for no cors headers (#1374)
* test for no cors headers

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

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

* fix tests

* suggested changes

* disable directly

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

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

* add error message

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

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

* improve test

* improve error message

* remove py-config tag from cors test

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-05-02 18:43:11 +05:30
Andrea Giammarchi
82613d016a Fix #1429 - Use basic-devtools module (#1430)
This MR brings in `$`, `$$`, and `$x` browsers devtools' utilities to our code so we can use these whenever we find it convenient.
2023-05-02 15:12:28 +02:00
Jeff Glass
3a66be585f Add @when decorator (#1428)
* Add new _event_handling.py file with @when decorator

* @when decorate is in pyscript package namespace/_all__

* Write tests in new test_event_handling.py

* Add docs for @when decorator

------------

Co-authored-by: Mariana Meireles <marian.meireles@gmail.com>
2023-05-01 09:51:49 -05:00
Andrea Giammarchi
0a4e36ae09 Fix <script src> + test all py-script attributes (#1434) 2023-04-28 18:08:53 +02:00
Andrea Giammarchi
92643539cf Fix #735 - Test <script type="py"> against all special cases (#1431) 2023-04-27 17:46:42 +02:00
Andrea Giammarchi
a1281d1331 Fix #1326 - Allow <script type="py"> tag to work as <py-script> (#1396)
The goal of this MR is to unobtrusively allow the usage of `<script type="py">`, `<script type="pyscript">` or `<script type="py-script">` tags instead of `<py-script>` for all those case where the layout in custom elements get parsed and breaks users' expectations (including our SVG based tests).
2023-04-27 15:21:31 +02:00
Cameron Cairns
074ca0ef8f Adds missing dependency description (anaconda) to docs (#1409) 2023-04-27 12:06:31 +01:00
Fábio Rosado
464a9633dc Fix what is pyscript example h1 color (#1417) 2023-04-26 15:31:01 +01:00
Andrea Giammarchi
fc2d91c5bb Fix #801 - Simplified events listeners attachment: (#1403)
* always same listener, for easy removal and reduce RAM
  * avoid duplicated entries for smaller library outcome
  * use XPath to crawl all attributes names instead of CSS
2023-04-26 15:55:22 +02:00
MrValdez
d68169bffb Development documentation (#1410)
* Updated the instructions for setting up the documentation environment to be clearer

* Expanded on setting up the development and documentation environments.

Moved the documentation section to its own section as it's behavior and purpose is different from the development environment.

* Added alternative to git upstream

Indented list instead of using &nbsp;

* Add 'Using a Local Dev Server' to Getting Started Docs (#1400)

* Added alternative to git upstream

Indented list instead of using &nbsp;

Updated the test environment section

cleaned up "reviewing your work" section to make it easier to read.

* added "setting up environment" changes to changelog

* reverted additions to changelog

---------

Co-authored-by: Jeff Glass <glass.jeffrey@gmail.com>
2023-04-26 12:28:43 +01:00
Andrea Giammarchi
7efdb04e1e Increase commonly failing tests timeout (#1412) 2023-04-26 10:01:20 +02:00
Jeff Glass
0155e122fd Add nodejs=16 to docs conda env (#1413) 2023-04-25 11:36:27 -05:00
Jeff Glass
eb03f16a77 Improve PR template - Doc Changes Don't Need Changelogs(#1411) 2023-04-25 10:03:12 -05:00
Jeff Glass
5ac39641ab Add 'Using a Local Dev Server' to Getting Started Docs (#1400) 2023-04-25 08:17:57 -05:00
Ikko Eltociear Ashimine
8d1e48e400 Fix typo in py-config.md (#1399)
unspecifed -> unspecified
2023-04-21 10:01:59 -06:00
Andrea Giammarchi
0021ccb49f Remove redundant .shadow property as that is defined at the Custom Element level. (#1395) 2023-04-21 10:05:50 +02:00
woxtu
8590c7e5b8 Remove an unused dependency (#1390) 2023-04-16 14:23:52 +05:30
Antonio Cuni
8c5475f78f Move pyodide to a web worker (#1333)
This PR adds support for optionally running pyodide in a web worker:

- add a new option config.execution_thread, which can be `main` or `worker`. The default is `main`

- improve the test machinery so that we run all tests twice, once for `main` and once for `worker`

- add a new esbuild target which builds the code for the worker

The support for workers is not complete and many features are still missing: there are 71 tests which are marked as `@skip_worker`, but we can fix them in subsequent PRs.

The vast majority of tests fail because js.document is unavailable: for it to run transparently, we need the "auto-syncify" feature of synclink.


Co-authored-by: Hood Chatham <roberthoodchatham@gmail.com>
Co-authored-by: Madhur Tandon <20173739+madhur-tandon@users.noreply.github.com>
2023-04-14 10:55:31 +02:00
Jeff Glass
dfa116eb70 Improve validate() function for plugin options (#1323)
* Add `validateConfigParameter` and `validateConfigParameterFromArray` functions to validate user-provided parameters from py-config

* Add units tests for `validateConfigParameter` and `validateConfigParameterFromArray`

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-04-13 14:35:01 -05:00
Mike Chen
3a9fd3c074 Fix path errors on Windows systems (#1368)
* Add docs to repl with attr src

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

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

* Fix path errors on Windows systems

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

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

* Fix path errors on Windows systems

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-04-13 20:51:49 +05:30
Stefane Fermigier
5a92ef3c11 doc: remove duplicated link (#1386)
"How to write content to the page" appeared twice in the index.
2023-04-13 11:00:28 +05:30
woxtu
d3902f5c93 Update to the latest TypeScript (#1377) 2023-04-12 23:49:54 +05:30
Hood Chatham
c886f887ae Split pyscript into multiple files (#1338)
In the future this should help us leak fewer names into the pyscript
namespace.

Rather than assigning to the pyscript module from JavaScript, we
mount a separate private JS module with the extra names needed by
PyScript. I moved a bit more interpeter intialization into
remote_interpreter.

I added a deprecation warning for `pyscript.js`: the proper way to
access `js` is `import js`.

---------

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
2023-04-12 14:49:47 +02:00
Hood Chatham
fc5089ac59 same thread syncify (#1372)
Switch to using the new version of synclink with support for same thread syncify (and also correct types). 
Uses syncify to replace one use of `_unwrapped_remote`.
2023-04-11 21:31:05 -07:00
Madhur Tandon
e3602f464b remove pys-on* and py-on* attributes (#1361)
* remove pys-on* and py-on* attributes

* update changelog

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

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

* fix eslint

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-04-11 18:59:42 +05:30
Madhur Tandon
f3db6a339c remove PY_COMPLETE and the associated message of Python initialization complete (#1373)
* remove PY_COMPLETE

* fix test_multiple_async
2023-04-11 18:59:09 +05:30
cnelir98
c05195c045 DOCS Update display.md (#1375) 2023-04-10 18:44:08 +02:00
Antonio Cuni
af981fc719 Improve self.wait_for_console() (#1363)
- Previously, if the message appeared on the console immediately before the call to self.wait_for_console(), the call would hang forever until the timeout. Now, it returns immediately.

- `wait_for_pyscript` now logs the time actually taken for waiting

- `wait_for_pyscript` takes a `timeout` argument so that we can tweak it on a test-by-test basis
2023-04-05 16:00:17 +02:00
Mike Chen
088a264910 Add docs to repl with attr src (#1353)
* Add docs to repl with attr src

* [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>
2023-04-03 14:19:23 +02:00
Mike Chen
d7e80ad51b load code from the attr src of py-repl (#1292)
* load code from the attr src of py-repl

* load code from the attr src of py-repl

* load code from the attr src of py-repl

* load code from the attr src of py-repl

* [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>
2023-04-03 11:06:30 +02:00
Antonio Cuni
b53ddd401f re-enable source maps (#1340) 2023-03-31 16:42:19 +02:00
Hood Chatham
e9122bca9d Fix test_async and test_stdio_handling (#1319)
Resolves pyscript#1313 and pyscript#1314. On top of pyscript#1318.

The point of these tests is to define the execution order of Tasks
that are scheduled in <py-script> tags: first all the py-script tags
are executed and their related lifecycle events. Once all of this
is done, we schedule any enqueued tasks.

To delay the execution of these tasks, we use a custom event loop for
pyExec with this defer behavior. Until schedule_deferred_tasks is called,
we defer tasks started by user code. schedule_deferred_tasks starts all 
deferred user tasks and switches to immediately scheduling any further
user tasks.
2023-03-30 14:38:51 -07:00
Hood Chatham
b61e8435d1 Fix main.test.ts (#1320) 2023-03-30 10:52:39 -07:00
Hood Chatham
146afb6532 Remove all but 2 eslint-disable pragmas (#1335)
Turns off:
 - no-explicit-any (we need to handle any return values from runPython)
 - no-unsafe-assignment (noisy and pointless)

And resolves all but two remaining ones. The last two lints regard access to private Pyodide variables and so:
 - they are not easy to work around without an upstream Pyodide patch
 - they should trigger linter and require explicit override
2023-03-30 10:51:36 -07:00
Hood Chatham
854e9d1378 Refactor pyexec (#1318)
This is some refactoring I did on the way towards resolving pyscript#1313.
I added a new _run_pyscript Python function which executes the code
inside a context manager that sets the display target. We can then
return a JS object wrapper directly from Python.

I moved the "installation" of the pyscript module to loadInterpreter,
and pyimport pyscript_py there and give it a type. This avoids a bunch
of creating and deleting of proxies for pyscript_py and allows us to
give it a type once and for all.

I also did some minor logic cleanup in a few places.
2023-03-30 04:34:24 +02:00
Jeff Glass
689878ce32 Remove AWS upload (#1331)
Deleted final 2 steps of docs-review to un-break CI
2023-03-29 13:22:21 -05:00
Jeff Glass
d7ab177cc5 Deprecate py-mount Attribute (#1330)
* Deprecate py-mount attribute, with comments as to when it was deprecated

* Add changelog entry for deprecation

* Fix 'unused' examples that used py-mount (handtrack and mario)
2023-03-29 10:49:31 -05:00
aneesh98
f4c6093c47 Docs: make tests should be make test (#1332) 2023-03-29 07:33:32 -07:00
Hood Chatham
9fedfe3699 Use Promise.all to fetch files part of py-config (#1322)
This is a first step towards loading more stuff simultaneously rather
than sequentially.

The functional part of this is pretty small: call `calculateFetchPaths` and
then `Promise.all(fetchPaths.map(loadFileFromURL));`. I also transposed the
return type of `calculateFetchPaths` since it's more convenient to consume
this way.

I redid the logic in `calculateFetchPaths` a bit. I renamed `src/plugins/fetch.ts`
to `calculateFetchPaths.ts` since the file performs no fetching. I also
renamed `loadFromFile` to `loadFileFromURL`.
2023-03-29 07:32:09 -07:00
Hood Chatham
26f07246e1 Allow pyscript package to contain multiple files (#1309)
Followup to pyscript#1232. Closes pyscript#1226.

Use node to make a manifest of the src/python dir and then use an esbuild
plugin to resolve an import called `pyscript_python_package.esbuild_injected.json`
to an object indicating the directories and files in the package folder.
This object is then used to govern runtime installation of the package.
2023-03-29 07:31:14 -07:00
Antonio Cuni
3ae4b3c4de use a dynamic import for loading pyodide. This greatly simplifies the logic around interpreter loading and handling of UserError (#1306) 2023-03-27 18:46:50 +02:00
Madhur Tandon
c8f9f16791 synclink integration (#1258)
synclink integration + fixes for `py-repl` related tests and `display` tests
2023-03-27 20:56:31 +05:30
Antonio Cuni
88f0738500 re-enable blank issues
They were disabled by PR #1157 but without any discussion or consensus, so I guess it was a mistake. Personally I found them very useful and AFAIK we never had a problem of people abusing them, so I don't see why they should be disabled  (#1311)
2023-03-27 17:25:28 +02:00
Jeff Glass
03c79d5f2f Make repl hooks optional (#1310)
`beforeByReplExec()` and `afterPyReplExec()` only called if they exist on a plugin
2023-03-27 09:20:58 -05:00
zipperer
e7c3b7bcfe Update getting-started.md (#1307)
1. replace 'other then' with 'other than'
2. replace 'cherrie' with 'cherry'
2023-03-25 20:16:40 -05:00
Andrea Giammarchi
c8becca044 Slightly imporved pyrepl (#1296)
* removed unnecessary getAttribute
  * removed unnecessary shadow and ShadowDOM in general, as it was never used
  * dropped redundant constructor
  * removed unnecessary usage of the label element
  * fixed redundant always-same buttons IDs
2023-03-24 11:42:45 +01:00
Mariana Meireles
543a27271f Add docs for py-event* (#1300)
* Fix markdown
Add event-handlers.md

* Address changes from Jeff + Antonion and add it to index

* how tos don't exist anymore theyre now guides

* Restore p on contributing

* Adding changelog

* Aadd space

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

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

---------

Co-authored-by: Carmelo <carmelofiorello@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-03-23 17:57:49 +01:00
Fábio Rosado
a62aba83a0 Update changelog date (#1289) 2023-03-23 11:20:20 +00:00
pre-commit-ci[bot]
53c6cf5f45 [pre-commit.ci] pre-commit autoupdate (#1281)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/charliermarsh/ruff-pre-commit: v0.0.254 → v0.0.257](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.254...v0.0.257)
- [github.com/codespell-project/codespell: v2.2.2 → v2.2.4](https://github.com/codespell-project/codespell/compare/v2.2.2...v2.2.4)
- [github.com/pre-commit/mirrors-eslint: v8.35.0 → v8.36.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.35.0...v8.36.0)

* Fixes lint

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2023-03-23 11:58:25 +01:00
Hood Chatham
89842e20da Set pre-commit autoupdate to monthly (#1271)
* Set pre-commit autoupdate to quarterly

Weekly autoupdate creates a lot of noise

* Update .pre-commit-config.yaml

Co-authored-by: Christian Clauss <cclauss@me.com>

---------

Co-authored-by: Christian Clauss <cclauss@me.com>
2023-03-23 10:27:01 +01:00
Jeff Glass
ef793aecf3 Add REPL plugin hooks; Add output, output-mode, stderr attributes (#1106)
* Add before, after REPL hooks

* Re-introduce 'output-mode' attribute for py-repl

* Add plugin execution tests

* Documentation

* Changelog

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: mariana <marianameireles@protonmail.com>
2023-03-22 20:19:22 -05:00
Andrea Giammarchi
51d51409d3 Using esbuild instead of rollup (#1298) 2023-03-22 16:57:37 +01:00
Fábio Rosado
371b5eac45 Add tests for snippets in docs (#1264) 2023-03-22 15:34:23 +00:00
Mariana Meireles
5319bd13d5 Fix tests running on osx + remove auto-gen where doesnt make sense (#1297)
* Fix tests running on osx + remove auto-gen where doesnt make sense

* Linting

* Adds a changelog

* [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>
2023-03-21 14:39:51 +01:00
Andrea Giammarchi
e10d055453 Docked auto py-terminal (#1284) 2023-03-20 10:22:16 +00:00
Mariana Meireles
716254e655 Revert "Ruff: Add pylint (#1277)" (#1283)
This reverts commit 4c00b1683f.
2023-03-14 17:46:13 +01:00
Christian Clauss
4c00b1683f Ruff: Add pylint (#1277) 2023-03-13 18:03:15 +01:00
Hood Chatham
37c9db09c6 Fix many ESlint errors (#1265)
* Unvendor toml package

* Fix many ESlint errors

For mysterious reasons, these errors appear on my branch #1262 even
though they are not related to changes there. The eslint config seems
a bit unstable.

Anyways this fixes them.

* Put back Record

* Fix typescript compilation

* Fix lints

* Try @iarna/toml instead

* Fix import

* Use @ltd/j-toml

* Update test

* Use toml-j0.4

* Some changes

* Fix toml import

* Try adding eslint gha job

* Add forgotten checkout action

* Force CI to run

* Blah

* Fix

* Revert changes to github workflow

* Fix lints

* wget toml-j0.4 type definitions

* Add toml-j types workaround to eslint workflow

* Apply formatter

* Use @hoodmane/toml-j0.4

* Import from @hoodmane/toml-j0.4
2023-03-13 15:51:28 +01:00
Fábio Rosado
653e2c9be4 Revert changes to the sync workflow (#1276) 2023-03-13 13:39:17 +00:00
Kanishk Pachauri
a2a9613da1 Added Pull request template (#1279)
* Added Pull request template

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

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

---------

Co-authored-by: you@example.com <you@example.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-03-13 13:03:47 +00:00
Antonio Cuni
e8d92d0d34 we cannot use ../build paths in the main examples/ directory (#1275) 2023-03-11 10:35:26 +00:00
Fábio Rosado
755b98a8c0 Update sync-examples CI to be run manually as well (#1274) 2023-03-11 10:34:59 +00:00
Hood Chatham
13e9252260 Run eslint in github actions, skip it in precommit.ci (#1268)
precommit.ci seems to have different results than when I run eslint
locally. At least at first glance, github seems to behave the same
as local. So this turns off eslint in pre-commit.ci and turns it on
in gha.
2023-03-09 14:48:24 +05:30
Hood Chatham
6a9c27325a Fix typo in workflow file (#1266) 2023-03-09 14:45:36 +05:30
Hood Chatham
a1cb78eb85 Fix paths in py-unit/conftest.py (#1269)
The path logic here assumes that the tests are being run from inside
the pyscriptjs directory. It is better to compute releative to `Path(__file__)`
so that it does not depend on the working directory
2023-03-09 14:44:33 +05:30
Hood Chatham
716b57ebd3 Pass --fix to ruff in pre-commit to enable autofixes (#1270) 2023-03-09 14:43:42 +05:30
pre-commit-ci[bot]
8e231313b8 [pre-commit.ci] pre-commit autoupdate (#1260)
updates:
- [github.com/charliermarsh/ruff-pre-commit: v0.0.247 → v0.0.254](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.247...v0.0.254)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Madhur Tandon <20173739+madhur-tandon@users.noreply.github.com>
2023-03-09 14:42:59 +05:30
Hood Chatham
84e4e361c5 Unvendor toml package (#1263)
* Unvendor toml package

* Try @iarna/toml instead

* Fix import

* Use @ltd/j-toml

* Update test

* Use toml-j0.4

* Fix toml import
2023-03-09 14:36:43 +05:30
Mariana Meireles
41a8d804e3 Attrs doc (#1125)
* adds attr ref

* lint

* address comments

* Addressing to Fabio's rewrite
2023-03-07 11:49:46 +01:00
Hood Chatham
03e798a079 Add prettier to pre-commit (#1255)
* Add prettier to pre-commit

* Apply prettier
2023-03-07 15:02:16 +05:30
Hood Chatham
34a0205757 Add missing </body> tags (#1256) 2023-03-06 22:11:46 +05:30
dependabot[bot]
ba145f04ea Bump json5 from 2.2.1 to 2.2.3 in /pyscriptjs (#1216) 2023-03-06 16:24:17 +00:00
Hood Chatham
22fd023635 More automatically generated formatter changes (#1254)
Apparently some of these were accidentally lost when generating #1210...
2023-03-06 15:06:30 +00:00
Hood Chatham
08f34f748b Apply prettier to css, html, js, md, ts, and yml (#1249)
* Apply prettier to css, js, html, md, ts, and yml

As a followup I will add prettier to the .pre-commit config.
This patch is 100% generated by prettier.
I used a forked version of prettier that understands the
py-script tag.
See https://github.com/hoodmane/pyscript-prettier-precommit
for more info.

* Apply old pre-commit

* Revert some problems

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

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

* Revert some changes

* More changes

* Fix pre-commit

* [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>
2023-03-06 14:20:21 +00:00
Christian Clauss
7ffe6a598e pre-commit: Add ruff to replace bandit, flake8, isort, and pyupgrade (#1210)
* pre-commit: Add ruff to replace bandit, flake8, isort, and pyupgrade

* Upgrade ruff

* Update .pre-commit-config.yaml

* Update .pre-commit-config.yaml

* Update .pre-commit-config.yaml
2023-03-06 14:20:08 +00:00
Kd-Here
71d24a445e Add description of src attribute to py-script (#1136)
* Added description of src attribute to py-script

* Description for py-script src attribute

* resolved mistake of raised by pre-commit

* Update docs/reference/elements/py-script.md

---------

Co-authored-by: Fábio Rosado <hello@fabiorosado.dev>
2023-03-06 12:39:55 +00:00
Fábio Rosado
6bcbbfb085 Add tutorial for using requests (#1164) 2023-03-06 12:36:52 +00:00
Hood Chatham
04fe1348d8 Fix test reporter again (#1247)
* Fix test reporter again

* Escape brackets
2023-03-06 17:15:01 +05:30
Madhur Tandon
3033c779b0 use mkdirTree in emscripten FS (#1245)
* try mkdirTree

* suggested changes

* fix pre-commit
2023-03-04 18:48:01 +05:30
Hood Chatham
4483f0db0f Move prism.js and prism.css to prism.min.* (#1248) 2023-03-03 17:32:06 +00:00
Madhur Tandon
727267ae22 split interpreter class (#1218)
* split interpreter class

* add new files

* add newlines

* disable eslint for run

* remove usage of interpreter from unit test

* delete fakeinterpreter class

* fix unit tests

* add comments

* remove interpreter.ts and pyodide.ts files

* suggested changes
2023-03-03 22:23:52 +05:30
Hood Chatham
b5d15c2f7e Actually generate test reports (#1246) 2023-03-03 14:10:48 +01:00
Hood Chatham
589c614e57 Fix syntax errors in html files, apply dos2unix, prettier everything (#1244)
* Fix syntax errors in html files

* [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>
2023-03-03 12:59:49 +01:00
Hood Chatham
4588e90226 Add test reporter (#1242)
* Add test reporter

* Fix indendation

* [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>
2023-03-02 12:38:51 +00:00
Hood Chatham
8665a14dec Begin making pyscript.py into a Python package (#1232)
* Begin making pyscript.py into a Python package

* Fix path
2023-03-02 12:30:43 +00:00
Jeff Glass
43d598d951 Fix Failing test_multiple_async (#1237) 2023-02-28 07:21:10 -06:00
Fábio Rosado
68018cf078 Add intersphinx and some docs (#1217)
* Add intersphinx and some docs

* Remove spaces

* Address Jeff comments
2023-02-28 11:37:21 +00:00
Jeff Glass
ef4ab0d7a8 Add typing for tagExecutionLock (#1235) 2023-02-28 12:27:49 +05:30
Hood Chatham
e66a2702df Fix error message (#1225) 2023-02-28 12:22:40 +05:30
Hood Chatham
c57d4a7054 Remove @staticmethod decorator from top level definitions (#1224) 2023-02-28 12:22:13 +05:30
Hood Chatham
a36f08f0f1 Try new import path and fall back to old one (#1223) 2023-02-28 12:21:55 +05:30
pre-commit-ci[bot]
760a8c75a5 [pre-commit.ci] pre-commit autoupdate (#1234)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.34.0 → v8.35.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.34.0...v8.35.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-02-28 12:12:28 +05:30
Jeff Glass
740fd921e1 Make plugin methods optional (#1134)
* Make plugin methods optional using optional chaining on all methods.
2023-02-27 20:14:07 -06:00
Jeff Glass
065c697070 Fix by comparing to str(results)) (#1233) 2023-02-27 19:45:24 -06:00
Madhur Tandon
e2c2459290 wrap runPython in async (#1212) 2023-02-21 20:35:19 +00:00
pre-commit-ci[bot]
11c79a5344 [pre-commit.ci] pre-commit autoupdate (#1211)
updates:
- [github.com/macisamuele/language-formatters-pre-commit-hooks: v2.6.0 → v2.7.0](https://github.com/macisamuele/language-formatters-pre-commit-hooks/compare/v2.6.0...v2.7.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-02-21 09:16:17 +00:00
pre-commit-ci[bot]
429fe4c356 [pre-commit.ci] pre-commit autoupdate (#1202)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.33.0 → v8.34.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.33.0...v8.34.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-02-14 11:14:02 +00:00
Russell Keith-Magee
a18b4edfc0 Updated freedom demo to make use of Toga 0.3.0 and briefcase web backend. (#1203) 2023-02-14 11:13:39 +00:00
Mariana Meireles
b14a2bba5f Marimeireles fix/#1081 (#1155)
* Improves repl id output

* Fix tests for new REPL output ids

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

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

* Add new REPL tests

* Pre commit linting

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

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

* Remove mistake

* Fixing tests that i didn't notice were broken?

* [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>
2023-02-14 07:51:43 +01:00
Ted Patrick
1f825edc28 Issues Configuration (#1157)
* Issues Configuration

* format

* Remove issue staler
2023-02-09 17:05:54 -06:00
Mariana Meireles
6ed834807a Adding info on how to set up test env + rewording a few things (#1156)
* Adding info on how to set up test env + rewording a few things

* changelog entry

* lint
2023-02-08 11:25:12 -08:00
Madhur Tandon
9a908e5fd0 Upgrade Pyodide to v0.22.1 (#1144)
* upgrade to pyodide 0.22.1

* pin bokeh in panel examples

* fix typo

* fix tests by using custom bokeh wheel

* fix bokeh interactive test

* adhere to new loadPackage API
2023-02-08 22:01:51 +05:30
Mariana Meireles
4c30359b71 Missing one line to make test (#1154)
`make test` command was incomplete.
2023-02-07 11:18:45 +05:30
pre-commit-ci[bot]
34dfe2d80b [pre-commit.ci] pre-commit autoupdate (#1153)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/psf/black: 22.12.0 → 23.1.0](https://github.com/psf/black/compare/22.12.0...23.1.0)

* [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>
2023-02-07 11:17:57 +05:30
Fábio Rosado
25bcff10b7 Fix import warning for js.document (#1151) 2023-02-06 16:11:47 +00:00
Fábio Rosado
81268d0545 Add config option to splashscreen so users can disable it plus docs (#1138)
* Allow disabling splashscreen

* Move disabled to if statement

* Add docs for py-splashscreen and test for logging

* Add entry to changelog

* Address Jeff's comments

* Rename disabled option to enabled and set to true by default

* Fix logic and tests

* Uncomment test

* Fix test
2023-02-04 15:56:48 +00:00
Madhur Tandon
8f0a7706d7 fix py-markdown plugin test (#1145) 2023-02-04 20:57:17 +05:30
Mariana Meireles
46150f9b80 complete install guide (#1140) 2023-01-31 08:18:58 -08:00
INC
247745b7e7 Fixing docs Issue #1033 (#1037)
* Move the info in /pyscriptjs/README.md to /docs/development/developing.md

* developing.md: Markdown linting

* Fixing docs issue #1033

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

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

* setting-up-environment.md: Markdown Linting

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-31 12:28:25 +00:00
pre-commit-ci[bot]
94cc09b610 [pre-commit.ci] pre-commit autoupdate (#1139)
updates:
- [github.com/pycqa/isort: 5.11.4 → 5.12.0](https://github.com/pycqa/isort/compare/5.11.4...5.12.0)
- [github.com/pre-commit/mirrors-eslint: v8.32.0 → v8.33.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.32.0...v8.33.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-31 10:49:14 +05:30
Jeff Glass
a210b2d5f5 Improve typing on PyScriptTag (#1135) 2023-01-26 09:38:07 -06:00
Jeff Glass
12bf6db331 Change Plugin Hooks to Use options object/kwargs (#1132) 2023-01-26 07:20:04 -06:00
Madhur Tandon
697ac9de9a fix exception thrown but not shown in DOM in event handler (#1131)
* fix exception not thrown in event handler

* fix implicit display 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>
2023-01-25 20:08:05 +05:30
Fábio Rosado
4124bb5edc Restructure the tutorials index page (#1090) 2023-01-25 12:28:23 +00:00
Fabio Pliger
d55340a817 Better test support for Python Plugins (#1108)
* add plugins testing utils module

* add plugins manager fixture and init plugins tests helper in conftest

* add _custom_elements attribute to pyscript.Plugin to allow plugins to track the CE they register

* add test for py_tutor

* remove unrelated code from prims js script

* ensure a Plugin always has the app attribute and improve tests

* add tests for py_tutor create_code_section

* implement PluginsManager reset and add teardown on plugins_manager fixture to clean it up after a test

* add test to check if plugin has been registered

* add docstrings to new tests

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

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

* add docstrings to plugins tester

* add changes from main

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

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

* lint

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

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

* add todo to add remaining PluginsManager lifecycle events

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-24 13:32:16 -08:00
Mohammad Anash
0de8cd9ab7 Update README to point to development docs (#1129) 2023-01-24 19:57:00 +00:00
Madhur Tandon
4e8281c749 fix display multiple append with target (#1126)
* fix display multiple append with target

* flake8 ignore long lines

* fix img render test
2023-01-24 22:01:19 +05:30
pre-commit-ci[bot]
357fbc644d [pre-commit.ci] pre-commit autoupdate (#1127)
updates:
- [github.com/macisamuele/language-formatters-pre-commit-hooks: v2.5.0 → v2.6.0](https://github.com/macisamuele/language-formatters-pre-commit-hooks/compare/v2.5.0...v2.6.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-24 11:20:07 +05:30
Fábio Rosado
7947a8a2dc Add an id if the user forgot when using py-attribute (#1122) 2023-01-21 20:48:27 +00:00
Fábio Rosado
35de3aa154 Add f string formatting ignore (#1121) 2023-01-20 21:14:43 +05:30
pre-commit-ci[bot]
1ea687beb8 [pre-commit.ci] pre-commit autoupdate (#1111)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.31.0 → v8.32.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.31.0...v8.32.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-20 21:14:32 +05:30
Fábio Rosado
bb5c59307a Rename runtimes with interpreter (#1082) 2023-01-16 18:52:31 +00:00
Mariana Meireles
5a3c414c8f we don't really use numpy here (#1101) 2023-01-11 19:43:26 -08:00
Fábio Rosado
cc4b460183 Allow fetching plugins from URL (#1065) 2023-01-11 17:03:53 +00:00
Jeff Glass
470c3489dd Restore output attribute of py-script tags, add py-script exec lifecycle hooks (#1063)
* Add beforePyScriptExec, afterPyScriptExec lifecycle hooks

* Add stdiodirector plugin for `output`, `stderr` attributes of py-script tag

* Add docs on `output` and `stderr` attributes of py-script tag

* Tests

* Removed output deprecation warning for `output` attribute

* Add createSingularWarning(), with createDeprecationWarning as alias
2023-01-10 13:00:29 -06:00
Jeff Glass
e1b4415193 Fix Flaky test_execute_on_shift_enter (#1097)
* Wait for text to render in DOM before 'assert', to fix timing issue.
2023-01-05 07:29:20 -06:00
Jeff Glass
77d98a565e In a Py-Repl, Shift Enter Shouldn't Insert Newline (#1094)
* Prevent shift-enter adding newlines in Py-Repl

* Add test
2023-01-04 12:26:46 -06:00
Fábio Rosado
412da2de08 Add version file (#1087) 2023-01-03 17:31:13 +00:00
Fábio Rosado
dbdcd0b3d0 Remove deprecated elements and adds deprecation banner to pys-on (#1084)
* Show deprecation banner

* Add test for deprecation warning

* Remove deprecated elements

* Add entry in changelog

* Update test_style

* Remove random color rule

* Add PR link to changelog
2023-01-03 13:14:20 +00:00
pre-commit-ci[bot]
5c67384fbf [pre-commit.ci] pre-commit autoupdate (#1086)
updates:
- [github.com/pre-commit/mirrors-eslint: v8.30.0 → v8.31.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.30.0...v8.31.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-01-03 10:55:37 +00:00
Fábio Rosado
35b0f9d377 pys-onClick shouldn't prevent splashscreen from closing (#1069) 2022-12-30 12:34:27 +00:00
Fábio Rosado
95783bc284 Add changelog to docs (#1066) 2022-12-29 23:07:39 +00:00
Ioannis Chrysostomakis
4b840f7cbd Minor refactoring in logger and pyconfig (#1072) 2022-12-28 10:51:21 +00:00
pre-commit-ci[bot]
f73d6cd9f2 [pre-commit.ci] pre-commit autoupdate (#1078)
updates:
- [github.com/pycqa/isort: v5.11.3 → 5.11.4](https://github.com/pycqa/isort/compare/v5.11.3...5.11.4)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-27 19:05:40 +00:00
Roman Kehr
15bb8f03ea Pandas example file for /examples folder (#1067)
* Add files via upload

* [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-26 10:38:16 +00:00
Jeff Glass
059dbc88c9 Don't add plugin to manager twice (#1064)
* Prevent Python plugins from being added to PluginManager twice
2022-12-21 12:10:01 -06:00
Fabio Pliger
c0f36aa047 examples inspector plugin (#1040)
* replace unnecessary elements from hello_world example and replace with py-tutor tag

* add py_tutor plugin

* port altair example

* add code for more granular tutor mode

* add support for including modules source in pytutor

* remove js dependencies in hello_world

* put antigravity on a diet ;)

* use py-tutor on antigravity example

* use py-tutor on d3 example

* use py-tutor on bokeh example

* use py-tutor on bokeh_interactive example

* fix issue when module_paths is undefined

* remove prism js dependency leftovers

* ooops, really remove prism js dependency leftovers

* port follium example to pytutor

* port pymarkdown and matplotlib example to pytutor

* port message_passing and numpy_convas_fractals examples to pytutor

* port the panel complex  examples to pytutor

* port the panel complex  examples to pytutor

* port last examples to py-tutor

* remove prism

* remore most debugging logs and replace log with info

* add new d3.py file

* add comments to connect method

* clean pyscript class from logs

* revert class pySrc attribute

* add check_tutor_generated_code to test code inspector plugin in examples

* add doctsting to PyTutor connect

* add check for tutor code inspection on all examples

* Update pyscriptjs/src/plugins/python/py_tutor.py

fix template indentation

Co-authored-by: Fábio Rosado <fabioglrosado@gmail.com>

* Update examples/todo-pylist.html

fix typo (stray = )

Co-authored-by: Fábio Rosado <fabioglrosado@gmail.com>

* fix pymarkdown example

Co-authored-by: Fabio Pliger <fpliger@anaconda.com>
Co-authored-by: Fábio Rosado <fabioglrosado@gmail.com>
2022-12-20 07:48:07 -08:00
pre-commit-ci[bot]
d4120d2af3 [pre-commit.ci] pre-commit autoupdate (#1056)
updates:
- [github.com/pycqa/isort: 5.11.1 → v5.11.3](https://github.com/pycqa/isort/compare/5.11.1...v5.11.3)
- [github.com/pre-commit/mirrors-eslint: v8.29.0 → v8.30.0](https://github.com/pre-commit/mirrors-eslint/compare/v8.29.0...v8.30.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2022-12-20 12:09:44 +00:00
Nayan Khedkar
dd1c008447 missing closing > in img tag (#1058) 2022-12-20 10:26:22 +00:00
Jeff Glass
3721d2cd72 Add name:pyscript to minified output (#1054) 2022-12-16 19:11:58 -06:00
Roman Kehr
e0dda0e547 Fixed "Direct usage of document is deprecated." warning (#1052) 2022-12-16 20:28:12 +00:00
Jeff Glass
3c7568c72c Adjust version_info test regex - no dot (#1045)
Tweaked the `test_version_info` test to remove matching against an extraneous '.'
2022-12-13 16:10:06 -06:00
Ted Patrick
6be1758548 Back to development 2022-12-13 11:39:11 -06:00
484 changed files with 19808 additions and 34057 deletions

View File

@@ -2,62 +2,64 @@ name: Bug Report
description: Create a report to help us improve
labels: ["type: bug", "needs-triage"]
body:
- type: markdown
- type: markdown
attributes:
value: |
Thanks for helping PyScript! 🐍
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.
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 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
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
Finally, if you are opening **a bug report related to PyScript.com** please [use this repository instead](https://github.com/anaconda/pyscript-dot-com-issues/issues/new/choose).
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
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!
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
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
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
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
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.
label: Additional Context
description: Add any additional context information or screenshots you think are useful.

View File

@@ -1,5 +1,8 @@
blank_issues_enabled: true
contact_links:
- name: Question
url: https://community.anaconda.cloud/c/tech-topics/pyscript
- name: Feature Proposals
url: https://github.com/pyscript/pyscript/discussions/new?category=proposals
about: Create a feature request to make PyScript even better
- name: Questions
url: https://github.com/pyscript/pyscript/discussions/new?category=q-a
about: For questions or discussions about pyscript

View File

@@ -1,67 +0,0 @@
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,37 +0,0 @@
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

15
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,15 @@
## Description
<!--Please describe the changes in your pull request in few words here. -->
## Changes
<!-- List the changes done to fix a bug or introduce a new feature.Please note both user-facing changes and changes to internal API's here -->
## Checklist
<!-- Note: Only user-facing changes require a changelog entry. Internal-only API changes do not require a changelog entry. Changes in documentation do not require a changelog entry. -->
- [ ] All tests pass locally
- [ ] I have updated `CHANGELOG.md`
- [ ] I have created documentation for this(if applicable)

13
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
# Keep GitHub Actions up to date with GitHub's Dependabot...
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem
version: 2
updates:
- package-ecosystem: github-actions
directory: /
groups:
github-actions:
patterns:
- "*" # Group all Actions updates into a single larger pull request
schedule:
interval: weekly

6
.github/release.yml vendored
View File

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

26
.github/stale.yaml vendored
View File

@@ -1,26 +0,0 @@
# 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,101 +0,0 @@
name: '[CI] Build Unstable'
on:
push: # Only run on merges into main that modify files under pyscriptjs/ and examples/
branches:
- main
paths:
- pyscriptjs/**
- examples/**
- .github/workflows/build-latest.yml # Test that workflow works when changed
pull_request: # Run on any PR that modifies files under pyscriptjs/ and examples/
branches:
- main
paths:
- pyscriptjs/**
- examples/**
- .github/workflows/build-unstable.yml # Test that workflow works when changed
workflow_dispatch:
jobs:
BuildAndTest:
runs-on: ubuntu-latest
defaults:
run:
working-directory: pyscriptjs
env:
MINICONDA_PYTHON_VERSION: py38
MINICONDA_VERSION: 4.11.0
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
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
- 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 --quiet ./build/ s3://pyscript.net/unstable/

View File

@@ -1,66 +0,0 @@
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/

View File

@@ -1,74 +0,0 @@
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

View File

@@ -1,55 +0,0 @@
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/

View File

@@ -1,60 +1,56 @@
name: '[CI] Prepare Release'
name: "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
- "[0-9][0-9][0-9][0-9].[0-9][0-9].[0-9]+" # YYYY.MM.MICRO
defaults:
run:
working-directory: pyscriptjs
working-directory: ./pyscript.core
jobs:
build:
prepare-release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v3
- name: Install node
uses: actions/setup-node@v4
with:
node-version: 18.x
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v4
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: 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: NPM Install
run: npm install && npx playwright install
- name: setup Miniconda
uses: conda-incubator/setup-miniconda@v2
- name: Build
run: npm run build
- name: Setup Environment
run: make setup
- name: Generate index.html
working-directory: .
run: sed 's#_PATH_#./#' ./public/index.html > ./pyscript.core/dist/index.html
- name: Build and Test
run: make test
- name: Zip dist folder
run: zip -r -q ./build.zip ./dist
- 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
- name: Prepare Release
uses: softprops/action-gh-release@v2
with:
draft: true
prerelease: true
generate_release_notes: true
files: ./build.zip

View File

@@ -1,62 +1,63 @@
name: '[CI] Publish Release'
name: "Publish Release"
on:
release:
types: [published]
env:
MINICONDA_PYTHON_VERSION: py38
MINICONDA_VERSION: 4.11.0
defaults:
run:
working-directory: pyscriptjs
working-directory: ./pyscript.core
jobs:
build:
publish-release:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v4
- name: Install node
uses: actions/setup-node@v3
with:
node-version: 18.x
- name: Install node
uses: actions/setup-node@v4
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: Cache node modules
uses: actions/cache@v4
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: npm install
run: npm install && npx playwright install
- name: Setup Environment
run: make setup
- name: build
run: npm run build
- name: Build and Test
run: make test
- name: Generate index.html in snapshot
working-directory: .
run: sed 's#_PATH_#https://pyscript.net/releases/${{ github.ref_name }}/#' ./public/index.html > ./pyscript.core/dist/index.html
# Upload 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: Generate release.tar from snapshot and put it in dist/
working-directory: .
run: tar -cvf ../release.tar * && mv ../release.tar .
- name: Sync to S3
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 }}/
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3
run:
| # Update /latest and create an explicitly versioned directory under releases/YYYY.MM.MICRO/
aws s3 sync --quiet ./dist/ s3://pyscript.net/latest/
aws s3 sync --quiet ./dist/ s3://pyscript.net/releases/${{ github.ref_name }}/

View File

@@ -1,26 +1,61 @@
name: '[CI] Publish Snapshot'
# Copy /unstable/ to /snapshots/2022.09.1.RC1/
name: "Publish Snapshot"
on:
workflow_dispatch:
inputs:
snapshot_version:
description: 'The calver version of this snapshot: 2022.09.1 or 2022.09.1.RC1'
description: "The calver version of this snapshot: 2022.09.1 or 2022.09.1.RC1"
type: string
required: true
defaults:
run:
working-directory: ./pyscript.core
jobs:
snapshot:
publish-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 }}/
- name: Checkout
uses: actions/checkout@v4
- name: Install node
uses: actions/setup-node@v4
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v4
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: Install Dependencies
run: npm install && npx playwright install
- name: Build Pyscript.core
run: npm run build
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Generate index.html in snapshot
working-directory: .
run: sed 's#_PATH_#https://pyscript.net/snapshots/${{ inputs.snapshot_version }}/#' ./public/index.html > ./pyscript.core/dist/index.html
- name: Copy to Snapshot
run: >
aws s3 sync ./dist/ s3://pyscript.net/snapshots/${{ inputs.snapshot_version }}/

61
.github/workflows/publish-unstable.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: "Publish Unstable"
on:
push: # Only run on merges into main that modify files under pyscript.core/ and examples/
branches:
- main
paths:
- pyscript.core/**
- examples/**
workflow_dispatch:
jobs:
publish-unstable:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
defaults:
run:
working-directory: ./pyscript.core
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install node
uses: actions/setup-node@v4
with:
node-version: 18.x
- name: Cache node modules
uses: actions/cache@v4
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: NPM Install
run: npm install && npx playwright install
- name: Build
run: npm run build
- name: Generate index.html in snapshot
working-directory: .
run: sed 's#_PATH_#https://pyscript.net/unstable/#' ./public/index.html > ./pyscript.core/dist/index.html
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ secrets.AWS_REGION }}
role-to-assume: ${{ secrets.AWS_OIDC_RUNNER_ROLE }}
- name: Sync to S3
run: aws s3 sync --quiet ./dist/ s3://pyscript.net/unstable/

View File

@@ -1,29 +0,0 @@
name: '[CI] Sync Examples'
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
defaults:
run:
working-directory: examples
steps:
# Deploy to S3
- name: Checkout
uses: actions/checkout@v3
- 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
# Sync outdated or new files, delete ones no longer in source
run: aws s3 sync --quiet --delete . s3://pyscript.net/examples/ # Sync directory, delete what is not in source

92
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,92 @@
name: "[CI] Test"
on:
push: # Only run on merges into main that modify certain files
branches:
- main
paths:
- pyscript.core/**
- .github/workflows/test.yml
pull_request: # Only run on merges into main that modify certain files
branches:
- main
paths:
- pyscript.core/**
- .github/workflows/test.yml
workflow_dispatch:
jobs:
BuildAndTest:
runs-on: ubuntu-latest-8core
env:
MINICONDA_PYTHON_VERSION: py38
MINICONDA_VERSION: 4.11.0
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 3
# display a git log: when you run CI on PRs, github automatically
# merges the PR into main and run the CI on that commit. The idea
# here is to show enough of git log to understand what is the
# actual commit (in the PR) that we are using. See also
# 'fetch-depth: 3' above.
- name: git log
run: git log --graph -3
- name: Install node
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Cache node modules
uses: actions/cache@v4
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@v3
- name: Create and activate virtual environment
run: |
python3 -m venv test_venv
source test_venv/bin/activate
echo PATH=$PATH >> $GITHUB_ENV
echo VIRTUAL_ENV=$VIRTUAL_ENV >> $GITHUB_ENV
- name: Setup dependencies in virtual environment
run: |
make setup
- name: Build
run: make build
- name: Integration Tests
#run: make test-integration-parallel
run: |
make test-integration
- uses: actions/upload-artifact@v4
with:
name: pyscript
path: |
pyscript.core/dist/
if-no-files-found: error
retention-days: 7
- uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: test_results
path: test_results/
if-no-files-found: error

16
.github/workflows/test_report.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
name: Test Report
on:
workflow_run:
workflows: ['\[CI\] Test']
types:
- completed
jobs:
report:
runs-on: ubuntu-latest-8core
steps:
- uses: dorny/test-reporter@v1.9.0
with:
artifact: test_results
name: Test reports
path: "*.xml"
reporter: java-junit

14
.gitignore vendored
View File

@@ -51,7 +51,6 @@ coverage.xml
*.py,cover
.hypothesis/
.pytest_cache/
pyscriptjs/examples
# Translations
*.mo
@@ -138,3 +137,16 @@ dmypy.json
node_modules/
coverage/
# junit xml for test results
test_results
# @pyscript/core npm artifacts
pyscript.core/test-results/*
pyscript.core/core.*
pyscript.core/dist
pyscript.core/dist.zip
pyscript.core/src/plugins.js
pyscript.core/src/stdlib/pyscript.js
pyscript.core/src/3rd-party/*
!pyscript.core/src/3rd-party/READMEmd

View File

@@ -1,89 +1,53 @@
# This is the configuration for pre-commit, a local framework for managing pre-commit hooks
# Check out the docs at: https://pre-commit.com/
ci:
#skip: [eslint]
autoupdate_schedule: monthly
default_stages: [commit]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-builtin-literals
- id: check-case-conflict
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-json
exclude: tsconfig.json
- id: check-toml
- id: check-xml
- id: check-yaml
- id: detect-private-key
- id: end-of-file-fixer
exclude: \.min\.js$
- id: trailing-whitespace
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: check-builtin-literals
- id: check-case-conflict
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-json
exclude: tsconfig\.json
- id: check-toml
exclude: bad\.toml
- id: check-xml
- id: check-yaml
- id: detect-private-key
- id: end-of-file-fixer
exclude: pyscript\.core/dist|\.min\.js$
- id: trailing-whitespace
- repo: https://github.com/PyCQA/bandit
rev: 1.7.4
hooks:
- id: bandit
args:
- --skip=B101,B201
- repo: https://github.com/psf/black
rev: 24.4.2
hooks:
- id: black
exclude: pyscript\.core/src/stdlib/pyscript/__init__\.py
- repo: https://github.com/psf/black
rev: 22.12.0
hooks:
- id: black
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell # See 'pyproject.toml' for args
exclude: \.js\.map$
additional_dependencies:
- tomli
- repo: https://github.com/hoodmane/pyscript-prettier-precommit
rev: "v3.0.0-alpha.6"
hooks:
- id: prettier
exclude: pyscript\.core/test|pyscript\.core/dist|pyscript\.core/types|pyscript.core/src/stdlib/pyscript.js|pyscript\.sw/|pyscript.core/src/3rd-party
args: [--tab-width, "4"]
- repo: https://github.com/codespell-project/codespell
rev: v2.2.2
hooks:
- id: codespell # See 'setup.cfg' for args
- repo: https://github.com/PyCQA/flake8
rev: 6.0.0
hooks:
- id: flake8 # See 'setup.cfg' for args
additional_dependencies: [flake8-bugbear, flake8-comprehensions]
- repo: https://github.com/pycqa/isort
rev: 5.11.1
hooks:
- id: isort
name: isort (python)
args: [--profile, black]
- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
rev: v2.5.0
hooks:
- id: pretty-format-yaml
args: [--autofix, --indent, '4']
exclude: .github/ISSUE_TEMPLATE/.*\.yml$
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.1
hooks:
- id: pyupgrade
args:
- --py310-plus
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.29.0
hooks:
- id: eslint
files: pyscriptjs/src/.*\.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx
types: [file]
additional_dependencies:
- eslint@8.25.0
- typescript@4.8.4
- '@typescript-eslint/eslint-plugin@5.39.0'
- '@typescript-eslint/parser@5.39.0'
# 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
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
name: isort (python)
args: [--profile, black]

5
.prettierignore Normal file
View File

@@ -0,0 +1,5 @@
ISSUE_TEMPLATE
*.min.*
package-lock.json
docs
examples/panel.html

View File

@@ -25,4 +25,4 @@ conda:
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt
- requirements: docs/requirements.txt

97
CHANGELOG.md Normal file
View File

@@ -0,0 +1,97 @@
# Release Notes
## 2024.05.21
### Features
### Bug fixes
### Enhancements
- `py-editor` run buttons now display a spinner when disabled, which occurs when the editor is running code.
## 2023.05.01
### Features
- Added the `xterm` attribute to `py-config`. When set to `True` or `xterm`, an (output-only) [xterm.js](http://xtermjs.org/) terminal will be used in place of the default py-terminal.
- The default version of Pyodide is now `0.23.2`. See the [Pyodide Changelog](https://pyodide.org/en/stable/project/changelog.html#version-0-23-2) for a detailed list of changes.
- Added the `@when` decorator for attaching Python functions as event handlers
- The `py-mount` attribute on HTML elements has been deprecated, and will be removed in a future release.
#### Runtime py- attributes
- Added logic to react to `py-*` attributes changes, removal, `py-*` attributes added to already live nodes but also `py-*` attributes added or defined via injected nodes (either appended or via `innerHTML` operations). ([#1435](https://github.com/pyscript/pyscript/pull/1435))
#### &lt;script type="py"&gt;
- Added the ability to optionally use `<script type="py">`, `<script type="pyscript">` or `<script type="py-script">` instead of a `<py-script>` custom element, in order to tackle cases where the content of the `<py-script>` tag, inevitably parsed by browsers, could accidentally contain _HTML_ able to break the surrounding page layout. ([#1396](https://github.com/pyscript/pyscript/pull/1396))
#### &lt;py-terminal&gt;
- Added a `docked` field and attribute for the `<py-terminal>` custom element, enabled by default when the terminal is in `auto` mode, and able to dock the terminal at the bottom of the page with auto scroll on new code execution.
#### &lt;py-script&gt;
- Restored the `output` attribute of `py-script` tags to route `sys.stdout` to a DOM element with the given ID. ([#1063](https://github.com/pyscript/pyscript/pull/1063))
- Added a `stderr` attribute of `py-script` tags to route `sys.stderr` to a DOM element with the given ID. ([#1063](https://github.com/pyscript/pyscript/pull/1063))
#### &lt;py-repl&gt;
- The `output` attribute of `py-repl` tags now specifies the id of the DOM element that `sys.stdout`, `sys.stderr`, and the results of a REPL execution are written to. It no longer affects the location of calls to `display()`
- Added a `stderr` attribute of `py-repl` tags to route `sys.stderr` to a DOM element with the given ID. ([#1106](https://github.com/pyscript/pyscript/pull/1106))
- Resored the `output-mode` attribute of `py-repl` tags. If `output-mode` == 'append', the DOM element where output is printed is _not_ cleared before writing new results.
- Load code from the attribute src of py-repl and preload it into the corresponding py-repl tag by use the attribute `str` in your `py-repl` tag([#1292](https://github.com/pyscript/pyscript/pull/1292))
- &lt;py-repl&gt; elements now have a `getPySrc()` method, which returns the code inside the REPL as a string.([#1516](https://github.com/pyscript/pyscript/pull/1292))
#### Plugins
- Plugins may now implement the `beforePyReplExec()` and `afterPyReplExec()` hooks, which are called immediately before and after code in a `py-repl` tag is executed. ([#1106](https://github.com/pyscript/pyscript/pull/1106))
#### Web worker support
- introduced the new experimental `execution_thread` config option: if you set `execution_thread = "worker"`, the python interpreter runs inside a web worker
- worker support is still **very** experimental: not everything works, use it at your own risk
### Bug fixes
- Fixes [#1280](https://github.com/pyscript/pyscript/issues/1280), which describes the errors on the PyRepl tests related to having auto-gen tags that shouldn't be there.
### Enhancements
- Py-REPL tests now run on both osx and non osx OSs
- migrated from _rollup_ to _esbuild_ to create artifacts
- updated `@codemirror` dependency to its latest
### Docs
- Add docs for event handlers
## 2023.03.1
### Features
### Bug fixes
- Fixed an issue where `pyscript` would not be available when using the minified version of PyScript. ([#1054](https://github.com/pyscript/pyscript/pull/1054))
- Fixed missing closing tag when rendering an image with `display`. ([#1058](https://github.com/pyscript/pyscript/pull/1058))
- Fixed a bug where Python plugins methods were being executed twice. ([#1064](https://github.com/pyscript/pyscript/pull/1064))
### Enhancements
- When adding a `py-` attribute to an element but didn't added an `id` attribute, PyScript will now generate a random ID for the element instead of throwing an error which caused the splash screen to not shutdown. ([#1122](https://github.com/pyscript/pyscript/pull/1122))
- You can now disable the splashscreen by setting `enabled = false` in your `py-config` under the `[splashscreen]` configuration section. ([#1138](https://github.com/pyscript/pyscript/pull/1138))
### Documentation
- Fixed 'Direct usage of document is deprecated' warning in the getting started guide. ([#1052](https://github.com/pyscript/pyscript/pull/1052))
- Added reference documentation for the `py-splashscreen` plugin ([#1138](https://github.com/pyscript/pyscript/pull/1138))
- Adds doc for installing tests ([#1156](https://github.com/pyscript/pyscript/pull/1156))
- Adds docs for custom Pyscript attributes (`py-*`) that allow you to add event listeners to an element ([#1125](https://github.com/pyscript/pyscript/pull/1125))
### Deprecations and Removals
- The py-config `runtimes` to specify an interpreter has been deprecated. The `interpreters` config should be used instead. ([#1082](https://github.com/pyscript/pyscript/pull/1082))
- The attributes `pys-onClick` and `pys-onKeyDown` have been deprecated, but the warning was only shown in the console. An alert banner will now be shown on the page if the attributes are used. They will be removed in the next release. ([#1084](https://github.com/pyscript/pyscript/pull/1084))
- The pyscript elements `py-button`, `py-inputbox`, `py-box` and `py-title` have now completed their deprecation cycle and have been removed. ([#1084](https://github.com/pyscript/pyscript/pull/1084))
- The attributes `pys-onClick` and `pys-onKeyDown` have been removed. Use `py-click` and `py-keydown` instead ([#1361](https://github.com/pyscript/pyscript/pull/1361))

View File

@@ -4,17 +4,24 @@ Thank you for wanting to contribute to the PyScript project!
## Table of contents
* [Code of Conduct](#code-of-conduct)
* [Contributing](#contributing)
* [Reporting bugs](#reporting-bugs)
* [Reporting security issues](#reporting-security-issues)
* [Asking questions](#asking-questions)
* [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
* [Places to start](#places-to-start)
* [Submitting a change](#submitting-a-change)
* [License terms for contributions](#license-terms-for-contributions)
* [Becoming a maintainer](#becoming-a-maintainer)
* [Trademarks](#trademarks)
- [Contributing to PyScript](#contributing-to-pyscript)
- [Table of contents](#table-of-contents)
- [Code of Conduct](#code-of-conduct)
- [Contributing](#contributing)
- [Reporting bugs](#reporting-bugs)
- [Creating useful issues](#creating-useful-issues)
- [Reporting security issues](#reporting-security-issues)
- [Asking questions](#asking-questions)
- [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
- [Developing](#developing)
- [Rebasing changes](#rebasing-changes)
- [Building the docs](#building-the-docs)
- [Places to start](#places-to-start)
- [Setting up your local environment and developing](#setting-up-your-local-environment-and-developing)
- [Submitting a change](#submitting-a-change)
- [License terms for contributions](#license-terms-for-contributions)
- [Becoming a maintainer](#becoming-a-maintainer)
- [Trademarks](#trademarks)
# Code of Conduct
@@ -28,10 +35,10 @@ Bugs are tracked on the [project issues page](https://github.com/pyscript/pyscri
## Creating useful issues
* 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 behavior you observed, and the behavior you had expected.
* Include screenshots if they help make the issue clear.
- 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 behavior you observed, and the behavior you had expected.
- Include screenshots if they help make the issue clear.
## Reporting security issues
@@ -43,18 +50,18 @@ If you have questions about the project, using PyScript, or anything else, pleas
## 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:
* **Read over the existing documentation.** Are there things missing, or could they be clearer? Make some changes/additions to those documents.
* **Review the open issues.** Are they clear? Can you reproduce them? You can add comments, clarifications, or additions to those issues. If you think you have an idea of how to address the issue, submit a fix!
* **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.
- **Read over the existing documentation.** Are there things missing, or could they be clearer? Make some changes/additions to those documents.
- **Review the open issues.** Are they clear? Can you reproduce them? You can add comments, clarifications, or additions to those issues. If you think you have an idea of how to address the issue, submit a fix!
- **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.
## Setting up your local environment and developing
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.
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/contributing/#set-up-your-development-environment) will help you get started.
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.
You can also read about PyScript's [development process](https://docs.pyscript.net/latest/developers/) to learn how to contribute code to PyScript, how to run tests and what's the PR etiquette of the community!
## License terms for contributions
@@ -69,5 +76,106 @@ Contributors are invited to be maintainers of the project by demonstrating good
The Project abides by the Organization's [trademark policy](https://github.com/pyscript/governance/blob/main/TRADEMARKS.md).
---
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/).
# Quick guide to pytest
We make 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-x.y.z...
[ 0.18 request ] 200 - CACHED - https://cdn.jsdelivr.net/pyodide/vx.y.z/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.
### To run only main thread or worker tests
By default, we run each test twice: one with execution_thread = "main" and one with execution_thread = "worker". If you want to run only half of them, you can use -m:
$ pytest -m main # run only the tests in the main thread
$ pytest -m worker # ron only the tests in the web worker
## 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:
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.

View File

@@ -41,5 +41,6 @@ Any names, trademarks, logos, or goodwill developed by and associated with the P
Amendments to this governance policy may be made by affirmative vote of 2/3 of all Maintainers, with approval by the Organization's Steering Committee.
---
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/).

View File

@@ -186,7 +186,11 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Copyright (c) 2022-present, PyScript Development Team
Originated at Anaconda, Inc. in 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -9,15 +9,16 @@ This document lists the Maintainers of the Project. Maintainers may be added onc
| Philipp Rudiger | Anaconda, Inc |
| Peter Wang | Anaconda, Inc |
| Kevin Goldsmith | Anaconda, Inc |
| Mariana Meireles | Anaconda, Inc |
| Mariana Meireles | |
| Nicholas H.Tollervey | Anaconda, Inc |
| Madhur Tandon | Anaconda, Inc |
| Ted Patrick | Anaconda, Inc |
| Jeff Glass | --- |
| Paul Everitt | --- |
| Fabio Rosado | --- |
| Jeff Glass | |
| Paul Everitt | |
| Fabio Rosado | Anaconda, Inc |
| Andrea Giammarchi | Anaconda, Inc |
______________________________________________________________________
---
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/).

92
Makefile Normal file
View File

@@ -0,0 +1,92 @@
MIN_NODE_VER := 20
MIN_NPM_VER := 6
MIN_PY3_VER := 8
NODE_VER := $(shell node -v | cut -d. -f1 | sed 's/^v\(.*\)/\1/')
NPM_VER := $(shell npm -v | cut -d. -f1)
PY3_VER := $(shell python3 -c "import sys;t='{v[1]}'.format(v=list(sys.version_info[:2]));print(t)")
PY_OK := $(shell python3 -c "print(int($(PY3_VER) >= $(MIN_PY3_VER)))")
all:
@echo "\nThere is no default Makefile target right now. Try:\n"
@echo "make setup - check your environment and install the dependencies."
@echo "make clean - clean up auto-generated assets."
@echo "make build - build PyScript."
@echo "make precommit-check - run the precommit checks (run eslint)."
@echo "make test-integration - run all integration tests sequentially."
@echo "make fmt - format the code."
@echo "make fmt-check - check the code formatting.\n"
.PHONY: check-node
check-node:
@if [ $(NODE_VER) -lt $(MIN_NODE_VER) ]; then \
echo "\033[0;31mBuild requires Node $(MIN_NODE_VER).x or higher: $(NODE_VER) detected.\033[0m"; \
false; \
fi
.PHONY: check-npm
check-npm:
@if [ $(NPM_VER) -lt $(MIN_NPM_VER) ]; then \
echo "\033[0;31mBuild requires Node $(MIN_NPM_VER).x or higher: $(NPM_VER) detected.\033[0m"; \
false; \
fi
.PHONY: check-python
check-python:
@if [ $(PY_OK) -eq 0 ]; then \
echo "\033[0;31mRequires Python 3.$(MIN_PY3_VER).x or higher: 3.$(PY3_VER) detected.\033[0m"; \
false; \
fi
# Check the environment, install the dependencies.
setup: check-node check-npm check-python
cd pyscript.core && npm install && cd ..
ifeq ($(VIRTUAL_ENV),)
echo "\n\n\033[0;31mCannot install Python dependencies. Your virtualenv is not activated.\033[0m"
false
else
python -m pip install -r requirements.txt
playwright install
endif
# Clean up generated assets.
clean:
find . -name \*.py[cod] -delete
rm -rf $(env) *.egg-info
rm -rf .pytest_cache .coverage coverage.xml
# Build PyScript.
build:
cd pyscript.core && npx playwright install && npm run build
# Run the precommit checks (run eslint).
precommit-check:
pre-commit run --all-files
# Run all integration tests sequentially.
test-integration:
mkdir -p test_results
pytest -vv $(ARGS) pyscript.core/tests/integration/ --log-cli-level=warning --junitxml=test_results/integration.xml
# Run all integration tests in parallel.
test-integration-parallel:
mkdir -p test_results
pytest --numprocesses auto -vv $(ARGS) pyscript.core/tests/integration/ --log-cli-level=warning --junitxml=test_results/integration.xml
# Format the code.
fmt: fmt-py
@echo "Format completed"
# Check the code formatting.
fmt-check: fmt-py-check
@echo "Format check completed"
# Format Python code.
fmt-py:
black -l 88 --skip-string-normalization .
isort --profile black .
# Check the format of Python code.
fmt-py-check:
black -l 88 --check .
.PHONY: $(MAKECMDGOALS)

View File

@@ -4,48 +4,92 @@
### Summary
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.
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/), [MicroPython](https://micropython.org/) and [WASM](https://webassembly.org/), and modern web technologies.
To get started see the [getting started tutorial](docs/tutorials/getting-started.md).
To get started see the [Beginning PyScript tutorial](https://docs.pyscript.net/latest/beginning-pyscript/).
For examples see [here](examples).
For examples see [here](https://pyscript.com/@examples).
Other useful resources:
- The [official technical docs](https://docs.pyscript.net/).
- Our current [Home Page](https://pyscript.net/) on the web.
- A free-to-use [online editor](https://pyscript.com/) for trying PyScript.
- Our community [Discord Channel](https://discord.gg/BYB2kvyFwm), to keep in touch .
Every Tuesday at 15:30 UTC there is the _PyScript Community Call_ on zoom, where we can talk about PyScript development in the open. Most of the maintainers regularly participate in the call, and everybody is welcome to join.
Every other Thursday at 16:00 UTC there is the _PyScript FUN_ call: this is a call in which everybody is encouraged to show what they did with PyScript.
For more details on how to join the calls and up to date schedule, consult the official calendar:
- [Google calendar](https://calendar.google.com/calendar/u/0/embed?src=d3afdd81f9c132a8c8f3290f5cc5966adebdf61017fca784eef0f6be9fd519e0@group.calendar.google.com&ctz=UTC) in UTC time;
- [iCal format](https://calendar.google.com/calendar/ical/d3afdd81f9c132a8c8f3290f5cc5966adebdf61017fca784eef0f6be9fd519e0%40group.calendar.google.com/public/basic.ics).
### 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.
## Try PyScript
To try PyScript, import the appropriate pyscript files into the ```<head>``` tag of your html page with:
To try PyScript, import the appropriate pyscript files into the `<head>` tag of your html page:
```html
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<link
rel="stylesheet"
href="https://pyscript.net/releases/2024.6.2/core.css"
/>
<script
type="module"
src="https://pyscript.net/releases/2024.6.2/core.js"
></script>
</head>
<body>
<script type="py" terminal>
from pyscript import display
display("Hello World!") # this goes to the DOM
print("Hello terminal") # this goes to the terminal
</script>
</body>
```
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-repl>`: creates a REPL component that is rendered to the page as a code editor and allows users to write executable code
You can then use PyScript components in your html page. PyScript currently offers various ways of running Python code:
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.
- `<script type="py">`: can be used to define python code that is executable within the web page.
- `<script type="py" src="hello.py">`: same as above, but the python source is fetched from the given URL.
- `<script type="py" terminal>`: same as above, but also creates a terminal where to display stdout and stderr (e.g., the output of `print()`); `input()` does not work.
- `<script type="py" terminal worker>`: run Python inside a web worker: the terminal is fully functional and `input()` works.
- `<py-script>`: same as `<script type="py">`, but it is not recommended because if the code contains HTML tags, they could be parsed wrongly.
- `<script type="mpy">`: same as above but use MicroPython instead of Python.
Check out the [official docs](https://docs.pyscript.net/) for more detailed documentation.
## How to Contribute
Read the [contributing guide](CONTRIBUTING.md) to learn about our development process, reporting bugs and improvements, creating issues and asking questions.
Read the [contributing guide](https://docs.pyscript.net/latest/contributing/) to learn about our development process, reporting bugs and improvements, creating issues and asking questions.
## Resources
* [Official docs](https://docs.pyscript.net)
* [Discussion board](https://community.anaconda.cloud/c/tech-topics/pyscript)
* [Home Page](https://pyscript.net/)
* [Blog Post](https://engineering.anaconda.com/2022/04/welcome-pyscript.html)
* [Discord Channel](https://discord.gg/BYB2kvyFwm)
## Notes
* This is an extremely experimental project, so expect things to break!
* PyScript has been only tested on Chrome at the moment.
Check out the [developing process](https://docs.pyscript.net/latest/developers/) documentation for more information on how to setup your development environment.
## Governance
The [PyScript organization governance](https://github.com/pyscript/governance) is documented in a separate repository.
## Release
To cut a new release of PyScript simply
[add a new release](https://github.com/pyscript/pyscript/releases) while
remembering to write a comprehensive changelog. A [GitHub action](https://github.com/pyscript/pyscript/blob/main/.github/workflows/publish-release.yml)
will kick in and ensure the release is described and deployed to a URL with the
pattern: https://pyscript.net/releases/YYYY.M.v/ (year/month/version - as per
our [CalVer](https://calver.org/) versioning scheme).
Then, the following three separate repositories need updating:
- [Documentation](https://github.com/pyscript/docs) - Change the `version.json`
file in the root of the directory and then `node version-update.js`.
- [Homepage](https://github.com/pyscript/pyscript.net) - Ensure the version
referenced in `index.html` is the latest version.
- [PSDC](https://pyscript.com) - Use discord or Anaconda Slack (if you work at
Anaconda) to let the PSDC team know there's a new version, so they can update
their project templates.

View File

@@ -3,7 +3,8 @@
This page is meant for troubleshooting common problems with PyScript.
## Table of contents:
* [Make Setup](#make-setup)
- [Make Setup](#make-setup)
## Make setup

View File

@@ -1,46 +0,0 @@
# 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)

View File

@@ -1,31 +0,0 @@
# 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

@@ -1,48 +0,0 @@
<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>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,16 +0,0 @@
<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>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,33 +0,0 @@
# 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>
```
:::
::::

View File

@@ -1,103 +0,0 @@
# 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

@@ -1,30 +0,0 @@
# 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

@@ -1,203 +0,0 @@
# 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`.

View File

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

View File

@@ -1,69 +0,0 @@
# 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)

View File

@@ -1,18 +0,0 @@
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

View File

@@ -1,3 +0,0 @@
# 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/)

View File

@@ -1,35 +0,0 @@
# 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

@@ -1,213 +0,0 @@
# 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)

View File

@@ -1,20 +0,0 @@
# 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

@@ -1,295 +0,0 @@
# 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>
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -1,57 +0,0 @@
# 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
```

View File

@@ -1,35 +0,0 @@
@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

@@ -1,8 +0,0 @@
# `__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

@@ -1,87 +0,0 @@
# `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

@@ -1,309 +0,0 @@
# `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

@@ -1,16 +0,0 @@
# `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

@@ -1,487 +0,0 @@
# &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

@@ -1,30 +0,0 @@
# &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

@@ -1,111 +0,0 @@
# &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

@@ -1,39 +0,0 @@
# 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.

View File

@@ -1,160 +0,0 @@
# 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.

View File

@@ -1,54 +0,0 @@
# 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

@@ -1,77 +0,0 @@
# 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

@@ -1,41 +0,0 @@
# &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>`.
```

View File

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

View File

@@ -1,268 +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
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>
```

View File

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

View File

@@ -1,188 +0,0 @@
# 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

@@ -1,88 +0,0 @@
# 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

@@ -1,212 +0,0 @@
# 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>
```

View File

@@ -1,154 +0,0 @@
<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>

View File

@@ -1,118 +0,0 @@
<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,45 +0,0 @@
import random
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):
self.target = (
document.getElementById(target)
if isinstance(target, str)
else document.body
)
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

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 212 KiB

View File

@@ -1,90 +0,0 @@
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

@@ -1,70 +0,0 @@
.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

@@ -1,24 +0,0 @@
@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

@@ -1,22 +0,0 @@
*,
*: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

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

View File

@@ -1,3 +0,0 @@
/* 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

@@ -1,26 +0,0 @@
<!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

@@ -1,40 +0,0 @@
<!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

@@ -1,37 +0,0 @@
<!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

@@ -1,40 +0,0 @@
<!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

@@ -1,34 +0,0 @@
<!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

@@ -1,19 +0,0 @@
<!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>

View File

@@ -1,115 +0,0 @@
<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

@@ -1,216 +0,0 @@
<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>

View File

@@ -1,314 +0,0 @@
<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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,136 +0,0 @@
<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

@@ -1,139 +0,0 @@
import numpy as np
from numpy.polynomial import Polynomial
def mandelbrot(
width: int,
height: int,
*,
x: float = -0.5,
y: float = 0,
zoom: int = 1,
max_iterations: int = 100
) -> np.array:
"""
https://www.learnpythonwithrune.org/numpy-compute-mandelbrot-set-by-vectorization
"""
# To make navigation easier we calculate these values
x_width, y_height = 1.5, 1.5 * height / width
x_from, x_to = x - x_width / zoom, x + x_width / zoom
y_from, y_to = y - y_height / zoom, y + y_height / zoom
# Here the actual algorithm starts
x = np.linspace(x_from, x_to, width).reshape((1, width))
y = np.linspace(y_from, y_to, height).reshape((height, 1))
c = x + 1j * y
# Initialize z to all zero
z = np.zeros(c.shape, dtype=np.complex128)
# To keep track in which iteration the point diverged
div_time = np.zeros(z.shape, dtype=int)
# To keep track on which points did not converge so far
m = np.full(c.shape, True, dtype=bool)
for i in range(max_iterations):
z[m] = z[m] ** 2 + c[m]
diverged = np.greater(
np.abs(z), 2, out=np.full(c.shape, False), where=m
) # Find diverging
div_time[diverged] = i # set the value of the diverged iteration number
m[np.abs(z) > 2] = False # to remember which have diverged
return div_time
def julia(
width: int,
height: int,
*,
c: complex = -0.4 + 0.6j,
x: float = 0,
y: float = 0,
zoom: int = 1,
max_iterations: int = 100
) -> np.array:
"""
https://www.learnpythonwithrune.org/numpy-calculate-the-julia-set-with-vectorization
"""
# To make navigation easier we calculate these values
x_width, y_height = 1.5, 1.5 * height / width
x_from, x_to = x - x_width / zoom, x + x_width / zoom
y_from, y_to = y - y_height / zoom, y + y_height / zoom
# Here the actual algorithm starts
x = np.linspace(x_from, x_to, width).reshape((1, width))
y = np.linspace(y_from, y_to, height).reshape((height, 1))
z = x + 1j * y
# Initialize z to all zero
c = np.full(z.shape, c)
# To keep track in which iteration the point diverged
div_time = np.zeros(z.shape, dtype=int)
# To keep track on which points did not converge so far
m = np.full(c.shape, True, dtype=bool)
for i in range(max_iterations):
z[m] = z[m] ** 2 + c[m]
m[np.abs(z) > 2] = False
div_time[m] = i
return div_time
Range = tuple[float, float]
def newton(
width: int,
height: int,
*,
p: Polynomial,
a: complex,
xr: Range = (-2.5, 1),
yr: Range = (-1, 1),
max_iterations: int = 100
) -> tuple[np.array, np.array]:
""" """
# To make navigation easier we calculate these values
x_from, x_to = xr
y_from, y_to = yr
# Here the actual algorithm starts
x = np.linspace(x_from, x_to, width).reshape((1, width))
y = np.linspace(y_from, y_to, height).reshape((height, 1))
z = x + 1j * y
# Compute the derivative
dp = p.deriv()
# Compute roots
roots = p.roots()
epsilon = 1e-5
# Set the initial conditions
a = np.full(z.shape, a)
# To keep track in which iteration the point diverged
div_time = np.zeros(z.shape, dtype=int)
# To keep track on which points did not converge so far
m = np.full(a.shape, True, dtype=bool)
# To keep track which root each point converged to
r = np.full(a.shape, 0, dtype=int)
for i in range(max_iterations):
z[m] = z[m] - a[m] * p(z[m]) / dp(z[m])
for j, root in enumerate(roots):
converged = (np.abs(z.real - root.real) < epsilon) & (
np.abs(z.imag - root.imag) < epsilon
)
m[converged] = False
r[converged] = j + 1
div_time[m] = i
return div_time, r

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