Skip to content

Add docstrings checking with ruff and implement the fixes #196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,15 @@ format:
check-format:
poetry run ruff format --check awslambdaric/ tests/

.PHONY: check-docstr
check-docstr:
python3 scripts/dev.py check-docstr

.PHONY: dev
dev: init test

.PHONY: pr
pr: init check-format check-security dev
pr: init check-format check-annotations check-types check-type-usage check-security dev

.PHONY: codebuild
codebuild: setup-codebuild-agent
Expand All @@ -70,17 +74,18 @@ define HELP_MESSAGE
Usage: $ make [TARGETS]

TARGETS
check-security Run bandit to find security issues.
format Run black to automatically update your code to match formatting.
build Build the package using scripts/dev.py.
clean Cleans the working directory using scripts/dev.py.
dev Run all development tests using scripts/dev.py.
init Install dependencies via scripts/dev.py.
build-container Build awslambdaric wheel in isolated container.
test-rie Test with RIE using pre-built wheel (run build-container first).
pr Perform all checks before submitting a Pull Request.
test Run unit tests using scripts/dev.py.
lint Run all linters via scripts/dev.py.
test-smoke Run smoke tests inside Docker.
test-integ Run all integration tests.
check-security Run bandit to find security issues.
check-docstr Check docstrings in project using ruff format check.
format Run ruff to automatically format your code.
build Build the package using scripts/dev.py.
clean Cleans the working directory using scripts/dev.py.
dev Run all development tests using scripts/dev.py.
init Install dependencies via scripts/dev.py.
build-container Build awslambdaric wheel in isolated container.
test-rie Test with RIE using pre-built wheel (run build-container first).
pr Perform all checks before submitting a Pull Request.
test Run unit tests using scripts/dev.py.
lint Run all linters via scripts/dev.py.
test-smoke Run smoke tests inside Docker.
test-integ Run all integration tests.
endef
4 changes: 1 addition & 3 deletions awslambdaric/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
"""
Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
"""
"""Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved."""

__version__ = "3.1.1"
5 changes: 2 additions & 3 deletions awslambdaric/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"""
Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
"""
"""Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved."""

import os
import sys
Expand All @@ -9,6 +7,7 @@


def main(args):
"""Run the Lambda runtime main entry point."""
app_root = os.getcwd()

try:
Expand Down
50 changes: 44 additions & 6 deletions awslambdaric/bootstrap.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
"""
Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
"""
"""Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved."""

import importlib
import json
Expand Down Expand Up @@ -36,6 +34,7 @@


