"TypeError: BlobMedia content must be a byte string" when generating BlobMedia csv file

I started getting this error in a production app that generates csv files for my customers.

After having no luck fixing in my production app, I replicated the error in a bare-bones Anvil app.

# Client
class Form1(Form1Template):

  def __init__(self, **properties):
    # Set Form properties and Data Bindings.
    self.init_components(**properties)

  def button_1_click(self, **event_args):
    """This method is called when the button is clicked"""
    anvil.server.call('create_csv')

# Server
@anvil.server.callable
def create_csv():
    df = pd.DataFrame({'a': [1,2,3]})
    df_as_csv = df.to_csv(index=False)
    csv_media = anvil.BlobMedia('text/plain', df_as_csv, name='my_data.csv')
    return csv_media

TypeError: BlobMedia content must be a byte string. at /downlink/anvil/__init__.py, line 71 called from [ServerModule1, line 22](javascript:void(0)) called from [Form1, line 15](javascript:void(0))


https://anvil.works/build#clone:R2NBKU22TZCVEVGR=AXR3HDECV7O3CVKIZNFQL3U4

If possible, I’d love to know if this is indeed an Anvil framework issue.

Update:

Forcing the string to bytes fixes the error. I might be mistaken, but I don’t think I ever had to do this before. I’m glad, though, to have things working again.

# Server
@anvil.server.callable
def create_csv():
    df = pd.DataFrame({'a': [1,2,3]})
    df_as_csv = df.to_csv(index=False)

    csv_bytes = bytes(df_as_csv, 'utf-8') # fix

    csv_media = anvil.BlobMedia('text/plain', csv_bytes, name='my_data.csv')
    return csv_media

I’m seeing this change too. I tried an old app that I had posted on the forum and got the same error.

For example:

1 Like

Thanks, @alcampopiano, for confirming that I am not (totally) crazy.

Does anyone know if there is a log of changes to the Anvil backend that we can access? I checked out the open-source github projects but it looks like they are not updated in real time.

The open source project is just a very small parts of the hosted Anvil system, I am afraid.

At the moment, it apprears that no info about breaking changes is officially available unfortunately. However, you can submit a feature request.

Hi @matt and @alcampopiano,

You’re right that this is a recent change. Media objects contain raw binary data, so in Python 3 the second argument to the BlobMedia() constructor should always have been bytes rather than str. Using a str will cause weird downstream breakage with non-ASCII characters, so we recently added a more helpful up-front error message.

To convert a str to bytes, you can just call .encode() on the content you’d like to create your BlobMedia object with. To take your example, @matt:

@anvil.server.callable
def create_csv():
  df = pd.DataFrame({'a': [1,2,3]})
  df_as_csv = df.to_csv(index=False)
  csv_media = anvil.BlobMedia('text/plain', df_as_csv.encode(), name='my_data.csv')
  return csv_media
3 Likes