This commit is contained in:
2025-10-03 19:31:41 -03:00
parent 48ed8d8345
commit 5ae2128dee
29 changed files with 996 additions and 168 deletions

View File

@@ -1,6 +1,5 @@
import json
import os
from datetime import date
from functools import partial
from typing import Any
@@ -9,26 +8,13 @@ from aws_lambda_powertools.event_handler.api_gateway import (
APIGatewayHttpResolver,
CORSConfig,
)
from aws_lambda_powertools.event_handler.exceptions import NotFoundError, ServiceError
from aws_lambda_powertools.event_handler.exceptions import ServiceError
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.shared.json_encoder import Encoder
from aws_lambda_powertools.utilities.typing import LambdaContext
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
from api_gateway import JSONResponse
from boto3clients import dynamodb_client
from config import COURSE_TABLE
dyn = DynamoDBPersistenceLayer(COURSE_TABLE, dynamodb_client)
class JSONEncoder(Encoder):
def default(self, obj):
if isinstance(obj, date):
return obj.isoformat()
return super().default(obj)
from json_encoder import JSONEncoder
from routes import courses, enrollments
tracer = Tracer()
logger = Logger(__name__)
@@ -44,27 +30,8 @@ app = APIGatewayHttpResolver(
debug='AWS_SAM_LOCAL' in os.environ,
serializer=partial(json.dumps, separators=(',', ':'), cls=JSONEncoder),
)
@app.get('/users/<user_id>')
@tracer.capture_method
def get_user(user_id: str):
return {'id': user_id}
@app.get('/users/<user_id>/emails')
@tracer.capture_method
def get_emails(user_id: str):
return [{'email': 'sergio@somosbeta.com.br'}]
@app.get('/courses/<course_id>')
@tracer.capture_method
def get_course(course_id: str):
return dyn.collection.get_item(
KeyPair(course_id, '0'),
exc_cls=NotFoundError,
)
app.include_router(courses.router, prefix='/courses')
app.include_router(enrollments.router, prefix='/enrollments')
@app.exception_handler(ServiceError)

View File

@@ -8,14 +8,13 @@ if TYPE_CHECKING:
else:
DynamoDBClient = object
AWS_SAM_LOCAL = os.getenv('AWS_SAM_LOCAL')
def get_dynamodb_client() -> DynamoDBClient:
if not AWS_SAM_LOCAL:
if os.getenv('AWS_LAMBDA_FUNCTION_NAME'):
return boto3.client('dynamodb')
host = 'host.docker.internal' if AWS_SAM_LOCAL else '127.0.0.1'
# Use the Docker network address when running in a container
host = 'host.docker.internal' if os.getenv('AWS_SAM_LOCAL') else '127.0.0.1'
return boto3.client('dynamodb', endpoint_url=f'http://{host}:8000')

View File

@@ -1,4 +1,5 @@
import os
USER_TABLE: str = os.getenv('USER_TABLE') # type: ignore
ENROLLMENT_TABLE: str = os.getenv('ENROLLMENT_TABLE') # type: ignore
COURSE_TABLE: str = os.getenv('COURSE_TABLE') # type: ignore

View File

@@ -0,0 +1,11 @@
from datetime import date
from aws_lambda_powertools.shared.json_encoder import Encoder
class JSONEncoder(Encoder):
def default(self, obj):
if isinstance(obj, date):
return obj.isoformat()
return super().default(obj)

View File

@@ -0,0 +1,71 @@
from io import BytesIO
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.exceptions import (
BadRequestError,
NotFoundError,
)
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
from pydantic import UUID4, BaseModel
from python_multipart import parse_form
from boto3clients import dynamodb_client
from config import COURSE_TABLE
logger = Logger(__name__)
router = Router()
dyn = DynamoDBPersistenceLayer(COURSE_TABLE, dynamodb_client)
@router.get('/<course_id>')
def get_course(course_id: str):
return dyn.collection.get_item(
KeyPair(course_id, '0'),
exc_cls=NotFoundError,
)
class Cert(BaseModel):
exp_interval: int
rawfile: bytes
class FormData(BaseModel):
id: UUID4
name: str
access_period: int
cert: Cert | None = None
@router.post('/<course_id>')
def edit_course(course_id: str):
event = router.current_event
if not event.decoded_body:
raise BadRequestError('Invalid request body')
ret = {'id': course_id}
body = BytesIO(event.decoded_body.encode())
def on_field(field):
field_name = field.field_name.decode().split('.')
if len(field_name) > 1:
field_name, subfield_name = field_name
print(field_name, subfield_name)
else:
field_name, *_ = field_name
ret[field_name] = field.value
parse_form(
event.headers, # type: ignore
body,
on_field=on_field,
on_file=on_field,
)
# print(ret.keys())
data = FormData.model_validate(ret)
print(data)
return {}

View File

@@ -0,0 +1,19 @@
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 layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
from boto3clients import dynamodb_client
from config import ENROLLMENT_TABLE
logger = Logger(__name__)
router = Router()
dyn = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
@router.get('/<enrollment_id>')
def get_enrollment(enrollment_id: str):
return dyn.collection.get_item(
KeyPair(enrollment_id, '0'),
exc_cls=NotFoundError,
)