Files
ai-exchange/src/api/training.py
T

173 lines
5.3 KiB
Python

from typing import Optional
from src.services.training import TrainingCaseService
from src.services.training.training_case_service import sanitize_public_training_payload
def get_training_cases(
status: Optional[str] = None,
skill_tag: Optional[str] = None,
instrument_id: Optional[int] = None,
limit: int = 100,
service: Optional[TrainingCaseService] = None,
) -> list[dict]:
return _service(service).list_cases(
status=status,
skill_tag=skill_tag,
instrument_id=instrument_id,
limit=limit,
)
def get_training_case(case_id: int, service: Optional[TrainingCaseService] = None) -> Optional[dict]:
return _service(service).get_case(case_id)
def create_training_attempt(body: dict, service: Optional[TrainingCaseService] = None) -> dict:
case_id = _require_int(body, "case_id")
user_id = _get_str(body, "user_id", "local")
current_frame_index = _get_int(body, "current_frame_index", 0)
meta = _get_dict(body, "meta", {})
response = _service(service).create_attempt(
case_id=case_id,
user_id=user_id,
current_frame_index=current_frame_index,
meta=meta,
)
return _public_id_response(response)
def add_training_annotation(attempt_id: int, body: dict, service: Optional[TrainingCaseService] = None) -> dict:
annotation_type = _require_str(body, "annotation_type")
annotation_payload = _require_dict(body, "payload")
user_id = _get_str(body, "user_id", "local")
task_id = _get_optional_int(body, "task_id")
response = _service(service).add_annotation(
attempt_id=attempt_id,
annotation_type=annotation_type,
payload=annotation_payload,
user_id=user_id,
task_id=task_id,
)
return _public_id_response(response)
def submit_training_attempt(attempt_id: int, body: dict, service: Optional[TrainingCaseService] = None) -> dict:
total_score = _get_optional_float(body, "total_score")
response = _service(service).submit_attempt(attempt_id=attempt_id, total_score=total_score)
return sanitize_public_training_payload(response)
def get_training_progress(
user_id: str = "local",
skill_tag: Optional[str] = None,
limit: int = 100,
service: Optional[TrainingCaseService] = None,
) -> list[dict]:
progress = _service(service).get_progress(user_id=user_id, skill_tag=skill_tag, limit=limit)
return sanitize_public_training_payload(progress)
def export_training_case_package(
status: Optional[str] = None,
skill_tag: Optional[str] = None,
instrument_id: Optional[int] = None,
limit: int = 100,
service: Optional[TrainingCaseService] = None,
) -> dict:
return _service(service).export_cases(
status=status,
skill_tag=skill_tag,
instrument_id=instrument_id,
limit=limit,
)
def import_training_case_package(body: dict, service: Optional[TrainingCaseService] = None) -> dict:
return _service(service).import_cases(body)
def _service(service: Optional[TrainingCaseService]) -> TrainingCaseService:
return service or TrainingCaseService()
def _public_id_response(response) -> dict:
if isinstance(response, dict):
return sanitize_public_training_payload(response)
return sanitize_public_training_payload({"id": response})
def _require_int(body: dict, key: str) -> int:
value = _require_value(body, key)
try:
return int(value)
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid_json_field:{key}") from exc
def _get_optional_int(body: dict, key: str) -> Optional[int]:
value = body.get(key)
if value is None:
return None
try:
return int(value)
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid_json_field:{key}") from exc
def _get_int(body: dict, key: str, default: int) -> int:
value = body.get(key)
if value is None:
return default
try:
return int(value)
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid_json_field:{key}") from exc
def _get_optional_float(body: dict, key: str) -> Optional[float]:
value = body.get(key)
if value is None:
return None
try:
return float(value)
except (TypeError, ValueError) as exc:
raise ValueError(f"invalid_json_field:{key}") from exc
def _require_str(body: dict, key: str) -> str:
value = _require_value(body, key)
if not isinstance(value, str) or value == "":
raise ValueError(f"invalid_json_field:{key}")
return value
def _get_str(body: dict, key: str, default: str) -> str:
value = body.get(key, default)
if not isinstance(value, str) or value == "":
raise ValueError(f"invalid_json_field:{key}")
return value
def _require_dict(body: dict, key: str) -> dict:
value = _require_value(body, key)
if not isinstance(value, dict):
raise ValueError(f"invalid_json_field:{key}")
return value
def _get_dict(body: dict, key: str, default: dict) -> dict:
value = body.get(key, default)
if not isinstance(value, dict):
raise ValueError(f"invalid_json_field:{key}")
return value
def _require_value(body: dict, key: str):
if not isinstance(body, dict):
raise ValueError("invalid_json_body")
value = body.get(key)
if value is None:
raise ValueError(f"missing_required_json_field:{key}")
return value