dieterich-lab / rp-bp

Rp-Bp is a Bayesian approach to predict, at base-pair resolution, ribosome occupancy and translation.
MIT License
7 stars 5 forks source link

How to run the app locally w/o calling the python script? #136

Closed eboileau closed 1 year ago

dokempf commented 1 year ago

I will look into this (do not have rights to assign to me).

eboileau commented 1 year ago

What is done now

To launch the app, we need to call the python script e.g. under a local clone of rp-bp

python src/rpbp/analysis/profile_construction/dashboard/rpbp_profile_construction_dashboard.py /path/to/config.yaml

What we would like

An easier "entry point" for users to call the app, with the resulting dashboard showing up in a browser.

I initially just added the script to console_scripts, but last time I tried this resulted in

  File "/beegfs/prj/rpbp-dev/bullseye/envs/rpbp-cmdstan/bin/rpbp-profile-construction-dashboard", line 33, in <module>
    sys.exit(load_entry_point('rpbp', 'console_scripts', 'rpbp-profile-construction-dashboard')())
  File "/beegfs/prj/rpbp-dev/bullseye/envs/rpbp-cmdstan/bin/rpbp-profile-construction-dashboard", line 25, in importlib_load_entry_point
    return next(matches).load()
  File "/prj/rpbp-dev/bullseye/envs/rpbp-cmdstan/lib/python3.10/importlib/metadata/__init__.py", line 173, in load
    return functools.reduce(getattr, attrs, module)
AttributeError: module 'rpbp.analysis.profile_construction.dashboard.rpbp_profile_construction_dashboard' has no attribute 'main'
eboileau commented 1 year ago

@dokempf

The easiest way to generate test data for the app is the following:

1 - Run pytest locally, this will generate results somewhere e.g. /scratch/global_tmp/pytest-of-eboileau/pytest-82/data0/c-elegans-chrI-example/

2 - Call the prep scripts on this data e.g.

summarize-rpbp-profile-construction /scratch/global_tmp/pytest-of-eboileau/pytest-82/data0/c-elegans-chrI-example/c-elegans-test.yaml

summarize-rpbp-predictions /scratch/global_tmp/pytest-of-eboileau/pytest-82/data0/c-elegans-chrI-example/c-elegans-test.yaml --circos-bin-width 100000 --circos-show-chroms I

3 - Run the app (by calling the python script, and passing the same yml config file as used above), e.g.

python src/rpbp/analysis/rpbp_predictions/dashboard/rpbp_predictions_dashboard.py /scratch/global_tmp/pytest-of-eboileau/pytest-82/data0/c-elegans-chrI-example/c-elegans-test.yaml -d

With this data however, you won't face IGV loading issues...

eboileau commented 1 year ago

@dokempf please keep an eye in case you can reproduce this: https://github.com/dieterich-lab/rp-bp/issues/131#issuecomment-1359561022

eboileau commented 1 year ago

This solution works. I added a host argument e.g. if running the app remotely see https://github.com/dieterich-lab/rp-bp/commit/c9bcf2e03efb0747b2d8e7cddfe2a7d28d3e6ac7

eboileau commented 1 year ago

Next, we want to see what can be done to improve the user's experience.

Launching the app without the --debug flag results in verbose output to screen and a warning

WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.

So even if running only locally, why not serve it e.g. using Waitress? e.g.

from waitress import serve
from rpbp_predictions_dashboard import server 

serve(server)

With this, however, I don't know how we could pass arguments (config) to the app? I don't know either if we actually gain anything in performance (currently the prediction app is a bit slow, not even considering the IGV issue)? And we need an extra dependency...

Would this make sense to keep the current set-up, and wrap it in a bash script for the user (provided we can control output, etc. )?

Is there another way of stopping an app from running than CTRL+C?

Also, we need to make sure whatever solution we have, that it easily works with containers (so far we can't test it).

eboileau commented 1 year ago

It would be nice to launch a browser when starting the app, but this actually seems a bit more work than I initially thought, and would probably require more dependencies to do that properly... so I keep this for future/long term improvements.

dokempf commented 1 year ago

This SO Post describes how to auto-launch a browser and it seems to work for me. Do you want me to prepare a PR for it @eboileau ?

eboileau commented 1 year ago

Hi @dokempf that seems much simpler than what I've seen... but I'm not sure how we can handle the case of running remotely e.g. when I launch the app from our cluster? webbrowser.open_new() requires a url, which we cannot hard code. Any ideas?

Let me first push some changes to the dev-ssciwr branch before you do anything. Thanks.

dokempf commented 1 year ago

I would suggest to check os.environ["DISPLAY"] to check whether we open the filebrowser. The URL can then be constructed from the given hostname and port, which are both known.

eboileau commented 1 year ago

I just pushed to the dev-ssciwr branch.

We need to keep the --host option to run on all addresses (0.0.0.0), or this needs to be handled so this also works when running remotely.

eboileau commented 1 year ago

This seems to work remotely (i.e. falls back to not opening a browser page), but only tested a reduced example locally... with the debug -d flag it sometimes opened multiple browser pages...

Once we get a release with containers, we need to test how this work with Docker/Singularity, I don't know at this point. I'll leave the issue open until then.

dokempf commented 1 year ago

The fact it loads multiple windows in debug mode might be caused by Flask initializing twice in Debug mode