@@ -48,6 +48,8 @@ class UrlParseRequest(BaseModel):
4848 False ,
4949 description = "Enable ranges and zones automatic detection" ,
5050 )
51+ raw_data : bool = Field (
52+ False , description = "Include raw data in the output (default: data source)" )
5153
5254 model_config = {
5355 "json_schema_extra" : {
@@ -92,8 +94,9 @@ def run_command(
9294 capture_snapshot : bool = False ,
9395 auto_processing : bool = False ,
9496 auto_detection : bool = False ,
95- ) -> dict :
96- """Execute nmr-cli command in Docker container"""
97+ raw_data : bool = False ,
98+ ) -> StreamingResponse :
99+ """Execute nmr-cli parse-spectra command in Docker container."""
97100
98101 cmd = ["nmr-cli" , "parse-spectra" ]
99102
@@ -108,41 +111,33 @@ def run_command(
108111 cmd .append ("-p" )
109112 if auto_detection :
110113 cmd .append ("-d" )
114+ if raw_data :
115+ cmd .append ("-r" )
111116
112117 try :
113118 result = subprocess .run (
114119 ["docker" , "exec" , NMR_CLI_CONTAINER ] + cmd ,
115120 capture_output = True ,
116- text = False ,
117- timeout = 120
121+ timeout = 120 ,
118122 )
119123 except subprocess .TimeoutExpired :
120124 raise HTTPException (
121- status_code = 408 ,
122- detail = "Processing timeout exceeded"
123- )
125+ status_code = 408 , detail = "Processing timeout exceeded" )
124126 except FileNotFoundError :
125127 raise HTTPException (
126- status_code = 500 ,
127- detail = "Docker not found or nmr-converter container not running."
128- )
128+ status_code = 500 , detail = "Docker not found or nmr-converter container not running." )
129129
130130 if result .returncode != 0 :
131- error_msg = result .stderr .decode (
132- "utf-8" ) if result .stderr else "Unknown error"
133131 raise HTTPException (
134132 status_code = 422 ,
135- detail = f"NMR CLI error: { error_msg } "
133+ detail = f"NMR CLI error: { result . stderr . decode ( 'utf-8' ) or 'Unknown error' } " ,
136134 )
137135
138- # Parse output
139- try :
140- return json .loads (result .stdout .decode ("utf-8" ))
141- except json .JSONDecodeError as e :
142- raise HTTPException (
143- status_code = 500 ,
144- detail = f"Invalid JSON from NMR CLI: { e } "
145- )
136+ return StreamingResponse (
137+ io .BytesIO (result .stdout ),
138+ media_type = "application/json" ,
139+ headers = {"Content-Disposition" : "attachment; filename=parse-output.json" },
140+ )
146141
147142
148143def run_publication_string_command (publication_string : str ) -> dict :
@@ -229,16 +224,20 @@ def remove_file_from_container(container_path: str) -> None:
229224class PeakItem (BaseModel ):
230225 """A single NMR peak."""
231226 x : float = Field (..., description = "Chemical shift in ppm" )
232- y : Optional [float ] = Field (1.0 , description = "Peak intensity (default: 1.0)" )
233- width : Optional [float ] = Field (1.0 , description = "Peak width in Hz (default: 1.0)" )
227+ y : Optional [float ] = Field (
228+ 1.0 , description = "Peak intensity (default: 1.0)" )
229+ width : Optional [float ] = Field (
230+ 1.0 , description = "Peak width in Hz (default: 1.0)" )
234231
235232
236233class PeaksToNMRiumOptions (BaseModel ):
237234 """Options for peaks-to-NMRium conversion."""
238- nucleus : Optional [str ] = Field ("1H" , description = "Nucleus type (e.g. '1H', '13C')" )
235+ nucleus : Optional [str ] = Field (
236+ "1H" , description = "Nucleus type (e.g. '1H', '13C')" )
239237 solvent : Optional [str ] = Field ("" , description = "NMR solvent" )
240238 frequency : Optional [float ] = Field (400 , description = "NMR frequency in MHz" )
241- nbPoints : Optional [int ] = Field (131072 , description = "Number of points for spectrum generation" , alias = "nb_points" )
239+ nbPoints : Optional [int ] = Field (
240+ 131072 , description = "Number of points for spectrum generation" , alias = "nb_points" )
242241
243242 model_config = {"populate_by_name" : True }
244243
@@ -276,7 +275,8 @@ class PeaksToNMRiumRequest(BaseModel):
276275def run_peaks_to_nmrium_command (payload : dict ) -> str :
277276 """Execute nmr-cli peaks-to-nmrium command in Docker container via stdin."""
278277
279- cmd = ["docker" , "exec" , "-i" , NMR_CLI_CONTAINER , "nmr-cli" , "peaks-to-nmrium" ]
278+ cmd = ["docker" , "exec" , "-i" , NMR_CLI_CONTAINER ,
279+ "nmr-cli" , "peaks-to-nmrium" ]
280280 stdin_data = json .dumps (payload )
281281
282282 try :
@@ -298,7 +298,8 @@ def run_peaks_to_nmrium_command(payload: dict) -> str:
298298 )
299299
300300 if result .returncode != 0 :
301- error_msg = result .stderr .decode ("utf-8" ) if result .stderr else "Unknown error"
301+ error_msg = result .stderr .decode (
302+ "utf-8" ) if result .stderr else "Unknown error"
302303 raise HTTPException (
303304 status_code = 422 ,
304305 detail = f"NMR CLI error: { error_msg } " ,
@@ -344,7 +345,8 @@ def run_peaks_to_nmrium_command(payload: dict) -> str:
344345 },
345346)
346347async def parse_spectra_from_file (
347- file : UploadFile = File (..., description = "NMR spectra file to parse (JCAMP-DX, Bruker zip, etc.)" ),
348+ file : UploadFile = File (
349+ ..., description = "NMR spectra file to parse (JCAMP-DX, Bruker zip, etc.)" ),
348350 capture_snapshot : bool = Form (
349351 False ,
350352 description = "Generate an image snapshot of the spectra" ,
@@ -357,6 +359,8 @@ async def parse_spectra_from_file(
357359 False ,
358360 description = "Enable ranges and zones automatic detection" ,
359361 ),
362+ raw_data : bool = Form (
363+ False , description = "Include raw data in the output (default: data source references)" )
360364):
361365 """
362366 ## Parse spectra from an uploaded file
@@ -369,7 +373,7 @@ async def parse_spectra_from_file(
369373 | `capture_snapshot` | Capture an image snapshot of the spectra |
370374 | `auto_processing` | Automatically process FID → FT spectra |
371375 | `auto_detection` | Automatically detect ranges and zones |
372-
376+ | `raw_data` | Include raw data in the output (default: data source) |
373377 ### Returns
374378 Parsed spectra data in NMRium-compatible JSON format.
375379 """
@@ -398,6 +402,7 @@ async def parse_spectra_from_file(
398402 capture_snapshot = capture_snapshot ,
399403 auto_processing = auto_processing ,
400404 auto_detection = auto_detection ,
405+ raw_data = raw_data ,
401406 )
402407
403408 except HTTPException :
@@ -445,6 +450,7 @@ async def parse_spectra_from_url(request: UrlParseRequest):
445450 | `capture_snapshot` | Capture an image snapshot of the spectra |
446451 | `auto_processing` | Automatically process FID → FT spectra |
447452 | `auto_detection` | Automatically detect ranges and zones |
453+ | `raw_data` | Include raw data in the output (default: data source) |
448454
449455 ### Returns
450456 Parsed spectra data in NMRium-compatible JSON format.
@@ -455,6 +461,7 @@ async def parse_spectra_from_url(request: UrlParseRequest):
455461 capture_snapshot = request .capture_snapshot ,
456462 auto_processing = request .auto_processing ,
457463 auto_detection = request .auto_detection ,
464+ raw_data = request .raw_data ,
458465 )
459466
460467 except HTTPException :
0 commit comments