6
6
from traitlets .config import Configurable
7
7
from tornado import httpclient
8
8
from warnings import warn
9
- from .handlers import SuperviseAndProxyHandler , AddSlashHandler , RewritableResponse
9
+ from .handlers import (
10
+ NamedLocalProxyHandler , SuperviseAndProxyHandler , AddSlashHandler ,
11
+ )
10
12
import pkg_resources
11
13
from collections import namedtuple
12
14
from .utils import call_with_asked_args
17
19
except ImportError :
18
20
from .utils import Callable
19
21
20
- def _make_serverproxy_handler (name , command , environment , timeout , absolute_url , port , mappath , request_headers_override , rewrite_response ):
22
+
23
+ LauncherEntry = namedtuple ('LauncherEntry' , ['enabled' , 'icon_path' , 'title' , 'path_info' ])
24
+ ServerProcess = namedtuple ('ServerProcess' , [
25
+ 'name' , 'command' , 'environment' , 'timeout' , 'absolute_url' , 'port' , 'unix_socket' ,
26
+ 'mappath' , 'launcher_entry' , 'new_browser_tab' , 'request_headers_override' , 'rewrite_response' ,
27
+ ])
28
+
29
+
30
+ def _make_namedproxy_handler (sp : ServerProcess ):
31
+ class _Proxy (NamedLocalProxyHandler ):
32
+ def __init__ (self , * args , ** kwargs ):
33
+ super ().__init__ (* args , ** kwargs )
34
+ self .name = sp .name
35
+ self .proxy_base = sp .name
36
+ self .absolute_url = sp .absolute_url
37
+ self .port = sp .port
38
+ self .unix_socket = sp .unix_socket
39
+ self .mappath = sp .mappath
40
+ self .rewrite_response = sp .rewrite_response
41
+
42
+ def get_request_headers_override (self ):
43
+ return self ._realize_rendered_template (sp .request_headers_override )
44
+
45
+ return _Proxy
46
+
47
+ def _make_supervisedproxy_handler (sp : ServerProcess ):
21
48
"""
22
49
Create a SuperviseAndProxyHandler subclass with given parameters
23
50
"""
24
51
# FIXME: Set 'name' properly
25
52
class _Proxy (SuperviseAndProxyHandler ):
26
53
def __init__ (self , * args , ** kwargs ):
27
54
super ().__init__ (* args , ** kwargs )
28
- self .name = name
29
- self .command = command
30
- self .proxy_base = name
31
- self .absolute_url = absolute_url
32
- self .requested_port = port
33
- self .mappath = mappath
34
- self .rewrite_response = rewrite_response
35
-
36
- @property
37
- def process_args (self ):
38
- return {
39
- 'port' : self .port ,
40
- 'base_url' : self .base_url ,
41
- }
42
-
43
- def _render_template (self , value ):
44
- args = self .process_args
45
- if type (value ) is str :
46
- return value .format (** args )
47
- elif type (value ) is list :
48
- return [self ._render_template (v ) for v in value ]
49
- elif type (value ) is dict :
50
- return {
51
- self ._render_template (k ): self ._render_template (v )
52
- for k , v in value .items ()
53
- }
54
- else :
55
- raise ValueError ('Value of unrecognized type {}' .format (type (value )))
56
-
57
- def _realize_rendered_template (self , attribute ):
58
- '''Call any callables, then render any templated values.'''
59
- if callable (attribute ):
60
- attribute = self ._render_template (
61
- call_with_asked_args (attribute , self .process_args )
62
- )
63
- return self ._render_template (attribute )
64
-
65
- def get_cmd (self ):
66
- return self ._realize_rendered_template (self .command )
55
+ self .name = sp .name
56
+ self .command = sp .command
57
+ self .proxy_base = sp .name
58
+ self .absolute_url = sp .absolute_url
59
+ self .requested_port = sp .port
60
+ self .requested_unix_socket = sp .unix_socket
61
+ self .mappath = sp .mappath
62
+ self .rewrite_response = sp .rewrite_response
67
63
68
64
def get_env (self ):
69
- return self ._realize_rendered_template (environment )
65
+ return self ._realize_rendered_template (sp . environment )
70
66
71
67
def get_request_headers_override (self ):
72
- return self ._realize_rendered_template (request_headers_override )
68
+ return self ._realize_rendered_template (sp . request_headers_override )
73
69
74
70
def get_timeout (self ):
75
- return timeout
71
+ return sp . timeout
76
72
77
73
return _Proxy
78
74
@@ -93,30 +89,25 @@ def make_handlers(base_url, server_processes):
93
89
"""
94
90
handlers = []
95
91
for sp in server_processes :
96
- handler = _make_serverproxy_handler (
97
- sp . name ,
98
- sp . command ,
99
- sp . environment ,
100
- sp .timeout ,
101
- sp .absolute_url ,
102
- sp . port ,
103
- sp . mappath ,
104
- sp . request_headers_override ,
105
- sp . rewrite_response ,
106
- )
92
+ if sp . command :
93
+ handler = _make_supervisedproxy_handler ( sp )
94
+ kwargs = dict ( state = {})
95
+ else :
96
+ if not ( sp .port or isinstance ( sp . unix_socket , str )):
97
+ warn ( f"Server proxy { sp .name } does not have a command, port "
98
+ f"number or unix_socket path. At least one of these is "
99
+ f"required." )
100
+ continue
101
+ handler = _make_namedproxy_handler ( sp )
102
+ kwargs = {}
107
103
handlers .append ((
108
- ujoin (base_url , sp .name , r'(.*)' ), handler , dict ( state = {}) ,
104
+ ujoin (base_url , sp .name , r'(.*)' ), handler , kwargs ,
109
105
))
110
106
handlers .append ((
111
107
ujoin (base_url , sp .name ), AddSlashHandler
112
108
))
113
109
return handlers
114
110
115
- LauncherEntry = namedtuple ('LauncherEntry' , ['enabled' , 'icon_path' , 'title' , 'path_info' ])
116
- ServerProcess = namedtuple ('ServerProcess' , [
117
- 'name' , 'command' , 'environment' , 'timeout' , 'absolute_url' , 'port' ,
118
- 'mappath' , 'launcher_entry' , 'new_browser_tab' , 'request_headers_override' , 'rewrite_response' ,
119
- ])
120
111
121
112
def make_server_process (name , server_process_config , serverproxy_config ):
122
113
le = server_process_config .get ('launcher_entry' , {})
@@ -127,6 +118,7 @@ def make_server_process(name, server_process_config, serverproxy_config):
127
118
timeout = server_process_config .get ('timeout' , 5 ),
128
119
absolute_url = server_process_config .get ('absolute_url' , False ),
129
120
port = server_process_config .get ('port' , 0 ),
121
+ unix_socket = server_process_config .get ('unix_socket' , None ),
130
122
mappath = server_process_config .get ('mappath' , {}),
131
123
launcher_entry = LauncherEntry (
132
124
enabled = le .get ('enabled' , True ),
@@ -154,8 +146,9 @@ class ServerProxy(Configurable):
154
146
Value should be a dictionary with the following keys:
155
147
command
156
148
An optional list of strings that should be the full command to be executed.
157
- The optional template arguments {{port}} and {{base_url}} will be substituted with the
158
- port the process should listen on and the base-url of the notebook.
149
+ The optional template arguments {{port}}, {{unix_socket}} and {{base_url}}
150
+ will be substituted with the port or Unix socket path the process should
151
+ listen on and the base-url of the notebook.
159
152
160
153
Could also be a callable. It should return a list.
161
154
@@ -165,7 +158,7 @@ class ServerProxy(Configurable):
165
158
166
159
environment
167
160
A dictionary of environment variable mappings. As with the command
168
- traitlet, {{port}} and {{base_url}} will be substituted.
161
+ traitlet, {{port}}, {{unix_socket}} and {{base_url}} will be substituted.
169
162
170
163
Could also be a callable. It should return a dictionary.
171
164
@@ -179,6 +172,13 @@ class ServerProxy(Configurable):
179
172
port
180
173
Set the port that the service will listen on. The default is to automatically select an unused port.
181
174
175
+ unix_socket
176
+ If set, the service will listen on a Unix socket instead of a TCP port.
177
+ Set to True to use a socket in a new temporary folder, or a string
178
+ path to a socket. This overrides port.
179
+
180
+ Proxying websockets over a Unix socket requires Tornado >= 6.3.
181
+
182
182
mappath
183
183
Map request paths to proxied paths.
184
184
Either a dictionary of request paths to proxied paths,
@@ -210,7 +210,7 @@ class ServerProxy(Configurable):
210
210
211
211
request_headers_override
212
212
A dictionary of additional HTTP headers for the proxy request. As with
213
- the command traitlet, {{port}} and {{base_url}} will be substituted.
213
+ the command traitlet, {{port}}, {{unix_socket}} and {{base_url}} will be substituted.
214
214
215
215
rewrite_response
216
216
An optional function to rewrite the response for the given service.
0 commit comments