diff --git a/IPython/html/nbconvert/handlers.py b/IPython/html/nbconvert/handlers.py
index 1460505..f173209 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 d57d2d0..3edf6fb 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/exporter.py b/IPython/nbconvert/exporters/exporter.py
index 3a594d0..c7c60d0 100644
--- a/IPython/nbconvert/exporters/exporter.py
+++ b/IPython/nbconvert/exporters/exporter.py
@@ -53,6 +53,10 @@ class Exporter(LoggingConfigurable):
help="Extension of the file that should be written to disk"
)
+ mime_type = Unicode('', config=True,
+ help="MIME type of the result file, for HTTP response headers."
+ )
+
#Configurability, allows the user to easily add filters and preprocessors.
preprocessors = List(config=True,
help="""List of preprocessors, by name or namespace, to enable.""")
diff --git a/IPython/nbconvert/exporters/html.py b/IPython/nbconvert/exporters/html.py
index bb63397..3a9147c 100644
--- a/IPython/nbconvert/exporters/html.py
+++ b/IPython/nbconvert/exporters/html.py
@@ -36,6 +36,10 @@ class HTMLExporter(TemplateExporter):
help="Extension of the file that should be written to disk"
)
+ mime_type = Unicode('text/html', config=True,
+ help="MIME type of the result file, for HTTP response headers."
+ )
+
default_template = Unicode('full', config=True, help="""Flavor of the data
format to use. I.E. 'full' or 'basic'""")
diff --git a/IPython/nbconvert/exporters/latex.py b/IPython/nbconvert/exporters/latex.py
index a095262..369dcf5 100644
--- a/IPython/nbconvert/exporters/latex.py
+++ b/IPython/nbconvert/exporters/latex.py
@@ -40,6 +40,10 @@ class LatexExporter(TemplateExporter):
'tex', config=True,
help="Extension of the file that should be written to disk")
+ mime_type = Unicode('application/x-tex', config=True,
+ help="MIME type of the result file, for HTTP response headers."
+ )
+
default_template = Unicode('article', config=True, help="""Template of the
data format to use. I.E. 'article' or 'report'""")
diff --git a/IPython/nbconvert/exporters/markdown.py b/IPython/nbconvert/exporters/markdown.py
index fb38539..da4900b 100644
--- a/IPython/nbconvert/exporters/markdown.py
+++ b/IPython/nbconvert/exporters/markdown.py
@@ -36,6 +36,10 @@ class MarkdownExporter(TemplateExporter):
def _raw_mimetypes_default(self):
return ['text/markdown', 'text/html']
+ mime_type = Unicode('text/x-markdown', config=True,
+ help="MIME type of the result file, for HTTP response headers."
+ )
+
@property
def default_config(self):
c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
diff --git a/IPython/nbconvert/exporters/python.py b/IPython/nbconvert/exporters/python.py
index 1d13bc3..d618cd7 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."
+ )
diff --git a/IPython/nbconvert/exporters/rst.py b/IPython/nbconvert/exporters/rst.py
index 22dfc82..34b9eca 100644
--- a/IPython/nbconvert/exporters/rst.py
+++ b/IPython/nbconvert/exporters/rst.py
@@ -32,7 +32,11 @@ class RSTExporter(TemplateExporter):
def _raw_mimetype_default(self):
return 'text/restructuredtext'
-
+
+ mime_type = Unicode('text/x-rst', config=True,
+ help="MIME type of the result file, for HTTP response headers."
+ )
+
@property
def default_config(self):
c = Config({'ExtractOutputPreprocessor':{'enabled':True}})
diff --git a/IPython/nbconvert/exporters/slides.py b/IPython/nbconvert/exporters/slides.py
index 6ecb5a9..7f8ab46 100644
--- a/IPython/nbconvert/exporters/slides.py
+++ b/IPython/nbconvert/exporters/slides.py
@@ -31,6 +31,10 @@ class SlidesExporter(HTMLExporter):
help="Extension of the file that should be written to disk"
)
+ mime_type = Unicode('text/html', config=True,
+ help="MIME type of the result file, for HTTP response headers."
+ )
+
default_template = Unicode('reveal', config=True, help="""Template of the
data format to use. I.E. 'reveal'""")