-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate Dash components at buildtime rather than runtime (#150) #271
Conversation
Amazing stuff @rmarren1 ! I'm on the road now, I'll take a deeper look at this on Friday |
@rmarren1 - This looks great to me. Excellent tests and code organization. The only change that I'd like to make is including a comment at the top of the auto-generated files that says:
And now that we have this framework in place, we can start working on improving the autogenerated code. I think that this can happen in a separate PR. I'm thinking changes like:
With those fixes in place, then editors should stop complaining 😸 I'll create a new issue with these. |
Added those comments here, and in all the |
Looks great @rmarren1 ! I'm 💃 to this. Anyone else from @plotly/dash have feedback? |
I had to make some small changes to properly set the I also now generate an edit: I just got PyCharm up, it also fixes the |
Just use a sentinel object: sentinel = object()
class Component(...):
def __init__(self, figure=sentinel, id=sentinel, ...):
... This avoids the need to introduce new API such as the suggested |
It would be nice if we could set the default to the actual default value of the property though, since those values do show up in text editors (they are showing up in Atom) and it would quickly let users know the type of an argument. We could do something like this:
|
And these default properties get set on the React-side in One caveat is that adding in the default properties would be a backwards incompatible change, as the current behaviour is "if the value isn't specified, it's app.layout = html.Button(id='button')
@app.callback(..., [Input('button', 'n_clicks')])
def run(n_clicks):
if n_clicks is None: # but the default property would be `0`
raise dash.exceptions.PreventException() That's not to say that we shouldn't do it, but it would require a major version upgrade and some careful announcements to make sure everyone is aware when they upgrade. |
This roughly follows the suggestions in (#150) to create dash components at build-time via importing from an intermediary python class file rather than at creating them all at runtime.
Summary of changes:
In
dash/development/base_component.py
generate_class_string
which generates the intermediary class string which was previously created ingenerate_class
. This does not changegenerate_class
as it just moves some work to a subroutine.generate_class_file
which prepends the proper import statement (from dash.development.base_component import Component
) to the class string fromgenerate_class_string
and writes to file.In
dash/development/component_loader.py
_get_metadata
generate_classes
which consumes ametadata.json
at a filepath and writes all the classes within to file in an output directory. The filepath and output directory are 'lib/metadata.json' and 'lib' respectively making the no-arguments call work in the components libraries.In
tests/development/metadata_test.py
In
tests/development/test_base_component.py
generate_class_string
andgenerate_class_file
functions.In
tests/development/test_component_loader.py
generate_classes
function, specifically that the build-time generate classes produce the same objects as the run-time classes by comparing theirrepr
s.