panel icon indicating copy to clipboard operation
panel copied to clipboard

Generator function not working

Open MarcSkovMadsen opened this issue 1 year ago • 9 comments

I'm on panel==1.3.8. I thought generator functions worked. But it seems not.

Furthermore they just don't display anything which can make it super hard to understand for beginners.

I would suggest generator functions worked. They can be a simple way for users to create animations and progressively updating apps.

Alternative that some exception was raised.

Minimum Reproducible Example

import panel as pn
from time import sleep
pn.extension()

def generator():
    yield "hello"
    sleep(0.3)
    yield "world"

pn.pane.Str(generator).servable()

The app is just blank and no errors are shown in the terminal.

image

Additional Context

Async Generators work. But async is not for basic users.

MarcSkovMadsen avatar Feb 02 '24 07:02 MarcSkovMadsen

That is why I commented on https://github.com/holoviz/panel/pull/6213/files#diff-23f2a17c4d19972dadffda8107a86a3900a75f300afe3e5f518ea7e51d9552ecR45-R61

But surprisingly that works haha

ahuang11 avatar Feb 02 '24 18:02 ahuang11

That is why I commented on https://github.com/holoviz/panel/pull/6213/files#diff-23f2a17c4d19972dadffda8107a86a3900a75f300afe3e5f518ea7e51d9552ecR45-R61

But surprisingly that works haha

For me generator functions are working in the chat interface. My guess is that I filed a bug back in the days and you fixed it?

MarcSkovMadsen avatar Feb 02 '24 18:02 MarcSkovMadsen

Generators really do not seem useful here, a generator function is blocking, therefore even if this did work you'd just get the final output and never see the intermediate outputs.

philippjfr avatar Feb 02 '24 18:02 philippjfr

There is clearly something wrong here though, you should see something or get an error.

philippjfr avatar Feb 02 '24 18:02 philippjfr

Generators really do not seem useful here, a generator function is blocking, therefore even if this did work you'd just get the final output and never see the intermediate outputs.

Unless you wrapped the generator in an async generator behind the scenes that did await a little bit for each yield. The benefit would be simplicity for basic users.

MarcSkovMadsen avatar Feb 02 '24 19:02 MarcSkovMadsen

Yeah would have to be executed on a thread but with asyncify that should be easy right?

philippjfr avatar Feb 02 '24 20:02 philippjfr

Yes this is what is done in ChatInterface: https://github.com/holoviz/panel/blob/main/panel/chat/feed.py#L498-L501

Ideally, Panel has a public pn.execute_in_thread util.

ahuang11 avatar Feb 02 '24 20:02 ahuang11

I'm used to generators working. For example the Migrate from Streamlit guides contains example close to the below which I will be adding to the basic tutorial.

import panel as pn
from time import sleep

pn.extension()


def classify(image):
    sleep(2)
    return "Wind Turbine"


run = pn.widgets.Button(name="Run", button_type="primary")

progress_message = pn.Row(
    pn.indicators.LoadingSpinner(
        value=True, width=25, height=25, align="center", margin=(5, 0, 5, 10)
    ),
    pn.panel("Running classifier ...", margin=0),
)

def run_classification(running):
    print(running)
    if not running:
        yield "Click Run"
        return

    yield progress_message
    prediction = classify(None)
    yield f"Its a {prediction}"


pn.Column(run, pn.bind(run_classification, run)).servable()

https://github.com/holoviz/panel/assets/42288570/aee0e381-b799-4540-bb42-ea358e1ba448

MarcSkovMadsen avatar Feb 04 '24 06:02 MarcSkovMadsen

This will have to be implemented at the Param level. Currently Param does not recognize generators as valid refs and what's happening here is that a much older mechanism in Param is allowing the generator to be a valid value for the parameter, which seemingly does not resolve the value correctly. I fully agree that we can and should make this work.

philippjfr avatar Feb 04 '24 17:02 philippjfr