def html_export(nbin, htmlout, imgfmt='b64', slides=False): """ Does a complete HTML export, including cell attachments. Function heavily inpired by the code in the github issue: https://github.com/jupyter/nbconvert/issues/699 by Søren Fuglede Jørgensen and Donghyun Kwak. """ contents = nbin.read() # first convert it the normal way notebook = nbformat.reads(contents, as_version=4) if slides: exporter = nbconvert.SlidesExporter() else: exporter = nbconvert.HTMLExporter() #exporter = Exp() exporter = nbconvert.HTMLExporter() #exporter.template_file = '/home/grochmal/programs/my/daml/basic.tpl' exporter.template_file = '/home/grochmal/programs/my/daml/bookhtml.tpl' print('PATH', Exp.default_template_path) resources = { 'title': 'NB Title', #'mathjax': 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS_HTML' 'mathjax': 'MathJax-2.7.5/MathJax.js?config=TeX-AMS_HTML', 'main_style': 'bookhtml.css', 'extra_style': None, } body, _ = exporter.from_notebook_node(notebook, resources=resources) # save a mapping of all attachments images = [] for cell in notebook['cells']: if 'attachments' in cell: atts = cell['attachments'] for filename, att in atts.items(): for mime, base64 in att.items(): images.append({ 'att_name': f'attachment:{filename}', 'name': f'{filename}', 'href': f'{filename}', 'b64': f'data:{mime};base64,{base64}', }) # fix the HTML by hand for i in images: att = i['att_name'] data = i[imgfmt] body = body.replace(f'src="{att}"', f'src="{data}"', 1) short = data[:60] if len(data) > 60: short += '...' click.echo(f'Image at: src="{short}"') click.echo('%s %s' % (dir(body), type(body))) click.echo(body[:200]) htmlout.write(body)
def _genNBViewer(self, filename, account='MLGeophysics', repo='community'): # check that the .ipynb is in the filename ext = os.path.splitext(filename)[1] if ext is '': fname = fname + '.ipynb' # get the directory of this file and clean that from the directory of # the notebook file so it has a relative file path under the repo # TODO: this is complicated and I aint spending the time to figure it out tonight # Make the filename url firnely # filename = quote(filename) # return the div iframe pointing to nbviewer # return [r''' # <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; height: auto;"> # <iframe src="http://nbviewer.jupyter.org/github/{}/{}/blob/master/{}" frameborder="0" allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe> # </div> # '''.format(account, repo, filename)] import nbconvert #return [nbconvert.HTMLExporter().from_filename(filename)[0]] return [ r''' <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; height: 50%;"> {} </div> '''.format(nbconvert.HTMLExporter().from_filename(filename)[0].split('</head>') [1]) ]
def html_export(nbin, htmlout, slides=False): """ Does a complete HTML export, including cell attachments. Function heavily inpired by the code in the github issue: https://github.com/jupyter/nbconvert/issues/699 by Søren Fuglede Jørgensen and Donghyun Kwak. """ contents = nbin.read() # first convert it the normal way notebook = nbformat.reads(contents, as_version=4) if slides: exporter = nbconvert.SlidesExporter() else: exporter = nbconvert.HTMLExporter() body, _ = exporter.from_notebook_node(notebook) # save a mapping of all attachments images = [] for cell in notebook['cells']: if 'attachments' in cell: atts = cell['attachments'] for filename, att in atts.items(): for mime, base64 in att.items(): images.append( {'name': f'attachment:{filename}', 'data': f'data:{mime};base64,{base64}'}) # fix the HTML by hand for i in images: src = i['name'] base64 = i['data'] body = body.replace(f'src="{src}"', f'src="{base64}"', 1) htmlout.write(body)
def get_notebook_html(filepath_notebook, execute=True): """Store iframes from a notebook in html files, remove them when done.""" if execute: subprocess.run([ 'jupyter', 'nbconvert', '--to', 'notebook', '--execute', filepath_notebook, ]) filepath_notebook = filepath_notebook.replace('.ipynb', '.nbconvert.ipynb') html_exporter = nbconvert.HTMLExporter() html_exporter.template_file = 'basic' body, _ = html_exporter.from_filename(filepath_notebook) parser = IframeParser() parser.feed(body) iframes = parser.iframes for i, iframe in enumerate(iframes): filepath_html = filepath_notebook.replace('.ipynb', '.{}.html'.format(i)) filepath_html = os.path.abspath(filepath_html) with open(filepath_html, 'wb') as f: f.write(iframe) try: yield filepath_html finally: os.remove(filepath_html)
def runtest(self): self._skip() with io.open(self.name,encoding='utf8') as nb: notebook = nbformat.read(nb, as_version=4) # TODO: which kernel? run in pytest's or use new one (make it option) _timeout = self.parent.parent.config.getini('nbsmoke_cell_timeout') kwargs = dict(timeout=int(_timeout) if _timeout!='' else 300, allow_errors=False, # or sys.version_info[1] ? kernel_name='python') ep = ExecutePreprocessor(**kwargs) with cwd(os.path.dirname(self.name)): # jupyter notebook always does this, right? ep.preprocess(notebook,{}) # TODO: clean up this option handling if self.parent.parent.config.option.store_html != '': he = nbconvert.HTMLExporter() # Backwards incompatible change in nbconvert 6 in template file names if nbconvert.version_info[0] < 6: he.template_file = 'basic' else: he.template_file = 'classic/base.html.j2' # could maybe use this for chance of testing the html? but not the aim of this project #he.template_file = 'basic' html, resources = he.from_notebook_node(notebook) with io.open(os.path.join(self.parent.parent.config.option.store_html,os.path.basename(self.name)+'.html'),'w',encoding='utf8') as f: f.write(html)
def main(targets=list(), outdir='', exclude='', version=nbformat.NO_CONVERT): """The actual function that performs notebook conversion.""" print(exclude) print(version) # argument checking if os.path.exists(outdir): assert(os.path.isdir(outdir)) else: os.makedirs(outdir, exist_ok=True) html_exporter = nbconvert.HTMLExporter() html_exporter.template_file = 'basic' # Setup and configure file writer file_writer = nbconvert.writers.FilesWriter() file_writer.build_directory = outdir for i in targets: paths = glob.glob(i) for path in paths: assert(os.path.exists(path) and os.path.isfile(path)) filename = os.path.basename(path) basename = filename[:filename.rfind('.')] if glob.fnmatch.fnmatch(filename, exclude): continue # Read the notebook and export as HTML print("Converting:", filename) notebook = nbformat.read(path, version) body, resources = html_exporter.from_notebook_node(notebook) # Write the HTML file_writer.write(body, resources, notebook_name=basename)
def notebook2HTML(filename): ''' Converts notebook file to a html string ''' html_exp = nc.HTMLExporter() html, resources = html_exp.from_filename(filename) # SED rules: # Replace '../folders' in links with './folders' # for folders images, data, code html = html.replace('../images', './images') html = html.replace('../data', './data') html = html.replace('../code', './code') # Replace '.ipynb' in links with '.html' html = html.replace('.ipynb', '.html') # Horrible hack because <code> environment doesn't seem to work with CSS sheet # For plaintext blocks html = html.replace('<pre><code>', '<pre><code style="">') # For inline highlighting html = html.replace( '<code>', '<code style="background-color:#F7F7F7;border:1px solid #CFCFCF">') # Another hack since \n is converted to [space] in links html = html.replace('%0A"', '%20"') # Add the favicon html = html.replace( '<head><meta charset="utf-8" />', '<head><meta charset="utf-8" />\n<link rel="icon" type="image/png" href="css/favicon.png"/>' ) return html
def run( self, path: str = None, parameters: dict = None, output_format: str = None, ) -> str: """ Run a Jupyter notebook and output as HTML or JSON Args: - path (string, optional): path to fetch the notebook from; can also be a cloud storage path - parameters (dict, optional): dictionary of parameters to use for the notebook - output_format (str, optional): Notebook output format. Currently supported: json, html (default: json) """ nb: nbformat.NotebookNode = pm.execute_notebook( path, "-", parameters=parameters, kernel_name=self.kernel_name) if output_format == "json": return nbformat.writes(nb) if output_format == "html": html_exporter = nbconvert.HTMLExporter() (body, resources) = html_exporter.from_notebook_node(nb) return body raise NotImplementedError("Notebook output %s not supported", output_format)
def run_notebook_test(notebook_path, parameters=None): # Ensure workload identity is ready. # TODO(jlewi): Need to skip this when not running on GCP. gcp_util.get_gcp_credentials() output_path = execute_notebook(notebook_path, parameters=parameters) logging.info(f"Reading notebook {output_path}") with open(output_path, "r") as hf: actual_output = hf.read() logging.info("Converting notebook to html") nb = nbformat.reads(actual_output, as_version=4) html_exporter = nbconvert.HTMLExporter() (html_output, _) = html_exporter.from_notebook_node(nb) gcs_path = os.getenv("OUTPUT_GCS") # Per https://github.com/kubeflow/testing/issues/715 # we need to add some uniquness to the name since different test runs # will use the same OUTPUT_GCS directory subdir = datetime.datetime.now().strftime("%Y%m%d-%H%M") subdir = subdir + "-" + uuid.uuid4().hex[0:4] gcs_path = os.path.join(gcs_path, subdir, "notebook.html") logging.info(f"Uploading notebook to {gcs_path}") _upload_notebook_html(html_output, gcs_path)
def notebook_details(request, notebook_id): notebook = SharedNotebook.objects.get(pk=notebook_id) if notebook.master_notebook: other_notebooks = notebook.master_notebook.sharednotebook_set.exclude( pk=notebook.id) else: other_notebooks = notebook.sharednotebook_set.exclude( pk=notebook.id) liked = False if request.user.is_authenticated: if notebook.notebooklike_set.filter(oh_member=request.user.oh_member): liked = True format_notebook = nbformat.reads(notebook.notebook_content, as_version=nbformat.NO_CONVERT) html_exporter = nbconvert.HTMLExporter() html_exporter.template_file = 'basic' (body, resources) = html_exporter.from_notebook_node(format_notebook) # below removes input code of code cells html_exporter.exclude_input = True (no_code_body, resources) = html_exporter.from_notebook_node( format_notebook) return render(request, 'main/notebook_details.html', {'notebook': notebook, 'other_notebooks': other_notebooks, 'notebook_preview': body, 'codeless_notebook_preview': no_code_body, 'liked': liked})
def render(cls, request, document): format_notebook = nbformat.reads(document.document_content, as_version=nbformat.NO_CONVERT) html_exporter = nbconvert.HTMLExporter() html_exporter.template_file = 'basic' # below also removes output of code # html_exporter.exclude_code_cell = True (body, resources) = html_exporter.from_notebook_node(format_notebook) return body
def render_notebook(request, notebook_id): notebook = SharedNotebook.objects.get(pk=notebook_id) format_notebook = nbformat.reads(notebook.notebook_content, as_version=nbformat.NO_CONVERT) html_exporter = nbconvert.HTMLExporter() html_exporter.template_file = 'basic' (body, resources) = html_exporter.from_notebook_node(format_notebook) return HttpResponse(body)
def export_as_html(filename): html_exporter = nbconvert.HTMLExporter() # Backwards incompatible change in nbconvert 6 in template file names if nbconvert.version_info[0] < 6: html_exporter.template_file = 'basic' else: html_exporter.template_file = 'classic/base.html.j2' body, _ = html_exporter.from_filename(filename) return body
async def notebook_to_pdf(notebook_model, pdf_path): """ Convert given notebook model to PDF """ exporter = nbconvert.HTMLExporter(config={}) exported_html, _ = exporter.from_notebook_node(notebook_model) with tempfile.NamedTemporaryFile(suffix='.html') as f: f.write(exported_html.encode()) f.flush() await html_to_pdf(f.name, pdf_path)
async def notebook_to_pdf(notebook, pdf_path, config=None, resources=None, **kwargs): """Convert a notebook to PDF""" if config is None: config = {} exporter = nbconvert.HTMLExporter(config=config) exported_html, _ = exporter.from_notebook_node( notebook, resources=resources, **kwargs ) with tempfile.NamedTemporaryFile(suffix=".html") as f: f.write(exported_html.encode()) f.flush() await html_to_pdf(f.name, pdf_path)
def run_notebook_test(notebook_path, parameters=None): import nbformat #pylint: disable=import-error import nbconvert #pylint: disable=import-error output_path = execute_notebook(notebook_path, parameters=parameters) with open(output_path, "r") as hf: actual_output = hf.read() nb = nbformat.reads(actual_output, as_version=4) html_exporter = nbconvert.HTMLExporter() (html_output, _) = html_exporter.from_notebook_node(nb) gcs_path = os.getenv("OUTPUT_GCS") _upload_notebook_html(html_output, gcs_path)
def generate_html(base_dir, fn, conditions=None, show_details=True, include_images=True, sort_samples=True): logo_fn = Path(os.path.realpath(__file__)).parent / 'logo_v2.png' logo_URI, logo_width, logo_height = fn_to_URI(logo_fn) nb = nbf.new_notebook() documentation_cell_contents = f'''\ <a target="_blank" href="https://github.com/jeffhussmann/knock-knock" rel="nofollow"><img width={logo_width} height={logo_height} src={logo_URI} alt="knock-knock" align="left"></a> <br clear="all"> knock-knock is a tool for exploring, categorizing, and quantifying the full spectrum of sequence outcomes produced by CRISPR knock-in experiments. <a href="https://github.com/jeffhussmann/knock-knock/blob/master/docs/visualization.md#interactive-exploration-of-outcomes" target="_blank">How to use this table</a> <a href="https://github.com/jeffhussmann/knock-knock/blob/master/docs/visualization.md" target="_blank">How to interpret read diagrams</a> ''' table_cell_contents = f'''\ import knock_knock.table conditions = {conditions} knock_knock.table.make_table('{base_dir}', conditions, show_details={show_details}, include_images={include_images}, sort_samples={sort_samples}, ) ''' nb['cells'] = [ nbf.new_markdown_cell(documentation_cell_contents), nbf.new_code_cell(table_cell_contents), ] nb['metadata'] = { 'title': str(fn.name), 'include_images': include_images, } exporter = nbconvert.HTMLExporter(exclude_input=True, exclude_output_prompt=True) template_path = Path(os.path.realpath(__file__)).parent / 'modal_template.tpl' exporter.template_file = str(template_path) ep = nbconvert.preprocessors.ExecutePreprocessor(timeout=600, kernel_name='python3') ep.preprocess(nb, {}) body, resources = exporter.from_notebook_node(nb) with open(fn, 'w') as fh: fh.write(body)
def analyze_sweep(work_dir, name, implicit): prefix = 'imp' if implicit else 'exp' full_name = f'{prefix}-{name}' aname = dt.pyname(name) if implicit: from .algorithms import implicit_algos as algo_mod sfx = '-imp' else: from .algorithms import explicit_algos as algo_mod sfx = '' props = {'title': full_name} attrs = getattr(algo_mod, f'{aname}_attrs', []) _log.info('reading source notebook') nbf = nbformat.read('sweep-results/SweepAccuracy.ipynb', as_version=4) for cell in nbf.cells: lkv = cell.metadata.get('lk_var', None) if 'lk_template' in cell.metadata: tmpl = string.Template(cell.source) cell.source = tmpl.safe_substitute(props) elif lkv == 'sweep_name': _log.info('using sweep name %s', full_name) cell.source = f"sweep_name = '{full_name}'" elif lkv == 'attrs': _log.info('using attributes %s', attrs) cell.source = f"attrs = {repr(attrs)}" elif lkv == 'data_sfx': cell.source = f"data_sfx = '{sfx}'" fn = Path(f'sweep-results/sweep-{full_name}.ipynb') _log.info('writing %s', fn) nbformat.write(nbf, fspath(fn)) nbexec = nbconvert.preprocessors.ExecutePreprocessor(timeout=600, kernel_name='python3') _log.info('executing notebook %s', fn) nbexec.preprocess(nbf, {'metadata': {'path': 'work/'}}) _log.info('writing executed notebook %s', fn) nbformat.write(nbf, fspath(fn)) html_fn = fn.with_suffix('.html') _log.info('exporting html to %s', html_fn) html_e = nbconvert.HTMLExporter() html_e.template_file = 'full' body, resources = html_e.from_notebook_node(nbf) html_fn.write_text(body)
def notebook_details(request, notebook_id): notebook = SharedNotebook.objects.get(pk=notebook_id) liked = False if request.user.is_authenticated: if notebook.notebooklike_set.filter(oh_member=request.user.oh_member): liked = True format_notebook = nbformat.reads(notebook.notebook_content, as_version=nbformat.NO_CONVERT) html_exporter = nbconvert.HTMLExporter() html_exporter.template_file = 'basic' (body, resources) = html_exporter.from_notebook_node(format_notebook) return render(request, 'main/notebook_details.html', { 'notebook': notebook, 'notebook_preview': body, 'liked': liked })
def ipynb_export_html(nb): exporter = nbconvert.HTMLExporter() export, resources = exporter.from_notebook_node(nb) # Strip things from export soup = BeautifulSoup(export, 'html.parser') soup.find('meta').decompose() # remove meta soup.find('title').decompose() # remove title soup.find( 'script').decompose() # remove first 2 scripts (require.js and jquery) soup.find('script').decompose() # soup.find('style').decompose() # remove first style (bootstrap) soup.find('link').decompose() # remove link to custom stylesheet nb_container = soup.select('#notebook-container')[0] nb_container['class'] = '' nb_container['id'] = '' return str(soup)
def run_notebook_test(notebook_path, parameters=None): # Ensure workload identity is ready. # TODO(jlewi): Need to skip this when not running on GCP. gcp_util.get_gcp_credentials() output_path = execute_notebook(notebook_path, parameters=parameters) logging.info(f"Reading notebook {output_path}") with open(output_path, "r") as hf: actual_output = hf.read() logging.info("Converting notebook to html") nb = nbformat.reads(actual_output, as_version=4) html_exporter = nbconvert.HTMLExporter() (html_output, _) = html_exporter.from_notebook_node(nb) gcs_path = os.getenv("OUTPUT_GCS") logging.info(f"Uploading notebook to {gcs_path}") _upload_notebook_html(html_output, gcs_path)
def convert_notebook(cls, nb_path, dest, debug=False, **kwargs): assert shutil.which("wkhtmltopdf") is not None, "Cannot export via HTML without wkhtmltopdf" options = cls.default_options.copy() options.update(kwargs) nb = cls.load_notebook(nb_path, filtering=options["filtering"], pagebreaks=options["pagebreaks"]) if NBCONVERT_6: nbconvert.TemplateExporter.extra_template_basedirs = [TEMPLATE_DIR] orig_template_name = nbconvert.TemplateExporter.template_name nbconvert.TemplateExporter.template_name = options["template"] exporter = nbconvert.HTMLExporter() if not NBCONVERT_6: exporter.template_file = os.path.join(TEMPLATE_DIR, options["template"] + ".tpl") if options["save_html"]: html, _ = export(exporter, nb) html_path = os.path.splitext(dest)[0] + ".html" with open(html_path, "wb+") as f: f.write(html.encode("utf-8")) merger = PdfFileMerger() for subnb in notebook_pdf_generator(nb): html, _ = export(exporter, subnb) pdfkit_options = { 'enable-local-file-access': None, 'quiet': '', 'print-media-type': '', 'javascript-delay': 2000 } pdf_contents = pdfkit.from_string(html, False, options=pdfkit_options) output = BytesIO() output.write(pdf_contents) output.seek(0) merger.append(output, import_bookmarks=False) merger.write(dest) if NBCONVERT_6: nbconvert.TemplateExporter.template_name = orig_template_name
def run_notebook_test(notebook_path, expected_messages, parameters=None): output_path = execute_notebook(notebook_path, parameters=parameters) import nbformat #pylint: disable=import-error import nbconvert #pylint: disable=import-error actual_output = open(output_path, 'r').read() nb = nbformat.reads(actual_output, as_version=4) html_exporter = nbconvert.HTMLExporter() (html_output, _) = html_exporter.from_notebook_node(nb) gcs_path = os.getenv("OUTPUT_GCS") kf_util.upload_to_gcs(html_output, gcs_path) for expected_message in expected_messages: if not expected_message in actual_output: logger.error(actual_output) assert False, "Unable to find from output: " + expected_message
def get_notebook_html(filepath_notebook, execute=True): """Store iframes from a notebook in html files, remove them when done.""" if execute: subprocess.run([ 'jupyter', 'nbconvert', '--to', 'notebook', '--execute', filepath_notebook, ]) filepath_notebook = filepath_notebook.replace('.ipynb', '.nbconvert.ipynb') html_exporter = nbconvert.HTMLExporter() html_exporter.template_file = 'basic' body, _ = html_exporter.from_filename(filepath_notebook) parser = IframeParser() parser.feed(body) iframes = parser.iframes for iframe in iframes: with temp_html_filepath(iframe) as filepath_html: yield filepath_html
def post_new(request): if request.method == "POST": form = PostForm(request.POST) if form.is_valid(): post = form.save(request.user, commit=False) post.published_date = timezone.now() try: data = request.FILES['docfile'] htx = nbconvert.HTMLExporter() html = htx.from_file(data) post.docfile = html[0] except: print("no docfile") pass post.save() return redirect('post_detail', pk=post.pk) else: form = PostForm() return render(request, 'blog/post_edit.html', {'form': form})
def display_as_html(filename, html_outputfile=None): """opens the file as html in the web browser""" import nbconvert import webbrowser output = nbconvert.exporters.export(nbconvert.HTMLExporter(), filename)[0] if html_outputfile is None: import tempfile # create temporary file temp = tempfile.NamedTemporaryFile(mode="w+t", suffix=".html", delete=False) temp.write(output) temp.seek(0) webbrowser.open(temp.name) else: with open(html_outputfile, 'w+') as f: f.write(output) webbrowser.open(html_outputfile)
def convert_notebook_to_html(notebook_file, html_file): """ Function to convert a Jupyter notebook file (.ipynb) into an html file :param notebook_file: object storage client :param html_file: name of what the html output file should be :return: html_file: the converted notebook in html format """ import nbconvert import nbformat print("Converting from ipynb to html....") nb = nbformat.read(notebook_file, as_version=4) html_exporter = nbconvert.HTMLExporter() data, resources = html_exporter.from_notebook_node(nb) with open(html_file, "w") as f: f.write(data) f.close() return html_file
def _output_conv(self, obj): eol = os.linesep if self._debug: print('node: ', type(obj)) if hasattr(obj, '_repr_html_'): return obj # ._repr_html_() elif isinstance(obj, str): return (obj) elif isinstance(obj, nbformat.notebooknode.NotebookNode): html_exporter = nbconvert.HTMLExporter() #html_exporter.template_name = "basic" html_exporter.template_name = "classic" (html_output, resources) = html_exporter.from_notebook_node(obj) return HTML(html_output) elif isinstance(obj, dict): dic = {'': list(obj.keys()), ' ': list(obj.values())} return pandas.DataFrame(dic) elif isinstance(obj, (int, float)): return str(obj) elif isinstance(obj, list) and all([isinstance(el, str) for el in obj]): max_length = 2000 # performance of widget above is extremely poor if len(obj) < max_length: return str(''.join(obj)) else: return str(''.join(obj[:max_length]) + eol + ' .... file too long: skipped ....') elif isinstance(obj, list): return pandas.DataFrame(obj, columns=['list']) elif isinstance(obj, np.ndarray): return self.plot_array(obj) elif str(type(obj)).split('.')[0] == "<class 'PIL": try: data_cp = obj.copy() data_cp.thumbnail((800, 800)) except: data_cp = obj return data_cp else: return obj
def ipynb_to_html(file_path): """ Return html using nbconvert module for .ipynb's . Parameters ---------- file_path: string path to ipynb file Returns ------- boolean Whether or not this completed succesfully """ try: if os.path.exists(file_path) and '.ipynb' in file_path: my_nb_content = nbformat.reads(open(file_path, 'r', errors='ignore').read(), as_version=4) html_exporter = nbconvert.HTMLExporter() html_exporter.template_file = 'basic' (body, _) = html_exporter.from_notebook_node(my_nb_content) out_file_name = file_path.replace('.ipynb', '.html') # Extra level of catching just in case we can read # in a dir but not write -- itertools happened try: out_file = open(out_file_name, 'w') out_file.write(body) out_file.close() return True except PermissionError as exception: sys.stderr.write(str(exception)) return False else: return False except PermissionError as exception: sys.stderr.write(str(exception)) return False
def generate_preview(nb_file_path): # Obtain the file paths dir_path = os.path.dirname(nb_file_path) preview_path = os.path.join(dir_path, 'preview') # Generate the preview html_exporter = nbconvert.HTMLExporter() html_exporter.template_path = [ '.', os.path.join(os.path.dirname(os.path.abspath(__file__)), 'preview') ] html_exporter.template_file = 'genepattern' output, resources = html_exporter.from_file(nb_file_path) # Set the notebook name in the metadata # nb_name = os.path.splitext(os.path.basename(nb_file_path))[0] # resources['metadata']['name'] = nb_name # Write to disk writer = nbconvert.writers.FilesWriter() writer.write(output, resources, preview_path)