Git Product home page Git Product logo

jhsingle-native-proxy's Introduction

jhsingle-native-proxy

Wrap an arbitrary webapp so it can be used in place of jupyter-singleuser in a JupyterHub setting.

Within JupyterHub this allows similar operation to jupyter-server-proxy except it also removes the Jupyter notebook itself, so is working directly with the arbitrary web service.

OAuth authentication is enforced based on JUPYTERHUB_* environment variables.

This project is used in ContainDS Dashboards, which is a user-friendly way to launch Jupyter notebooks as shareable dashboards inside JupyterHub. Also works with Streamlit and other visualization frameworks.

Install and Run

Install using pip.

pip install jhsingle-native-proxy

The process to start is specified on the command line, for example a streamlit web app:

jhsingle-native-proxy streamlit hello

By default the jhsingle-native-proxy server will listen on port 8888, forwarding to port 8500.

But you will normally need to tell jhsingle-native-proxy which port the end process will run in, and maybe tell the end process which port you want it to use (which you can do with the substitution variable {port}).

Note the use of -- to signal the end of command line options to jhsingle-native-proxy. Then the third party command line itself can contain options starting with dashes. An alternative is to use the substitution {--}

jhsingle-native-proxy -- streamlit hello --server.port {port} --server.headless True --server.enableCORS False

To run jhsingle-native-proxy itself listening on a different port use:

jhsingle-native-proxy --port 8000 streamlit hello

To run jhsingle-native-proxy on port 8000, and the end process on 8505:

jhsingle-native-proxy --port 8000 --destport 8505 -- streamlit hello --server.port {port} --server.headless True --server.enableCORS False

Use the JUPYTERHUB_SERVICE_PREFIX env var to specify the first part of the URL to listen to (and then strip before forwarding). E.g. JUPYTERHUB_SERVICE_PREFIX=/user/dan will mean requests on http://localhost:8888/user/dan/something will forward to http://localhost:8500/something

You can also specify --ip 0.0.0.0 for the address to listen on.

Below we use the substitution {--} for the command to run, allowing us to specify --ip to jhsingle-native-proxy instead of the command being run.

jhsingle-native-proxy --port 8000 --destport 8505 streamlit hello {--}server.port {port} {--}server.headless True {--}server.enableCORS False --ip 0.0.0.0 

Similarly, use e.g. {-}m to represent -m in the final command.

Voila example:

Running voila at the subfolder URL e.g. /user/dan/:

python -m jhsingle_native_proxy.main --destport 0 voila ./Presentation.ipynb {--}port={port} {--}no-browser {--}Voila.server_url=/ {--}Voila.base_url={base_url}/ {--}debug

'destport 0' above instructs jhsingle-native-proxy to choose a random free port on which to run the sub-process (Voila), and of course substitutes that as {port} in the Voila command line so it knows which port to listen on. destport 0 is the default anyway.

Or specify presentation_path as a substitution instead of hard-coding, which is sometimes easier in your wrapper code:

python -m jhsingle_native_proxy.main --destport 0 voila {presentation_path} {--}port={port} {--}no-browser {--}Voila.server_url=/ {--}Voila.base_url={base_url}/ {--}debug --presentation_path=./Presentation.ipynb

In addition, if presentation_path is provided, two further substitution variables are available: presentation_dirname and presentation_basename. These are computed using Python's os.path.dirname and os.path.basename functions on presentation_path.

Authentication

The above examples all assume OAuth will be enforced, as per the JUPYTERHUB_* env vars.

Alternatives can be specified via the authtype flag:

Same as default:

jhsingle-native-proxy --authtype=oauth streamlit hello

No auth required at all:

jhsingle-native-proxy --authtype=none streamlit hello

Specifying Authorized Users

The env vars JUPYTERHUB_USER and JUPYTERHUB_GROUP can be used, as typical for any JupyterHub single server, to specify user/groups of JupyterHub that should be allowed access via OAuth. There is an additional bespoke env var called JUPYTERHUB_ANYONE which can be set to 1 to allow any authenticated user access. (i.e. anyone who has an account on the JupyterHub)

