|
3 | 3 | """
|
4 | 4 |
|
5 | 5 | import sys
|
6 |
| -from collections import namedtuple |
7 | 6 | from warnings import warn
|
8 | 7 |
|
9 | 8 | if sys.version_info < (3, 10): # pragma: no cover
|
|
19 | 18 | Instance,
|
20 | 19 | Int,
|
21 | 20 | List,
|
22 |
| - TraitError, |
23 | 21 | Tuple,
|
24 | 22 | Unicode,
|
25 | 23 | Union,
|
|
32 | 30 | from .handlers import AddSlashHandler, NamedLocalProxyHandler, SuperviseAndProxyHandler
|
33 | 31 | from .rawsocket import RawSocketHandler, SuperviseAndRawSocketHandler
|
34 | 32 |
|
35 |
| -LauncherEntry = namedtuple( |
36 |
| - "LauncherEntry", ["enabled", "icon_path", "title", "path_info", "category"] |
37 |
| -) |
| 33 | + |
| 34 | +class LauncherEntry(Configurable): |
| 35 | + enabled = Bool( |
| 36 | + True, |
| 37 | + help=""" |
| 38 | + Set to True (default) to make an entry in the launchers. Set to False to have no |
| 39 | + explicit entry. |
| 40 | + """, |
| 41 | + ) |
| 42 | + |
| 43 | + icon_path = Unicode( |
| 44 | + "", |
| 45 | + help=""" |
| 46 | + Full path to an svg icon that could be used with a launcher. Currently only used by the |
| 47 | + JupyterLab launcher |
| 48 | + """, |
| 49 | + ) |
| 50 | + |
| 51 | + title = Unicode( |
| 52 | + allow_none=False, |
| 53 | + help=""" |
| 54 | + Title to be used for the launcher entry. Defaults to the name of the server if missing. |
| 55 | + """, |
| 56 | + ) |
| 57 | + |
| 58 | + path_info = Unicode( |
| 59 | + help=""" |
| 60 | + The trailing path that is appended to the user's server URL to access the proxied server. |
| 61 | + By default it is the name of the server followed by a trailing slash. |
| 62 | + """, |
| 63 | + ) |
| 64 | + |
| 65 | + @default("path_info") |
| 66 | + def _default_path_info(self): |
| 67 | + return self.title + "/" |
| 68 | + |
| 69 | + category = Unicode( |
| 70 | + "Notebook", |
| 71 | + help=""" |
| 72 | + The category for the launcher item. Currently only used by the JupyterLab launcher. |
| 73 | + By default it is "Notebook". |
| 74 | + """, |
| 75 | + ) |
38 | 76 |
|
39 | 77 |
|
40 | 78 | class ServerProcess(Configurable):
|
@@ -107,9 +145,8 @@ class ServerProcess(Configurable):
|
107 | 145 | """,
|
108 | 146 | ).tag(config=True)
|
109 | 147 |
|
110 |
| - # Can't use Instance(LauncherEntry) because LauncherEntry is not a class |
111 | 148 | launcher_entry = Union(
|
112 |
| - [Instance(object), Dict()], |
| 149 | + [Instance(LauncherEntry), Dict()], |
113 | 150 | allow_none=False,
|
114 | 151 | help="""
|
115 | 152 | A dictionary of various options for entries in classic notebook / jupyterlab launchers.
|
@@ -139,23 +176,13 @@ class ServerProcess(Configurable):
|
139 | 176 |
|
140 | 177 | @validate("launcher_entry")
|
141 | 178 | def _validate_launcher_entry(self, proposal):
|
142 |
| - le = proposal["value"] |
143 |
| - invalid_keys = set(le.keys()).difference( |
144 |
| - {"enabled", "icon_path", "title", "path_info", "category"} |
145 |
| - ) |
146 |
| - if invalid_keys: |
147 |
| - raise TraitError( |
148 |
| - f"launcher_entry {le} contains invalid keys: {invalid_keys}" |
149 |
| - ) |
150 |
| - return ( |
151 |
| - LauncherEntry( |
152 |
| - enabled=le.get("enabled", True), |
153 |
| - icon_path=le.get("icon_path"), |
154 |
| - title=le.get("title", self.name), |
155 |
| - path_info=le.get("path_info", self.name + "/"), |
156 |
| - category=le.get("category", "Notebook"), |
157 |
| - ), |
158 |
| - ) |
| 179 | + kwargs = {"title": self.name} |
| 180 | + kwargs.update(proposal["value"]) |
| 181 | + return LauncherEntry(**kwargs) |
| 182 | + |
| 183 | + @default("launcher_entry") |
| 184 | + def _default_launcher_entry(self): |
| 185 | + return LauncherEntry(title=self.name) |
159 | 186 |
|
160 | 187 | new_browser_tab = Bool(
|
161 | 188 | True,
|
|
0 commit comments