title: Parsing Base64 encoded data containing an image from AWS Lambda with Python
body: <p>I have a Lambda function setup with a <code>POST</code> method that should be able to receive an image as multi-form data, load the image, do some calculations and return a simple array of numbers. The Lambda function sits behind a API Gateway with Lambda-Proxy integration on and <code>multipart/form-data</code> set as a Binary Media Type.</p>
  
  <p>However, I can't for the life of me seem to figure out how to parse the multi-form data that is returned from AWS Lambda. </p>
  
  <p>The <code>event['body']</code> contains base64 encoded data that I can't post here because it takes up too much space. </p>
  
  <p>I use the following snip of code to parse the multi-form data:</p>
  
  <pre><code>from requests_toolbelt.multipart import decoder
  multipart_string = base64.b64decode(body)
  content_type = data['event']['headers']['Content-Type']
  multipart_data = decoder.MultipartDecoder(multipart_string, content_type)
  </code></pre>
  
  <p>where <code>content_type</code> is <code>'multipart/form-data; boundary=--------------------------881952313555430391739156'</code>. </p>
  
  <p>Running through the components of <code>multipart_data</code> like this..</p>
  
  <pre><code>for part in multipart_data.parts:
      print(part.content)
      print(part.headers)
  </code></pre>
  
  <p>gives this. The content (too long to post) looks like this:</p>
  
  <pre><code>b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\ ... x00\x7f\xff\xd9'
  </code></pre>
  
  <p>and the headers:</p>
  
  <pre><code>{b'Content-Disposition': b'form-data; name="image"; filename="8281460-3x2-700x467.jpg"', b'Content-Type': b'image/jpeg'}
  </code></pre>
  
  <p>However, it still is not clear to me <strong>a</strong>) What part of the content is the actual image? <strong>b</strong>) How can I extract the image, and e.g. get it into <code>PIL</code> with <code>Image.open</code>?</p>
  
  <hr>
  
  <p><strong>Supplementary information:</strong></p>
  
  <p>Here is the small Flask app I use to POST the image and return the event data:</p>
  
  <pre><code>import json
  
  from flask import Flask, request 
  
  app = Flask(__name__)
  
  @app.route('/', methods=['GET', 'POST'])
  def hello(event, context):
  
      response = {
          "statusCode": 200,
          "event": event
      }
  
      return {
          "body": json.dumps(response),
      }
  </code></pre>
  
  <p>and here is the POSTMAN request as Python code:</p>
  
  <pre><code>import requests
  
  url = "url-to-lambda-function"
  
  payload = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image\"; filename=\"8281460-3x2-700x467.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
  headers = {
      'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
      'User-Agent': "PostmanRuntime/7.18.0",
      'Accept': "*/*",
      'Cache-Control': "no-cache",
      'Content-Type': "multipart/form-data; boundary=--------------------------881952313555430391739156",
      'Accept-Encoding': "gzip, deflate",
      'Content-Length': "30417",
      'Connection': "keep-alive",
      'cache-control': "no-cache"
      }
  
  response = requests.request("POST", url, data=payload, headers=headers)
  
  print(response.text)
  </code></pre>