The backend infrastructure for Jupyter web applications providing core services, APIs, and REST endpoints.
The core application layer provides the main ServerApp class and supporting infrastructure for running Jupyter servers.
The main Jupyter server application class that coordinates all server components.
from jupyter_server.serverapp import ServerAppfrom 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 stopsfrom jupyter_server.serverapp import ServerApp
app = ServerApp()
app.certfile = "/path/to/cert.pem"
app.keyfile = "/path/to/key.pem"
app.port = 8443 # Use HTTPS portfrom 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)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),
])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 nextfrom 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',
# }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 hashfrom 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()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# 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'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}")
raisefrom 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()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())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