plotly / dash-component-boilerplate

Get started creating your own Dash components here.
265 stars 182 forks source link

Using component without formally installing via pip #132

Open gmweaver opened 2 years ago

gmweaver commented 2 years ago

Is it possible to incorporate a custom component without wrapping it into a formal Python package?

For context, we use Bazel for handling build dependencies and do not have formal pypi packages in our internal codebase, which is my reason for trying to avoid that step. The component works fine if I install, but is failing when I try to add the generated folder into my project.

I assume this may be related to the expected package_name when resolving resources (i.e. _js_dist) and the fact that the component folder is nested within the codebase. This could just be a Bazel problem, but wanted to check if I am missing anything or if pushing to pypi is my best option.

alexcjohnson commented 2 years ago

There may be a way to make this work just by tweaking package_name or some such as you say, and this could be an interesting thing to explore... But what we've mostly done in this situation is create the components with the structure of a pypi package, but then instead of uploading it just make a tarball (python setup.py sdist) and pip-install that (either as a line in a requirements file or just pip install my_custom_components-0.0.1.tar.gz)

See for example dash-user-guide-components with their tarball that we install from requirements.txt (note that repo isn't used anymore for the docs but you get the idea)

gmweaver commented 2 years ago

Thanks for the feedback! I can probably work with a tarball for now, but it would be great to get this working without that step. At this point, the issue is really my dev environment with Bazel, which will require something hacky to get it installed in the Bazel workflow.

I was able to get the component to import, but it does not seem to pickup/register the resources. I tried a simple nested folder structure for testing.

top_folder
    my_component
        MyComponent.py

I checked whether it was grabbing the scripts by doing something similar to below.

import dash
import top_folder.my_component

app = dash.Dash(...)

for x in app._collect_and_register_resources(app.scripts.get_all_scripts()):
    print(x)

My understanding is that importing should be enough for Dash to know that the resource is needed. If I move my_component to the top-level, it does register. Played with the package_name, but I don't have a good enough understanding of how Dash is looking for resources to find a fix for the nested case.

Feel free to close out unless you think this could be a useful feature.