API Reference
Complete API documentation for the ASL Methods Section Generator
The ASL Methods Section Generator provides a RESTful API for programmatic access to ASL data processing and report generation capabilities. This document describes all available endpoints, request/response formats, and usage examples.
Authentication
Currently, the API does not require authentication. All endpoints are publicly accessible.
Content Types
- Request:
multipart/form-datafor file uploads,application/jsonfor data - Response:
application/jsonfor all endpoints
GET /
Returns information about the API service.
Response:
{
"name": "ASL Methods Parameter Generator API Service",
"version": "0.0.1",
"description": "This service provides an API for generating ASL methods parameters based on user input.",
"organization": "The ISMRM Open Science Initiative for Perfusion Imaging",
"authors": [
{"Ibrahim Abdelazim": "ibrahim.abdelazim@fau.de"},
{"Hanliang Xu": "hxu110@jh.edu"}
],
"supervisors": [
"Jan Petr",
"David Thomas"
],
"Specs": {
"Programming Language": "Python",
"Framework": "FastAPI",
"Operating System": "OS Independent"
},
"license": "MIT"
}
POST /api/report/process
Processes uploaded ASL data files and generates a comprehensive report.
Request:
- Content-Type:
multipart/form-data
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
files | File[] | Yes | ASL JSON files and TSV files |
nifti_file | File | Yes | NIfTI image file |
dcm_files | File[] | No | DICOM files (optional) |
Example Request (Python):
import requests
files = {
'files': [
open('sub-01_ses-01_asl.json', 'rb'),
open('sub-01_ses-01_asl.tsv', 'rb')
],
'nifti_file': open('sub-01_ses-01_asl.nii.gz', 'rb'),
'dcm_files': [
open('dicom1.dcm', 'rb'),
open('dicom2.dcm', 'rb')
]
}
response = requests.post('http://localhost:8000/api/report/process', files=files)
result = response.json()
Example Request (cURL):
curl -X POST "http://localhost:8000/api/report/process" \
-F "files=@sub-01_ses-01_asl.json" \
-F "files=@sub-01_ses-01_asl.tsv" \
-F "nifti_file=@sub-01_ses-01_asl.nii.gz" \
-F "dcm_files=@dicom1.dcm" \
-F "dcm_files=@dicom2.dcm"
Response:
{
"report": {
"basic_report": {
"asl_parameters": {
"LabelingDuration": "1.5s",
"PostLabelingDelay": "1.8s",
"EchoTime": "12.5ms",
"RepetitionTime": "4000ms",
"NumberOfVolumes": 100
},
"validation_status": "valid",
"file_information": {
"processed_files": ["asl.json", "asl.nii.gz", "asl.tsv"],
"total_files": 3
}
},
"extended_report": {
"parameter_analysis": {
"consistency_check": "passed",
"vendor_specific_info": "GE Healthcare",
"bids_compliance": "compliant"
},
"recommendations": [
"Consider including M0 scan for better quantification",
"Verify labeling efficiency parameters"
]
},
"errors": {
"major_errors": [],
"minor_errors": [
{
"parameter": "M0Scan",
"issue": "Missing M0 scan data",
"severity": "minor"
}
]
},
"warnings": [
{
"parameter": "PostLabelingDelay",
"message": "PLD varies slightly across volumes",
"value": "1.8s ± 0.1s"
}
]
},
"parameters": {
"extracted_parameters": {
"LabelingDuration": 1.5,
"PostLabelingDelay": 1.8,
"EchoTime": 0.0125,
"RepetitionTime": 4.0
},
"missing_required_parameters": [],
"validation_results": {
"total_checks": 15,
"passed_checks": 14,
"failed_checks": 1
}
}
}
POST /api/report/report-pdf
Generates a PDF report from the processed data.
Request:
- Content-Type:
application/json
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
report_data | Object | Yes | Complete report data from processing |
Example Request:
import requests
# First get the report data
report_response = requests.post('http://localhost:8000/api/report/process', files=files)
report_data = report_response.json()
# Then generate PDF
pdf_response = requests.post(
'http://localhost:8000/api/report/report-pdf',
json={'report_data': report_data['report']}
)
# Save the PDF
with open('asl_report.pdf', 'wb') as f:
f.write(pdf_response.content)
Response:
- Content-Type:
application/pdf - Body: PDF file content
- Headers:
Content-Disposition: attachment; filename="report.pdf"
Response Status Codes
| Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad Request - Invalid input data |
| 422 | Validation Error - Missing required fields |
| 500 | Internal Server Error |
| 503 | Service Unavailable |
Complete Workflow Example
import requests
import json
class ASLReportClient:
def __init__(self, base_url="http://localhost:8000"):
self.base_url = base_url
def process_asl_data(self, asl_files, nifti_file, dcm_files=None):
"""Process ASL data and generate report."""
files = {
'files': asl_files,
'nifti_file': nifti_file
}
if dcm_files:
files['dcm_files'] = dcm_files
response = requests.post(f"{self.base_url}/api/report/process", files=files)
response.raise_for_status()
return response.json()
def generate_pdf(self, report_data):
"""Generate PDF report."""
response = requests.post(
f"{self.base_url}/api/report/report-pdf",
json={'report_data': report_data}
)
response.raise_for_status()
return response.content
# Usage example
client = ASLReportClient()
# Process data
with open('asl.json', 'rb') as f1, open('asl.nii.gz', 'rb') as f2:
result = client.process_asl_data([f1], f2)
# Generate PDF
pdf_content = client.generate_pdf(result['report'])
with open('asl_report.pdf', 'wb') as f:
f.write(pdf_content)
Using Fetch API
class ASLReportClient {
constructor(baseUrl = 'http://localhost:8000') {
this.baseUrl = baseUrl;
}
async processASLData(aslFiles, niftiFile, dcmFiles = null) {
const formData = new FormData();
aslFiles.forEach(file => {
formData.append('files', file);
});
formData.append('nifti_file', niftiFile);
if (dcmFiles) {
dcmFiles.forEach(file => {
formData.append('dcm_files', file);
});
}
const response = await fetch(`${this.baseUrl}/api/report/process`, {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async generatePDF(reportData) {
const response = await fetch(`${this.baseUrl}/api/report/report-pdf`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ report_data: reportData })
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.blob();
}
}
// Usage example
const client = new ASLReportClient();
// Process data
const aslFile = new File(['content'], 'asl.json', { type: 'application/json' });
const niftiFile = new File(['content'], 'asl.nii.gz', { type: 'application/octet-stream' });
client.processASLData([aslFile], niftiFile)
.then(result => {
console.log('Processing result:', result);
// Generate PDF
return client.generatePDF(result.report);
})
.then(pdfBlob => {
// Download PDF
const url = URL.createObjectURL(pdfBlob);
const a = document.createElement('a');
a.href = url;
a.download = 'asl_report.pdf';
a.click();
})
.catch(error => {
console.error('Error:', error);
});
Using curl for Testing
# Test API information
curl http://localhost:8000/
# Test file processing (with sample files)
curl -X POST "http://localhost:8000/api/report/process" \
-F "files=@sample_asl.json" \
-F "nifti_file=@sample_asl.nii.gz"
# Test missing parameters submission
curl -X POST "http://localhost:8000/api/report/missing-parameters" \
-H "Content-Type: application/json" \
-d '{"M0Scan": {"value": "included"}}'
Using Postman
- Import the API endpoints into Postman
- Set up environment variables for base URL
- Create test collections for different scenarios
- Use Postman's automated testing features
File Size Limits
- Maximum file size: 100MB per file
- Total upload size: 500MB per request
- Recommended: Compress large files before upload
Processing Time
- Small datasets (< 50MB): 5-10 seconds
- Medium datasets (50-200MB): 10-30 seconds
- Large datasets (> 200MB): 30+ seconds

