Skip to content

Commit

Permalink
fix(api,lambda): close old connections whenever the lambda handler is… (
Browse files Browse the repository at this point in the history
#569)

* fix(api,lambda): close old connections whenever the lambda handler is invoked

* fix(api,lambda): rework previous fix and also make tests work
  • Loading branch information
nutrina authored Apr 12, 2024
1 parent be013e1 commit 37c9223
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 45 deletions.
12 changes: 10 additions & 2 deletions api/aws_lambdas/passport/analysis_GET.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@
This module provides a handler to manage API requests in AWS Lambda.
"""

from aws_lambdas.utils import format_response, with_api_request_exception_handling
from aws_lambdas.utils import (
with_api_request_exception_handling,
)
from passport.api import handle_get_analysis
from django.db import close_old_connections


@with_api_request_exception_handling
def handler(event, _context, _request, _user_account, _body):
def _handler(event, _context, _request, _user_account, _body):
"""
Handles the incoming events and translates them into Django's context.
"""
Expand All @@ -17,3 +20,8 @@ def handler(event, _context, _request, _user_account, _body):
analysis = handle_get_analysis(address)

return analysis


def handler(*args, **kwargs):
close_old_connections()
return _handler(*args, **kwargs)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from aws_lambdas.scorer_api_passport.tests.helpers import MockContext
from passport.test.test_analysis import MockLambdaClient

from ..analysis_GET import handler
from ..analysis_GET import _handler

pytestmark = pytest.mark.django_db

Expand All @@ -31,7 +31,7 @@ def test_successful_analysis(
"passport.api.get_lambda_client",
MockLambdaClient,
)
response = handler(event, MockContext())
response = _handler(event, MockContext())

assert response is not None
assert response["statusCode"] == 200
Expand Down Expand Up @@ -59,7 +59,7 @@ def test_bad_auth(
"passport.api.get_lambda_client",
MockLambdaClient,
)
response = handler(event, MockContext())
response = _handler(event, MockContext())

assert response is not None
assert response["statusCode"] == 403
Expand All @@ -86,7 +86,7 @@ def test_bad_address(
"passport.api.get_lambda_client",
MockLambdaClient,
)
response = handler(event, MockContext())
response = _handler(event, MockContext())

assert response is not None
print(response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def test_score_get(
}
context = MockContext()

response = score_GET.handler(event, context)
response = score_GET._handler(event, context)

body = json.loads(response["body"])

Expand All @@ -71,7 +71,7 @@ def test_score_post(

assert Score.objects.count() == 0

response = score_POST.handler(event, context)
response = score_POST._handler(event, context)

body = json.loads(response["body"])

Expand All @@ -98,7 +98,7 @@ def test_stamp_get(

context = MockContext()

response = stamp_GET.handler(event, context)
response = stamp_GET._handler(event, context)

body = json.loads(response["body"])

Expand All @@ -113,7 +113,7 @@ def test_weights_get():

context = MockContext()

response = weights_GET.handler(event, context)
response = weights_GET._handler(event, context)

body = json.loads(response["body"])

Expand Down
8 changes: 7 additions & 1 deletion api/aws_lambdas/scorer_api_passport/v1/authenticate_POST.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@
with_request_exception_handling,
)
from ceramic_cache.api.v1 import CacaoVerifySubmit, handle_authenticate
from django.db import close_old_connections


@with_request_exception_handling
def handler(event, context):
def _handler(event, context):
body = parse_body(event)

payload = CacaoVerifySubmit(**body)

return format_response(handle_authenticate(payload))


def handler(*args, **kwargs):
close_old_connections()
return _handler(*args, **kwargs)
8 changes: 7 additions & 1 deletion api/aws_lambdas/scorer_api_passport/v1/score_GET.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@
with_request_exception_handling,
)
from ceramic_cache.api.v1 import handle_get_ui_score
from django.db import close_old_connections


@with_request_exception_handling
def handler(event, context):
def _handler(event, context):
address = authenticate_and_get_address(event)
alternate_scorer_id = event.get("queryStringParameters", {}).get(
"alternate_scorer_id", None
)

return format_response(handle_get_ui_score(address, alternate_scorer_id))


def handler(*args, **kwargs):
close_old_connections()
return _handler(*args, **kwargs)
8 changes: 7 additions & 1 deletion api/aws_lambdas/scorer_api_passport/v1/score_POST.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@
parse_body,
)
from ceramic_cache.api.v1 import get_detailed_score_response_for_address
from django.db import close_old_connections


@with_request_exception_handling
def handler(event, context):
def _handler(event, context):
address = authenticate_and_get_address(event)
body = parse_body(event)
alternate_scorer_id = body.get("alternate_scorer_id", None)

return format_response(
get_detailed_score_response_for_address(address, alternate_scorer_id)
)


def handler(*args, **kwargs):
close_old_connections()
return _handler(*args, **kwargs)
8 changes: 7 additions & 1 deletion api/aws_lambdas/scorer_api_passport/v1/stamp_GET.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@
with_request_exception_handling,
)
from ceramic_cache.api.v1 import handle_get_stamps
from django.db import close_old_connections


@with_request_exception_handling
def handler(event, context):
def _handler(event, context):
address = get_address_param(event)

return format_response(handle_get_stamps(address))


def handler(*args, **kwargs):
close_old_connections()
return _handler(*args, **kwargs)
8 changes: 7 additions & 1 deletion api/aws_lambdas/scorer_api_passport/v1/weights_GET.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@
with_request_exception_handling,
)
from ceramic_cache.api.v1 import handle_get_scorer_weights
from django.db import close_old_connections


@with_request_exception_handling
def handler(event, context):
def _handler(event, context):
return format_response(handle_get_scorer_weights())


def handler(*args, **kwargs):
close_old_connections()
return _handler(*args, **kwargs)
18 changes: 10 additions & 8 deletions api/aws_lambdas/submit_passport/submit_passport.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,22 @@
This module provides a handler to manage API requests in AWS Lambda.
"""

import base64
import json

from asgiref.sync import async_to_sync
from aws_lambdas.utils import format_response, with_api_request_exception_handling
from django.http import HttpRequest
from aws_lambdas.utils import (
with_api_request_exception_handling,
)
from registry.api.v1 import (
DetailedScoreResponse,
SubmitPassportPayload,
ahandle_submit_passport,
)
from registry.api.utils import save_api_key_analytics
from django.db import close_old_connections

# Now this script or any imported module can use any part of Django it needs.
# from myapp import models


@with_api_request_exception_handling
def handler(event, _context, request, user_account, body):
def _handler(event, _context, request, user_account, body):
"""
Handles the incoming events and translates them into Django's context.
"""
Expand All @@ -30,3 +27,8 @@ def handler(event, _context, request, user_account, body):
)

