s3-delete-object
AWS region
import sys
import os
import subprocess
import time
import urllib.request
import json
# ─────────────────────────────────────────
# PRE_EXECUTION
# ─────────────────────────────────────────
for attempt in range(2):
try:
req = urllib.request.Request(
"https://checklist.day/api/registry/boto3",
headers={"User-Agent": "checklist-agent/1.0"}
)
with urllib.request.urlopen(req, timeout=10) as resp:
registry = json.loads(resp.read())
break
except Exception as e:
if attempt == 1:
print(f"ABORT: registry unreachable — {e}")
sys.exit(1)
time.sleep(2)
warnings = registry.get("warnings", [])
if warnings:
print("[boto3] WARNINGS:")
for w in warnings if isinstance(warnings, list) else [warnings]:
print(f" ⚠ {w}")
# ─────────────────────────────────────────
# EXECUTION
# ─────────────────────────────────────────
subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "boto3>=1.26.0"])
import boto3
from botocore.exceptions import ClientError
AWS_ACCESS_KEY_ID = os.environ.get("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = os.environ.get("AWS_SECRET_ACCESS_KEY")
AWS_REGION = os.environ.get("AWS_REGION", "us-east-1")
S3_BUCKET = os.environ.get("S3_BUCKET")
if not AWS_ACCESS_KEY_ID:
print("ABORT: AWS_ACCESS_KEY_ID not set"); sys.exit(1)
if not AWS_SECRET_ACCESS_KEY:
print("ABORT: AWS_SECRET_ACCESS_KEY not set"); sys.exit(1)
if not S3_BUCKET:
print("ABORT: S3_BUCKET not set"); sys.exit(1)
KEY = "checklist-test/delete-test.txt"
MISSING = "checklist-test/does-not-exist-abc123.txt"
client = boto3.client(
"s3",
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
region_name=AWS_REGION,
)
# Setup: create object to delete
client.put_object(Bucket=S3_BUCKET, Key=KEY, Body=b"delete me")
print(f" created: {KEY}")
# 1. Delete existing object
client.delete_object(Bucket=S3_BUCKET, Key=KEY)
print(f" deleted: {KEY}")
# Verify deletion via head_object
# FOOTGUN: delete_object always returns 204 even if key didn't exist — must verify with head_object
delete_ok = False
try:
client.head_object(Bucket=S3_BUCKET, Key=KEY)
print(f" FAIL: object still exists after delete")
except ClientError as e:
if e.response["Error"]["Code"] == "404":
delete_ok = True
print(f" verified deleted: 404 on head_object")
# 2. Delete non-existent key — should NOT raise
# FOOTGUN: delete_object silently succeeds on missing keys — always returns 204
missing_key_silent = False
try:
client.delete_object(Bucket=S3_BUCKET, Key=MISSING)
missing_key_silent = True
print(f" missing key delete: silent success (expected)")
except Exception as e:
print(f" missing key delete raised unexpectedly: {e}")
# ─────────────────────────────────────────
# POST_EXECUTION
# ─────────────────────────────────────────
assert delete_ok, "FAIL: object still exists after delete_object"
assert missing_key_silent, "FAIL: delete_object raised on missing key (unexpected)"
result = {
"delete_ok": delete_ok,
"missing_key_silent": missing_key_silent,
"versioned_delete": False,
}
print(json.dumps(result, indent=2))
print("PASS")