0
# Services
1
2
The Jupyter Server provides a comprehensive set of service modules that handle core functionality like file management, kernel orchestration, session tracking, and API endpoints.
3
4
## Contents Service
5
6
Manages file and notebook operations with support for different storage backends.
7
8
```python
9
from jupyter_server.services.contents.manager import ContentsManager, AsyncContentsManager
10
from jupyter_server.services.contents.filemanager import FileContentsManager, AsyncFileContentsManager
11
from jupyter_server.services.contents.largefilemanager import LargeFileManager, AsyncLargeFileManager
12
from jupyter_server.services.contents.checkpoints import Checkpoints, FileCheckpoints, AsyncCheckpoints, AsyncFileCheckpoints
13
```
14
15
### ContentsManager
16
17
Abstract base class for content management systems.
18
19
```python{ .api }
20
from jupyter_server.services.contents.manager import ContentsManager
21
22
class MyContentsManager(ContentsManager):
23
"""Custom contents manager implementation."""
24
25
def get(self, path: str, content: bool = True, type: str = None, format: str = None):
26
"""Get a file or directory model."""
27
# Return file/directory model dictionary
28
return {
29
"name": "example.ipynb",
30
"path": path,
31
"type": "notebook",
32
"format": "json",
33
"content": notebook_content if content else None,
34
"size": 1024,
35
"last_modified": datetime.now().isoformat(),
36
"created": datetime.now().isoformat(),
37
"mimetype": "application/x-ipynb+json",
38
}
39
40
def save(self, model: dict, path: str):
41
"""Save a file or directory."""
42
# Save the model and return updated model
43
return self.get(path)
44
45
def delete_file(self, path: str):
46
"""Delete a file."""
47
# Implement file deletion
48
pass
49
50
def rename_file(self, old_path: str, new_path: str):
51
"""Rename a file."""
52
# Implement file renaming
53
pass
54
55
def file_exists(self, path: str) -> bool:
56
"""Check if file exists."""
57
return True # Implement existence check
58
59
def dir_exists(self, path: str) -> bool:
60
"""Check if directory exists."""
61
return True # Implement directory check
62
63
def is_hidden(self, path: str) -> bool:
64
"""Check if path is hidden."""
65
return path.startswith('.')
66
```
67
68
### FileContentsManager
69
70
File system-based implementation.
71
72
```python{ .api }
73
from jupyter_server.services.contents.filemanager import FileContentsManager
74
75
# Configure file contents manager
76
contents_manager = FileContentsManager()
77
contents_manager.root_dir = "/path/to/notebooks"
78
contents_manager.hide_globs = ["__pycache__", "*.pyc", ".git"]
79
contents_manager.untitled_notebook = "Untitled.ipynb"
80
contents_manager.untitled_file = "untitled.txt"
81
contents_manager.untitled_directory = "Untitled Folder"
82
83
# Get file/directory listing
84
model = contents_manager.get("") # Root directory
85
print(f"Found {len(model['content'])} items")
86
87
# Save notebook
88
notebook_model = {
89
"type": "notebook",
90
"format": "json",
91
"content": {
92
"cells": [],
93
"metadata": {},
94
"nbformat": 4,
95
"nbformat_minor": 5,
96
}
97
}
98
saved = contents_manager.save(notebook_model, "new_notebook.ipynb")
99
```
100
101
### AsyncContentsManager
102
103
Asynchronous version of ContentsManager for better performance in async contexts.
104
105
```python{ .api }
106
from jupyter_server.services.contents.manager import AsyncContentsManager
107
import asyncio
108
109
class MyAsyncContentsManager(AsyncContentsManager):
110
"""Custom async contents manager implementation."""
111
112
async def get(self, path: str, content: bool = True, type: str = None, format: str = None):
113
"""Get a file or directory model asynchronously."""
114
# Async file operations here
115
await asyncio.sleep(0) # Simulate async operation
116
return {
117
"name": "example.ipynb",
118
"path": path,
119
"type": "notebook",
120
"format": "json",
121
"content": notebook_content if content else None,
122
}
123
124
async def save(self, model: dict, path: str):
125
"""Save a file or directory asynchronously."""
126
# Async save operations here
127
await asyncio.sleep(0) # Simulate async operation
128
return await self.get(path)
129
130
# Usage
131
async def example_usage():
132
contents_manager = MyAsyncContentsManager()
133
model = await contents_manager.get("example.ipynb")
134
print(f"Got notebook: {model['name']}")
135
```
136
137
### LargeFileManager
138
139
Optimized contents manager for handling large files efficiently.
140
141
```python{ .api }
142
from jupyter_server.services.contents.largefilemanager import LargeFileManager
143
144
# Configure for large file handling
145
large_file_manager = LargeFileManager()
146
large_file_manager.root_dir = "/path/to/large/files"
147
large_file_manager.max_file_size_to_upload = 10 * 1024 * 1024 * 1024 # 10GB
148
149
# Use for large file operations
150
large_file = large_file_manager.get("huge_dataset.csv", content=False)
151
print(f"Large file size: {large_file['size']} bytes")
152
```
153
154
### Checkpoints
155
156
Version control and backup functionality for files.
157
158
```python{ .api }
159
from jupyter_server.services.contents.checkpoints import (
160
Checkpoints,
161
FileCheckpoints,
162
GenericCheckpointsMixin,
163
)
164
165
class MyCheckpoints(Checkpoints):
166
"""Custom checkpoint implementation."""
167
168
def create_checkpoint(self, contents_mgr, path: str) -> dict:
169
"""Create a checkpoint."""
170
checkpoint_id = f"checkpoint-{int(time.time())}"
171
return {
172
"id": checkpoint_id,
173
"last_modified": datetime.now().isoformat(),
174
}
175
176
def restore_checkpoint(self, contents_mgr, checkpoint_id: str, path: str):
177
"""Restore from checkpoint."""
178
# Implement checkpoint restoration
179
pass
180
181
def delete_checkpoint(self, checkpoint_id: str, path: str):
182
"""Delete a checkpoint."""
183
# Implement checkpoint deletion
184
pass
185
186
def list_checkpoints(self, path: str) -> list:
187
"""List available checkpoints."""
188
return [
189
{
190
"id": "checkpoint-123456789",
191
"last_modified": datetime.now().isoformat(),
192
}
193
]
194
195
# Use with file contents manager
196
contents_manager = FileContentsManager()
197
contents_manager.checkpoints = MyCheckpoints()
198
199
# Create checkpoint
200
checkpoint = contents_manager.create_checkpoint("example.ipynb")
201
print(f"Created checkpoint: {checkpoint['id']}")
202
203
# List checkpoints
204
checkpoints = contents_manager.list_checkpoints("example.ipynb")
205
print(f"Available checkpoints: {len(checkpoints)}")
206
```
207
208
### Contents Utilities
209
210
```python{ .api }
211
from jupyter_server.services.contents.fileio import atomic_writing, copy2_safe
212
213
# Safe atomic file writing
214
with atomic_writing("/path/to/file.txt") as f:
215
f.write("Content that will be written atomically")
216
217
# Safe file copying
218
copy2_safe("/source/file.txt", "/dest/file.txt")
219
```
220
221
## Kernels Service
222
223
Manages Jupyter kernel lifecycles and communication.
224
225
```python
226
from jupyter_server.services.kernels.kernelmanager import MappingKernelManager, AsyncMappingKernelManager
227
```
228
229
### MappingKernelManager
230
231
Manages multiple kernel instances.
232
233
```python{ .api }
234
from jupyter_server.services.kernels.kernelmanager import MappingKernelManager
235
from jupyter_client.kernelspec import KernelSpecManager
236
237
# Create kernel manager
238
kernel_spec_manager = KernelSpecManager()
239
kernel_manager = MappingKernelManager(
240
kernel_spec_manager=kernel_spec_manager
241
)
242
243
# Start a kernel
244
kernel_id = await kernel_manager.start_kernel(kernel_name="python3")
245
print(f"Started kernel: {kernel_id}")
246
247
# Get kernel info
248
kernel = kernel_manager.get_kernel(kernel_id)
249
print(f"Kernel status: {kernel.execution_state}")
250
251
# List running kernels
252
kernels = kernel_manager.list_kernels()
253
for k in kernels:
254
print(f"Kernel {k['id']}: {k['name']} ({k['execution_state']})")
255
256
# Interrupt kernel
257
await kernel_manager.interrupt_kernel(kernel_id)
258
259
# Restart kernel
260
await kernel_manager.restart_kernel(kernel_id)
261
262
# Shutdown kernel
263
await kernel_manager.shutdown_kernel(kernel_id)
264
```
265
266
### AsyncMappingKernelManager
267
268
Asynchronous version for better performance.
269
270
```python{ .api }
271
from jupyter_server.services.kernels.kernelmanager import AsyncMappingKernelManager
272
import asyncio
273
274
async def manage_kernels():
275
kernel_manager = AsyncMappingKernelManager()
276
277
# Start multiple kernels
278
kernel_ids = []
279
for i in range(3):
280
kernel_id = await kernel_manager.start_kernel(kernel_name="python3")
281
kernel_ids.append(kernel_id)
282
print(f"Started kernel {i+1}: {kernel_id}")
283
284
# Execute code in kernels
285
for kernel_id in kernel_ids:
286
kernel = kernel_manager.get_kernel(kernel_id)
287
msg_id = kernel.execute("print('Hello from kernel!')")
288
print(f"Executed in kernel {kernel_id}: {msg_id}")
289
290
# Shutdown all kernels
291
for kernel_id in kernel_ids:
292
await kernel_manager.shutdown_kernel(kernel_id)
293
294
# Run async function
295
asyncio.run(manage_kernels())
296
```
297
298
## Sessions Service
299
300
Manages the relationship between kernels and frontend clients.
301
302
```python
303
from jupyter_server.services.sessions.sessionmanager import SessionManager
304
```
305
306
### SessionManager
307
308
Tracks kernel-frontend session relationships.
309
310
```python{ .api }
311
from jupyter_server.services.sessions.sessionmanager import SessionManager
312
from jupyter_server.services.kernels.kernelmanager import MappingKernelManager
313
314
# Create session manager
315
kernel_manager = MappingKernelManager()
316
session_manager = SessionManager(kernel_manager=kernel_manager)
317
318
# Create a session
319
session = await session_manager.create_session(
320
path="notebook.ipynb",
321
type="notebook",
322
name="Python 3",
323
kernel_name="python3",
324
)
325
326
print(f"Created session: {session['id']}")
327
print(f"Session path: {session['path']}")
328
print(f"Kernel ID: {session['kernel']['id']}")
329
330
# List all sessions
331
sessions = session_manager.list_sessions()
332
for s in sessions:
333
print(f"Session {s['id']}: {s['path']} -> {s['kernel']['id']}")
334
335
# Get session by ID
336
session = session_manager.get_session(session_id=session['id'])
337
338
# Update session (change path/name)
339
updated_session = await session_manager.update_session(
340
session_id=session['id'],
341
path="renamed_notebook.ipynb",
342
type="notebook",
343
name="Python 3 (Updated)",
344
)
345
346
# Delete session (also shuts down kernel)
347
await session_manager.delete_session(session_id=session['id'])
348
```
349
350
### Session Records
351
352
```python{ .api }
353
from jupyter_server.services.sessions.sessionmanager import KernelSessionRecord
354
355
# Session record tracking
356
record = KernelSessionRecord(
357
kernel_id="kernel-123",
358
session_id="session-456",
359
kernel_name="python3",
360
)
361
362
print(f"Kernel: {record.kernel_id}")
363
print(f"Session: {record.session_id}")
364
print(f"Name: {record.kernel_name}")
365
```
366
367
## Kernel Specs Service
368
369
Manages available kernel specifications.
370
371
```python
372
from jupyter_server.services.kernelspecs.handlers import kernelspec_model
373
```
374
375
### Kernel Spec Operations
376
377
```python{ .api }
378
from jupyter_server.services.kernelspecs.handlers import (
379
kernelspec_model,
380
is_kernelspec_model,
381
)
382
from jupyter_client.kernelspec import KernelSpecManager
383
384
# Create kernel spec manager
385
spec_manager = KernelSpecManager()
386
387
# Get all kernel specs
388
specs = spec_manager.get_all_specs()
389
for name, spec in specs.items():
390
print(f"Kernel: {name}")
391
print(f" Display name: {spec['spec']['display_name']}")
392
print(f" Language: {spec['spec']['language']}")
393
394
# Get specific kernel spec
395
python_spec = spec_manager.get_kernel_spec("python3")
396
print(f"Python kernel: {python_spec.display_name}")
397
398
# Create kernel spec model for API
399
model = kernelspec_model(spec_manager, "python3")
400
print(f"Model: {model}")
401
402
# Validate kernel spec model
403
is_valid = is_kernelspec_model(model)
404
print(f"Valid model: {is_valid}")
405
```
406
407
## Configuration Service
408
409
Provides runtime configuration management.
410
411
```python
412
from jupyter_server.services.config.manager import ConfigManager
413
```
414
415
### ConfigManager
416
417
Manages JSON configuration files and runtime settings.
418
419
```python{ .api }
420
from jupyter_server.services.config.manager import ConfigManager
421
import json
422
423
# Create config manager
424
config_manager = ConfigManager()
425
426
# Get configuration section
427
config = config_manager.get("my_extension")
428
print(f"Extension config: {config}")
429
430
# Set configuration value
431
config_manager.set("my_extension", "setting", "value")
432
433
# Update multiple settings
434
config_manager.update("my_extension", {
435
"setting1": "value1",
436
"setting2": 42,
437
"setting3": True,
438
})
439
440
# Get updated config
441
updated_config = config_manager.get("my_extension")
442
print(f"Updated config: {json.dumps(updated_config, indent=2)}")
443
```
444
445
## API Service
446
447
Provides OpenAPI specifications and server status endpoints.
448
449
```python
450
from jupyter_server.services.api.handlers import APISpecHandler, APIStatusHandler
451
```
452
453
### API Information
454
455
```python{ .api }
456
# Get API specification (handled by APISpecHandler)
457
# GET /api/spec.yaml returns OpenAPI spec
458
459
# Get server status (handled by APIStatusHandler)
460
# GET /api/status returns:
461
{
462
"started": "2023-01-01T00:00:00.000000Z",
463
"last_activity": "2023-01-01T01:00:00.000000Z",
464
"kernels": 2,
465
"connections": 5,
466
}
467
468
# Get user identity (handled by IdentityHandler)
469
# GET /api/me returns:
470
{
471
"username": "user",
472
"name": "User Name",
473
"display_name": "User Name",
474
"initials": "UN",
475
"color": "#orange",
476
}
477
```
478
479
## Events Service
480
481
Handles server-side events and WebSocket subscriptions.
482
483
```python
484
from jupyter_server.services.events.handlers import EventHandler, SubscribeWebsocket
485
```
486
487
### Event Handling
488
489
```python{ .api }
490
# Events are handled through WebSocket connections
491
# GET /api/events/subscribe opens WebSocket
492
493
# Event message format:
494
{
495
"schema_id": "https://events.jupyter.org/jupyter_server/session/v1",
496
"version": 1,
497
"timestamp": "2023-01-01T00:00:00.000Z",
498
"data": {
499
"session_id": "session-123",
500
"action": "started",
501
}
502
}
503
```
504
505
## NBConvert Service
506
507
Provides notebook conversion capabilities.
508
509
```python
510
from jupyter_server.services.nbconvert.handlers import NbconvertRootHandler
511
```
512
513
### Notebook Conversion
514
515
```python{ .api }
516
# Convert notebook via API
517
# POST /api/nbconvert/format/path/to/notebook.ipynb
518
519
# Request body:
520
{
521
"output_format": "html", # html, pdf, latex, etc.
522
"options": {
523
"template": "classic",
524
"exclude_input": False,
525
}
526
}
527
528
# Response: converted content or download link
529
```
530
531
## Security Service
532
533
Content Security Policy and security reporting.
534
535
```python
536
from jupyter_server.services.security.handlers import CSPReportHandler
537
```
538
539
### CSP Reporting
540
541
```python{ .api }
542
# CSP violation reports are sent to:
543
# POST /api/security/csp-report
544
545
# Report format:
546
{
547
"csp-report": {
548
"blocked-uri": "eval",
549
"document-uri": "http://localhost:8888/",
550
"original-policy": "default-src 'self'",
551
"violated-directive": "script-src",
552
}
553
}
554
```
555
556
## Custom Service Implementation
557
558
### Creating a Custom Service
559
560
```python{ .api }
561
from jupyter_server.base.handlers import APIHandler
562
from jupyter_server.auth.decorator import authorized
563
from tornado import web
564
import json
565
566
class MyCustomService:
567
"""Custom service implementation."""
568
569
def __init__(self):
570
self.data = {}
571
572
async def store_data(self, key: str, value):
573
"""Store data in service."""
574
self.data[key] = value
575
return {"success": True, "key": key}
576
577
async def get_data(self, key: str = None):
578
"""Retrieve data from service."""
579
if key:
580
return self.data.get(key)
581
return self.data
582
583
async def delete_data(self, key: str):
584
"""Delete data from service."""
585
if key in self.data:
586
del self.data[key]
587
return {"success": True, "key": key}
588
raise web.HTTPError(404, f"Key '{key}' not found")
589
590
class MyServiceHandler(APIHandler):
591
"""API handler for custom service."""
592
593
def initialize(self, service):
594
self.service = service
595
596
@authorized
597
async def get(self, key=None):
598
"""Get data from service."""
599
try:
600
data = await self.service.get_data(key)
601
self.finish({"data": data})
602
except Exception as e:
603
raise web.HTTPError(500, str(e))
604
605
@authorized
606
async def post(self):
607
"""Store data in service."""
608
try:
609
body = json.loads(self.request.body)
610
key = body.get("key")
611
value = body.get("value")
612
613
if not key:
614
raise web.HTTPError(400, "Missing 'key' parameter")
615
616
result = await self.service.store_data(key, value)
617
self.finish(result)
618
except json.JSONDecodeError:
619
raise web.HTTPError(400, "Invalid JSON")
620
except Exception as e:
621
raise web.HTTPError(500, str(e))
622
623
@authorized
624
async def delete(self, key):
625
"""Delete data from service."""
626
try:
627
result = await self.service.delete_data(key)
628
self.finish(result)
629
except Exception as e:
630
if isinstance(e, web.HTTPError):
631
raise
632
raise web.HTTPError(500, str(e))
633
634
# Register service handlers
635
def register_custom_service(web_app):
636
"""Register custom service with server."""
637
service = MyCustomService()
638
639
handlers = [
640
(r"/api/custom", MyServiceHandler, {"service": service}),
641
(r"/api/custom/(.+)", MyServiceHandler, {"service": service}),
642
]
643
644
web_app.add_handlers(".*$", handlers)
645
```
646
647
## Service Integration
648
649
### Integrating Services with Extensions
650
651
```python{ .api }
652
from jupyter_server.extension.application import ExtensionApp
653
654
## Events Service
655
656
Handles event logging and tracking across the Jupyter server.
657
658
```python{ .api }
659
from jupyter_server.services.events import EventLogger
660
from jupyter_events import event_logger
661
662
# Create event logger
663
event_logger = EventLogger()
664
665
# Log custom events
666
event_logger.emit(
667
schema_id="https://events.jupyter.org/jupyter_server",
668
version=1,
669
event={
670
"action": "server_start",
671
"timestamp": datetime.now().isoformat(),
672
"details": {"port": 8888}
673
}
674
)
675
676
# Register event schema
677
event_logger.register_event_schema({
678
"schema_id": "https://my-app.com/events",
679
"version": 1,
680
"properties": {
681
"action": {"type": "string"},
682
"user_id": {"type": "string"}
683
}
684
})
685
```
686
687
## Kernelspecs Service
688
689
Manages available kernel specifications and types.
690
691
```python{ .api }
692
from jupyter_server.services.kernelspecs import KernelSpecManager
693
from jupyter_client.kernelspec import KernelSpecManager as ClientKernelSpecManager
694
695
# Get kernel specs manager
696
kernelspec_manager = KernelSpecManager()
697
698
# List available kernel specs
699
specs = kernelspec_manager.get_all_specs()
700
for name, spec in specs.items():
701
print(f"Kernel: {name}")
702
print(f" Display name: {spec['spec']['display_name']}")
703
print(f" Language: {spec['spec']['language']}")
704
705
# Get specific kernel spec
706
python_spec = kernelspec_manager.get_kernel_spec("python3")
707
print(f"Python kernel command: {python_spec.argv}")
708
```
709
710
## Extension Services Integration
711
712
Custom services can be integrated through extensions.
713
714
```python{ .api }
715
from jupyter_server.extension.application import ExtensionApp
716
717
class MyExtensionWithServices(ExtensionApp):
718
name = "my_service_extension"
719
720
def initialize_services(self):
721
"""Initialize custom services."""
722
# Create custom service
723
self.custom_service = MyCustomService()
724
725
# Configure existing services
726
self.contents_manager.hide_globs.append("*.tmp")
727
728
def initialize_handlers(self):
729
"""Register service handlers."""
730
handlers = [
731
(
732
r"/my_extension/api/data",
733
MyServiceHandler,
734
{"service": self.custom_service}
735
),
736
]
737
self.handlers.extend(handlers)
738
739
def initialize_settings(self):
740
"""Update server settings."""
741
self.settings.update({
742
"my_custom_service": self.custom_service,
743
})
744
```
745
746
### Service Configuration
747
748
```python{ .api }
749
# In jupyter_server_config.py
750
751
c = get_config()
752
753
# Configure contents manager
754
c.ServerApp.contents_manager_class = 'my_package.MyContentsManager'
755
c.MyContentsManager.root_dir = '/custom/notebook/path'
756
c.MyContentsManager.hide_globs = ['*.tmp', '__pycache__']
757
758
# Configure kernel manager
759
c.ServerApp.kernel_manager_class = 'my_package.MyKernelManager'
760
c.MyKernelManager.default_kernel_name = 'python3'
761
762
# Configure session manager
763
c.ServerApp.session_manager_class = 'my_package.MySessionManager'
764
c.MySessionManager.session_cleanup_interval = 300 # 5 minutes
765
```