Spaces:
Sleeping
Sleeping
GitHub Actions commited on
Commit ·
4e66db8
1
Parent(s): adab839
deploy: sync from GitHub fc8dfa83a03305c178bc306a3cbf1f4b6fe50ac7
Browse files- Dockerfile +4 -2
- app.py +7 -3
Dockerfile
CHANGED
|
@@ -41,8 +41,10 @@ COPY --chown=user . $HOME/app
|
|
| 41 |
# we should not need to chown, since we are using USER user above
|
| 42 |
RUN mkdir -p uploads results annotated .yolo_config
|
| 43 |
|
| 44 |
-
#
|
| 45 |
-
|
|
|
|
|
|
|
| 46 |
|
| 47 |
# Copy the rest of the application code into the container at /app
|
| 48 |
# This includes app.py, nemaquant.py, templates/, static/, etc.
|
|
|
|
| 41 |
# we should not need to chown, since we are using USER user above
|
| 42 |
RUN mkdir -p uploads results annotated .yolo_config
|
| 43 |
|
| 44 |
+
# Point YOLO config to /tmp so it is writable under Apptainer (read-only SIF)
|
| 45 |
+
# and HF Spaces. /home/user/app/.yolo_config is kept in the image but only used
|
| 46 |
+
# as a fallback when the container filesystem is writable (plain Docker).
|
| 47 |
+
ENV YOLO_CONFIG_DIR=/tmp/nemaquant/.yolo_config
|
| 48 |
|
| 49 |
# Copy the rest of the application code into the container at /app
|
| 50 |
# This includes app.py, nemaquant.py, templates/, static/, etc.
|
app.py
CHANGED
|
@@ -65,6 +65,10 @@ app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'tif', 'tiff'}
|
|
| 65 |
UPLOAD_FOLDER.mkdir(parents=True, exist_ok=True)
|
| 66 |
RESULTS_FOLDER.mkdir(parents=True, exist_ok=True)
|
| 67 |
ANNOT_FOLDER.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
print(f"Data root: /tmp/nemaquant | Weights: {WEIGHTS_FILE}")
|
| 69 |
|
| 70 |
# Load model once at startup, use CUDA if available
|
|
@@ -304,7 +308,7 @@ def annotate_image():
|
|
| 304 |
session_id = session['id']
|
| 305 |
uuid_map_to_uuid_imgname = session.get('uuid_map_to_uuid_imgname', {})
|
| 306 |
img_name = uuid_map_to_uuid_imgname.get(uuid)
|
| 307 |
-
orig_img_name = session
|
| 308 |
|
| 309 |
if not img_name:
|
| 310 |
return jsonify({'error': 'File not found'}), 404
|
|
@@ -392,7 +396,7 @@ def export_csv():
|
|
| 392 |
data = request.json
|
| 393 |
session_id = session['id']
|
| 394 |
job_state = session.get('job_state')
|
| 395 |
-
filename_map = session.get('filename_map')
|
| 396 |
threshold = float(data.get('confidence', 0.5))
|
| 397 |
if not job_state:
|
| 398 |
return jsonify({'error': 'Job not found'}), 404
|
|
@@ -410,7 +414,7 @@ def export_csv():
|
|
| 410 |
rows = []
|
| 411 |
for uuid in all_results.keys():
|
| 412 |
count = sum(1 for d in all_results[uuid] if d['score'] >= threshold)
|
| 413 |
-
rows.append({'Filename': filename_map
|
| 414 |
rows = sorted(rows, key=lambda x: x['Filename'].lower())
|
| 415 |
# write the CSV out
|
| 416 |
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
|
|
|
| 65 |
UPLOAD_FOLDER.mkdir(parents=True, exist_ok=True)
|
| 66 |
RESULTS_FOLDER.mkdir(parents=True, exist_ok=True)
|
| 67 |
ANNOT_FOLDER.mkdir(parents=True, exist_ok=True)
|
| 68 |
+
# YOLO_CONFIG_DIR points to /tmp/nemaquant/.yolo_config (set in Dockerfile ENV).
|
| 69 |
+
# Create it here so ultralytics can write its cache on read-only container filesystems
|
| 70 |
+
# (e.g. Apptainer SIF images).
|
| 71 |
+
Path(os.environ.get('YOLO_CONFIG_DIR', '/tmp/nemaquant/.yolo_config')).mkdir(parents=True, exist_ok=True)
|
| 72 |
print(f"Data root: /tmp/nemaquant | Weights: {WEIGHTS_FILE}")
|
| 73 |
|
| 74 |
# Load model once at startup, use CUDA if available
|
|
|
|
| 308 |
session_id = session['id']
|
| 309 |
uuid_map_to_uuid_imgname = session.get('uuid_map_to_uuid_imgname', {})
|
| 310 |
img_name = uuid_map_to_uuid_imgname.get(uuid)
|
| 311 |
+
orig_img_name = session.get('filename_map', {}).get(uuid)
|
| 312 |
|
| 313 |
if not img_name:
|
| 314 |
return jsonify({'error': 'File not found'}), 404
|
|
|
|
| 396 |
data = request.json
|
| 397 |
session_id = session['id']
|
| 398 |
job_state = session.get('job_state')
|
| 399 |
+
filename_map = session.get('filename_map') or {}
|
| 400 |
threshold = float(data.get('confidence', 0.5))
|
| 401 |
if not job_state:
|
| 402 |
return jsonify({'error': 'Job not found'}), 404
|
|
|
|
| 414 |
rows = []
|
| 415 |
for uuid in all_results.keys():
|
| 416 |
count = sum(1 for d in all_results[uuid] if d['score'] >= threshold)
|
| 417 |
+
rows.append({'Filename': filename_map.get(uuid, uuid), 'EggsDetected': count, 'ConfidenceThreshold': threshold})
|
| 418 |
rows = sorted(rows, key=lambda x: x['Filename'].lower())
|
| 419 |
# write the CSV out
|
| 420 |
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|