This AWS Lambda function is automatically triggered when a new file is uploaded to a monitored Amazon S3 bucket.
It generates a pre-signed URL for the uploaded file, invokes the /v1/files/fingerprint API with that URL,
and stores the file's SHA-256 fingerprint and metadata on the Algorand blockchain.
fingerprint_lambda/s3_auto_fingerprint_handler.pyimport json
import boto3
import requests
from urllib.parse import unquote_plus
# Constants
FINGERPRINT_API_URL = "https://sandbox.qudefense.com/v1/files/fingerprint"
EXPIRATION_SECONDS = 86400
HEADERS = {
"Content-Type": "application/json",
"qudefense-client-id": "qudefense-outlook-api",
"qudefense-secret-access-key": "G4ZsFDoS2Px7Jqy6oApxN1_onjxLPoH2-nqQnYXBeqo"
}
def lambda_handler(event, context):
try:
# Parse S3 event info
record = event["Records"][0]
bucket = record["s3"]["bucket"]["name"]
key = unquote_plus(record["s3"]["object"]["key"])
# Generate pre-signed URL for the uploaded object
try:
s3 = boto3.client("s3")
presigned_url = s3.generate_presigned_url(
ClientMethod="get_object",
Params={"Bucket": bucket, "Key": key},
ExpiresIn=EXPIRATION_SECONDS,
HttpMethod="GET",
)
print(f"Generated pre-signed URL: {presigned_url}")
except Exception as e:
print(f"Error generating pre-signed URL: {str(e)}")
return
payload = {
"s3_presigned_url": presigned_url
}
try:
response = requests.post(FINGERPRINT_API_URL, json=payload, headers=HEADERS)
print(f"API Response: {response.status_code} - {response.text}")
return {
"statusCode": 200,
"body": json.dumps({"message": "Fingerprint API called successfully"})
}
except Exception as e:
print(f"Error calling fingerprint API: {str(e)}")
except Exception as e:
print(f"Error in Lambda: {str(e)}")
return {
"statusCode": 500,
"body": json.dumps({"error": str(e)})
}
s3:ObjectCreated:Put/v1/files/fingerprintPOST{ "file_url": "<pre-signed-url>" }The following headers are used for API authentication and are hardcoded in the Lambda function:
qudefense-client-idqudefense-secret-access-keyEnsure the Lambda function role has the following AWS permissions:
AmazonS3ReadOnlyAccessAWSLambdaBasicExecutionRole{
"Records": [
{
"s3": {
"bucket": {
"name": "your-s3-bucket"
},
"object": {
"key": "user1/invoice.pdf"
}
}
}
]
}
{
"status": "success",
"fingerprint": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"metadata_hash": "7c4a8d09ca3762af61e59520943dc26494f8941b",
"file_metadata": {
"file_name": "invoice.pdf",
"file_size": 12345,
"file_type": "application/pdf",
"modified_date": "2024-01-01T12:00:00Z"
},
"blockchain_app_id": "123456789",
"blockchain_txid": "ABCDEF123456789",
"file_id": "550e8400-e29b-41d4-a716-446655440000"
}