return score


def handler(*args, **kwargs):
close_old_connections()
return _handler(*args, **kwargs)
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from aws_lambdas.scorer_api_passport.utils import strip_event
from registry.test.test_passport_submission import mock_passport

from ..submit_passport import handler
from ..submit_passport import _handler

# Sample mock event
sample_event = {
Expand Down Expand Up @@ -101,7 +101,7 @@ def test_successful_authentication(
scorer_api_key, address, scorer_community_with_binary_scorer.id
)

response = handler(event, MockContext())
response = _handler(event, MockContext())

assert response is not None
body = json.loads(response["body"])
Expand Down Expand Up @@ -146,7 +146,7 @@ def test_successful_authentication_and_base64_encoded_body(
scorer_api_key, address, scorer_community_with_binary_scorer.id
)

response = handler(event, MockContext())
response = _handler(event, MockContext())

assert response is not None
body = json.loads(response["body"])
Expand Down Expand Up @@ -176,7 +176,7 @@ def test_unsucessfull_auth(scorer_account, scorer_community_with_binary_scorer):
"bad_key", scorer_account.address, scorer_community_with_binary_scorer.id
)

response = handler(event, MockContext())
response = _handler(event, MockContext())

assert response is not None
assert response["statusCode"] == 403
Expand Down Expand Up @@ -283,7 +283,7 @@ def test_successful_authentication_and_analytics_logging(
"isBase64Encoded": False,
}

response = handler(event, MockContext())
response = _handler(event, MockContext())

assert response is not None
assert response["statusCode"] == 200
Expand Down Expand Up @@ -359,7 +359,7 @@ def test_failed_authentication_and_analytics_logging(
"isBase64Encoded": False,
}

response = handler(event, MockContext())
response = _handler(event, MockContext())

assert response is not None
assert response["statusCode"] == 403
Expand Down Expand Up @@ -420,12 +420,10 @@ def test_bad_scorer_id_and_analytics_logging(
"isBase64Encoded": False,
}

response = handler(event, MockContext())
response = _handler(event, MockContext())

assert response is not None
assert (
response["statusCode"] == 400
)
assert response["statusCode"] == 400
# Check for the proper analytics entry
analytics_entry = AccountAPIKeyAnalytics.objects.order_by("-created_at")[0]
assert analytics_entry.path == event["path"]
Expand Down
23 changes: 11 additions & 12 deletions api/aws_lambdas/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from functools import wraps
from traceback import print_exc
from typing import Any, Dict, Tuple
import boto3
from botocore.exceptions import ClientError

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "scorer.settings")
os.environ.setdefault("CERAMIC_CACHE_SCORER_ID", "1")
Expand All @@ -20,9 +22,6 @@
# https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
###########################################################

import boto3
from botocore.exceptions import ClientError


def load_secrets():
ssm_srn = os.environ["SCORER_SERVER_SSM_ARN"]
Expand Down Expand Up @@ -58,25 +57,25 @@ def load_secrets():

# pylint: disable=wrong-import-position

import django
import django # noqa: E402

django.setup()

import api_logging as logging
import api_logging as logging # noqa: E402

logger = logging.getLogger(__name__)

from aws_lambdas.exceptions import InvalidRequest
from django.http import HttpRequest
from django_ratelimit.exceptions import Ratelimited
from ninja_jwt.exceptions import InvalidToken
from registry.api.utils import ApiKey, check_rate_limit, save_api_key_analytics
from registry.exceptions import (
from aws_lambdas.exceptions import InvalidRequest # noqa: E402
from django.http import HttpRequest # noqa: E402
from django_ratelimit.exceptions import Ratelimited # noqa: E402
from ninja_jwt.exceptions import InvalidToken # noqa: E402
from registry.api.utils import ApiKey, check_rate_limit, save_api_key_analytics # noqa: E402
from registry.exceptions import ( # noqa: E402
InvalidAddressException,
NotFoundApiException,
Unauthorized,
)
from structlog.contextvars import bind_contextvars
from structlog.contextvars import bind_contextvars # noqa: E402

RESPONSE_HEADERS = {
"Content-Type": "application/json",
Expand Down

0 comments on commit 37c9223

Please sign in to comment.