"""API Gateway handler: validate API key, create job, start Step Functions.""" import json import uuid import time import os import boto3 from shared import get_user, api_response, JOBS_TABLE, S3_BUCKET sfn = boto3.client('stepfunctions') ddb = boto3.resource('dynamodb') def handler(event, context): # Parse body try: body = json.loads(event.get('body', '{}')) except Exception: return api_response(400, {'error': 'Invalid JSON body'}) api_key = body.get('api_key') or event.get('headers', {}).get('x-api-key', '') curl_command = body.get('curl') cookies = body.get('cookies', '') if not api_key: return api_response(401, {'error': 'Missing api_key'}) if not curl_command: return api_response(400, {'error': 'Missing curl'}) # Validate user user = get_user(api_key) if not user: return api_response(401, {'error': 'Invalid API key'}) # Create job job_id = str(uuid.uuid4())[:8] now = int(time.time()) ttl = now + 7 * 86400 # 7 days table = ddb.Table(JOBS_TABLE) table.put_item(Item={ 'job_id': job_id, 'api_key': api_key, 'email': user.get('email', ''), 'status': 'SUBMITTED', 'created_at': now, 'ttl': ttl, }) # Store curl + cookies in S3 (avoid DynamoDB size limits) s3 = boto3.client('s3') s3.put_object( Bucket=S3_BUCKET, Key=f"jobs/{job_id}/input.json", Body=json.dumps({ 'curl': curl_command, 'cookies': cookies, 'language': body.get('language', 'auto'), }), ContentType='application/json', ) # Start Step Functions state_machine_arn = os.environ.get('STATE_MACHINE', '') sfn.start_execution( stateMachineArn=state_machine_arn, name=f"job-{job_id}", input=json.dumps({ 'job_id': job_id, 'email': user.get('email', ''), 'user_name': user.get('name', ''), }), ) return api_response(200, { 'job_id': job_id, 'message': 'Job submitted, you will receive an email when complete.', })