from http import HTTPStatus from typing import Annotated from aws_lambda_powertools import Logger from aws_lambda_powertools.event_handler.api_gateway import Router from aws_lambda_powertools.event_handler.exceptions import NotFoundError from aws_lambda_powertools.event_handler.openapi.params import Body from glom import glom from layercake.dateutils import now from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey, TransactKey from api_gateway import JSONResponse from boto3clients import dynamodb_client from config import ENROLLMENT_TABLE logger = Logger(__name__) router = Router() dyn = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client) @router.get('//scorm') def get_scorm(enrollment_id: str): enrollment = dyn.collection.get_items( TransactKey(enrollment_id) + SortKey('0') + SortKey('SCORM_COMMIT#LAST', rename_key='last_commit') ) if not enrollment: raise NotFoundError('Enrollment not found') spec = {'id': 'course.id', 'scormset': 'course.scormset'} course_id, scormset_id = glom(enrollment, spec).values() scormset = dyn.collection.get_item( KeyPair(course_id, f'SCORMSET#{scormset_id}'), raise_on_error=False, default={}, ) return enrollment | {'scormset': scormset} @router.post('//scorm') def post_scorm( enrollment_id: str, cmi: Annotated[dict, Body(embed=True)], ): now_ = now() with dyn.transact_writer() as transact: transact.condition( key=KeyPair(enrollment_id, '0'), cond_expr='attribute_exists(sk)', exc_cls=NotFoundError, ) transact.put( item={ 'id': enrollment_id, 'sk': 'SCORM_COMMIT#LAST', 'cmi': cmi, 'created_at': now_, } ) transact.put( item={ 'id': f'SCORM_COMMIT#{enrollment_id}', 'sk': now_.isoformat(), 'cmi': cmi, 'created_at': now_, } ) return JSONResponse(HTTPStatus.NO_CONTENT)