Add Image models and clean up test code structure

Introduced `ImageCreate` and `Image` models to handle image-related data in the backend. Improved the organization and readability of the testing notebook by consolidating and formatting code into distinct sections with markdown cells.
This commit is contained in:
GotthardG
2025-02-26 13:33:23 +01:00
parent f588bc0cda
commit 1606e80f81
5 changed files with 277 additions and 51 deletions

View File

@ -1,4 +1,4 @@
from fastapi import APIRouter, HTTPException, Depends, UploadFile, File
from fastapi import APIRouter, HTTPException, Depends, UploadFile, File, Form
from sqlalchemy.orm import Session
from pathlib import Path
from typing import List
@ -9,11 +9,14 @@ from app.schemas import (
Sample as SampleSchema,
SampleEventCreate,
Sample,
Image,
ImageCreate,
)
from app.models import (
Puck as PuckModel,
Sample as SampleModel,
SampleEvent as SampleEventModel,
Image as ImageModel,
)
from app.dependencies import get_db
import logging
@ -89,29 +92,22 @@ async def create_sample_event(
return sample # Return the sample, now including `mount_count`
@router.post("/{sample_id}/upload-images")
@router.post("/{sample_id}/upload-images", response_model=Image)
async def upload_sample_image(
sample_id: int,
uploaded_file: UploadFile = File(...),
comment: str = Form(None),
db: Session = Depends(get_db),
):
logging.info(f"Received file: {uploaded_file.filename}")
"""
Uploads an image for a given sample and saves it to a directory structure.
Args:
sample_id (int): ID of the sample.
uploaded_file (UploadFile): The file uploaded with the request.
db (Session): Database session.
"""
# 1. Validate Sample
# Validate Sample
sample = db.query(SampleModel).filter(SampleModel.id == sample_id).first()
if not sample:
raise HTTPException(status_code=404, detail="Sample not found")
# 2. Define Directory Structure
pgroup = sample.puck.dewar.pgroups
# Define Directory Structure
pgroup = sample.puck.dewar.pgroups # adjust to sample or puck pgroups as needed
today = datetime.now().strftime("%Y-%m-%d")
dewar_name = (
sample.puck.dewar.dewar_name
@ -123,7 +119,7 @@ async def upload_sample_image(
base_dir = Path(f"images/{pgroup}/{today}/{dewar_name}/{puck_name}/{position}")
base_dir.mkdir(parents=True, exist_ok=True)
# 3. Validate MIME type and Save the File
# Validate MIME type and Save the File
if not uploaded_file.content_type.startswith("image/"):
raise HTTPException(
status_code=400,
@ -146,9 +142,26 @@ async def upload_sample_image(
f" Ensure the server has correct permissions.",
)
# 4. Return Saved File Information
logging.info(f"Uploaded 1 file for sample {sample_id}.")
return {
"message": "1 image uploaded successfully.",
"file": str(file_path),
}
# Create the payload from the Pydantic schema
image_payload = ImageCreate(
pgroup=pgroup,
comment=comment,
filepath=str(file_path),
status="active",
sample_id=sample_id,
).dict()
# Convert the payload to your mapped SQLAlchemy model instance.
# Make sure that ImageModel is your mapped model for images.
new_image = ImageModel(**image_payload)
db.add(new_image)
db.commit()
db.refresh(new_image)
logging.info(
f"Uploaded 1 file for sample {sample_id} and"
f" added record {new_image.id} to the database."
)
# Returning the mapped SQLAlchemy object, which will be converted to the
# Pydantic response model.
return new_image