Skip to content

Commit 5002625

Browse files
Add OpenAPI spec file
An OpenAPI spec file is added to keep track of APIs for better maintainability All APIs are moved into /server-proxy/ subdirectory. Seems like root / is used by jupyter_server and /lab/ is used by jupyterlab_server. Moving all APIs under /server-proxy will future incompatibilities Initialise ServersAPIHandler with manager instead of importing it Use a function to setup API handlers which can be called directly during extension loading
1 parent 3930b21 commit 5002625

File tree

2 files changed

+182
-16
lines changed

2 files changed

+182
-16
lines changed

jupyter_server_proxy/api.py

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
from jupyter_server.utils import url_path_join as ujoin
55
from tornado import web
66

7-
from .manager import manager
8-
97

108
class ServersInfoHandler(JupyterHandler):
119
def initialize(self, server_processes):
@@ -36,8 +34,9 @@ async def get(self):
3634
self.write({"server_processes": data})
3735

3836

39-
# Took it from JupyterHub LogoHandler
40-
class IconHandler(web.StaticFileHandler):
37+
# IconHandler has been copied from JupyterHub's IconHandler:
38+
# https://github.com/jupyterhub/jupyterhub/blob/4.0.0b2/jupyterhub/handlers/static.py#L22-L31
39+
class ServersIconHandler(web.StaticFileHandler):
4140
"""A singular handler for serving the icon."""
4241

4342
def get(self):
@@ -52,13 +51,22 @@ def get_absolute_path(cls, root, path):
5251

5352

5453
class ServersAPIHandler(JupyterHandler):
55-
"""Handler to get metadata or terminate of a given server"""
54+
"""Handler to get metadata or terminate of a given server or all servers"""
55+
56+
def initialize(self, manager):
57+
self.manager = manager
5658

