Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions desdeo/api/models/request_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""Requests models."""
from pydantic import BaseModel


class RepresentativeSolutionSetRequest(BaseModel):
"""Model of the request to the representative solution set."""
problem_id: int
name: str
description: str | None = None
solution_data: dict[str, list[float]]
ideal: dict[str, float]
nadir: dict[str, float]
162 changes: 161 additions & 1 deletion desdeo/api/routers/problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from fastapi import APIRouter, Depends, HTTPException, Request, UploadFile, status
from fastapi.responses import JSONResponse
from sqlmodel import select
from sqlmodel import Session, select

from desdeo.api.models import (
ForestProblemMetaData,
Expand All @@ -21,6 +21,7 @@
User,
UserRole,
)
from desdeo.api.models.request_models import RepresentativeSolutionSetRequest
from desdeo.api.routers.user_authentication import get_current_user
from desdeo.problem import Problem
from desdeo.tools.utils import available_solvers
Expand Down Expand Up @@ -318,3 +319,162 @@ def select_solver(
db_session.refresh(problem_metadata)

return JSONResponse(content={"message": "OK"}, status_code=status.HTTP_200_OK)

@router.post("/add_representative_solution_set")
def add_representative_solution_set(
payload: RepresentativeSolutionSetRequest,
context: Annotated[SessionContext, Depends(get_session_context_without_request)],
):
"""Add a new representative solution set as metadata to a problem.

Args:
payload (RepresentativeSolutionSetRequest): The JSON body containing the
details of the representative solution set (name, description, solution data, ideal, nadir).
context (SessionContext): The session context providing the current user and database session.

Raises:
HTTPException: If problem not found or unauthorized user.

Returns:
dict: Confirmation message.
"""
user = context.user
db_session: Session = context.db_session

# Fetch the problem
problem_db = db_session.get(ProblemDB, payload.problem_id)
if problem_db is None:
raise HTTPException(status_code=404, detail=f"Problem with ID {payload.problem_id} not found.")

# Check the user
if user.id != problem_db.user_id:
raise HTTPException(status_code=401, detail="Unauthorized user.")

# Ensure metadata object exists
if problem_db.problem_metadata is None:
problem_metadata = ProblemMetaDataDB(problem_id=problem_db.id, problem=problem_db)
db_session.add(problem_metadata)
db_session.commit()
db_session.refresh(problem_metadata)
else:
problem_metadata = problem_db.problem_metadata

# Add new representative solution set
repr_metadata = RepresentativeNonDominatedSolutions(
metadata_id=problem_metadata.id,
name=payload.name,
description=payload.description,
solution_data=payload.solution_data,
ideal=payload.ideal,
nadir=payload.nadir,
metadata_instance=problem_metadata,
)

db_session.add(repr_metadata)
db_session.commit()
db_session.refresh(repr_metadata)

# Attach to problem metadata
problem_metadata.representative_nd_metadata.append(repr_metadata)
db_session.add(problem_metadata)
db_session.commit()
db_session.refresh(problem_metadata)

return {"message": "Representative solution set added successfully."}

@router.get("/all_representative_solution_sets/{problem_id}")
def get_all_representative_solution_sets(
problem_id: int,
context: Annotated[SessionContext, Depends(get_session_context_without_request)],
):
"""Get meta information about all representative solution sets for a given problem.

Returns only name, description, ideal, and nadir for each set.
"""
db_session: Session = context.db_session
user = context.user

# Fetch problem
problem_db = db_session.get(ProblemDB, problem_id)
if not problem_db:
raise HTTPException(status_code=404, detail=f"Problem with ID {problem_id} not found.")

# Check the user
if problem_db.user_id != user.id:
raise HTTPException(status_code=401, detail="Unauthorized user.")

# Fetch metadata
problem_metadata = problem_db.problem_metadata
if not problem_metadata or not problem_metadata.representative_nd_metadata:
return {
"problem_id": problem_id,
"representative_sets": []
}

# Build response
sets_meta = [
{
"name": rep.name,
"description": rep.description,
"ideal": rep.ideal,
"nadir": rep.nadir
}
for rep in problem_metadata.representative_nd_metadata
]

return {
"problem_id": problem_id,
"representative_sets": sets_meta
}

@router.get("/representative_solution_set/{set_id}")
def get_representative_solution_set(
set_id: int,
context: Annotated[SessionContext, Depends(get_session_context_without_request)],
):
"""Fetch full information of a single representative solution set by its ID."""
db_session: Session = context.db_session

# Fetch the representative set
repr_set = db_session.get(RepresentativeNonDominatedSolutions, set_id)
if repr_set is None:
raise HTTPException(status_code=404, detail=f"Representative set with ID {set_id} not found.")

# Check the user
if repr_set.metadata_instance.problem.user_id != context.user.id:
raise HTTPException(status_code=401, detail="Unauthorized user.")

# Return all fields as a dict
return {
"id": repr_set.id,
"name": repr_set.name,
"description": repr_set.description,
"solution_data": repr_set.solution_data,
"ideal": repr_set.ideal,
"nadir": repr_set.nadir,
}

@router.delete("/representative_solution_set/{set_id}")
def delete_representative_solution_set(
set_id: int,
context: Annotated[SessionContext, Depends(get_session_context_without_request)],
):
"""Delete a representative solution set by its ID."""
db_session: Session = context.db_session
user = context.user

# Fetch the set
repr_metadata = db_session.get(RepresentativeNonDominatedSolutions, set_id)
if repr_metadata is None:
raise HTTPException(status_code=404, detail=f"Representative solution set with ID {set_id} not found.")

# Ensure the user owns the problem this set belongs to
problem_metadata = repr_metadata.metadata_instance
if problem_metadata.problem.user_id != user.id:
raise HTTPException(status_code=401, detail="Unauthorized user.")

# Delete the set
db_session.delete(repr_metadata)
db_session.commit()

return {"detail": "Deleted successfully"}
Loading
Loading