Extra Arguments

--request-timeout=300 specifies the timeout in seconds that it waits for the underlying subprocess to return when proxying normal requests. Default is 300.

{origin_host} in the command argument will be replaced with the first 'host' seen in any request to the jhsingle-native-proxy server.

--last-activity-interval=300 specifies how often in seconds to update the hub to provide the last time any traffic passed through the proxy (default 300). Specify 0 to never update. --force-keep-alive or --no-force-keep-alive: the former (default) ensures that the hub is notified of recent activity even if there wasn't any - only works if last-activity-interval is not 0.

--ready-check-path (default /) to change the URL on the subprocess used to poll with an HTTP request to check for readiness.

--repo - use git to check out a repo before running the sub process

--repofolder - the path of a folder (to be created if necessary) to contain the git repo contents

--forward-user-info - forward to the underlying process an X-CDSDASHBOARDS-JH-USER HTTP header containing JupyterHub user info as JSON-encoded string

--query-user-info - add a GET query param named CDSDASHBOARDS_JH_USER when calling underlying process containing JupyterHub user info as JSON-encoded string

--ready-timeout - integer timeout for period of checking the process is running at startup (default 10). Increase if your process is not able to return anything at --ready-check-path until a longer time after it first starts up. Be aware that the process must (once ready) return its HTTP response within 1 second. Note this argument is different from --request-timeout which applies to individual HTTP proxy calls during normal operation (not just at startup).

--websocket-max-message-size - message size in bytes allowed by websocket connections made to the underlying process (default is to rely on the tornado library defaults).

--progressive - flush buffer from underlying service whenever chunks appear (this is useful to see results from Voila sooner)

Changelog

v0.8.2 released 30 Nov 2023

  • Better logging output via Tornado. Thanks to aditipate.

v0.8.1 released 13 Jun 2023

  • Pin simpervisor version to avoid conflict with version 1.0. Thanks to dangercrow.

v0.8.0 released 8 Nov 2021

  • Change to work with JupyterHub 2 (detects port from JUPYTERHUB_SERVICE_URL env var if no --port set)

v0.7.6 released 20 Apr 2021

  • New command-line options --ready-timeout and --websocket-max-message-size

v0.7.3 released 9 Apr 2021

  • New command-line option --progressive to flush buffer from underlying service whenever chunks appear (this is useful to see results from Voila sooner)
  • oauth_callback URL now accessible when running with JUPYTERHUB_BASE_URL of /

v0.7.1 released 22 Feb 2021

  • New command-line option --query-user-info to add a CDSDASHBOARDS_JH_USER GET query param to the http request to the underlying service.

v0.7.0 released 12 Feb 2021

  • New command-line option --forward-user-info to add a X-CDSDASHBOARDS-JH-USER header to the http request to the underlying service. The header value is a JSON-encoded dict containing kind, name, admin, groups fields from the logged-in JupyterHub user if available.

v0.6.1 released 6 Jan 2021

  • Require simpervisor >= 0.4 to ensure Python 3.9 compat.

v0.6.0 released 20 Nov 2020

  • Displays INFO level logs by default, which includes output of the subprocess (turn off with --no-logs) Issue #7
  • Logs from subprocess written out at different level depending on source (stderr -> error, stdout -> info)
  • Long subprocess logs are handled and truncated instead of throwing an error cdsdashboards issue #44
  • Different handling of branch checkout when using git repo source, when switching brances compared to what was checked out before

v0.5.6 released 18 Sep 2020

  • Always convert presentation_path to an absolute path (based on CWD) before passing to the sub-command.

v0.5.5 released 10 Sep 2020

  • Also accept URLs at the URL-encoded equivalent of the prefix and redirect to the regular version of the URL.

v0.5.4 released 3 Sep 2020

  • Change working folder to repofolder when specified

v0.5.2 released 17 Aug 2020

  • Require tornado 6.0.4+