def _get_handler(handler):
"""Get handler function from module."""
try:
(modname, fname) = handler.rsplit(".", 1)
except ValueError as e:
Expand Down Expand Up @@ -82,6 +81,7 @@ def make_error(
stack_trace,
invoke_id=None,
):
"""Create error response."""
result = {
"errorMessage": error_message if error_message else "",
"errorType": error_type if error_type else "",
Expand All @@ -92,6 +92,7 @@ def make_error(


def replace_line_indentation(line, indent_char, new_indent_char):
"""Replace line indentation characters."""
ident_chars_count = 0
for c in line:
if c != indent_char:
Expand All @@ -104,6 +105,7 @@ def replace_line_indentation(line, indent_char, new_indent_char):
_ERROR_FRAME_TYPE = _JSON_FRAME_TYPES[logging.ERROR]

def log_error(error_result, log_sink):
"""Log error in JSON format."""
error_result = {
"timestamp": time.strftime(
_DATETIME_FORMAT, logging.Formatter.converter(time.time())
Expand All @@ -119,6 +121,7 @@ def log_error(error_result, log_sink):
_ERROR_FRAME_TYPE = _TEXT_FRAME_TYPES[logging.ERROR]

def log_error(error_result, log_sink):
"""Log error in text format."""
error_description = "[ERROR]"

error_result_type = error_result.get("errorType")
Expand Down Expand Up @@ -161,6 +164,7 @@ def handle_event_request(
tenant_id,
log_sink,
):
"""Handle Lambda event request."""
error_result = None
try:
lambda_context = create_lambda_context(
Expand Down Expand Up @@ -212,6 +216,7 @@ def handle_event_request(


def parse_json_header(header, name):
"""Parse JSON header."""
try:
return json.loads(header)
except Exception as e:
Expand All @@ -230,6 +235,7 @@ def create_lambda_context(
invoked_function_arn,
tenant_id,
):
"""Create Lambda context object."""
client_context = None
if client_context_json:
client_context = parse_json_header(client_context_json, "Client Context")
Expand All @@ -248,6 +254,7 @@ def create_lambda_context(


def build_fault_result(exc_info, msg):
"""Build fault result from exception info."""
etype, value, tb = exc_info
tb_tuples = extract_traceback(tb)
for i in range(len(tb_tuples)):
Expand All @@ -263,6 +270,7 @@ def build_fault_result(exc_info, msg):


def make_xray_fault(ex_type, ex_msg, working_dir, tb_tuples):
"""Create X-Ray fault object."""
stack = []
files = set()
for t in tb_tuples:
Expand All @@ -281,13 +289,15 @@ def make_xray_fault(ex_type, ex_msg, working_dir, tb_tuples):


def extract_traceback(tb):
"""Extract traceback information."""
return [
(frame.filename, frame.lineno, frame.name, frame.line)
for frame in traceback.extract_tb(tb)
]


def on_init_complete(lambda_runtime_client, log_sink):
"""Handle initialization completion."""
from . import lambda_runtime_hooks_runner

try:
Expand All @@ -311,21 +321,29 @@ def on_init_complete(lambda_runtime_client, log_sink):


class LambdaLoggerHandler(logging.Handler):
"""Lambda logger handler."""

def __init__(self, log_sink):
"""Initialize logger handler."""
logging.Handler.__init__(self)
self.log_sink = log_sink

def emit(self, record):
"""Emit log record."""
msg = self.format(record)
self.log_sink.log(msg)


class LambdaLoggerHandlerWithFrameType(logging.Handler):
"""Lambda logger handler with frame type."""

def __init__(self, log_sink):
"""Initialize logger handler."""
super().__init__()
self.log_sink = log_sink

def emit(self, record):
"""Emit log record with frame type."""
self.log_sink.log(
self.format(record),
frame_type=(
Expand All @@ -336,14 +354,20 @@ def emit(self, record):


class LambdaLoggerFilter(logging.Filter):
"""Lambda logger filter."""

def filter(self, record):
"""Filter log record."""
record.aws_request_id = _GLOBAL_AWS_REQUEST_ID or ""
record.tenant_id = _GLOBAL_TENANT_ID
return True


class Unbuffered(object):
"""Unbuffered stream wrapper."""

def __init__(self, stream):
"""Initialize unbuffered stream."""
self.stream = stream

def __enter__(self):
Expand All @@ -356,16 +380,21 @@ def __getattr__(self, attr):
return getattr(self.stream, attr)

def write(self, msg):
"""Write message to stream."""
self.stream.write(msg)
self.stream.flush()

def writelines(self, msgs):
"""Write multiple lines to stream."""
self.stream.writelines(msgs)
self.stream.flush()


class StandardLogSink(object):
"""Standard log sink."""

def __init__(self):
"""Initialize standard log sink."""
pass

def __enter__(self):
Expand All @@ -375,17 +404,19 @@ def __exit__(self, exc_type, exc_value, exc_tb):
pass

def log(self, msg, frame_type=None):
"""Log message to stdout."""
sys.stdout.write(msg)

def log_error(self, message_lines):
"""Log error message to stdout."""
error_message = ERROR_LOG_LINE_TERMINATE.join(message_lines) + "\n"
sys.stdout.write(error_message)


class FramedTelemetryLogSink(object):
"""
FramedTelemetryLogSink implements the logging contract between runtimes and the platform. It implements a simple
framing protocol so message boundaries can be determined. Each frame can be visualized as follows:
"""FramedTelemetryLogSink implements the logging contract between runtimes and the platform.

It implements a simple framing protocol so message boundaries can be determined. Each frame can be visualized as follows:
<pre>
{@code
+----------------------+------------------------+---------------------+-----------------------+
Expand All @@ -399,6 +430,7 @@ class FramedTelemetryLogSink(object):
"""

def __init__(self, fd):
"""Initialize framed telemetry log sink."""
self.fd = int(fd)

def __enter__(self):
Expand All @@ -409,6 +441,7 @@ def __exit__(self, exc_type, exc_value, exc_tb):
self.file.close()

def log(self, msg, frame_type=None):
"""Log message with frame type."""
encoded_msg = msg.encode("utf8")

timestamp = int(time.time_ns() / 1000) # UNIX timestamp in microseconds
Expand All @@ -421,6 +454,7 @@ def log(self, msg, frame_type=None):
self.file.write(log_msg)

def log_error(self, message_lines):
"""Log error message."""
error_message = "\n".join(message_lines)
self.log(
error_message,
Expand All @@ -429,6 +463,7 @@ def log_error(self, message_lines):


def update_xray_env_variable(xray_trace_id):
"""Update X-Ray trace ID environment variable."""
if xray_trace_id is not None:
os.environ["_X_AMZN_TRACE_ID"] = xray_trace_id
else:
Expand All @@ -437,6 +472,7 @@ def update_xray_env_variable(xray_trace_id):


def create_log_sink():
"""Create appropriate log sink."""
if "_LAMBDA_TELEMETRY_LOG_FD" in os.environ:
fd = os.environ["_LAMBDA_TELEMETRY_LOG_FD"]
del os.environ["_LAMBDA_TELEMETRY_LOG_FD"]
Expand All @@ -451,6 +487,7 @@ def create_log_sink():


def _setup_logging(log_format, log_level, log_sink):
"""Set up logging configuration."""
logging.Formatter.converter = time.gmtime
logger = logging.getLogger()

Expand All @@ -477,6 +514,7 @@ def _setup_logging(log_format, log_level, log_sink):


def run(app_root, handler, lambda_runtime_api_addr):
"""Run Lambda runtime."""
sys.stdout = Unbuffered(sys.stdout)
sys.stderr = Unbuffered(sys.stderr)

Expand Down
Loading