CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-jupyter-server

The backend infrastructure for Jupyter web applications providing core services, APIs, and REST endpoints.

Overview
Eval results
Files

core-application.mddocs/

Core Application

The core application layer provides the main ServerApp class and supporting infrastructure for running Jupyter servers.

ServerApp

The main Jupyter server application class that coordinates all server components.

from jupyter_server.serverapp import ServerApp

Basic Server Setup

from jupyter_server.serverapp import ServerApp

# Create server instance
app = ServerApp()

# Configure basic settings
app.port = 8888
app.ip = "127.0.0.1"
app.allow_remote_access = True
app.open_browser = False

# Set authentication
app.token = "my-secret-token"
# OR disable authentication (not recommended for production)
app.token = ""
app.disable_check_xsrf = True

# Initialize and start
app.initialize()
app.start()  # Blocks until server stops

SSL/TLS Configuration

from jupyter_server.serverapp import ServerApp

app = ServerApp()
app.certfile = "/path/to/cert.pem"
app.keyfile = "/path/to/key.pem"
app.port = 8443  # Use HTTPS port

Server Lifecycle Management

from jupyter_server.serverapp import ServerApp, list_running_servers, shutdown_server

# Start server in background
import threading

def start_server():
    app = ServerApp()
    app.initialize()
    app.start()

server_thread = threading.Thread(target=start_server)
server_thread.daemon = True
server_thread.start()

# List running servers
servers = list_running_servers()
for server_info in servers:
    print(f"Server running on {server_info['url']}")

# Shutdown specific server
shutdown_server(server_info)

ServerWebApplication

Tornado web application wrapper that handles request routing and middleware.

from jupyter_server.serverapp import ServerWebApplication
from tornado.web import RequestHandler

# Custom handler
class CustomHandler(RequestHandler):
    def get(self):
        self.write({"message": "Hello World"})

# Create web application
web_app = ServerWebApplication(
    jupyter_app=None,  # Will be set by ServerApp
    default_services=None,
    kernel_manager=None,
    contents_manager=None,
    session_manager=None,
    kernel_spec_manager=None,
    config_manager=None,
    event_logger=None,
    extra_services=[],
)

# Add custom handlers
web_app.add_handlers(".*$", [
    (r"/custom", CustomHandler),
])

Server Utilities

Random Port Generation

def random_ports(port: int, n: int) -> Generator[int, None, None]:
    """
    Generate a list of n random ports near the given port.

    The first 5 ports will be sequential, and the remaining n-5 will be
    randomly selected in the range [port-2*n, port+2*n].

    Args:
        port: Starting port number
        n: Number of ports to generate

    Yields:
        int: Port numbers
    """

Usage example:

from jupyter_server.serverapp import random_ports

# Generate 5 available ports starting from 8888
for port in random_ports(8888, 5):
    # Try to bind to this port
    try:
        # Attempt to start server on this port
        break
    except OSError:
        continue  # Port in use, try next

Handler Loading

from jupyter_server.serverapp import load_handlers, JUPYTER_SERVICE_HANDLERS

# Load service handlers dynamically
loaded_handlers = load_handlers("my_extension")

# Default service handler mapping
print(JUPYTER_SERVICE_HANDLERS)
# {
#     'api': 'jupyter_server.services.api.handlers',
#     'config': 'jupyter_server.services.config.handlers',
#     'contents': 'jupyter_server.services.contents.handlers',
#     'kernels': 'jupyter_server.services.kernels.handlers',
#     'sessions': 'jupyter_server.services.sessions.handlers',
#     'kernelspecs': 'jupyter_server.services.kernelspecs.handlers',
#     'nbconvert': 'jupyter_server.services.nbconvert.handlers',
# }

CLI Applications

Password Management

from jupyter_server.serverapp import JupyterPasswordApp

# Create password app
password_app = JupyterPasswordApp()
password_app.initialize()

# Set password interactively
password_app.start()  # Prompts for password and saves hash

Server Management

from jupyter_server.serverapp import (
    JupyterServerStopApp,
    JupyterServerListApp
)

# List running servers
list_app = JupyterServerListApp()
list_app.initialize()
list_app.start()

# Stop servers
stop_app = JupyterServerStopApp()
stop_app.initialize([str(port)])  # Port number as argument
stop_app.start()

Configuration

Common Configuration Options

from jupyter_server.serverapp import ServerApp

