An example deployed streamlit app -- PyMedPhys

I have created and deployed a Cypress tested streamlit app across three sites. I thought some people here might be interested in some of the implementation details.

To run it yourself type the following in a terminal:

pip install pymedphys==0.25.1
pymedphys gui

For information on how I deployed it across our sites see the release announcement over at https://groups.google.com/forum/#!topic/pymedphys/2LczVpmc_Ak

If you’re interested in sinking your teeth into the code the streamlit app itself is housed over at https://github.com/pymedphys/pymedphys/blob/0.25.x/pymedphys/_gui/streamlit/mudensity-compare.py.

Cheers,
Simon

5 Likes

Also, something that I would consider noteworthy, I created the following command for Cypress which waits until a streamlit computation is completed:

Very cool! Just to get an understanding of this. Does this mean that nothing in the front-end is changed until the full computation is completed or what is the result of this?

Yup, that’s what it means. To simplify things I made a bare minimum app template over at https://github.com/pymedphys/streamlit-template

If you look at one of the videos over at https://dashboard.cypress.io/projects/c2ekjb/runs you can see it waiting until the computation is complete.

3 Likes

Thanks for sharing @SimonBiggs, and welcome to the community! I don’t have the background to evaluate the actual content, but it looks like a great example of a Streamlit app :slight_smile:

Thanks :slight_smile: . It’s an amazing tool you guys built. I really appreciate all the work gone into it. You’ve given me wings to do awesome things. Thank you.

1 Like

While building it by the way, I greatly desired for there to be a way to flag an import as “please watch for changes within this package also”. Either that or an option to say “please watch all files in this git repo that are not found within gitignore, and then update if anything in this repo changes”.

Also, another item hoped for, is a way to host multiple Streamlit apps from the one server. My thought is one could point to a directory then the landing page would be a neat index of all nested files that are both .py and have an import streamlit within them. Clicking on each of those can then take one to a url named after the file itself (but without the .py extension) as well as the url being nested if the file is found nested within the directory tree.

By default, Streamlit monitors for changes within the current working directory. So as long as the code in your app resides in that directory, we should be picking it up.

If you’re talking about other packages that are imported, we intentionally do not monitor those, because of the performance implications of walking the entire tree of packages.

We’ve heard this feedback from many users, and it’s my guess that we’ll find a solution for this somewhat soonish. Unfortunately, I don’t have a timeline on when at this moment.

1 Like

Do you think it might be neat to have some sort of functionality to auto-reload just one package by choice of the user? I do this within Jupyter notebooks by using the following tool:

https://ipython.org/ipython-doc/stable/config/extensions/autoreload.html

If you don’t implement it, I’ll just implement it myself by adding a watchdog watcher to the git repo filtered by the git ignore, and then on file change running the standard library’s deepreload method and then running Streamlit’s rerun execution method.

I think that’s probably the best way to go for now. If you implement it and then show that it’s really valuable, then perhaps that’s a good candidate for a future community-supported custom component.

Kk, sounds good. Will do.

1 Like

@SimonBiggs @randyzwitch Hosting multiple apps on one server natively in Streamlit would be great! In the meantime, I built streamlit-launchpad which can carry this out for you:

3 Likes

Cool! I starred the repo, can’t wait to see how it evolves.

Thanks for your enthusiasm… But hopefully it won’t need to evolve - ideally it will be superseded by native Streamlit functionality…!

1 Like

Awesome for most cases, except it doesn’t always work after attaching a file to the uploader…

Using

cy.get('input[accept=".zip"]').attach_file('zipFilePath', 'zip').trigger('change', { force: true })
cy.compute();

with

Cypress.Commands.add( 'attach_file',  {prevSubject: 'element'},
  (input, fileName, fileType) => {
    cy.fixture(fileName)
      .then(content => Cypress.Blob.base64StringToBlob(content, fileType))
      .then(blob => {
        const testFile = new File([blob], fileName)
        const dataTransfer = new DataTransfer()
        dataTransfer.items.add(testFile)
        input[0].files = dataTransfer.files
        return input
 })})

Any suggestion for this case ? Thanks !

Hi @Johann,

Yup, I have an example covering that case over at:

Cheers,
Simon

See the following part for where “cy.compute” is used:

And cy compute is defined over at:

Thanks, I’ve tried using cypress-file-upload and following exactly how you do it. It seems to be a little better, but I still got some fails, my script need sometimes 3 retries to get all to pass…

Can you describe how your compute function works ? particularly the ReportStatus bit
Thanks a lot

Update : This flakiness happens only on remote server. On a local machine, all tests pass (it did before using your method, and still do). I’ve temporarily used timeouts everywhere, they do the job for now, but it would be nice to have your solution adapted to this case ^^.

We are working on this idea. I think it’s a great idea too! :heart:

1 Like

Fantastic! My solution spins up new processes on different ports in a slightly hacky way, but I’m sure you’ll be able to do something a bit neater… :slight_smile:

1 Like