@@ -55,6 +55,19 @@ def serve_sitemap():
5555@app .route ('/api/convert' , methods = ['POST' ])
5656def 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' ])
0 commit comments