Metadata-Version: 2.4
Name: jhub-apps
Version: 2025.2.1
Summary: JupyterHub Apps
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.8
Requires-Dist: bokeh
Requires-Dist: bokeh-root-cmd
Requires-Dist: cachetools
Requires-Dist: conda-project==0.4.2
Requires-Dist: fastapi
Requires-Dist: gitpython
Requires-Dist: hatch
Requires-Dist: hatchling
Requires-Dist: jhsingle-native-proxy==0.8.3
Requires-Dist: jupyter
Requires-Dist: jupyterhub>4
Requires-Dist: panel
Requires-Dist: plotlydash-tornado-cmd
Requires-Dist: pyjwt<2.10.0
Requires-Dist: python-multipart
Requires-Dist: python-slugify
Requires-Dist: requests
Requires-Dist: structlog
Requires-Dist: traitlets
Requires-Dist: uvicorn
Provides-Extra: dev
Requires-Dist: dash; extra == 'dev'
Requires-Dist: gradio; extra == 'dev'
Requires-Dist: playwright; extra == 'dev'
Requires-Dist: pre-commit; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-playwright; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: streamlit; extra == 'dev'
Requires-Dist: voila; extra == 'dev'
Description-Content-Type: text/markdown

# JupyterHub Apps Launcher

[![Lint](https://github.com/nebari-dev/jhub-apps/actions/workflows/lint.yml/badge.svg)](https://github.com/nebari-dev/jhub-apps/actions/workflows/lint.yml)
[![Test](https://github.com/nebari-dev/jhub-apps/actions/workflows/test.yml/badge.svg)](https://github.com/nebari-dev/jhub-apps/actions/workflows/test.yml)

JupyterHub Apps Launcher is a generalized server launcher. The goal of this project is to support
launching anything like say a Flask Server, FastAPI server or a Panel Dashboard via a user supplied
command. Currently, the following frameworks are supported:

- [x] Panel
- [x] Bokeh
- [x] Streamlit
- [x] Plotly Dash
- [x] Voila
- [x] Gradio
- [x] JupyterLab
- [x] Generic Python Command

![JHub Apps Demo](https://raw.githubusercontent.com/nebari-dev/jhub-apps/main/demo.gif)

## Installation

```
pip install jhub-apps
```

or via conda

```bash
conda install -c conda-forge jhub-apps
```

## Development Installation

### Install Dependencies

```bash
conda env create -f environment-dev.yml
conda activate jhub-apps-dev
pip install -e .
```

To develop the React UI frontend, also run:

```bash
cd ui
npm install
cd -
```

## Starting JupyterHub

Set the following environment variable:

```bash
export JHUB_APP_JWT_SECRET_KEY=$(openssl rand -hex 32)
```

Start JupyterHub:

```bash
jupyterhub -f jupyterhub_config.py
```

Now go to http://127.0.0.1:8000/hub/home to access JHub Apps Launcher

## API Endpoints

The Hub service is exposed via FastAPI endpoints. The documentation for the same can be accessed at:
http://127.0.0.1:10202/services/japps/docs

To try out authenticated endpoints click on the Authorize button on the top right of
the above url and choose `OAuth2AuthorizationCodeBearer` and click on Authorize.

## Developing Locally

_Note: In order to develop locally, both the JupyterHub backend and React UI frontend should be running._

1. To start the JupyterHub Backend, run the following in a terminal:

```bash
jupyterhub -f jupyterhub_config.py
```

2. To start the React UI frontend, run the following in a separate terminal from the `ui` directory:

```bash
npm run watch
```

## Running Tests

### Unit Tests

```bash
pytest jhub_apps/tests
```

### E2E Tests

```bash
pytest jhub_apps/tests/tests_e2e -vvv -s --headed
```

## Usage

JHub Apps has been tested with local JupyterHub using `SimpleLocalProcessSpawner` and with
The Littlest JupyterHub using `SystemdSpawner`.

- Install JHub Apps

```python
pip install git+https://github.com/nebari-dev/jhub-apps.git
```

- Add the following in The Littlest JupyterHub's `jupyterhub_config.py`

```python
from tljh.user_creating_spawner import UserCreatingSpawner
from jhub_apps.configuration import install_jhub_apps

c.JupyterHub.bind_url = "<YOUR_JUPYTERHUB_URL>"
c.SystemdSpawner.unit_name_template = 'jupyter-{USERNAME}{JHUBSERVERNAME}'
c.JAppsConfig.apps_auth_type = "oauth" # or none (if you don't want authentication on apps)
c.JAppsConfig.python_exec = "python3"
# Pass in the path to jupyterhub config
c.JAppsConfig.jupyterhub_config_path = "jupyterhub_config.py"
# Either a static list of conda environments to show in the
# create panel apps form or a callable to fetch conda enviornments
# dynamically, e.g. from conda-store API
c.JAppsConfig.conda_envs = []
c = install_jhub_apps(c, UserCreatingSpawner)
```

## Acknowledgments

This project is heavily inspired by and uses code from @danlester's [cdsdashboards](https://github.com/ideonate/cdsdashboards), without his work building this would have been a whole lot harder.
