Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding prelaunch hook for kernel instances #218

Closed
wants to merge 3 commits into from
Closed

Adding prelaunch hook for kernel instances #218

wants to merge 3 commits into from

Conversation

timkpaine
Copy link
Member

@timkpaine timkpaine commented Jun 11, 2019

I will have an example of hooking this into auth in my dashboard repo, but for now here is a simple example of pre-processing a notebook prior to launch, which adds an extra title to the page.

import voila.app

v = voila.app.Voila()
v.notebook_path = './notebooks/bqplot.ipynb'


def prelaunch_add_header(req, notebook, **kwargs):
    from nbformat import NotebookNode
    new_node = NotebookNode()
    new_node.cell_type = 'markdown'
    new_node.metadata = {}
    new_node.source = '# An added title!'
    notebook.cells.insert(0, new_node)

v.prelaunch_hook = prelaunch_add_header

v.initialize()
v.start()

Which yields:

Screen Shot 2019-06-11 at 9 04 04 AM

@maartenbreddels
Copy link
Member

Hi Tim, I like the idea, I wonder if this isn't better solved with a template?

@timkpaine
Copy link
Member Author

@maartenbreddels the tough part is making #216 and #239 and #105 play nicely together. I agree that my simple example here is better handled by a template (and indeed, I have a template that does exactly this). But if you can specify a template with a url parameter (which I think is a good idea), you'll still want some hook in (for example, I will want to put things like FOR INTERNAL USE ONLY regardless of the template my users use).

IMO we should try to build in a few of the same hooks that exist in JLab

  • pre execute (equivalent of presave hook in jupyter contents managers)
  • The authentication for who can launch a kernel should match who can launch a lab instance

probably more to follow

@leogout
Copy link
Contributor

leogout commented Jul 21, 2019

Hey, I would love to hear from this. I've been wondering how to authenticate a user before he gets to a voila rendered notebook. I would like to experiment and give feedback on what's possible to do with these hooks, especially with OAuth2.
Do you think it would be possible to redirect a user to a third party login page back and forth with this solution ? I'm having a hard time getting used to the voila codebase so I can't tell if it's feasible or not...

@maartenbreddels
Copy link
Member

IMO we should try to build in a few of the same hooks that exist in JLab

Could you give a few pointers to where that is in the jlab code?

@timkpaine
Copy link
Member Author

Prelaunch hook is actually from IPython, you can specify lines to execute at startup
https://ipython.readthedocs.io/en/stable/config/options/kernel.html

All of these are useable via jupyter_server, so that's definitely the right approach

@timkpaine
Copy link
Member Author

I just wanted to comment here, I've been using this HEAVILY in my fork. Its super useful as a per-user hook into the notebook, letting you inject arbitrary code cells which is super nice for doing validation and authentication.

@maartenbreddels
Copy link
Member

Thanks for letting us know, we'll have to see how this mixes with the progressive loading and follow up plans, but I understand its usefulness.

@timkpaine
Copy link
Member Author

Another good use is logging, I can grab the notebook name and inject a cell that sends remote log info about who is executing what notebook

@mgmarino
Copy link

I'd just like to +1 this. Given the current implementation, this looks like it's a nice way to handle granular authorization.

That is, on a production system, we would like to put the voila app behind e.g. an OAuth authentication service (like e.g. here), which would pass on information (like user, scopes, etc.) in the request headers to voila. This information could be used to decide whether or not to load the notebook (ideally using information from the notebook, perhaps an access list stored in metadata?) and raise a tornado.web.HTTPError(404, 'file not found') if access is not allowed:.

This approach is somewhat different than that suggested by @leogout since the authentication would be handled elsewhere.

@timkpaine
Copy link
Member Author

@mgmarino we do something very similar, thats why the prelaunch hook has access to the handler. For us, it remote logs the user accessing the server, attempts to authenticate, raises a 401 with a redirect to authenticate if there are issues, then injects a few cells to log some other miscellaneous info.

@timkpaine
Copy link
Member Author

@maartenbreddels @SylvainCorlay you can also pretty trivally use this to embed arguments. just install a variable in the kernel from handler.request.arguments in your hook

@timkpaine
Copy link
Member Author

timkpaine commented Nov 13, 2019

for example:

def prelaunch_hook(handler, notebook, cwd):
    args = handler.request.arguments
    cell = NotebookNode()
    cell.metadata = {}
    cell.execution_count = 1
    cell.outputs = []
    cell.source = 'ARGS={}'.format(json.dumps(args))'
    notebook.cells.insert(0, cell)

now ARGS is available in the kernel. Some other ideas include:

  • headers: handler.request.headers.get_all()
  • remote_ip: handler.request.remote_ip
  • full url

@maartenbreddels
Copy link
Member

Hey Tim, I want to let you know that I still like the idea, but I'm still not sure of the consequences for voila long term, e.g. for caching, kernel-forking. Not forgotten about it.

voila/app.py Show resolved Hide resolved
@timkpaine
Copy link
Member Author

@martinRenou theres a Callable traitlet added a while back but not in the docs still

@timkpaine
Copy link
Member Author

@KKammoun
Copy link

KKammoun commented May 21, 2020

Hi Tim, this looks very useful! However when starting the voila.app on a folder of notebooks instead of a single one it seems the prelaunch hook does not run on individual notebooks inside the folder once clicked from the voila served links.

@timkpaine
Copy link
Member Author

reimplemented in #724

@timkpaine timkpaine closed this Sep 25, 2020
@timkpaine timkpaine deleted the preflight_hook branch September 25, 2020 17:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants