173 lines
5.3 KiB
Python
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
|