diff --git a/IPython/html/nbconvert/handlers.py b/IPython/html/nbconvert/handlers.py
new file mode 100644
index 000000000..476acfeca
--- /dev/null
+++ b/IPython/html/nbconvert/handlers.py
@@ -0,0 +1,68 @@
+import os
+
+from tornado import web
+
+from ..base.handlers import IPythonHandler
+from IPython.nbformat.current import to_notebook_json
+from IPython.nbconvert.exporters.export import exporter_map
+from IPython.utils import tz
+
+
+def has_resource_files(resources):
+ output_files_dir = resources.get('output_files_dir', "")
+ return bool(os.path.isdir(output_files_dir) and \
+ os.listdir(output_files_dir))
+
+class NbconvertFileHandler(IPythonHandler):
+
+ SUPPORTED_METHODS = ('GET',)
+
+ @web.authenticated
+ def get(self, format, path='', name=None):
+ exporter = exporter_map[format]()
+
+ path = path.strip('/')
+ os_path = self.notebook_manager.get_os_path(name, path)
+ if not os.path.isfile(os_path):
+ raise web.HTTPError(404, u'Notebook does not exist: %s' % name)
+
+ info = os.stat(os_path)
+ self.set_header('Last-Modified', tz.utcfromtimestamp(info.st_mtime))
+
+ output, resources = exporter.from_filename(os_path)
+
+ # TODO: If there are resources, combine them into a zip file
+ assert not has_resource_files(resources)
+
+ self.finish(output)
+
+class NbconvertPostHandler(IPythonHandler):
+ SUPPORTED_METHODS = ('POST',)
+
+ @web.authenticated
+ def post(self, format):
+ exporter = exporter_map[format]()
+
+ model = self.get_json_body()
+ nbnode = to_notebook_json(model['content'])
+ output, resources = exporter.from_notebook_node(nbnode)
+
+ # TODO: If there are resources, combine them into a zip file
+ assert not has_resource_files(resources)
+
+ self.finish(output)
+
+#-----------------------------------------------------------------------------
+# URL to handler mappings
+#-----------------------------------------------------------------------------
+
+_format_regex = r"(?P\w+)"
+_path_regex = r"(?P(?:/.*)*)"
+_notebook_name_regex = r"(?P[^/]+\.ipynb)"
+_notebook_path_regex = "%s/%s" % (_path_regex, _notebook_name_regex)
+
+default_handlers = [
+ (r"/nbconvert/%s%s" % (_format_regex, _notebook_path_regex),
+ NbconvertFileHandler),
+ (r"/nbconvert/%s" % _format_regex, NbconvertPostHandler),
+]
\ No newline at end of file
diff --git a/IPython/html/notebookapp.py b/IPython/html/notebookapp.py
index 5c6850001..c49c8eb4d 100644
--- a/IPython/html/notebookapp.py
+++ b/IPython/html/notebookapp.py
@@ -192,6 +192,7 @@ class NotebookWebApplication(web.Application):
handlers.extend(load_handlers('auth.login'))
handlers.extend(load_handlers('auth.logout'))
handlers.extend(load_handlers('notebook.handlers'))
+ handlers.extend(load_handlers('nbconvert.handlers'))
handlers.extend(load_handlers('services.kernels.handlers'))
handlers.extend(load_handlers('services.notebooks.handlers'))
handlers.extend(load_handlers('services.clusters.handlers'))
diff --git a/IPython/html/services/notebooks/filenbmanager.py b/IPython/html/services/notebooks/filenbmanager.py
index 3ae54ed6a..749892fbc 100644
--- a/IPython/html/services/notebooks/filenbmanager.py
+++ b/IPython/html/services/notebooks/filenbmanager.py
@@ -178,7 +178,7 @@ class FileNotebookManager(NotebookManager):
return notebooks
def get_notebook_model(self, name, path='', content=True):
- """ Takes a path and name for a notebook and returns it's model
+ """ Takes a path and name for a notebook and returns its model
Parameters
----------