Skip to content

Commit abb8c41

Browse files
committed
Robust error handling and notebook validation for perfect conversion reliability
1 parent 0fd4540 commit abb8c41

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

app.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ def serve_sitemap():
5555
@app.route('/api/convert', methods=['POST'])
5656
def convert_ipynb_to_pdf():
5757
"""Convert uploaded IPYNB file to PDF using HTML export and WeasyPrint for speed."""
58+
import json
59+
from jsonschema import validate, ValidationError
60+
# Minimal Jupyter notebook schema for validation
61+
notebook_schema = {
62+
"type": "object",
63+
"properties": {
64+
"cells": {"type": "array"},
65+
"metadata": {"type": "object"},
66+
"nbformat": {"type": "integer"},
67+
"nbformat_minor": {"type": "integer"}
68+
},
69+
"required": ["cells", "metadata", "nbformat", "nbformat_minor"]
70+
}
5871
try:
5972
if 'file' not in request.files:
6073
return jsonify({'error': 'No file provided'}), 400
@@ -69,6 +82,18 @@ def convert_ipynb_to_pdf():
6982
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
7083
file.save(file_path)
7184

85+
# Validate notebook structure before conversion
86+
try:
87+
with open(file_path, 'r', encoding='utf-8') as f:
88+
notebook_json = json.load(f)
89+
validate(instance=notebook_json, schema=notebook_schema)
90+
except ValidationError as ve:
91+
os.remove(file_path)
92+
return jsonify({'error': f'Invalid notebook structure: {ve.message}'}), 400
93+
except Exception as ve:
94+
os.remove(file_path)
95+
return jsonify({'error': f'Invalid or corrupted notebook file: {str(ve)}'}), 400
96+
7297
try:
7398
# Export notebook to HTML
7499
html_exporter = HTMLExporter()
@@ -92,9 +117,9 @@ def convert_ipynb_to_pdf():
92117
except Exception as convert_error:
93118
if os.path.exists(file_path):
94119
os.remove(file_path)
95-
return jsonify({'error': f'Conversion failed: {str(convert_error)}'}), 500
120+
return jsonify({'error': f'Conversion failed: {str(convert_error)}. Please ensure your notebook is valid and try again.'}), 500
96121
except Exception as e:
97-
return jsonify({'error': str(e)}), 500
122+
return jsonify({'error': f'Unexpected server error: {str(e)}'}), 500
98123

99124

100125
@app.route('/api/health', methods=['GET'])

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mistune==2.0.5
12
Flask==2.3.3
23
Flask-CORS==4.0.0
34
nbconvert==7.10.0

0 commit comments

Comments
 (0)