v0.5.1 released 17 Aug 2020

  • Fix to ensure both websockets are opened at the same time, to avoid writing to a websocket that's not yet open.

v0.5.0 released 17 Aug 2020

  • Open up underlying process' websocket before connecting our own with the client. This ensures any other GET headers can be passed back to the client. (Fix for Streamlit XSRF problems.)

v0.4.3 released 30 July 2020

  • Added --allow-root option (currently ignored) to avoid errors if this flag is usually passed to jupyter-singleuser

v0.4.2 released 23 July 2020

  • Switch to a Conda env before running subprocess by specifying --conda-env option

v0.4.1 released 20 July 2020

  • fix because subprocess sometimes blocked if too much output generated

v0.4.0 released 15 July 2020

  • repo and repofolder optional arguments added

v0.3.2 released 25 June 2020

v0.3.1 released 18 June 2020

  • Defaults presentation_path to empty str ('') if not supplied, avoiding error

v0.3.0 released 17 June 2020

  • presentation_path can be provided as a command line argument to become a substitution variable.
  • presentation_basename and presentation_dirname are also available when presentation_path is supplied.

v0.2.0 released 11 June 2020

  • Better websocket handling (subprotocols)
  • {origin_host} variable added

v0.1.3 released 1 June 2020

  • request-timeout added to the proxy call, and the default set to 300 (20 seconds was the httpclient's default previously)

v0.1.2 released 29 May 2020

  • Now allows single-dash placeholder, e.g. {-}m translates to -m in the final subprocess command.

Development install

git clone https://github.com/ideonate/jhsingle-native-proxy.git
cd jhsingle-native-proxy

pip install -e .

To run directly in python: python -m jhsingle_native_proxy.main <rest of command line>

Testing git puller:

python -m jhsingle_native_proxy.main --authtype=none --destport=0 --port=8888 voila ./sincosfolder/Presentation.ipynb {--}port={port} {--}no-browser {--}Voila.server_url=/ {--}Voila.base_url={base_url}/ --repo=https://github.com/danlester/binder-sincos --repofolder=sincosfolder

jhsingle-native-proxy's People

Contributors

aditipate avatar bruwozniak avatar dangercrow avatar danlester avatar fcollonval avatar infinitechai avatar ktaletsk avatar manics avatar tdhopper avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

jhsingle-native-proxy's Issues

Make readiness timeout configurable

I'm having an issue integrating cdsdashboards to our ML platform http://iko.ai, my dashboard server is timing out during readiness and there is no way to configure the time out value because it's hardcoded here: https://github.com/ideonate/jhsingle-native-proxy/blob/master/jhsingle_native_proxy/proxyhandlers.py#L700

I'd like to be able to configure the readiness timeout value through command-line argument and/or environment variables?

Debug logs:

INFO:tornado.application:SuperviseAndProxyHandler http_get 55527
DEBUG:tornado.application:Allowing Hub user USER_NAME
DEBUG:tornado.application:Storing origin host SERVER_NAME
INFO:tornado.application:['streamlit', 'run', '/home/USER_NAME/./vosk_app.py', '--server.port=55527', '--server.headless=True', '--browser.             serverAddress=SERVER_NAME', '--browser.gatherUsageStats=false']
DEBUG:tornado.application:Trying to start mainprocess
DEBUG:tornado.application:Started mainprocess
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 0.00495457649230957 seconds, next check in 0.01s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 0.017713308334350586 seconds, next check in 0.02s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 0.04067730903625488 seconds, next check in 0.04s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 0.08370685577392578 seconds, next check in 0.08s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 0.1665360927581787 seconds, next check in 0.16s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 0.329953670501709 seconds, next check in 0.32s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 0.6533911228179932 seconds, next check in 0.64s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 1.2969000339508057 seconds, next check in 1.28s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 2.5811028480529785 seconds, next check in 2.56s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 5.144717454910278 seconds, next check in 4.847672929763794s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 9.998777389526367 seconds, next check in -0.0035436248779296877s
DEBUG:tornado.application:Connection to http://localhost:55527/ refused
DEBUG:tornado.application:Readyness: False after 10.007751226425171 seconds, next check in -0.007087249755859375s

py39 compat

Hi @danlester , thanks for this and cdsdashboards! Deployed cdsdashboards to a python 3.9 environment and got the following stack trace when trying to deploy a dashboard

Traceback (most recent call last):
  File "/opt/envs/system/jupyterhub/lib/python3.9/site-packages/tornado/web.py", line 1704, in _execute
    result = await result
  File "/opt/envs/system/jupyterhub/lib/python3.9/site-packages/jhsingle_native_proxy/websocket.py", line 103, in get
    return await self.http_get(*args, **kwargs)
  File "/opt/envs/system/jupyterhub/lib/python3.9/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 724, in http_get
    return await self.proxy(self.port, path)
  File "/opt/envs/system/jupyterhub/lib/python3.9/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 718, in proxy
    return await self.oauth_proxy(port, path)
  File "/opt/envs/system/jupyterhub/lib/python3.9/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 673, in oauth_proxy
    return await self.core_proxy(port, path)
  File "/opt/envs/system/jupyterhub/lib/python3.9/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 704, in core_proxy
    if not await self.ensure_process():
  File "/opt/envs/system/jupyterhub/lib/python3.9/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 618, in ensure_process
    await proc.start()
  File "/opt/envs/system/jupyterhub/lib/python3.9/site-packages/simpervisor/process.py", line 83, in start
    with (await self._proc_lock):
TypeError: object Lock can't be used in 'await' expression

It's resolved by reverting back to python 3.8. Mostly wanted to let you know about future incompatibilities. Regrettably, I don't have any bandwidth to submit a PR at this time.

jhsingle-native-proxy not showing running notebook while using voila until notebook finish its execution

Hi Dan,

I'm trying to use the jhsingle-native-proxy on top of voila. The authentication works well, until I noticed that when voila is used without the proxy, the behavior is a little different.

A template is being used that shows the progress of the running notebook while voila is processing it, a template was created that is passed to voilà using the --template flag, this work well along with jupyterhub. However, with jhsingle-native-proxy the notebook is not shown until voilà finishes its execution, therefore, we are not capable to see the progress of the notebook itself. This is very important due to some notebooks taking a while to run, the template shows the progress, while with jhsingle-native-proxy shows a blank page and it only shows the result of converted notebooks when it finishes. For some notebooks, the user will have to wait until the notebooks completes, the user won't know if the notebook is running or not. Is there a a solution to this problem? Any ideas or suggestions?

Best regards.

Jhsingle-native-proxy 0.8.1 logger not outputting log messages to the console

I am using Jhsingle-native-proxy locally and with Docker but despite using the --debug option it seems that the DEBUG and INFO log messages are not being displayed in my console. Currently Jhsingle-native-proxy does not seem to be logging/outputting any log messages seen in proxyhandlers.py to my console.

I have also noticed that Jhsingle-native-proxy is using the app_log logger from tornado.log, whose level is set to either DEBUG or INFO depending on whether the --debug option is used.

Is there a way to get the log messages to display in the console and fix this issue?

idea : support for UNIX sockets

Hello everyone,

Running web applications on multi-user systems (even behind a JupyterHub) requires that the web application supports some kind of authentication (this can be a token that has to be passed in the URL, as we know it from Jupyter/JupyterLab).

However, some applications lack this basic security and are accessible to anyone who can log into the multi-user system and access their port.

If these web applications would not use a port but a UNIX socket for internal communication with jhsingle-native-proxy, this security hole could be closed in a quite elegant way.
For jupyter-server-proxy this great feature was just recently added - jupyterhub/jupyter-server-proxy#321 and might be a starting point.

await None

Hey thanks for the great tool.

Using cdsdashboard, I got the following error when starting a dashboard:

[I 2020-06-26 09:57:43.527 JupyterHub proxy:262] Adding user fcollonval to proxy /user/fcollonval/dash-sin-and-cos-graph/ => http://127.0.0.1:42893
ERROR:tornado.application:Uncaught exception GET /user/fcollonval/dash-sin-and-cos-graph/ (127.0.0.1)
HTTPServerRequest(protocol='http', host='127.0.0.1:42893', method='GET', uri='/user/fcollonval/dash-sin-and-cos-graph/', version='HTTP/1.1', remote_ip='127.0.0.1')
Traceback (most recent call last):
  File "/opt/conda/lib/python3.7/site-packages/tornado/web.py", line 1703, in _execute
    result = await result
  File "/opt/conda/lib/python3.7/site-packages/jhsingle_native_proxy/websocket.py", line 94, in get
    return await self.http_get(*args, **kwargs)
  File "/opt/conda/lib/python3.7/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 592, in http_get
    return await self.proxy(self.port, path)
  File "/opt/conda/lib/python3.7/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 586, in proxy
    return await self.oauth_proxy(port, path)
TypeError: object NoneType can't be used in 'await' expression

Installation:

In Docker with base docker = debian:buster-slim

Python package of interest:

python 3.7.0
cdsdashboards          0.0.19             
jhsingle-native-proxy  0.3.1              
jupyter-archive        0.6.2              
jupyter-client         6.1.3              
jupyter-core           4.6.3              
jupyter-server         0.1.1              
jupyter-telemetry      0.0.5              
jupyterhub             1.1.0              
jupyterlab             2.1.5              
jupyterlab-git         0.20.0             
jupyterlab-pygments    0.1.1              
jupyterlab-server      1.1.5

simpervisor update breaks jhsingle-native-proxy

Recent update of simpervisor from 0.4 to 1.0 breaks apps wrapped in jhsingle-native-proxy.

In the immediate term, we need to pin dependency for the current version to simpervisor=0.4 or simpervisor<1 to stop new builds from breaking, but in the longer term updating to reflect changes in simpervisor 1.0 will be required.

I'll be happy to open PR(s)!

Intermittent 500 Internal Server Error due to Premature Child Process Termination in `ensure_process`

I am having trouble with dash apps to respond with the Error report from ContainDS Dashboards. I get an intermittent 500 Internal server error instead. I have tried using the --ready-timeout flag hoping that it would help, but no luck. I think that the child process is getting killed before the error could propagate up.

`Traceback (most recent call last):
File "/usr/local/lib64/python3.11/site-packages/tornado/web.py", line 1713, in _execute
result = await result
^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/jhsingle_native_proxy/websocket.py", line 102, in get
return await self.http_get(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 849, in http_get
return await self.proxy(self.port, path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 843, in proxy
return await self.oauth_proxy(port, path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 798, in oauth_proxy
return await self.core_proxy(port, path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 829, in core_proxy
if not await self.ensure_process():
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/jhsingle_native_proxy/proxyhandlers.py", line 762, in ensure_process
await proc.kill()
File "/usr/local/lib/python3.11/site-packages/simpervisor/process.py", line 167, in kill
return await self._signal_and_wait(signal.SIGKILL)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/simpervisor/process.py", line 140, in _signal_and_wait
self.proc.send_signal(signum)
File "/usr/lib64/python3.11/asyncio/subprocess.py", line 140, in send_signal
self._transport.send_signal(signal)
File "/usr/lib64/python3.11/asyncio/base_subprocess.py", line 145, in send_signal
self._check_proc()
File "/usr/lib64/python3.11/asyncio/base_subprocess.py", line 142, in _check_proc
raise ProcessLookupError()```

Expected behavior:
The ensure_process method should capture error details, and allow the exception to propagate up for higher-level exception handling so that the error is appropriately reported instead of terminating the process prematurely, leading to generic 500 Internal Server Errors.

Expected response:
image

Just wanted to see if we can adjust the behavior within the if not is_ready block to let the error handled by the higher level handler? Is there any other solution we could try?

Exposing some logs from the process being proxied

Hi, thanks for writing this very useful utility! I had a question/feature request, hopefully this is not too bad of a place to submit it.

Right now, I've successfully used jhsingle-native-proxy to serve a notebook via Voila behind JupyterHub, and this is really nice as it allows me to take advantage of JupyterHub's authentication mechanism before allowing access to the Hub-managed service.

I was wondering if there's a good way to expose some of the logs of the process being proxied. Right now, in jhsingle-native-proxy, I see the --debug flag, which will set both the tornado app_log level to DEBUG, and pass debug=True to the tornado Application.

Would it be possible to get INFO level logs though? Right now, if I don't set the --debug argument, then all of my Voila logs seems to get swallowed by the proxy, but if I use the --debug flag, then it logs too much information.

Getting 404 error while launching Streamlit dashboard

I'm trying to launch a Streamlit dashboard on Jupyterhub-K8s (EKS) but facing 404 : Not Found You are requesting a page that does not exist! error. I've looked in to the dashboard pod container log, I see below error, and there are no other log statements in the log file.

Screenshot 2022-06-14 at 7 24 39 PM

Screenshot 2022-06-14 at 7 24 22 PM

Whereas same setup is working fine in Minikube, though I see the above error in the log file, Streamlit dashboard launched successfully.

@danlester Could you please help me find the root cause of this issue? TIA.

Error: No such option: --SingleUserNotebookApp.default_url

Getting the following error "Error: No such option: --SingleUserNotebookApp.default_url" when using this package in a single user container image with Jupyterhub. The image is loaded as a profile list of single user environments.

Integrating JupyterHub with Voila's progressive rendering

Hey,

I've been using the jhsingle-native-proxy to expose voila to an authenticated JupyterHub and its working great. However one thing that's been noticed is that we no longer get the spinning loader and instead we have a blank page until the notebook has been fully executed. For some of our more complex applications this can be 15-20 seconds of load time with no visible indicator to users that work is progressing,

After digging into the details, it looks like voila flushes progressively so that the user is presented with an initial response then progressively sees progress until the notebook execution has completed.

However when sat behind the proxy, we're waiting for the response to be completed before writing back out. This means that nothing is rendered to the user until execution has been completed.

Is this something that has already been witnessed with the proxy and is there a known way to work around it? If not, any suggestion on an approach to look to support it?

Unable to setup with TLJH

Thanks for this package, it seems to be exactly what we're looking for. We have a web app developed using Voila, and a running TLJH instance on AWS. We'd like to display the web app when users login to the hub (as opposed to a lab dashboard or notebook tree). However, we're not totally clear on how to make this function.

We've been testing locally with a Docker install of TLJH, and from the github page, it seems that we can just have python -m jhsingle_native_proxy.main --destport 0 voila ./WebApp.ipynb {--}port={port} {--}no-browser {--}Voila.server_url=/ {--}Voila.base_url={base_url}/ {--}debug running and be forwarded to the rendered webapp. But it doesn't seem that anything in particular happens.

Is it possible to expand on what exactly needs to be done to get to the rendered Voila web app?

Thanks again!

timeouts

I'm using this with jupyterhub and cdsdashboards (the combo is perfect for my use case) but I was having issues with connect timeouts for notebooks that were a bit more computationally expensive. It was hitting the tornado 20 sec default request timeout. My quick and dirty solution was to change the proxy_request_options function to return dict(follow_redirects=False, request_timeout=300) I someone mention issues with timeouts and thought posting this might help others. Hardwiring it here fixes my problem, but maybe a more elegant solution is to have jupyterhub's c.Spawner.http_timeout passed along, though I just started playing with all of this last week and don't know the pros and cons of that approach.

Thanks for the awesome work

Is --template is supported?

Hi,
I would like to use your dockerfile with voila-reveal (and with voila-gridstacks) it requires to pass an extra keyword
--template=reveal (or gridstack).

I've tried to add {--}template=reveal it but it does seem to work.
Could you tell how to proceed to be able to make it work?

Best

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.