Issues with serializing a base64 encoded media object

What I’m trying to do:
I am attempting to send pdf/jpeg files over an api using base64 encoding (I am at the will of the api structure as it is not mine).

What I’ve tried and what’s not working:

I attempting following both of these links:

Code Sample:

import base64
import anvil.http

def complete_order(order):
  """Method to send complete order back"""
  
 
  files = get_transaction_files(order)
  url = f''
  
  data = {
    "status":1, 
    "transaction_files": files
  }

  #
  # Get Token
  #
  token = pc_get_token()
  
  resp = anvil.http.request(
    url=url,
    method="PUT",
    data=data,
    headers= {
      "Authentication": f"Bearer {token}"
    }
  )

def get_transaction_files(order):
  """get all the files associated with an order, pdf/images"""

  files = []

  #
  # Get uploaded images from driver
  #
  medias = get_media_by_order(order)
  
  for media in medias:
    media = media['media']
    data = encode_media(media)
    file = structure_encoded_data(False,media.name,media.length,data)
    files.append(file)
    
  return files

def structure_encoded_data(private,name,size,data):
  file = {
    "is_private":private,
    "filename":name,
    "file_size":size,
    "base_64_content":data
  }
  
  return file
  
def encode_media(media):
  """base64 encode media data"""
  encoded_data = base64.b64encode(media.get_bytes())
  return encoded_data

Errors:

anvil.server.SerializationError: Cannot serialize arguments to function. Cannot serialize <class 'bytes'> object at msg['kwargs']['data']['transaction_files'][0]['base_64_content']

Print Out of data

'transaction_files': [{'is_private': False, 'filename': 'Order.pdf', 'file_size': 411128, 'base_64_content': b'JVBERi0xLj...'

Is the file size too large?

Clone link:

EDIT
Reading the error more, the issue seams to be I am attempting to serialize bytes, but I can’t see the difference between my method and the two linked methods above! :woozy_face:

I found the explanation to my issue here:

TLDR;
when encoding bytes you receive a bytes object, not a string object.

it was resolved by changing the above encode_media function as follows:

def encode_media(media):
  """base64 encode media data"""
  encoded_data = base64.b64encode(media.get_bytes())
  return encoded_data.decode('utf-8')

This returns the string representation of the encoded bytes.

1 Like