|
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 |
|
18 | 17 | Instance, |
19 | 18 | Int, |
20 | 19 | List, |
21 | | - TraitError, |
22 | 20 | Tuple, |
23 | 21 | Unicode, |
24 | 22 | Union, |
|
38 | 36 | from .utils import Callable |
39 | 37 |
|
40 | 38 |
|
41 | | -LauncherEntry = namedtuple( |
42 | | - "LauncherEntry", ["enabled", "icon_path", "title", "path_info", "category"] |
43 | | -) |
| 39 | +class LauncherEntry(Configurable): |
| 40 | + enabled = Bool( |
| 41 | + True, |
| 42 | + help=""" |
| 43 | + Set to True (default) to make an entry in the launchers. Set to False to have no |
| 44 | + explicit entry. |
| 45 | + """, |
| 46 | + ) |
| 47 | + |
| 48 | + icon_path = Unicode( |
| 49 | + "", |
| 50 | + help=""" |
| 51 | + Full path to an svg icon that could be used with a launcher. Currently only used by the |
| 52 | + JupyterLab launcher |
| 53 | + """, |
| 54 | + ) |
| 55 | + |
| 56 | + title = Unicode( |
| 57 | + allow_none=False, |
| 58 | + help=""" |
| 59 | + Title to be used for the launcher entry. Defaults to the name of the server if missing. |
| 60 | + """, |
| 61 | + ) |
| 62 | + |
| 63 | + path_info = Unicode( |
| 64 | + help=""" |
| 65 | + The trailing path that is appended to the user's server URL to access the proxied server. |
| 66 | + By default it is the name of the server followed by a trailing slash. |
| 67 | + """, |
| 68 | + ) |
| 69 | + |
| 70 | + @default("path_info") |
| 71 | + def _default_path_info(self): |
| 72 | + return self.title + "/" |
| 73 | + |
| 74 | + category = Unicode( |
| 75 | + "Notebook", |
| 76 | + help=""" |
| 77 | + The category for the launcher item. Currently only used by the JupyterLab launcher. |
| 78 | + By default it is "Notebook". |
| 79 | + """, |
| 80 | + ) |
44 | 81 |
|
45 | 82 |
|
46 | 83 | class ServerProcess(Configurable): |
@@ -113,9 +150,8 @@ class ServerProcess(Configurable): |
113 | 150 | """, |
114 | 151 | ).tag(config=True) |
115 | 152 |
|
116 | | - # Can't use Instance(LauncherEntry) because LauncherEntry is not a class |
117 | 153 | launcher_entry = Union( |
118 | | - [Instance(object), Dict()], |
| 154 | + [Instance(LauncherEntry), Dict()], |
119 | 155 | allow_none=False, |
120 | 156 | help=""" |
121 | 157 | A dictionary of various options for entries in classic notebook / jupyterlab launchers. |
@@ -145,23 +181,13 @@ class ServerProcess(Configurable): |
145 | 181 |
|
146 | 182 | @validate("launcher_entry") |
147 | 183 | def _validate_launcher_entry(self, proposal): |
148 | | - le = proposal["value"] |
149 | | - invalid_keys = set(le.keys()).difference( |
150 | | - {"enabled", "icon_path", "title", "path_info", "category"} |
151 | | - ) |
152 | | - if invalid_keys: |
153 | | - raise TraitError( |
154 | | - f"launcher_entry {le} contains invalid keys: {invalid_keys}" |
155 | | - ) |
156 | | - return ( |
157 | | - LauncherEntry( |
158 | | - enabled=le.get("enabled", True), |
159 | | - icon_path=le.get("icon_path"), |
160 | | - title=le.get("title", self.name), |
161 | | - path_info=le.get("path_info", self.name + "/"), |
162 | | - category=le.get("category", "Notebook"), |
163 | | - ), |
164 | | - ) |
| 184 | + kwargs = {"title": self.name} |
| 185 | + kwargs.update(proposal["value"]) |
| 186 | + return LauncherEntry(**kwargs) |
| 187 | + |
| 188 | + @default("launcher_entry") |
| 189 | + def _default_launcher_entry(self): |
| 190 | + return LauncherEntry(title=self.name) |
165 | 191 |
|
166 | 192 | new_browser_tab = Bool( |
167 | 193 | True, |
|
0 commit comments