Skip to content

Commit 0fd4540

Browse files
committed
Refactor: use HTML-to-PDF (WeasyPrint) for fast notebook conversion, remove XeLaTeX dependency
1 parent 6d22bb6 commit 0fd4540

2 files changed

Lines changed: 13 additions & 18 deletions

File tree

app.py

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import os
22
from flask import Flask, request, send_file, jsonify
33
from flask_cors import CORS
4-
from nbconvert import PDFExporter
4+
from nbconvert import HTMLExporter
55
from nbconvert.preprocessors import Preprocessor
6+
from weasyprint import HTML
67
import io
78
import tempfile
89
from werkzeug.utils import secure_filename
@@ -53,52 +54,45 @@ def serve_sitemap():
5354

5455
@app.route('/api/convert', methods=['POST'])
5556
def convert_ipynb_to_pdf():
56-
"""Convert uploaded IPYNB file to PDF."""
57+
"""Convert uploaded IPYNB file to PDF using HTML export and WeasyPrint for speed."""
5758
try:
58-
# Check if file is in request
5959
if 'file' not in request.files:
6060
return jsonify({'error': 'No file provided'}), 400
6161

6262
file = request.files['file']
63-
64-
# Check if file is selected
6563
if file.filename == '':
6664
return jsonify({'error': 'No file selected'}), 400
67-
68-
# Check file extension
6965
if not allowed_file(file.filename):
7066
return jsonify({'error': 'Only .ipynb files are allowed'}), 400
7167

72-
# Read file content
7368
filename = secure_filename(file.filename)
7469
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
7570
file.save(file_path)
7671

77-
# Convert to PDF
7872
try:
79-
pdf_exporter = PDFExporter()
80-
(pdf_output, _) = pdf_exporter.from_filename(file_path)
73+
# Export notebook to HTML
74+
html_exporter = HTMLExporter()
75+
(body, resources) = html_exporter.from_filename(file_path)
76+
77+
# Convert HTML to PDF using WeasyPrint
78+
pdf_io = io.BytesIO()
79+
HTML(string=body).write_pdf(pdf_io)
80+
pdf_io.seek(0)
81+
pdf_name = filename.rsplit('.', 1)[0] + '.pdf'
8182

8283
# Clean up temp file
8384
os.remove(file_path)
8485

85-
# Create response with PDF
86-
pdf_io = io.BytesIO(pdf_output)
87-
pdf_name = filename.rsplit('.', 1)[0] + '.pdf'
88-
8986
return send_file(
9087
pdf_io,
9188
mimetype='application/pdf',
9289
as_attachment=True,
9390
download_name=pdf_name
9491
)
95-
9692
except Exception as convert_error:
97-
# Clean up temp file
9893
if os.path.exists(file_path):
9994
os.remove(file_path)
10095
return jsonify({'error': f'Conversion failed: {str(convert_error)}'}), 500
101-
10296
except Exception as e:
10397
return jsonify({'error': str(e)}), 500
10498

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Flask==2.3.3
22
Flask-CORS==4.0.0
33
nbconvert==7.10.0
4+
weasyprint
45
jupyter==1.0.0
56
python-dotenv==1.0.0
67
Werkzeug==2.3.7

0 commit comments

Comments
 (0)