code: def handle_batch(image_urls: List[str]):
      tensor_list = []
  
      # download and preprocess each image
      for image_url in image_urls:
          if image_url.startswith("s3://"):
              bucket, image_key = re.match(
                  "s3://(.+?)/(.+)", image_url
              ).groups()
              image_bytes = s3.get_object(Bucket=bucket, Key=image_key)[
                  "Body"
              ].read()
          elif image_url.startswith("http"):
              image_bytes = requests.get(image_url).content
          else:
              raise RuntimeError(f"{image_url}: invalid image url")
  
          img_pil = Image.open(BytesIO(image_bytes))
          tensor_list.append(app.preprocess(img_pil))
  
      # classify the batch of images
      img_tensor = torch.stack(tensor_list).to(app.device)
      with torch.no_grad():
          prediction = app.model(img_tensor)
      _, indices = prediction.max(1)
  
      # extract predicted classes
      results = [
          {"url": image_urls[i], "class": app.labels[class_idx]}
          for i, class_idx in enumerate(indices)
      ]
      json_output = json.dumps(results)
  
      # save results
      prediction_id = uuid.uuid4()
      s3.put_object(
          Bucket=app.bucket,
          Key=f"{app.key}/{prediction_id}.json",
          Body=json_output,
      )
  
file_path: cortex/test/apis/batch/image-classifier-alexnet/app/main.py
imports: import os, json, re
  import requests
  import torch
  import torchvision
  import boto3
  import uuid
  from typing import List
  from PIL import Image
  from io import BytesIO
  from torchvision import transforms
  from fastapi import FastAPI, Request, status
  from fastapi.responses import PlainTextResponse
label_desc: Use image node_id 3 for calling a global function with example usage: handle_batch(image_urls) without return types