From 17c6af1fcfbcda8beca4cbafc4415a573de6dab7 Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Fri, 6 Dec 2013 15:42:53 -0800 Subject: [PATCH] Add MIME types to nbconvert exporters --- IPython/html/nbconvert/handlers.py | 13 ++++++++++++- IPython/html/nbconvert/tests/test_nbconvert_api.py | 10 +++++++--- IPython/nbconvert/exporters/python.py | 3 +++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/IPython/html/nbconvert/handlers.py b/IPython/html/nbconvert/handlers.py index 1460505b2..f173209e5 100644 --- a/IPython/html/nbconvert/handlers.py +++ b/IPython/html/nbconvert/handlers.py @@ -28,11 +28,17 @@ class NbconvertFileHandler(IPythonHandler): info = os.stat(os_path) self.set_header('Last-Modified', tz.utcfromtimestamp(info.st_mtime)) + + # Force download if requested if self.get_argument('download', 'false').lower() == 'true': filename = os.path.splitext(name)[0] + '.' + exporter.file_extension self.set_header('Content-Disposition', 'attachment; filename="%s"' % filename) + # MIME type + if exporter.mime_type: + self.set_header('Content-Type', '%s; charset=utf-8' % exporter.mime_type) + output, resources = exporter.from_filename(os_path) # TODO: If there are resources, combine them into a zip file @@ -49,8 +55,13 @@ class NbconvertPostHandler(IPythonHandler): model = self.get_json_body() nbnode = to_notebook_json(model['content']) - output, resources = exporter.from_notebook_node(nbnode) + # MIME type + if exporter.mime_type: + self.set_header('Content-Type', '%s; charset=utf-8' % exporter.mime_type) + + output, resources = exporter.from_notebook_node(nbnode) + # TODO: If there are resources, combine them into a zip file assert not has_resource_files(resources) diff --git a/IPython/html/nbconvert/tests/test_nbconvert_api.py b/IPython/html/nbconvert/tests/test_nbconvert_api.py index d57d2d05c..3edf6fb09 100644 --- a/IPython/html/nbconvert/tests/test_nbconvert_api.py +++ b/IPython/html/nbconvert/tests/test_nbconvert_api.py @@ -61,10 +61,12 @@ class APITest(NotebookTestBase): def test_from_file(self): r = self.nbconvert_api.from_file('html', 'foo', 'testnb.ipynb') self.assertEqual(r.status_code, 200) + self.assertIn(u'text/html', r.headers['Content-Type']) self.assertIn(u'Created by test', r.text) self.assertIn(u'print', r.text) - + r = self.nbconvert_api.from_file('python', 'foo', 'testnb.ipynb') + self.assertIn(u'text/x-python', r.headers['Content-Type']) self.assertIn(u'print(2*6)', r.text) def test_from_file_404(self): @@ -74,8 +76,8 @@ class APITest(NotebookTestBase): def test_from_file_download(self): r = self.nbconvert_api.from_file('python', 'foo', 'testnb.ipynb', download=True) content_disposition = r.headers['Content-Disposition'] - assert 'attachment' in content_disposition - assert 'testnb.py' in content_disposition + self.assertIn('attachment', content_disposition) + self.assertIn('testnb.py', content_disposition) def test_from_post(self): nbmodel_url = url_path_join(self.base_url(), 'api/notebooks/foo/testnb.ipynb') @@ -83,8 +85,10 @@ class APITest(NotebookTestBase): r = self.nbconvert_api.from_post(format='html', nbmodel=nbmodel) self.assertEqual(r.status_code, 200) + self.assertIn(u'text/html', r.headers['Content-Type']) self.assertIn(u'Created by test', r.text) self.assertIn(u'print', r.text) r = self.nbconvert_api.from_post(format='python', nbmodel=nbmodel) + self.assertIn(u'text/x-python', r.headers['Content-Type']) self.assertIn(u'print(2*6)', r.text) \ No newline at end of file diff --git a/IPython/nbconvert/exporters/python.py b/IPython/nbconvert/exporters/python.py index 1d13bc3e7..d618cd735 100644 --- a/IPython/nbconvert/exporters/python.py +++ b/IPython/nbconvert/exporters/python.py @@ -32,3 +32,6 @@ class PythonExporter(TemplateExporter): def _raw_mimetype_default(self): return 'application/x-python' + mime_type = Unicode('text/x-python', config=True, + help="MIME type of the result file, for HTTP response headers." + )