|
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