|
1 | 1 | import os |
2 | 2 | from flask import Flask, request, send_file, jsonify |
3 | 3 | from flask_cors import CORS |
4 | | -from nbconvert import PDFExporter |
| 4 | +from nbconvert import HTMLExporter |
5 | 5 | from nbconvert.preprocessors import Preprocessor |
| 6 | +from weasyprint import HTML |
6 | 7 | import io |
7 | 8 | import tempfile |
8 | 9 | from werkzeug.utils import secure_filename |
@@ -53,52 +54,45 @@ def serve_sitemap(): |
53 | 54 |
|
54 | 55 | @app.route('/api/convert', methods=['POST']) |
55 | 56 | 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.""" |
57 | 58 | try: |
58 | | - # Check if file is in request |
59 | 59 | if 'file' not in request.files: |
60 | 60 | return jsonify({'error': 'No file provided'}), 400 |
61 | 61 |
|
62 | 62 | file = request.files['file'] |
63 | | - |
64 | | - # Check if file is selected |
65 | 63 | if file.filename == '': |
66 | 64 | return jsonify({'error': 'No file selected'}), 400 |
67 | | - |
68 | | - # Check file extension |
69 | 65 | if not allowed_file(file.filename): |
70 | 66 | return jsonify({'error': 'Only .ipynb files are allowed'}), 400 |
71 | 67 |
|
72 | | - # Read file content |
73 | 68 | filename = secure_filename(file.filename) |
74 | 69 | file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) |
75 | 70 | file.save(file_path) |
76 | 71 |
|
77 | | - # Convert to PDF |
78 | 72 | 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' |
81 | 82 |
|
82 | 83 | # Clean up temp file |
83 | 84 | os.remove(file_path) |
84 | 85 |
|
85 | | - # Create response with PDF |
86 | | - pdf_io = io.BytesIO(pdf_output) |
87 | | - pdf_name = filename.rsplit('.', 1)[0] + '.pdf' |
88 | | - |
89 | 86 | return send_file( |
90 | 87 | pdf_io, |
91 | 88 | mimetype='application/pdf', |
92 | 89 | as_attachment=True, |
93 | 90 | download_name=pdf_name |
94 | 91 | ) |
95 | | - |
96 | 92 | except Exception as convert_error: |
97 | | - # Clean up temp file |
98 | 93 | if os.path.exists(file_path): |
99 | 94 | os.remove(file_path) |
100 | 95 | return jsonify({'error': f'Conversion failed: {str(convert_error)}'}), 500 |
101 | | - |
102 | 96 | except Exception as e: |
103 | 97 | return jsonify({'error': str(e)}), 500 |
104 | 98 |
|
|
0 commit comments