title: Uploading a file from memory to S3 with Boto3
body: <p>This question has been asked many times, but my case is ever so slightly different. I'm trying to create a lambda that makes an .html file and uploads it to S3. It works when the file was created on disk, then I can upload it like so:</p>
  <pre><code>boto3.client('s3').upload_file('index.html', bucket_name, 'folder/index.html')
  </code></pre>
  <p>So now I have to create the file in memory, for this I first tried <a href="https://docs.python.org/3/library/io.html#io.StringIO" rel="noreferrer">StringIO()</a>. However then <code>.upload_file</code> throws an error.</p>
  <pre><code>boto3.client('s3').upload_file(temp_file, bucket_name, 'folder/index.html')
  ValueError: Filename must be a string`. 
  </code></pre>
  <p>So I tried using <code>.upload_fileobj()</code> but then I get the error <code>TypeError: a bytes-like object is required, not 'str'</code></p>
  <p>So I tried using <a href="https://docs.python.org/3/library/io.html" rel="noreferrer">Bytesio()</a> which wants me to convert the str to bytes first, so I did:</p>
  <pre><code>temp_file = BytesIO()
  temp_file.write(index_top.encode('utf-8'))
  print(temp_file.getvalue())
  boto3.client('s3').upload_file(temp_file, bucket_name, 'folder/index.html')
  </code></pre>
  <p>But now it just uploads an empty file, despite the <code>.getvalue()</code> clearly showing that it does have content in there.</p>
  <p>What am I doing wrong?</p>