In AWS Lambda's Python code, I created a function that returns a result based on a specified date (one year ago if not specified).
from datetime import datetime
from dateutil.relativedelta import relativedelta
one_year_ago = (datetime.now() - relativedelta(years=1)).isoformat()[:-3] + "Z"
def lambda_handler(event, context):
#Function in question
def test_func(last_time: str = one_year_ago) -> str:
return "last_time: " + last_time
print(one_year_ago)
#Where the function is called
print(test_func("2019-09-20T06:28:26.000Z"))
print(test_func())
return 0
lambda_handler("","")
Execution result
2018-12-08T20:22:57.183Z
last_time: 2019-09-20T06:28:26.000Z
last_time: 2018-12-08T20:22:57.183Z
According to AWS Lambda's Best Practices, it is better to separate the logic. Because it was a thing, I corrected it as follows.
from datetime import datetime
from dateutil.relativedelta import relativedelta
one_year_ago: str = ""
def lambda_handler(event, context):
global one_year_ago
one_year_ago = (datetime.now() - relativedelta(years=1)).isoformat()[:-3] + "Z"
print(one_year_ago)
#Where the function is called
print(test_func("2019-09-20T06:28:26.000Z"))
print(test_func())
return 0
#Function in question
def test_func(last_time: str = one_year_ago) -> str:
return "last_time: " + last_time
lambda_handler("","")
--Other than the Lambda handler part, it is called only at the time of cold start [^ 1], so it is in the handler to ask for one year ago.
- Therefore, the first code itself does not work properly.
--Define the variable with an empty string in advance (otherwise it will be "not defined").
What happened
If you specify a date, it works, but if you do not specify it, an error occurs. The default value seems to be disabled.
Execution result
2018-12-08T20:15:21.611Z
last_time: 2019-09-20T06:28:26.000Z
last_time:
- The actual code was throwing a boto3 request, and the error InvalidParameterValueException [^ 2] was output.
Conclusion
The default argument is evaluated only the first time, so the first empty string has been set.
https://note.nkmk.me/python-argument-default/
I think it's not cool, but I avoided it by doing the following for the time being.
Code
from datetime import datetime
from dateutil.relativedelta import relativedelta
one_year_ago: str = ""
def lambda_handler(event, context):
global one_year_ago
one_year_ago = (datetime.now() - relativedelta(years=1)).isoformat()[:-3] + "Z"
print(one_year_ago)
#Where the function is called
print(test_func("2019-09-20T06:28:26.000Z"))
print(test_func())
return 0
#Function in question
def test_func(last_time: str = "one_year_ago") -> str:
if last_time == "one_year_ago":
last_time = one_year_ago
return "last_time: " + last_time
lambda_handler("","")
Execution result
2018-12-08T20:21:13.942Z
last_time: 2019-09-20T06:28:26.000Z
last_time: 2018-12-08T20:21:13.942Z
Digression
――I think there seems to be a more beautiful way of writing.
――There is a feeling of being forced to ask for a year ago. ..
one_year_ago = (datetime.now() - relativedelta(years=1)).isoformat()[:-3] + "Z"
--Actually, I want to store the inquiry history to AWS support in DynamoDB, I'm writing this code.
def cases_get(last_time: str = "one_year_ago") -> list:
if last_time == "one_year_ago":
last_time = one_year_ago
cases_detail: list = []
for lang in ("ja", "en"):
for page in cases_paginator.paginate(
includeResolvedCases=True,
maxResults=100,
language=lang,
includeCommunications=False,
afterTime=last_time,
):
for cases in page["cases"]:
cases["displayId"] = int(cases["displayId"])
cases["yearIndex"] = int(cases["timeCreated"][:4])
cases_detail.append(cases)
return cases_detail