5759
@web.authenticated
5860
async def delete(self, name):
5961
"""Delete a server proxy by name"""
62+
if not name:
63+
raise web.HTTPError(
64+
403, "Please set the name of a running server proxy that "
65+
"user wishes to terminate"
66+
)
67+
6068
try:
61-
val = await manager.terminate_server_proxy_app(name)
69+
val = await self.manager.terminate_server_proxy_app(name)
6270
if val is None:
6371
raise Exception(
6472
f"Proxy {name} not found. Are you sure the {name} "
@@ -73,17 +81,48 @@ async def delete(self, name):
7381
@web.authenticated
7482
async def get(self, name):
7583
"""Get meta data of a running server proxy"""
76-
app = manager.get_server_proxy_app(name)
84+
if name:
85+
apps = self.manager.get_server_proxy_app(name)._asdict()
86+
# If no server proxy found this will be a dict with empty values
87+
if not apps['name']:
88+
raise web.HTTPError(
89+
404, f"Server proxy {name} not found"
90+
)
91+
else:
92+
apps = [app._asdict() for app in self.manager.list_server_proxy_apps()]
93+
7794
self.set_status(200)
78-
self.finish(json.dumps(app._asdict()))
95+
self.finish(json.dumps(apps))
7996

8097

81-
class ListServersAPIHandler(JupyterHandler):
82-
"""Handler to list all running server proxies"""
98+
def setup_api_handlers(web_app, manager, server_processes):
99+
base_url = web_app.settings["base_url"]
100+
101+
# Make a list of icon handlers
102+
icon_handlers = []
103+
for sp in server_processes:
104+
if sp.launcher_entry.enabled and sp.launcher_entry.icon_path:
105+
icon_handlers.append(
106+
(
107+
ujoin(base_url, f"server-proxy/icon/{sp.name}"),
108+
ServersIconHandler,
109+
{"path": sp.launcher_entry.icon_path},
110+
)
111+
)
112+
113+
web_app.add_handlers(
114+
".*",
115+
[
116+
(
117+
ujoin(base_url, "server-proxy/api/servers-info"),
118+
ServersInfoHandler,
119+
{"server_processes": server_processes},
120+
),
121+
(
122+
ujoin(base_url, r"server-proxy/api/servers/(?P<name>.*)"),
123+
ServersAPIHandler,
124+
{"manager": manager}
125+
),
126+
] + icon_handlers
127+
)
83128

84-
@web.authenticated
85-
async def get(self):
86-
"""list running servers"""
87-
apps = manager.list_server_proxy_apps()
88-
self.set_status(200)
89-
self.finish(json.dumps([app._asdict() for app in apps]))

jupyter_server_proxy/api.yml

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
openapi: "3.1.0"
2+
info:
3+
title: Jupyter Server Proxy
4+
description: The REST API for Jupyter Server Proxy Package
5+
version: 4.0.0
6+
license:
7+
name: BSD-3-Clause
8+
9+
paths:
10+
/server-proxy/api/servers-info:
11+
get:
12+
summary: Get List of Server Proxy Entrypoints
13+
description: |
14+
Gets the list of server proxy entrypoints and their launcher meta data
15+
responses:
16+
"200":
17+
description: Server Proxy Entrypoints
18+
content:
19+
application/json:
20+
schema:
21+
properties:
22+
server_processes:
23+
type: array
24+
description: list of server proxy entrypoints
25+
items:
26+
$ref: "#/components/schemas/ListEntryPoints"
27+
28+
/server-proxy/icon/{server_name}:
29+
get:
30+
summary: Get Icon of Server Proxy Application
31+
description: |
32+
Gets the icon of server proxy application
33+
responses:
34+
"200":
35+
description: Server Proxy Application's Icon
36+
content:
37+
image/*:
38+
schema:
39+
type: string
40+
description: encoded string of server proxy application's icon image
41+
format: binary
42+
43+
/server-proxy/api/servers/:
44+
get:
45+
summary: Get Currently Running Server Proxy Applications
46+
description: |
47+
Gets the list of all running server proxy applications along with their metadata
48+
responses:
49+
"200":
50+
description: Active Server Proxy Applications
51+
content:
52+
application/json:
53+
schema:
54+
type: array
55+
description: list of running server proxy applications and their metadata
56+
items:
57+
$ref: "#/components/schemas/Server"
58+
59+
/server-proxy/api/servers/{server_name}:
60+
parameters:
61+
- name: server_name
62+
description: Server Proxy Application Name
63+
in: path
64+
required: true
65+
schema:
66+
type: string
67+
get:
68+
summary: Get Metadata of a given Server Proxy Application
69+
description: |
70+
Gets metadata for a given server proxy application
71+
responses:
72+
"200":
73+
description: Metadata of Server Proxy Application
74+
content:
75+
application/json:
76+
schema:
77+
$ref: "#/components/schemas/Server"
78+
"404":
79+
description: Server proxy application not found
80+
delete:
81+
summary: Delete a Managed Server Proxy Application
82+
description: |
83+
Terminates and deletes a given managed server proxy application
84+
responses:
85+
"204":
86+
description: Succesfully terminated server proxy application
87+
"403":
88+
description: Forbidden. No server proxy application name set
89+
"404":
90+
description: Server proxy application not found
91+
92+
components:
93+
schemas:
94+
ListEntryPoints:
95+
type: object
96+
properties:
97+
name:
98+
type: string
99+
launcher_entry:
100+
type: object
101+
properties:
102+
enabled:
103+
type: string
104+
title:
105+
type: string
106+
path_info:
107+
type: string
108+
icon_url:
109+
type: string
110+
new_browser_tab:
111+
type: string
112+
Server:
113+
type: object
114+
properties:
115+
name:
116+
type: string
117+
url:
118+
type: string
119+
cmd:
120+
type: string
121+
port:
122+
type: string
123+
managed:
124+
type: string
125+
unix_socket:
126+
type: string
127+

0 commit comments

Comments
 (0)