New to Kestra?
Use blueprints to kickstart your first workflows.
Schedule a Kestra flow that checks an S3 object's last-modified date and reprocesses the file only when it changed since the previous run.
Reprocess an Amazon S3 object only when it has actually changed, instead of blindly running on every schedule tick. This flow checks the S3 object's LastModified timestamp against the previous execution time and skips work when the file is unchanged, saving compute and avoiding duplicate downstream processing for incremental S3 data pipelines.
schedule trigger (io.kestra.plugin.core.trigger.Schedule) fires every five minutes via the cron */5 * * * *.process_file_if_changed task (io.kestra.plugin.scripts.python.Commands) runs a Python script in a Docker taskRunner (io.kestra.plugin.scripts.runner.docker.Docker), installing awswrangler as a dependency.s3_modified.py from namespaceFiles and calls it with the bucket and object variables plus {{ trigger.date ?? execution.startDate }} as the comparison date.boto3 head_object to read the S3 object's LastModified value and compares it to the passed-in date, printing whether the file needs reprocessing or is unchanged.Add the following Python script named s3_modified.py in the Editor:
import boto3
from datetime import datetime
import argparse
def parse_date(date_str):
if date_str.endswith('Z'):
return datetime.fromisoformat(date_str.replace('Z', '+00:00'))
return datetime.fromisoformat(date_str)
def check_s3_object_modification(bucket, object, trigger_date):
s3 = boto3.client("s3")
response = s3.head_object(Bucket=bucket, Key=object)
last_modified = response["LastModified"]
comparison_datetime = parse_date(trigger_date)
if last_modified > comparison_datetime:
print(f"The file '{object}' was modified at {last_modified} and needs to be reprocessed.")
else:
print(f"The file '{object}' is unchanged.")
def main():
parser = argparse.ArgumentParser(description='Check if an S3 object was modified after a given date.')
parser.add_argument('bucket_name', help='Name of the S3 bucket')
parser.add_argument('object_key', help='Key of the S3 object')
parser.add_argument('comparison_date', help='Date to compare against in ISO format')
args = parser.parse_args()
check_s3_object_modification(args.bucket_name, args.object_key, args.comparison_date)
if __name__ == "__main__":
main()
awswrangler and boto3 available.A bare cron job would reprocess the file on every tick regardless of whether it changed. Kestra adds the event-aware comparison ({{ trigger.date ?? execution.startDate }}), declarative YAML, retries, execution history, and lineage across runs. The Schedule trigger and namespace files let you keep the logic versioned and observable, filling the gap that a plain scheduler and ad hoc scripts cannot: knowing what changed, when, and what ran as a result.
AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_DEFAULT_REGIONs3_modified.py script as a namespace file in the Editor.AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_DEFAULT_REGION Secrets.bucket and object variables to point at your S3 object.