Search code examples
pythonunicodeutf-8recurly

Recurly python client raising UnicodeDecodeError when supplying non-ascii characters


I'm trying to create accounts from the API of Recurly using the Python client. Python 2.7, recurly 2.2.17

When creating a new account with a first name (or any other attribute actually) containing non-ascii characters (fetched as a unicode), saving the entity raises UnicodeDecodeError: 'ascii' codec can't decode byte [...]

A simple account.first_name = u'Frédérique-Fançois'.encode('utf-8') still raises the same error but at another level in the module.


Solution

  • recurly.API_KEY and recurly.SUBDOMAIN must be passed str objects.

    You might be in trouble if your are using unicode_literals or if your configuration source provides unicode values. In this case, you need to convert them either through str if values do not contain non-ascii characters, or with encode().

    E.g.

    from __future__ import unicode_literals
    
    # You can force it like this
    account.API_KEY = str('my api key here')
    account.SUBDOMAIN = str('advanseez')
    

    Doing this ensures that the underlying httplib will not convert HTTP headers to unicode thus conflicting with any non-ascii characters present the message body which is always str when working with Recurly client.

    This way you can safely assign attributes in any Recurly resource using unicode.

    E.g.

    account = recurly.Account(account_code='12345689', first_name=u'Frédérique-François')
    account.save()  # Works without raising UnicodeDecodeError
    

    For detailed demonstration of the problem, workaround and explanation of the problem's origin see (Note use of import unicode_literals, which changes default string type as Unicode): https://gist.github.com/maximehardy/d3a0a6427d2b6791b3dc