1- """Client to test bookstore endpoints from within a notebook.
2-
3-
4- TODO: (Clarify) We want to test our bookstore endpoints, but it's no fun having
5- to do this in an insecure fashion. Better would be to have some security in
6- place.
7-
8- Example
9- -------
10-
11- [{'base_url': '/',
12- 'hostname': 'localhost',
13- 'notebook_dir': '/Users/mpacer/jupyter/eg_notebooks',
14- 'password': False,
15- 'pid': 96033,
16- 'port': 8888,
17- 'secure': False,
18- 'token': '',
19- 'url': 'http://localhost:8888/'}]
1+ """Client for accessing notebook server endpoints from within a notebook.
202"""
213import json
224import os
@@ -42,6 +24,21 @@ class LiveNotebookRecord(NamedTuple):
4224
4325 This is a record of an object returned by
4426 `notebook.notebookapp.list_running_servers()`.
27+
28+ Example
29+ -------
30+ ::
31+
32+ [{'base_url': '/',
33+ 'hostname': 'localhost',
34+ 'notebook_dir': '/Users/mpacer/jupyter/eg_notebooks',
35+ 'password': False,
36+ 'pid': 96033,
37+ 'port': 8888,
38+ 'secure': False,
39+ 'token': '',
40+ 'url': 'http://localhost:8888/'}]
41+
4542 """
4643
4744 base_url : str
@@ -56,11 +53,27 @@ class LiveNotebookRecord(NamedTuple):
5653
5754
5855class KernelInfo :
59- # id: str # 'f92b7c8b-0858-4d10-903c-b0631540fb36',
60- # name: str # 'dev',
61- # last_activity: str #'2019-03-14T23:38:08.137987Z',
62- # execution_state: str #'idle',
63- # connections: int # 0
56+ """Representation of kernel info returned by the notebook's /api/kernel endpoint.
57+
58+ Attributes
59+ ----------
60+ id: str
61+ name: str
62+ last_activity: str
63+ execution_state: str
64+ connections: int
65+
66+ Example
67+ -------
68+ ::
69+
70+ {id: 'f92b7c8b-0858-4d10-903c-b0631540fb36',
71+ name: 'dev',
72+ last_activity: '2019-03-14T23:38:08.137987Z',
73+ execution_state: 'idle',
74+ connections: 0}
75+ """
76+
6477 def __init__ (self , * args , id , name , last_activity , execution_state , connections ):
6578 self .model = {
6679 "id" : id ,
@@ -92,13 +105,35 @@ def __eq__(self, other):
92105 return False
93106
94107
95- class NotebookSession : # (NamedTuple):
96- # id: str #'68d9c58f-c57d-4133-8b41-5ec2731b268d',
97- # path: str #'Untitled38.ipynb',
98- # name: str #'',
99- # type: str #'notebook',
100- # kernel: KernelInfo
101- # notebook: dict # deprecated API {'path': 'Untitled38.ipynb', 'name': ''}
108+ class NotebookSession :
109+ """Representation of session info returned by the notebook's /api/sessions/ endpoint.
110+
111+ Attributes
112+ ----------
113+ id: str
114+ path: str
115+ name: str
116+ type: str
117+ kernel: KernelInfo
118+ notebook: dict
119+ model: dict
120+ Record of the raw response (without converting the KernelInfo).
121+
122+ Example
123+ -------
124+ ::
125+
126+ {id: '68d9c58f-c57d-4133-8b41-5ec2731b268d',
127+ path: 'Untitled38.ipynb',
128+ name: '',
129+ type: 'notebook',
130+ kernel: KernelInfo(id='f92b7c8b-0858-4d10-903c-b0631540fb36',
131+ name='dev',
132+ last_activity='2019-03-14T23:38:08.137987Z',
133+ execution_state='idle',
134+ connections=0),
135+ notebook: {'path': 'Untitled38.ipynb', 'name': ''}}
136+ """
102137
103138 def __init__ (self , * args , path , name , type , kernel , notebook = {}, ** kwargs ):
104139 self .model = {
@@ -133,7 +168,28 @@ def __eq__(self, other):
133168
134169
135170class NotebookClient :
136- """Client used to interact with bookstore from within a running notebook UI"""
171+ """EXPERIMENTAL SUPPORT: Client used to interact with a notebook server from within a notebook.
172+
173+ Parameters
174+ ----------
175+ nb_config: dict
176+ Dictionary of info compatible with creating a LiveNotebookRecord.
177+
178+ Attributes
179+ ----------
180+ nb_config: dict
181+ Dictionary of info compatible with creating a LiveNotebookRecord.
182+ nb_record: LiveNotebookRecord
183+ LiveNotebookRecord of info for this notebook
184+ url: str
185+ url from nb_record minus final /
186+ token: str
187+ token used for authenticating requests serverside
188+ xsrf_token: str
189+ xsrf_token used in cookie for authenticating requests
190+ req_session: requests.Session
191+ Session to be reused across methods
192+ """
137193
138194 def __init__ (self , nb_config ):
139195 self .nb_config = nb_config
@@ -154,23 +210,20 @@ def setup_auth(self):
154210 self .xsrf_token = first .cookies .get ("_xsrf" , "" )
155211
156212 def setup_request_sessions (self ):
157- """ Sets up a requests.Session object for sharing headers across API requests.
158- """
213+ """ Sets up a requests.Session object for sharing headers across API requests. """
159214 self .req_session = requests .Session ()
160215 self .req_session .headers .update (self .headers )
161216
162217 @property
163218 def sessions (self ):
164- """Current notebook sessions. Reissues request on each call.
165- """
219+ """Current notebook sessions. Reissues request on each call. """
166220 return {
167221 session ['kernel' ]['id' ]: NotebookSession (** session ) for session in self .get_sessions ()
168222 }
169223
170224 @property
171225 def headers (self ):
172- """Default headers to be shared across requests.
173- """
226+ """Default headers to be shared across requests. """
174227 headers = {
175228 'Authorization' : f'token { self .token } ' ,
176229 'X-XSRFToken' : self .xsrf_token ,
@@ -180,41 +233,48 @@ def headers(self):
180233
181234 @property
182235 def sessions_endpoint (self ):
236+ """Current server's kernels API endpoint."""
183237 api_endpoint = "/api/sessions/"
184238 return f"{ self .url } { api_endpoint } "
185239
186240 def get_sessions (self ):
241+ """Requests info about current sessions from notebook server."""
187242 target_url = f"{ self .sessions_endpoint } "
188243 resp = self .req_session .get (target_url )
189244 return resp .json ()
190245
191246 @property
192247 def kernels_endpoint (self ):
248+ """Current server's kernels API endpoint."""
193249 api_endpoint = "/api/kernels/"
194250 return f"{ self .url } { api_endpoint } "
195251
196252 def get_kernels (self ):
253+ """Requests info about current kernels from notebook server."""
197254 target_url = f"{ self .kernels_endpoint } "
198255 resp = self .req_session .get (target_url )
199256 return resp .json ()
200257
201258 @property
202259 def kernels (self ):
260+ """Current notebook kernels. Reissues request on each call."""
203261 return self .get_kernels ()
204262
205263 @property
206264 def contents_endpoint (self ):
265+ """Current server's contents API endpoint."""
207266 api_endpoint = "/api/contents/"
208267 return f"{ self .url } { api_endpoint } "
209268
210269 def get_contents (self , path ):
270+ """Requests info about current contents from notebook server."""
211271 target_url = f"{ self .contents_endpoint } { path } "
212272 resp = self .req_session .get (target_url )
213273 return resp .json ()
214274
215275
216276class NotebookClientCollection :
217- """Representation of a collection of notebook clients"""
277+ """EXPERIMENTAL SUPPORT: Representation of a collection of notebook clients"""
218278
219279 # TODO: refactor from lambda to a def
220280 nb_client_gen = lambda : (NotebookClient (x ) for x in list_running_servers ())
@@ -234,7 +294,7 @@ def current_server(cls):
234294
235295
236296class CurrentNotebookClient (NotebookClient ):
237- """Represents the currently active notebook client"""
297+ """EXPERIMENTAL SUPPORT: Represents the currently active notebook client. """
238298
239299 def __init__ (self ):
240300 self .nb_client = NotebookClientCollection .current_server ()
@@ -243,8 +303,10 @@ def __init__(self):
243303
244304 @property
245305 def connection_file (self ):
306+ """Connection file for connecting to current notebook's kernel."""
246307 return get_ipython ().parent .parent .connection_file
247308
248309 @property
249310 def kernel_id (self ):
311+ """Kernel id for identifying which notebook is currently being used by this session."""
250312 return extract_kernel_id (self .connection_file )
0 commit comments