Show More
@@ -0,0 +1,95 b'' | |||||
|
1 | """Test the sessions web service API.""" | |||
|
2 | ||||
|
3 | ||||
|
4 | import os | |||
|
5 | import sys | |||
|
6 | import json | |||
|
7 | from zmq.utils import jsonapi | |||
|
8 | ||||
|
9 | import requests | |||
|
10 | ||||
|
11 | from IPython.html.tests.launchnotebook import NotebookTestBase | |||
|
12 | ||||
|
13 | ||||
|
14 | class SessionAPITest(NotebookTestBase): | |||
|
15 | """Test the sessions web service API""" | |||
|
16 | ||||
|
17 | def notebook_url(self): | |||
|
18 | return super(SessionAPITest,self).base_url() + 'api/notebooks' | |||
|
19 | ||||
|
20 | def session_url(self): | |||
|
21 | return super(SessionAPITest,self).base_url() + 'api/sessions' | |||
|
22 | ||||
|
23 | def mknb(self, name='', path='/'): | |||
|
24 | url = self.notebook_url() + path | |||
|
25 | return url, requests.post(url) | |||
|
26 | ||||
|
27 | def delnb(self, name, path='/'): | |||
|
28 | url = self.notebook_url() + path + name | |||
|
29 | r = requests.delete(url) | |||
|
30 | return r.status_code | |||
|
31 | ||||
|
32 | def test_no_sessions(self): | |||
|
33 | """Make sure there are no sessions running at the start""" | |||
|
34 | url = self.session_url() | |||
|
35 | r = requests.get(url) | |||
|
36 | self.assertEqual(r.json(), []) | |||
|
37 | ||||
|
38 | def test_session_root_handler(self): | |||
|
39 | # POST a session | |||
|
40 | url, nb = self.mknb() | |||
|
41 | notebook = nb.json() | |||
|
42 | param = {'notebook_path': notebook['path'] + notebook['name']} | |||
|
43 | r = requests.post(self.session_url(), params=param) | |||
|
44 | data = r.json() | |||
|
45 | assert isinstance(data, dict) | |||
|
46 | assert data.has_key('name') | |||
|
47 | self.assertEqual(data['name'], notebook['name']) | |||
|
48 | ||||
|
49 | # GET sessions | |||
|
50 | r = requests.get(self.session_url()) | |||
|
51 | assert isinstance(r.json(), list) | |||
|
52 | assert isinstance(r.json()[0], dict) | |||
|
53 | self.assertEqual(r.json()[0]['id'], data['id']) | |||
|
54 | ||||
|
55 | # Clean up | |||
|
56 | self.delnb('Untitled0.ipynb') | |||
|
57 | sess_url = self.session_url() +'/'+data['id'] | |||
|
58 | r = requests.delete(sess_url) | |||
|
59 | self.assertEqual(r.status_code, 204) | |||
|
60 | ||||
|
61 | def test_session_handler(self): | |||
|
62 | # Create a session | |||
|
63 | url, nb = self.mknb() | |||
|
64 | notebook = nb.json() | |||
|
65 | param = {'notebook_path': notebook['path'] + notebook['name']} | |||
|
66 | r = requests.post(self.session_url(), params=param) | |||
|
67 | session = r.json() | |||
|
68 | ||||
|
69 | # GET a session | |||
|
70 | sess_url = self.session_url() + '/' + session['id'] | |||
|
71 | r = requests.get(sess_url) | |||
|
72 | assert isinstance(r.json(), dict) | |||
|
73 | self.assertEqual(r.json(), session) | |||
|
74 | ||||
|
75 | # PATCH a session | |||
|
76 | data = {'notebook_path': 'test.ipynb'} | |||
|
77 | r = requests.patch(sess_url, data=jsonapi.dumps(data)) | |||
|
78 | # Patching the notebook webservice too (just for consistency) | |||
|
79 | requests.patch(self.notebook_url() + '/Untitled0.ipynb', | |||
|
80 | data=jsonapi.dumps({'name':'test.ipynb'})) | |||
|
81 | assert isinstance(r.json(), dict) | |||
|
82 | assert r.json().has_key('name') | |||
|
83 | assert r.json().has_key('id') | |||
|
84 | self.assertEqual(r.json()['name'], 'test.ipynb') | |||
|
85 | self.assertEqual(r.json()['id'], session['id']) | |||
|
86 | ||||
|
87 | # DELETE a session | |||
|
88 | r = requests.delete(sess_url) | |||
|
89 | self.assertEqual(r.status_code, 204) | |||
|
90 | r = requests.get(self.session_url()) | |||
|
91 | assert r.json() == [] | |||
|
92 | ||||
|
93 | # Clean up | |||
|
94 | r = self.delnb('test.ipynb') | |||
|
95 | assert r == 204 No newline at end of file |
@@ -41,8 +41,7 b' class MainKernelHandler(IPythonHandler):' | |||||
41 | @web.authenticated |
|
41 | @web.authenticated | |
42 | def post(self): |
|
42 | def post(self): | |
43 | km = self.kernel_manager |
|
43 | km = self.kernel_manager | |
44 | nbm = self.notebook_manager |
|
44 | kernel_id = km.start_kernel() | |
45 | kernel_id = km.start_kernel(cwd=nbm.notebook_dir) |
|
|||
46 | model = km.kernel_model(kernel_id, self.ws_url) |
|
45 | model = km.kernel_model(kernel_id, self.ws_url) | |
47 | self.set_header('Location', '{0}kernels/{1}'.format(self.base_kernel_url, kernel_id)) |
|
46 | self.set_header('Location', '{0}kernels/{1}'.format(self.base_kernel_url, kernel_id)) | |
48 | self.finish(jsonapi.dumps(model)) |
|
47 | self.finish(jsonapi.dumps(model)) |
@@ -21,3 +21,16 b' class KernelAPITest(NotebookTestBase):' | |||||
21 | url = self.base_url() |
|
21 | url = self.base_url() | |
22 | r = requests.get(url) |
|
22 | r = requests.get(url) | |
23 | assert r.json() == [] |
|
23 | assert r.json() == [] | |
|
24 | ||||
|
25 | def test_main_kernel_handler(self): | |||
|
26 | # POST request | |||
|
27 | r = requests.post(self.base_url()) | |||
|
28 | data = r.json() | |||
|
29 | assert isinstance(data, dict) | |||
|
30 | ||||
|
31 | # GET request | |||
|
32 | r = requests.get(self.base_url()) | |||
|
33 | assert isinstance(r.json(), list) | |||
|
34 | self.assertEqual(r.json()[0], data['id']) | |||
|
35 | ||||
|
36 | No newline at end of file |
@@ -98,11 +98,11 b' class FileNotebookManager(NotebookManager):' | |||||
98 | full_path = self.get_os_path(notebook_name, notebook_path) |
|
98 | full_path = self.get_os_path(notebook_name, notebook_path) | |
99 | if change == "name": |
|
99 | if change == "name": | |
100 | new_path = self.get_os_path(data['name'], notebook_path) |
|
100 | new_path = self.get_os_path(data['name'], notebook_path) | |
101 | try: |
|
101 | if not os.path.isfile(new_path): | |
102 | os.rename(full_path, |
|
102 | os.rename(full_path, | |
103 | self.get_os_path(data['name'], notebook_path)) |
|
103 | self.get_os_path(data['name'], notebook_path)) | |
104 | notebook_name = data['name'] |
|
104 | notebook_name = data['name'] | |
105 |
e |
|
105 | else: | |
106 | raise web.HTTPError(409, u'Notebook name already exists.') |
|
106 | raise web.HTTPError(409, u'Notebook name already exists.') | |
107 | if change == "path": |
|
107 | if change == "path": | |
108 | new_path = self.get_os_path(data['name'], data['path']) |
|
108 | new_path = self.get_os_path(data['name'], data['path']) |
@@ -44,6 +44,7 b' class NotebookRootHandler(IPythonHandler):' | |||||
44 | """post creates a notebooks in the directory where the |
|
44 | """post creates a notebooks in the directory where the | |
45 | server was started""" |
|
45 | server was started""" | |
46 | nbm = self.notebook_manager |
|
46 | nbm = self.notebook_manager | |
|
47 | self.log.info(nbm.notebook_dir) | |||
47 | body = self.request.body.strip() |
|
48 | body = self.request.body.strip() | |
48 | format = self.get_argument('format', default='json') |
|
49 | format = self.get_argument('format', default='json') | |
49 | name = self.get_argument('name', default=None) |
|
50 | name = self.get_argument('name', default=None) |
@@ -1,10 +1,9 b'' | |||||
1 |
"""Test the |
|
1 | """Test the notebooks webservice API.""" | |
2 |
|
2 | |||
3 |
|
3 | |||
4 | import os |
|
4 | import os | |
5 | import sys |
|
5 | import sys | |
6 | import json |
|
6 | import json | |
7 | import urllib |
|
|||
8 | from zmq.utils import jsonapi |
|
7 | from zmq.utils import jsonapi | |
9 |
|
8 | |||
10 | import requests |
|
9 | import requests | |
@@ -14,29 +13,23 b' from IPython.html.tests.launchnotebook import NotebookTestBase' | |||||
14 | class APITest(NotebookTestBase): |
|
13 | class APITest(NotebookTestBase): | |
15 | """Test the kernels web service API""" |
|
14 | """Test the kernels web service API""" | |
16 |
|
15 | |||
17 |
def |
|
16 | def notebook_url(self): | |
18 | return super(APITest,self).base_url() |
|
17 | return super(APITest,self).base_url() + 'api/notebooks' | |
19 |
|
||||
20 | def notebooks_url(self): |
|
|||
21 | return self.base_url() + 'api/notebooks' |
|
|||
22 |
|
18 | |||
23 | def mknb(self, name='', path='/'): |
|
19 | def mknb(self, name='', path='/'): | |
24 |
url = self.notebook |
|
20 | url = self.notebook_url() + path | |
25 | return url, requests.post(url) |
|
21 | return url, requests.post(url) | |
26 |
|
22 | |||
27 | def delnb(self, name, path='/'): |
|
23 | def delnb(self, name, path='/'): | |
28 |
url = self.notebook |
|
24 | url = self.notebook_url() + path + name | |
29 | r = requests.delete(url) |
|
25 | r = requests.delete(url) | |
30 | return r.status_code |
|
26 | return r.status_code | |
31 |
|
27 | |||
32 | def test_no_notebooks(self): |
|
|||
33 | url = self.notebooks_url() |
|
|||
34 | r = requests.get(url) |
|
|||
35 | self.assertEqual(r.json(), []) |
|
|||
36 |
|
||||
37 | def test_notebook_root_handler(self): |
|
28 | def test_notebook_root_handler(self): | |
38 | # POST a notebook and test the dict thats returned. |
|
29 | # POST a notebook and test the dict thats returned. | |
39 | url, nb = self.mknb() |
|
30 | #url, nb = self.mknb() | |
|
31 | url = self.notebook_url() | |||
|
32 | nb = requests.post(url) | |||
40 | data = nb.json() |
|
33 | data = nb.json() | |
41 | assert isinstance(data, dict) |
|
34 | assert isinstance(data, dict) | |
42 | assert data.has_key("name") |
|
35 | assert data.has_key("name") | |
@@ -48,12 +41,14 b' class APITest(NotebookTestBase):' | |||||
48 | r = requests.get(url) |
|
41 | r = requests.get(url) | |
49 | assert isinstance(r.json(), list) |
|
42 | assert isinstance(r.json(), list) | |
50 | assert isinstance(r.json()[0], dict) |
|
43 | assert isinstance(r.json()[0], dict) | |
|
44 | ||||
|
45 | self.delnb('Untitled0.ipynb') | |||
51 |
|
46 | |||
52 | def test_notebook_handler(self): |
|
47 | def test_notebook_handler(self): | |
53 | # GET with a notebook name. |
|
48 | # GET with a notebook name. | |
54 | url, nb = self.mknb() |
|
49 | url, nb = self.mknb() | |
55 | data = nb.json() |
|
50 | data = nb.json() | |
56 |
url = self.notebook |
|
51 | url = self.notebook_url() + '/Untitled0.ipynb' | |
57 | r = requests.get(url) |
|
52 | r = requests.get(url) | |
58 | assert isinstance(data, dict) |
|
53 | assert isinstance(data, dict) | |
59 | self.assertEqual(r.json(), data) |
|
54 | self.assertEqual(r.json(), data) | |
@@ -65,7 +60,7 b' class APITest(NotebookTestBase):' | |||||
65 | assert isinstance(data, dict) |
|
60 | assert isinstance(data, dict) | |
66 |
|
61 | |||
67 | # make sure the patch worked. |
|
62 | # make sure the patch worked. | |
68 |
new_url = self.notebook |
|
63 | new_url = self.notebook_url() + '/test.ipynb' | |
69 | r = requests.get(new_url) |
|
64 | r = requests.get(new_url) | |
70 | assert isinstance(r.json(), dict) |
|
65 | assert isinstance(r.json(), dict) | |
71 | self.assertEqual(r.json(), data) |
|
66 | self.assertEqual(r.json(), data) | |
@@ -77,6 +72,7 b' class APITest(NotebookTestBase):' | |||||
77 | # POST notebooks to folders one and two levels down. |
|
72 | # POST notebooks to folders one and two levels down. | |
78 | os.makedirs(os.path.join(self.notebook_dir.name, 'foo')) |
|
73 | os.makedirs(os.path.join(self.notebook_dir.name, 'foo')) | |
79 | os.makedirs(os.path.join(self.notebook_dir.name, 'foo','bar')) |
|
74 | os.makedirs(os.path.join(self.notebook_dir.name, 'foo','bar')) | |
|
75 | assert os.path.isdir(os.path.join(self.notebook_dir.name, 'foo')) | |||
80 | url, nb = self.mknb(path='/foo/') |
|
76 | url, nb = self.mknb(path='/foo/') | |
81 | url2, nb2 = self.mknb(path='/foo/bar/') |
|
77 | url2, nb2 = self.mknb(path='/foo/bar/') | |
82 | data = nb.json() |
|
78 | data = nb.json() | |
@@ -112,7 +108,9 b' class APITest(NotebookTestBase):' | |||||
112 | self.assertEqual(r.status_code, 404) |
|
108 | self.assertEqual(r.status_code, 404) | |
113 |
|
109 | |||
114 | # DELETE notebooks |
|
110 | # DELETE notebooks | |
115 |
r = self.delnb('test |
|
111 | r0 = self.delnb('test.ipynb') | |
116 |
r |
|
112 | r1 = self.delnb('testfoo.ipynb', '/foo/') | |
117 | self.assertEqual(r, 204) |
|
113 | r2 = self.delnb('Untitled0.ipynb', '/foo/bar/') | |
118 |
self.assertEqual(r |
|
114 | self.assertEqual(r0, 204) | |
|
115 | self.assertEqual(r1, 204) | |||
|
116 | self.assertEqual(r2, 204) |
@@ -80,8 +80,8 b' class SessionHandler(IPythonHandler):' | |||||
80 | sm = self.session_manager |
|
80 | sm = self.session_manager | |
81 | nbm = self.notebook_manager |
|
81 | nbm = self.notebook_manager | |
82 | km = self.kernel_manager |
|
82 | km = self.kernel_manager | |
83 |
|
|
83 | data = jsonapi.loads(self.request.body) | |
84 | name, path = nbm.named_notebook_path(notebook_path) |
|
84 | name, path = nbm.named_notebook_path(data['notebook_path']) | |
85 | sm.update_session(session_id, name=name) |
|
85 | sm.update_session(session_id, name=name) | |
86 | model = sm.get_session(id=session_id) |
|
86 | model = sm.get_session(id=session_id) | |
87 | self.finish(jsonapi.dumps(model)) |
|
87 | self.finish(jsonapi.dumps(model)) | |
@@ -106,7 +106,9 b' class SessionHandler(IPythonHandler):' | |||||
106 | _session_id_regex = r"(?P<session_id>\w+-\w+-\w+-\w+-\w+)" |
|
106 | _session_id_regex = r"(?P<session_id>\w+-\w+-\w+-\w+-\w+)" | |
107 |
|
107 | |||
108 | default_handlers = [ |
|
108 | default_handlers = [ | |
|
109 | (r"api/sessions/%s/" % _session_id_regex, SessionHandler), | |||
109 | (r"api/sessions/%s" % _session_id_regex, SessionHandler), |
|
110 | (r"api/sessions/%s" % _session_id_regex, SessionHandler), | |
|
111 | (r"api/sessions/", SessionRootHandler), | |||
110 | (r"api/sessions", SessionRootHandler) |
|
112 | (r"api/sessions", SessionRootHandler) | |
111 | ] |
|
113 | ] | |
112 |
|
114 |
@@ -32,11 +32,12 b' var IPython = (function (IPython) {' | |||||
32 |
|
32 | |||
33 | Session.prototype.notebook_rename = function (notebook_path) { |
|
33 | Session.prototype.notebook_rename = function (notebook_path) { | |
34 | this.notebook_path = notebook_path; |
|
34 | this.notebook_path = notebook_path; | |
|
35 | name = {'notebook_path': notebook_path} | |||
35 | var settings = { |
|
36 | var settings = { | |
36 | processData : false, |
|
37 | processData : false, | |
37 | cache : false, |
|
38 | cache : false, | |
38 | type : "PATCH", |
|
39 | type : "PATCH", | |
39 | data: notebook_path, |
|
40 | data: JSON.stringify(name), | |
40 | dataType : "json", |
|
41 | dataType : "json", | |
41 | }; |
|
42 | }; | |
42 | var url = this._baseProjectUrl + 'api/sessions/' + this.session_id; |
|
43 | var url = this._baseProjectUrl + 'api/sessions/' + this.session_id; |
@@ -15,7 +15,7 b' class NotebookTestBase(TestCase):' | |||||
15 | and then starts the notebook server with a separate temp notebook_dir. |
|
15 | and then starts the notebook server with a separate temp notebook_dir. | |
16 | """ |
|
16 | """ | |
17 |
|
17 | |||
18 |
port = 1234 |
|
18 | port = 1234 | |
19 |
|
19 | |||
20 | def setUp(self): |
|
20 | def setUp(self): | |
21 | self.ipython_dir = TemporaryDirectory() |
|
21 | self.ipython_dir = TemporaryDirectory() | |
@@ -27,8 +27,7 b' class NotebookTestBase(TestCase):' | |||||
27 | '--no-browser', |
|
27 | '--no-browser', | |
28 | '--ipython-dir=%s' % self.ipython_dir.name, |
|
28 | '--ipython-dir=%s' % self.ipython_dir.name, | |
29 | '--notebook-dir=%s' % self.notebook_dir.name |
|
29 | '--notebook-dir=%s' % self.notebook_dir.name | |
30 | ] |
|
30 | ] | |
31 | #self.notebook = Popen(notebook_args) |
|
|||
32 | self.notebook = Popen(notebook_args, stdout=PIPE, stderr=PIPE) |
|
31 | self.notebook = Popen(notebook_args, stdout=PIPE, stderr=PIPE) | |
33 | time.sleep(3.0) |
|
32 | time.sleep(3.0) | |
34 |
|
33 | |||
@@ -36,6 +35,7 b' class NotebookTestBase(TestCase):' | |||||
36 | self.notebook.terminate() |
|
35 | self.notebook.terminate() | |
37 | self.ipython_dir.cleanup() |
|
36 | self.ipython_dir.cleanup() | |
38 | self.notebook_dir.cleanup() |
|
37 | self.notebook_dir.cleanup() | |
|
38 | time.sleep(3.0) | |||
39 |
|
39 | |||
40 | def base_url(self): |
|
40 | def base_url(self): | |
41 | return 'http://localhost:%i/' % self.port |
|
41 | return 'http://localhost:%i/' % self.port |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now