diff --git a/README.md b/README.md index 5f01c1d..cc7127a 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,32 @@ installed on the jupyter server, and use the proxied data server transformer: alt.data_transformers.enable('data_server_proxied') ``` +The `urlpath` parameter allows you to override the prefix of the proxy URL. By +default, it's set to `..`, which is currently the only way to make it work for +arbitrary users when running inside the classic notebook on Binder. If you +intend your notebooks to be run on Binder but inside JupyterLab, change it to +`.` instead, which will work provided JupyterLab is in the [default +workspace](https://jupyterlab.readthedocs.io/en/stable/user/urls.html#managing-workspaces-ui). + +```python +# for notebooks intended for JupyterLab on Binder +alt.data_transformers.enable('data_server_proxied', urlpath='.') +``` + +On a custom JupyterHub instance, a much more robust option is to take advantage +of JupyterHub's [`/user-redirect`](https://jupyterhub.readthedocs.io/en/stable/reference/urls.html#user-redirect) +feature (which is not available on Binder): + +```python +# this will work for any JupyterHub user, whether they're using the classic +# notebook, JupyterLab in the default workspace, or JupyterLab in a named +# workspace +alt.data_transformers.enable('data_server_proxied', urlpath='/user-redirect') +``` + +If your JupyterHub lives somewhere else than at your server's root, add the +appropriate prefix to `urlpath`. + ## Example [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/altair-viz/altair_data_server/master?urlpath=lab/tree/AltairDataServer.ipynb) diff --git a/altair_data_server/_altair_server.py b/altair_data_server/_altair_server.py index b488bd3..94de99c 100644 --- a/altair_data_server/_altair_server.py +++ b/altair_data_server/_altair_server.py @@ -56,13 +56,18 @@ def __call__( class AltairDataServerProxied(AltairDataServer): def __call__( - self, data: pd.DataFrame, fmt: str = "json", port: Optional[int] = None + self, + data: pd.DataFrame, + fmt: str = "json", + port: Optional[int] = None, + urlpath: str = "..", ) -> Dict[str, str]: result = super().__call__(data, fmt=fmt, port=port) url_parts = parse.urlparse(result["url"]) + urlpath = urlpath.rstrip("/") # vega defaults to /files, redirect it to /proxy// - result["url"] = f"../proxy/{url_parts.port}{url_parts.path}" + result["url"] = f"{urlpath}/proxy/{url_parts.port}{url_parts.path}" return result