title: Saving image from multipart/form-data using AWS Lambda (Python)
body: <p>I am using multipart/form-data with Ajax to send strings and upload a file. I am able to parse the strings somehow and I believe I am able to get the image file in string format as well but when I save the image to an S3 bucket and try to open it , it says "file format not supported".</p>
  
  <p>Here is the HTML code:</p>
  
  <pre><code>      &lt;div  class="form"&gt;
              &lt;form method="POST" enctype="multipart/form-data" id="fileUploadForm"&gt;
                  &lt;p class="contact"&gt;&lt;label for="company"&gt;Company&lt;/label&gt;&lt;/p&gt;
                      &lt;input id="company" name="company" placeholder="Company Name" required="" tabindex="1" type="text" value="MyCompany"&gt;
                      &lt;p class="contact"&gt;&lt;label for="name"&gt;Driver Name&lt;/label&gt;&lt;/p&gt;
                  &lt;input id="name" name="name" placeholder="First and last name" required="" tabindex="2" type="text" value="Alex"&gt;
                        &lt;p class="contact"&gt;&lt;label for="gender"&gt;Gender&lt;/label&gt;&lt;/p&gt;
              &lt;select class="select-style gender" name="gender" id="gender"&gt;
              &lt;option value="m" selected="selected"&gt;Male&lt;/option&gt;
              &lt;option value="f"&gt;Female&lt;/option&gt;
              &lt;option value="others"&gt;Other&lt;/option&gt;
              &lt;/select&gt;&lt;br&gt;&lt;br&gt;
  
                          &lt;p class="contact"&gt;&lt;label for="vehicletype"&gt;Vehicle Type&lt;/label&gt;&lt;/p&gt;
                          &lt;select class="select-style gender" name="vehicletype" id="vtype"&gt;
                          &lt;option value="car" selected="selected"&gt;Car&lt;/option&gt;
                          &lt;option value="truck"&gt;Truck&lt;/option&gt;
                          &lt;option value="bus"&gt;Bus&lt;/option&gt;
                          &lt;/select&gt;&lt;br&gt;&lt;br&gt;
  
                      &lt;p class="contact"&gt;&lt;label for="vehicleNo"&gt;Vehicle Registration Number&lt;/label&gt;&lt;/p&gt;
                      &lt;input id="vehicleNo" name="vehicleNo" placeholder="Vehicle Number" required="" type="text" value="PB03W1234"&gt;
  
            &lt;p class="contact"&gt;&lt;label for="phone"&gt;Mobile phone&lt;/label&gt;&lt;/p&gt;
              &lt;select name="Country_Code"&gt;
    &lt;option value="volvo"&gt;Select Country Code  &lt;/option&gt;
    &lt;option value="+91" selected="selected"&gt;+91 - India &lt;/option&gt;
  &lt;/select&gt;
  &lt;br&gt;
   &lt;br&gt;           &lt;input id="phone" name="phone" placeholder="Mobile number" required="" type="text" required="" pattern="[0-9]{10}" value="9999999999"&gt; &lt;br&gt;
          &lt;p class="contact"&gt;&lt;label for="phone"&gt;Photo&lt;/label&gt;&lt;/p&gt;
              &lt;input type="file" name="pic" accept="image/*"&gt;&lt;br&gt;
                  &lt;p class="contact"&gt;&lt;label for="phone"&gt;Driving License &lt;/label&gt;&lt;/p&gt;
              &lt;input type="file" name="dl" accept="image/*"&gt;&lt;br&gt;
          &lt;p class="contact"&gt;&lt;label for="phone"&gt;Registration Certificate &lt;/label&gt;&lt;/p&gt;
              &lt;input type="file" name="rc" accept="image/*"&gt;&lt;br&gt;
              &lt;input class="buttom" name="submit" id="submit" tabindex="5" value="Register" type="submit"&gt;
  
     &lt;/form&gt;
  
  </code></pre>
  
  <p>Here is AJAX Call:</p>
  
  <pre><code>        $.ajax({
              url: API_ENDPOINT,
              type: 'POST',
              /*headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
              },*/
              headers: {
                'Content-Type': 'multipart/form-data'
              },
              enctype: 'multipart/form-data',
              contentType: false,
              data: data,
              processData: false,
              // contentType: false,
              cache: false,
              timeout: 600000,
              success: function (data) {
  
                  $("#result").text(data);
                  console.log("SUCCESS : ", data);
                  $("#submit").prop("disabled", false);
  
              },
              error: function (e) {
  
                  $("#result").text(e.responseText);
                  console.log("ERROR : ", e);
                  $("#submit").prop("disabled", false);
  
              }
          });
  
  </code></pre>
  
  <p>and here is the Python Code with which I am trying to save the file:</p>
  
  <pre><code>import json
  from cgi import parse_header, parse_multipart, FieldStorage
  from io import StringIO, BytesIO
  import boto3
  import base64
  import re
  
  s3 = boto3.resource('s3')
  bucket = s3.Bucket('MyBucket1234')
  path_test = '/tmp/output'         # temp path in lambda.
  
  def lambda_handler(event, context):
  
      myEvent = event['body']
      for r in ((string2replace, ""), ('\r\n', ""), (abc, ""), ("name=", "")):
          myEvent = myEvent.replace(*r)
  
  
      myEvent = myEvent.replace('"*"', 'abc')
  
      resultStart = myEvent.find("Content-Type: image/png") + 23
      resultEnd = myEvent.find("dl") - 2
  
      data = myEvent[resultStart:resultEnd]  #This Give me start and end of Image File.
  
  
  
      key = "Image.png"          # assign filename to 'key' variable
  
  
   object = s3.Object('MyBucket1234', key)
      object.put(Body=data)
  
      return {
          'statusCode': 200,
          'body': json.dumps('Hello from Lambda!'),
          'headers': {
              'Content-Type': 'application/json',
              'Access-Control-Allow-Origin': '*'
              },
      }
  
  
  </code></pre>
  
  <p>From cloudwatch logs, I can see Event['body'] output like this:</p>
  
  <pre><code>
  'body': '------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="company"\r\n\r\nMyCmp\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="name"\r\n\r\nAlex\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="gender"\r\n\r\nm\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="vehicletype"\r\n\r\ncar\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="vehicleNo"\r\n\r\nDL03W1234\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="Country_Code"\r\n\r\n+91\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="phone"\r\n\r\n8989898998\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="pic"; filename="Ansible_Logo.png"\r\nContent-Type: image/png\r\n\r\n�PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00�\x00\x00\x00�\x08\x04\x00\x00\x00i7�@\x00\x00\x00\x04gAMA\x00\x00��\x0b�a\x05\x00\x00\x00\x01sRGB\x00��\x1c�\x00\x00\x00 cHRM\x00\x00z&amp;\x00\x00��\x00\x00�\x00\x00\x00��\x00\x00u0\x00\x00�`\x00\x00:�\x00\x00\x17p��Q&lt;\x00\x00\x00\x02bKGD\x00���̿\x00\x00\x00\tpHYs\x00\x00\x00H\x00\x00\x00H\x00F�k&gt;\x00\x00\x0c\x1aIDATx��kpTE\x16�\x7f3y\x07H�\x11Bx�\x10] ��D\x14T\x1e\x05Z� �\x12\x05V,\x04�\x05|�b\x15\n"�Z��%*R\x08,�+�(��"&gt;\x11\x04Vむ\x08&amp;D\t\x10 !\x04\x08\x10H&amp;C���\x0c�ͼ2�^�N������G�����t�~\x04"� �\x08"� �\x08"�m�\x16���ĸsg~+\x04؉%�t:�J"-IB\x00(�I\x19e������5\x12�L&amp;=�KoRI�\x05ͼ�8C\x15����Mle/%��:\x08��+C��~�b\x0f�\t��]|�Wl�ܭ#\x17)R\x18�2\x0eR�\x18H\x15la\x06}����Жɬ�Ґ��S\x1d{y�싍����Z�&amp;�?���C��ǵ^�R*.���4a\x07S���߂)\x14\\`�ϥj�ӻi���"ӭ&gt;p����7U�g}H��O��"��\to�vvY ~}SX@��f�F��"�\x05�,+�ܔj�\x0e\x0eX(~�W��˚N�\x17Y,~=\x05�Ii\n\x04\x0c�T�����i\x1en�{�]��\x17\x04\x07Ӊ\r��-YiF\x00�dH�t\x14��w��\x13&gt;�cy�\x1a3�O�\x13"R&amp;7��`+Y�"`(%f꿓8�\x1e[��\x19c���p�߆�͈o�ir\x0e52Č%8Ÿp����6C@\x0b�I��}�6C�wt���.�0W���KC�C~g�g8�hc�h\x0cQ�C\x0f3�E3�A�\t�3\x13��b\x1c�V�\x7f7~1���H�4D��4�F\x17O[�\x01Q�a��&lt;�+�w\x19��耝Qt���;��\\���Bw��d�҅�\x12k�N�Z5�1�\\��&amp;c��\x7f&amp;WH�2�}�u���\x1f3�\x1bR��ę�/�?��[��2��\r[e\x00�X\x139�F��\x06p�r���"��r���L��9ç�Ѐ&gt;�b1QLTžG9P�*5�2\x9c3\x1c@��\x0f�^1W�\x1d娻��r��oC�M�.�f�~�kC�\x01Iz��\x0e\x1f�q�7�;����\\ws�O��\n�\x13�j��Ռ�*�T����5w.���L\x03F��X�8x�N��\x060By�Ri��{�j\x18\x0e�l�\x11��\x17$ӯ\x01]̸�\x18�V����+\x07Y���D3�0=��F\x0b��\x7f�\n�8�*�k�+CX`fTp�^�Ԁhڙ1�w���\x7f�.��?�՝��\x00�:\x10�o�H/\x01Iff�R4��\x7f���Z�B�\x7fȸ!���\x13Я\x01���\x7f�\nۜ�\x07���g\x1cQ�Ʈ��))�$�\x12�\x1a\x10�\x14U\\\x1c/���R&gt;W�u��Q�]�&lt;�~\r0��=\x18��5�5��(��\x1bԹ�#ik� \t%\x01&amp;�\x15�=\n��K����G�w�.e�%�{�\x04�p\x19�\x0e�ў\x162�AH���J\x07\x1e�d!�^\x02NQa�\x00�(�t��9��\x7f��tVu-��;ߓ~�\x1a@](\tkcl\x11L3\x15�\x11yA�e�\x14i¡E2D�j��\r��7��\x15T1&gt;�\x04ı�\x08\x017�\x10H�d\x0bb���\x1b\r\x05��g�sߛ�F\x0b\'��\nNr[h\x1b�b��G�\n%�z%h+y�AX�Mw\x078A�R\x7f��\x7fҴ���\x120\x13�^\x02�����]\x1a���/R�� W��M�IJ_\n$Y/\x01{I\x0b-\x01\x7f��w\x12|�\x12�D�6�\x16%7K���2\x19)Q�JJU�|�^\x02��"�\x04�显Oj�\x11�\x05e�·�{�6\r\x05NyBR�E��c�d�Lo�z�H[��#`�Rh��\x10�&gt;��\x7f5�\x06����\x1a�ҷV�P�\x1c�Y�G�x�I��[�\t�8\x1b��y��5\x01�\x017���4Iϲ��4��c\x03��(�]c*��+)�\x13����\x13Ћ��\r�|�\x06�{¬w�%\x13�\x0c��`�a\x1ds�\x18@��~�\x04��2%ȼ T9M�탂�IBp��1�\x08Q#�\rn\x12t��\x1e�\x05%D�&lt;�C\x07\x06\x06G@�U+G3��\x1dl�qp�$&gt;�~��R�A�\x12�\nff�I��! �9�5.� �\x08������j)h@@��o��B+w��m|}p�|�\x048�s��&amp;\x1d�\x06\x14�n�\x00�\x0b��P����G\x00\x0e�����rՀ^�h@�\x04\x1e�:csi�PG\x197\x05Z�a�?��O&gt;��@��"jX�/��\x15{��\x1d�}�\x12�\x1a�V\x19�\x03�r6p\x13�U��J`�$K�$5���\\���dS\x18\x17�k�\x19\x1e�.�����\x1co\x02�ױڊ\x0e�/$�j�f`I�g�\x00�\x1f��:��W�U�\x1f�\x18Ȟ0�\x7f�y��+�u�wq4L��0�\x11��B叄�\x18~C7�\x04b��7Tz\x01�w��� ��z��&amp;Sn������A�,�������x�x\x0c?[�w���v+�\x12�X\x1bL��D:�\x0cZ҄ё�Bf\rβ�\x11��*\x1b��A\x0e\x1b��(�;�9�t.\x12td�\x05�\x07\'Y�Ц_�Zع���m�\x0c���\x7fDNS&lt;5$�nr\x16���D\'�\x00o32�g\x04�,i\x0e�p+��^G-�r�&lt;�`#�8B\x1b\u0530\x06Ѵ�j��A7.%�(�%���8{(`\x1b�ɧʊ�����6�%�L:�D�\nd���r�(��\x13\x1c����\x1d�iæ��k�\x11D\x10A\x04\x11D`�3�jd`\x03�,wt���8\x01�\\���쉖�#�\r���\x03�����/�k�I\x02PI\x11��Ei��ø�\x0f9���`�\x10�F\x15?�G��[�2������8zҗt�J���\x1f�\x1cԜ�R����\x1b)\'�Adv\x01\x9d\x1ew�\'�Z*(���Tr��̟U����4\\8��\x14�pp�y^�\x7f&amp;�b���n�,�q�{�\'9�{�G"�����&amp;���\x03N�($�,f3�C~�O�\x01�Y�r��6t �kØ�gP��\x17�\x1a;B\'\x1eb*�x�c+D �\x1d�c\x14�\x0c�Tb�\x15�8�CA\x10`g\x14�l�\x1f�X�u�&gt;H5�ǘI�_E��$o�\x05��jod�p�S�y�\x7f2�%A�V�ӗ�,`��wQ�[\x03!�\x11�d\x0eь�y���lg\x12w�}���f�ɳ\x1fmة�&amp;���*l�\x04c�\x03\x16;�.&lt;�\x17|�Mt���\n6��.��\x14����\x1dgXL/Ɠ�;�b��E,vR�\x00����\x1cg�_-�E�jF�\x10���:�,\x07}7��h��T0\x08��*\x1e�&gt;�\n�!��p���~� d�7�9K\x01\x7f�y���&gt;��\x0c����^\x1c\x08k�f\x02&amp;P\x17�\x08�2\x17�E%�Tr��F4�/}i�\x138Y�^rX���a\x19ݙ�L\x1e��m��\x14+\x18�mL\'��,��6���H.;�\x011��\x1a��\x00\x07�\x0eō�N\x0e��B\\@-y��?����]���h^����ԀD�\x1d\x1fS�#,��\x01�K7��\x18\'�\'\x08\r�����Wk���pƁ4�-�)gL0�\x06�\x1b�Lna\x07��#N擉�1&gt;w2\np�g(�q\x06\x06l�\x05��\x19�1�� [�9��\x16�"��K�=el\n�_u�\'�\x162��b&gt;e"[\x18F\x1c�\x078�`+���1[\x1fMG�UM\x08�\x08���6ڰcÎ\x1d;-\x19\x04\x14���|:o�8H\x1a�5�\x08Q��&lt;�S����Q&gt;\x01`;���D�\x19�V\r���hs���,f\x12��zڱ\x02\x07�ٍ�h�r\'NV{�\x00��*��t�\x06���-lf�WH�?�5��\x15�O\x1dc\x19ټ�u�\x06hN:%,��G���\x00Z�:��\x10���ä\x10�!��\x12�+E�a&gt;]\x18�v�֣��\x19�x�Ņ�"��?\x1ee\x1d����\x1f���j�k-+�ˁ\x06w\x1cf?��_��a�"@x�Z&amp;3�\t��\x16\x07kY�\x00�_3ҞC�&lt;�z%�M\x05{4-3�tNQ�Q�42��QL\x0c��B\n���0\x05\x1c���J��#\x04�D\'��e٨��+N\x1cG\x06�\x11\x0ex�\x14[ҍT����b�pD��\x11D\x10A\x04\x11D\x10A\x04\x11D\x10A\x04n�\x1f�0P�\x1a4\x0f�\x00\x00\x00MtEXtcomment\x00File source: https://commons.wikimedia.org/wiki/File:Ansible_Logo.png��K\x00\x00\x00%tEXtdate:create\x002015-10-07T12:57:59+00:00\x1a�Í\x00\x00\x00%tEXtdate:modify\x002015-10-07T12:57:59+00:00k�{1\x00\x00\x00GtEXtsoftware\x00ImageMagick 6.7.7-10 2014-03-06 Q16 http://www.imagemagick.orgo���\x00\x00\x00\x18tEXtThumb::Document::Pages\x001���/\x00\x00\x00\x18tEXtThumb::Image::height\x002002�\x16�\x00\x00\x00\x17tEXtThumb::Image::Width\x00200�&amp;E4\x00\x00\x00\x19tEXtThumb::Mimetype\x00image/png?�VN\x00\x00\x00\x17tEXtThumb::MTime\x001444222679��\x15=\x00\x00\x00\x13tEXtThumb::Size\x002.04KBB��\r{\x00\x00\x00\x00IEND�B`�\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="dl"; filename=""\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W\r\nContent-Disposition: form-data; name="rc"; filename=""\r\nContent-Type: application/octet-stream\r\n\r\n\r\n------WebKitFormBoundaryz3PvAgjndyUmKY0W--\r\n', 'isBase64Encoded': False}
  
  </code></pre>
  
  <p>I have been struggling with this from more than a week now. Please suggest something to unblock the situation.</p>