app = ServerApp()

# Network configuration
app.ip = "0.0.0.0"  # Listen on all interfaces
app.port = 8888
app.port_retries = 50  # Try 50 ports if default is busy
app.allow_remote_access = True

# Authentication and security
app.token = "secret-token-here"
app.password = "sha1:hash:of:password"
app.allow_password_change = True
app.disable_check_xsrf = False

# SSL/TLS
app.certfile = "/path/to/cert.pem"
app.keyfile = "/path/to/key.pem"

# Directories and paths
app.root_dir = "/path/to/notebook/root"
app.notebook_dir = "/path/to/notebooks"  # Deprecated, use root_dir
app.preferred_dir = "/path/to/default/directory"

# Browser and UI
app.open_browser = True
app.browser = "chrome"  # Or path to browser executable
app.base_url = "/"
app.default_url = "/lab"  # Default landing page

# Logging and debugging
app.log_level = "INFO"  # DEBUG, INFO, WARN, ERROR, CRITICAL
app.enable_pylab = "disabled"  # matplotlib integration

# Resource limits
app.max_buffer_size = 1024 * 1024 * 1024  # 1GB
app.max_body_size = 1024 * 1024 * 1024    # 1GB

# Shutdown behavior
app.shutdown_no_activity_timeout = 0  # Minutes, 0 = disabled
app.terminals_enabled = True

Config File Example

# jupyter_server_config.py

c = get_config()

# Basic server settings
c.ServerApp.port = 8888
c.ServerApp.ip = '127.0.0.1'
c.ServerApp.open_browser = False

# Authentication
c.ServerApp.token = 'your-secret-token'

# Enable extensions
c.ServerApp.jpserver_extensions = {
    'my_extension': True,
    'another_extension': True,
}

# Custom managers
c.ServerApp.contents_manager_class = 'my_package.MyContentsManager'
c.ServerApp.kernel_manager_class = 'my_package.MyKernelManager'

Error Handling

Common Patterns

from jupyter_server.serverapp import ServerApp
from tornado.ioloop import IOLoop
import logging

app = ServerApp()

try:
    app.initialize()

    # Setup signal handlers for graceful shutdown
    import signal
    def signal_handler(sig, frame):
        IOLoop.current().add_callback_from_signal(app.stop)

    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGINT, signal_handler)

    app.start()

except Exception as e:
    logging.error(f"Failed to start server: {e}")
    raise

Port Conflict Resolution

from jupyter_server.serverapp import ServerApp
import socket

def find_free_port(start_port=8888):
    for port in range(start_port, start_port + 100):
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.bind(('', port))
                return port
        except OSError:
            continue
    raise RuntimeError("No free ports found")

app = ServerApp()
app.port = find_free_port()
app.initialize()
app.start()

Integration Examples

Embedding in Custom Application

from jupyter_server.serverapp import ServerApp
from tornado.ioloop import IOLoop
import asyncio

class MyApplication:
    def __init__(self):
        self.server_app = ServerApp()
        self.server_app.port = 8888
        self.server_app.open_browser = False

    async def start_server(self):
        """Start Jupyter server in background"""
        self.server_app.initialize()

        # Start in separate thread or use asyncio
        loop = IOLoop.current()
        await loop.run_in_executor(None, self.server_app.start)

    def stop_server(self):
        """Stop the server"""
        self.server_app.stop()

# Usage
app = MyApplication()
asyncio.run(app.start_server())

Multi-Instance Management

from jupyter_server.serverapp import ServerApp, list_running_servers
import multiprocessing

def start_server_instance(port, token):
    """Start a server instance on specific port"""
    app = ServerApp()
    app.port = port
    app.token = token
    app.open_browser = False
    app.initialize()
    app.start()

# Start multiple server instances
processes = []
for i, port in enumerate([8888, 8889, 8890]):
    token = f"token-{i}"
    p = multiprocessing.Process(
        target=start_server_instance,
        args=(port, token)
    )
    p.start()
    processes.append(p)

# Monitor running servers
servers = list_running_servers()
print(f"Running {len(servers)} server instances")

# Cleanup
for p in processes:
    p.terminate()
    p.join()

Install with Tessl CLI

npx tessl i tessl/pypi-jupyter-server

docs

auth.md

configuration.md

core-application.md

extensions.md

handlers.md

index.md

services.md

tile.json