This project uses uv to manage dependencies, run tools such as linter, type-checker, testing, or publishing.
The monorepo contains multiple packages managed as a uv workspace.
Fork and clone the repository to your local workspace, then run:
# Use the sync command to create your python virtual environment,
# download the dependencies and install all packages
uv syncYou should see a .venv directory under the root of the project, activate it:
source .venv/bin/activateMake sure your virtual environment is active.
jupyter-deploy --helpThis project uses:
- ruff for linting, formatting and import sorting
- mypy for type checking enforcement
- pytest to run unit and integration tests
- playwright to run e2e tests
just lintjust unit-test- install aws-cli
- install terraform
- install the aws-ssm-plugin
- install jq
Integration tests (also called E2E tests) verify the entire deployment workflow, including infrastructure provisioning, configuration, and application functionality. These tests use the pytest-jupyter-deploy plugin and Playwright for UI testing.
The repository includes a containerized setup for running E2E tests. The E2E container image
(Dockerfile, docker-compose.yml) is bundled in the pytest-jupyter-deploy plugin package and
shared across all templates. It includes Python, Terraform, AWS CLI, and Playwright.
Requirements:
- Docker or Finch installed (automatically detected)
justcommand runner:cargo install just(or use homebrew/package manager)- For UI tests with authentication: SSH with X11 forwarding enabled (
ssh -X)
Using Docker + Just (Recommended)
First-time setup:
# Start E2E container in background (builds image automatically if needed)
just e2e-upProject files are synced into the container at runtime via just e2e-sync (called automatically by e2e-up).
The .auth/ directory is mounted at runtime to persist authentication state across container restarts.
If you change dependencies in pyproject.toml or modify code, run just e2e-sync.
Run E2E tests against an existing deployment:
# Run all E2E tests (base template)
just test-e2e-base <project-dir>
# Run only specific tests
just test-e2e-base sandbox3 test_application
# Or use the generic command with an explicit template
just test-e2e <project-dir> <test-filter> <options> <template>Full workflow (start container and run tests in one command):
just e2e-all <project-dir> [test-filter]Setup authentication (one-time, requires X11 forwarding):
just auth-setup <project-dir>Stop the E2E container when done:
just e2e-downE2E tests that interact with the JupyterLab UI require GitHub OAuth2 authentication. Since most GitHub accounts use 2FA/passkeys (which cannot be automated), you need to complete authentication manually once before running UI tests.
One-Time Setup (Using Docker)
-
Ensure you're SSH'd with X11 forwarding enabled:
ssh -X your-user@your-host
-
Verify DISPLAY is set in your terminal:
echo $DISPLAY # Should show something like "localhost:10.0"
Note: If using VS Code's embedded terminal, it won't inherit X11 forwarding. Either:
- Run commands from a regular SSH terminal, OR
- Manually export DISPLAY in VS Code terminal:
export DISPLAY=localhost:10.0
-
Run the authentication setup (a Firefox browser window will open via X11):
just auth-setup <project-dir>
Note: The setup uses Firefox for better X11 forwarding compatibility.
-
Complete the GitHub OAuth flow including 2FA/passkey authentication in the browser
-
The authenticated browser state is saved to
.auth/github-oauth-state.json -
Run E2E tests - they will reuse the saved authentication:
just test-e2e <project-dir>
Note: The .auth/ directory is excluded from version control to avoid committing sensitive authentication data.
Session Management: OAuth2 Proxy stores sessions in memory by default. When the OAuth2 Proxy server restarts (e.g., after running jd down and jd up), the OAuth2 Proxy session is lost. However, if your GitHub cookies are still valid (they last 7 days by default), tests will automatically re-authenticate by:
- Detecting the OAuth2 Proxy sign-in page
- Clicking "Sign in with GitHub"
- GitHub auto-authenticates using valid cookies (no manual 2FA needed)
- Redirecting back to JupyterLab
You only need to re-run just auth-setup when GitHub cookies have also expired (requiring manual 2FA/passkey authentication).
You will need to install xquartz: brew install --cask xquartz
- Open XQuartz:
Settings > Security > Allow connection from network client - reboot XQuartz (or restart your laptop)
Then, update ~/.ssh/config on your mac as follow:
Host your-devdesktop-host
ForwardX11 yes
ForwardX11Trusted yes
XAuthLocation /opt/X11/bin/xauth
Open a terminal (on your mac), and run:
ssh -X username@your-devdesktop-host
Get the port xquartz is listening to: echo $DISPLAY
Finally, verify that the xserver is running by running on that same mac terminal: xset q