reactive-python / reactpy Goto Github PK
View Code? Open in Web Editor NEWIt's React, but in Python
Home Page: https://reactpy.dev
License: MIT License
It's React, but in Python
Home Page: https://reactpy.dev
License: MIT License
This pattern is not allowed right now:
@idom.element
def GetsRenderedTwice(self):
return idom.html.div()
@idom.element
def CauseSecondRender(self, node):
events = idom.Events()
@event.on("Click")
def render_again():
self.update(node)
return node
This is because CauseSecondRender
uses the same instance of GetsRenderedTwice
and causes an error. We should not raise an error when this occurs though. Not sure why that limitation was put in there.
Here's where the error occurs:
See https://github.com/rmorshea/idom/blob/master/setup.py#L61. This should insert the path to extras.txt
in the error message.
This was actually intentional, but should really be a temporary solutions since it's rather inconvenient. In short we did this because requesting a resource from a different origin must be successful otherwise future requests to that resource will be blocked by the browser.
So if you restarted your kernel and refreshed the notebook page your IDOM widget views would fail to display when you re-ran it because the pre-existing view attempted to connect to the IDOM webserver when it didn't exist yet.
To work around this we temporarily displayed a script that set document.idomServerExists = true
so that views could check that flag before they displayed. This will be changed soon though.
https://travis-ci.com/rmorshea/idom/jobs/258370959
WARNING: Cannot resolve forward reference in type annotations of "idom.core.element.element": name 'VdomDict' is not defined
WARNING: Cannot resolve forward reference in type annotations of "idom.core.element.AbstractElement.mount": name 'AbstractLayout' is not defined
WARNING: Cannot resolve forward reference in type annotations of "idom.core.element.Element": name 'VdomDict' is not defined
WARNING: Cannot resolve forward reference in type annotations of "idom.core.element.Element.mount": name 'AbstractLayout' is not defined
WARNING: Cannot resolve forward reference in type annotations of "idom.server.base.AbstractRenderServer": name 'Element' is not defined
WARNING: Cannot resolve forward reference in type annotations of "idom.server.sanic.SanicRenderServer": name 'Element' is not defined
WARNING: Cannot resolve forward reference in type annotations of "idom.server.sanic.PerClientState": name 'Element' is not defined
WARNING: Cannot resolve forward reference in type annotations of "idom.server.sanic.SharedClientState": name 'Element' is not defined
WARNING: Cannot resolve forward reference in type annotations of "idom.widgets.common.EvalElement.mount": name 'AbstractLayout' is not defined
WARNING: Cannot resolve forward reference in type annotations of "idom.widgets.inputs.Input.mount": name 'AbstractLayout' is not defined
WARNING: Cannot treat a function defined as a local function: "idom.widgets.html.html" (use @functools.wraps)
WARNING: Cannot resolve forward reference in type annotations of "idom.widgets.html.html": name 'EventHandlerFunction' is not defined
It should be possible to support libraries that require transpilation if we expose Snowpack's API to Rollup: https://www.snowpack.dev/#non-standard-packages.
idom.node
allows you to pass children via *args
and attributes via **kwargs
. I think it would be cleaner to use if the interface was:
idom.node([...children], {...attributes})
Which makes it easier to specify attributes which are Python keywords (e.g. class
which is proxied by cls
now).
After #73 iDOM's spec was nearly compatible with Nteract's VDOM, but VDOM still doesn't have a way to indicate stopPropagation
or preventDefault
.
Animation callbacks should be unregistered from a layout when the element that saved it is unmounted. Once the element is unmounted there's no point in keeping the animation callback around since the element will never be shown again.
Animation callbacks proliferate in the introductory notebook if you repeatedly display the Snake Game. Eventually the notebook will slow down significantly since the animation callbacks reregister themselves indefinitely.
Add a %%dialect html
example in the intro notebook now that #121 is merged.
remove first_view_mounted
in intro notebook for snake game example
Instead of mypy.ini
or .flake8
just use a single setup.cfg
file. Example:
An update to mybinder's hosting situation now means that the binder will be served from either:
This is a problem because we need to know the URL of the notebook server in order to set up our websocket connection to the jupyter-server-proxy. The best thing I can think of is to use requests to check what url you get redirected to in order to figure out which cluster you've ended up at.
While you can technically use idom.Import
to import JS packages via URL and use them inside an application, this feature is a bit broken. For example, Material UI (imported from jspm) does not work. I'm not entirely sure of why this might be, but I suspect it has to do with the fact that importing it in this way creates two React instances that conflict with each other. From what I can tell, the only real solution is to provide a simple wrapper around NPM and some sort of bundler-like technology to install dependencies so they can be imported on the fly.
The most promising option I can see at the moment is Snowpack (probably because it seems like the most approachable to me). My plan for this is to rewrite the current client so it's ES6 compliant and then write a simple wrapper in Python that can install the dependencies with npm
, build them into ES6 modules with snowpack
and then serve them as part of the application. This will only work if the user installs npm
of course, however that seems like a fairly reasonable requirement for this sort of feature.
This would just be nice to have. Doing this later will only become more difficult.
The examples at https://idom.readthedocs.io/en/latest/examples.html seem to be based on an older version of code and there are some API changes that break many (maybe all?) of them.
For example in the To Do List example creates callbacks for events like this:
task_input = idom.html.input(onKeyDown=add_new_task)
... ...
delete_button = idom.html.td(idom.html.button("x"), onClick=remove)
but the current API has you pass the callbacks as a dictionary
Something like:
task_input = idom.html.input({'onKeyDown':add_new_task})
The JSON schema from the docs should be used to validate VDOM returned by layouts. We can add it to the tests and create a mock the wraps the layout's render function so that it validates every output.
Write tests with selenium
. Unit tests are helpful, but it would be good to get an end to end test in that covers the Javascript as well.
Add a link to the gitter channel to the docs: https://gitter.im/idom-for-python/community
We should at least try to execute all the cells in the into notebook. This will catch a lot of errors that might occur there due to breaking API changes. #125 is a good example of a breaking API change that wasn't modified in the intro notebook.
Because of ReactPy's granular core abstractions it should be possible to run ReactPy client-side with Pyodide or PyScript. Using ReactPy instead of a solution that relies on a transpiler could have some advantages:
ReactPy's client already uses React to render its JSON serializable VDOM into an actual view, so if the DOM representation were already client-side (as it would be with Pyodide) it should be trivial to send that representation to React directly rather than over a websocket.
Here is a functioning gist that uses ReactPy client-side via PyScript: https://gist.github.com/rmorshea/c888e6e34519edababf49351c63c335e
"Javascript Documentation" link in README goes nowhere.
Remove this from the docs.
Also we should probably copy the spec from Nteract's VDOM since we're no longer really relying, or supporting it in any capacity.
Use isort
to automatically sort imports (this should be enforced in CI). See pre-commit file:
Travis docs for PyPI deployment: https://docs.travis-ci.com/user/deployment/pypi/
The StaticBunch
class is missing a __delattr__
method that raises an error similar to __setattr__
.
Consider a case where a button click causes that button to be re-rendered. In this scenario, after the first click the backend will begin work to render again and eventually will delete state for the original button element. If shortly after the first button click a user clicks again it is possible that the button in the view and the button model in the backend are not the same. The event produced by this last click will result in an error because the element that would normally have handled it has already been deleted.
In particular we get a key error here:
Once Pyalect gets a 0.1.0 release we should pin the version:
We'll try this instead since travis is really fickle for some reason. https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
This limitation is due to the fact that there was no way to provide per-client parameters. Enabling clients to pass parameters to IDOM elements upon connection would enable them to display a unique view to each client based on which parameters were passed. There are probably other use cases for per-client view parameters beside just in the Jupyter Notebook so this is definitely worth doing.
The programmatic API is nice for installing dependencies on the fly, but in production I can't imagine anyone would ever do it that way. You'd want a CLI command you could run to install things ahead of time.
The specification docs show the eventHandler dict as having eventProps - those were removed a while ago.
Need to add a section to the docs which describes how iDOM works.
CHANGE: "For context, the following Python code would generate this HTML"
FROM: https://idom.readthedocs.io/en/latest/specs.html
TO: "For context, the following Python code would generate [the HTML above]"
CHANGE: "as a standalone application or as extension to an existing one"
FROM: https://idom.readthedocs.io/en/latest/concepts.html
TO: "as a standalone application or as [an] extension to an existing [application]."
There's a license file at the repo's top level and in src/py/
This is slightly more secure since the token can be revoked.
If we can make a JupyterLab extension for IDOM we won't need to set up a web server to display views, we can just use the builtin comm system.
Examples of other extensions:
While the asyncio
API looks nice and shiny to me, I've heard some feedback, that given the audience idom
might serve, the async/await
syntax might scare them off. Additionally, expensive backend processes block renders of minor changes. For example, the matplotlib example blocks updates to the sliders when the graph image is being created this causes the moving sliders to jitter each time the graph updates.
See https://pypi.org/project/setuptools-scm/
This should make the release process for dev versions extremely seamless.
Changes to the event handler system have broken the to-do list example. Pretty simple to fix though.
Fix bug in animation where you could register a new animation hook after stopping the original hook (i.e. by returning False). We solve this by marking whether or not an element's animation hook has stopped. If you register a hook after a prior one has stopped then a RuntimeError will be raised.
We also change the animation API by passing in a stop function. Once the stop function has been called then the animation hook will not be called again and no new animation hooks can be registered to the element.
The following will allow animation callbacks to produce frame with relatively consistent timing.
import time
import asyncio
class FramePace:
def __init__(self, rate):
self._rate = rate
self._last = time.time()
async def wait(self):
await asyncio.sleep(self._rate - (time.time() - self._last))
self._last = time.time()
Describe what's wrong with the documentation
We should reference https://github.com/jviide/htm.py instead of htm.js
in the Extra Features section.
It was reported that a key error could here due to an absent element.id
So the element managed to schedule an update even though it unmounted? Or the update was schedule, the element was unmounted, and then it tried to get rendered again? Not really sure.
There's a bug in the way event handlers are set up that assigns all event handlers under the same target ID. Thus registering handlers to more than one event type causes a conflict.
This:
async def InputWithShareableValue(self, value=""):
async def changed(event):
# this update is sent to all clients
self.update(value)
return idom.html.input(value=value, onChange=changed)
should be updated to:
async def InputWithShareableValue(self, value=""):
async def changed(event):
# this update is sent to all clients
self.update(event["value"])
return idom.html.input(value=value, onChange=changed)
FastAPI appears to be gaining a lot of traction and it would be great to integrate it into IDOM.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.