Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -512,6 +512,91 @@ def process_reports():
|
|
512 |
logger.exception("Node pipeline failed")
|
513 |
return jsonify({"error": "Node pipeline failed", "detail": str(e)}), 500
|
514 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
515 |
@app.route("/ping", methods=["GET"])
|
516 |
def ping():
|
517 |
return jsonify({"status": "ok"})
|
|
|
512 |
logger.exception("Node pipeline failed")
|
513 |
return jsonify({"error": "Node pipeline failed", "detail": str(e)}), 500
|
514 |
|
515 |
+
@app.route("/upload_reports", methods=["POST"])
|
516 |
+
def upload_reports():
|
517 |
+
"""
|
518 |
+
Upload one or more files for a patient.
|
519 |
+
|
520 |
+
Expects multipart/form-data with:
|
521 |
+
- patient_id (form field)
|
522 |
+
- files (one or multiple files; use the same field name 'files' for each file)
|
523 |
+
|
524 |
+
Example curl:
|
525 |
+
curl -X POST http://localhost:7860/upload_reports \
|
526 |
+
-F "patient_id=12345" \
|
527 |
+
-F "files[]=@/path/to/report1.pdf" \
|
528 |
+
-F "files[]=@/path/to/report2.pdf"
|
529 |
+
"""
|
530 |
+
try:
|
531 |
+
# patient id can be in form or args (for convenience)
|
532 |
+
patient_id = request.form.get("patient_id") or request.args.get("patient_id")
|
533 |
+
if not patient_id:
|
534 |
+
return jsonify({"error": "patient_id form field required"}), 400
|
535 |
+
|
536 |
+
# get uploaded files (support both files and files[] naming)
|
537 |
+
uploaded_files = request.files.getlist("files")
|
538 |
+
if not uploaded_files:
|
539 |
+
# fallback: single file under name 'file'
|
540 |
+
single = request.files.get("file")
|
541 |
+
if single:
|
542 |
+
uploaded_files = [single]
|
543 |
+
|
544 |
+
if not uploaded_files:
|
545 |
+
return jsonify({"error": "no files uploaded (use form field 'files')"}), 400
|
546 |
+
|
547 |
+
# create patient folder under REPORTS_ROOT/<patient_id>
|
548 |
+
patient_folder = REPORTS_ROOT / str(patient_id)
|
549 |
+
patient_folder.mkdir(parents=True, exist_ok=True)
|
550 |
+
|
551 |
+
saved = []
|
552 |
+
skipped = []
|
553 |
+
|
554 |
+
for file_storage in uploaded_files:
|
555 |
+
orig_name = getattr(file_storage, "filename", "") or ""
|
556 |
+
filename = secure_filename(orig_name)
|
557 |
+
if not filename:
|
558 |
+
skipped.append({"filename": orig_name, "reason": "invalid filename"})
|
559 |
+
continue
|
560 |
+
|
561 |
+
# extension check
|
562 |
+
ext = filename.rsplit(".", 1)[1].lower() if "." in filename else ""
|
563 |
+
if ext not in ALLOWED_EXTENSIONS:
|
564 |
+
skipped.append({"filename": filename, "reason": f"extension '{ext}' not allowed"})
|
565 |
+
continue
|
566 |
+
|
567 |
+
# avoid overwriting: if collision, add numeric suffix
|
568 |
+
dest = patient_folder / filename
|
569 |
+
if dest.exists():
|
570 |
+
base, dot, extension = filename.rpartition(".")
|
571 |
+
# if no base (e.g. ".bashrc") fallback
|
572 |
+
base = base or filename
|
573 |
+
i = 1
|
574 |
+
while True:
|
575 |
+
candidate = f"{base}__{i}.{extension}" if extension else f"{base}__{i}"
|
576 |
+
dest = patient_folder / candidate
|
577 |
+
if not dest.exists():
|
578 |
+
filename = candidate
|
579 |
+
break
|
580 |
+
i += 1
|
581 |
+
|
582 |
+
try:
|
583 |
+
file_storage.save(str(dest))
|
584 |
+
saved.append(filename)
|
585 |
+
except Exception as e:
|
586 |
+
logger.exception("Failed to save uploaded file %s: %s", filename, e)
|
587 |
+
skipped.append({"filename": filename, "reason": f"save failed: {e}"})
|
588 |
+
|
589 |
+
return jsonify({
|
590 |
+
"patient_id": str(patient_id),
|
591 |
+
"saved": saved,
|
592 |
+
"skipped": skipped,
|
593 |
+
"patient_folder": str(patient_folder)
|
594 |
+
}), 200
|
595 |
+
|
596 |
+
except Exception as exc:
|
597 |
+
logger.exception("Upload failed: %s", exc)
|
598 |
+
return jsonify({"error": "upload failed", "detail": str(exc)}), 500
|
599 |
+
|
600 |
@app.route("/ping", methods=["GET"])
|
601 |
def ping():
|
602 |
return jsonify({"status": "ok"})
|