funix icon indicating copy to clipboard operation
funix copied to clipboard

Support for Jupyter notebooks

Open ahuang11 opened this issue 1 year ago • 12 comments

Wondering if it's possible to run in notebook, or at least indirectly.

In Panel, there's panel_obj.show() which opens a new browser.

ahuang11 avatar May 19 '24 15:05 ahuang11

Thanks @ahuang11 for this suggestion. We heard the same feature request from many others at PyCon US 2024.

What's your suggestion on how a user can trigger the code-to-app conversion? As you know, Funix does not require the user to modify the code. So how can Jupyter know when is the time to map the user code to a GUI app? By adding a magic command and display the app when pressing Ctrl/Cmd + Enter? Or, by using a new button on Jupyter?

forrestbao avatar May 21 '24 07:05 forrestbao

A decorator probably?

@funix
def ...

Or magic command works too I guess, but I like decorator

%funix

def ...

ahuang11 avatar May 21 '24 14:05 ahuang11

Thanks. I am sitting on the fence between the two options. I feel the magic command is more a Juypte-way of doing things. The downside is that if you want to save the code from Jupyter cells to regular Python scripts, you need to comment out the magic commands.

forrestbao avatar May 21 '24 14:05 forrestbao

Perhaps the most Jupyter way of doing things is if the function is on the last line. If it is, display it.

i.e.

def hello(your_name: str) -> str:
    return f"Hello, {your_name}."

hello

ahuang11 avatar May 21 '24 14:05 ahuang11

Thanks. We will support at least one way to do it first. Then we can support more.

forrestbao avatar May 21 '24 15:05 forrestbao

On the develop branch, there is a way to run Funix indirectly in Jupyter:

from funix import funix


@funix()
def hello(a: str) -> str:
    return f"Hello {a}!"

This will directly open a new Flask application and show this by iframe.

Image

In the future, I will try to communicate with the kernel for calling functions.

The following is a reference steps for using funix with the develop branch:

  1. git clone https://github.com/TexteaInc/funix
  2. cd funix
  3. git checkout develop
  4. pip install -e .

Yazawazi avatar May 21 '24 21:05 Yazawazi

Cool, quick update!

I'm wondering if it's possible to, separately, import funix.notebook once at an upper cell, and all subsequent cells will automatically show iframe if there's the function variable at the end?

Cell 1

import funix.notebook

Cell 2

def hello(a: str) -> str:
    return f"Hello {a}!"

hello

ahuang11 avatar May 21 '24 22:05 ahuang11

I'll try to work on this idea 👀

Yazawazi avatar May 21 '24 22:05 Yazawazi

I am not sure about this idea below because it conflicts with expectations per Jupyter convention. A user's expectation for the last line, hello is printing the variable hello, which here will be the location in the RAM of the function.

What do you guys think?

Cool, quick update!

I'm wondering if it's possible to, separately, import funix.notebook once at an upper cell, and all subsequent cells will automatically show iframe if there's the function variable at the end?

Cell 1

import funix.notebook

Cell 2

def hello(a: str) -> str:
    return f"Hello {a}!"

hello

forrestbao avatar May 21 '24 23:05 forrestbao

which here will be the location in the RAM of the function.

I personally have never utilized the location in the RAM of the function. Also, if they really need it, print(hello) would return that.

Alternatively, I think you could inject a method on all functions like:

hello.servable() or hello.funix() to make it show, depending on whether you want users to modify their code.

Also, Jupyter conventions I think, more accurately, displays the variable in a pretty format e.g.

image

ahuang11 avatar May 21 '24 23:05 ahuang11

The expected behavior is as follows:

In [1]: def hello(a: str) -> str:
   ...:     return "Hello, " + a + "!"
   ...: 

In [2]: hello
Out[2]: <function __main__.hello(a: str) -> str>

In [3]: print(hello)
<function hello at 0x70565a7a2320>

forrestbao avatar May 21 '24 23:05 forrestbao

Yes, I think display(hello) results in <function __main__.hello(a: str) -> str>

image

ahuang11 avatar May 21 '24 23:05 ahuang11