0

I'm playing around with Microsoft Azure to send messages to a subscription in the Cloud via a Topic. But ran into issues with Microsofts python sdk, specifically a ValueError when deserializing a message from the cloud.

This is my code

bus_service = ServiceBusService(
    service_namespace='"<namegoeshere>"',
    shared_access_key_name='"<nameofkeygoeshere>"',
    shared_access_key_value='"<keyvaluegoeshere>"')

bus_service.create_topic('topic')
bus_service.create_subscription('topic', 'AllMessages')
msg = Message("HelloWorld")
bus_service.send_topic_message('topic', msg)

// at this point I can see the message arrive in my Azure portal

// then it crashes when I try to retrieve the message I just sent
msg = bus_service.receive_subscription_message('topic', 'AllMessages', peek_lock=False)
print(msg.body)

This is the error:

Traceback (most recent call last):
  File "C:/Users/user/PycharmProjects/test/helloworld.py", line 59, in <module>
msg = bus_service.receive_subscription_message('topic', 'AllMessages', peek_lock=False)
  File "D:\Program Files\Anaconda2\lib\site-packages\azure\servicebus\servicebusservice.py", line 976, in receive_subscription_message
timeout)
  File "D:\Program Files\Anaconda2\lib\site-packages\azure\servicebus\servicebusservice.py", line 764, in read_delete_subscription_message
return _create_message(response, self)
  File "D:\Program Files\Anaconda2\lib\site-packages\azure\servicebus\_serialization.py", line 101, in _create_message
elif str(int(float(value))) == value:
ValueError: could not convert string to float: max-age=31536000

Process finished with exit code 1

I went into the class and had a look:

def _create_message(response, service_instance):
    ''' Create message from response.

    response:
        response from service bus cloud server.
    service_instance:
        the service bus client.
'''
respbody = response.body
custom_properties = {}
broker_properties = None
message_type = None
message_location = None

# gets all information from respheaders.
for name, value in response.headers:
    if name.lower() == 'brokerproperties':
        broker_properties = json.loads(value)
    elif name.lower() == 'content-type':
        message_type = value
    elif name.lower() == 'location':
        message_location = value
    elif name.lower() not in ['content-type',
                              'brokerproperties',
                              'transfer-encoding',
                              'server',
                              'location',
                              'date']:

        if '"' in value:
            value = value[1:-1]
            try:
                custom_properties[name] = datetime.strptime(
                    value, '%a, %d %b %Y %H:%M:%S GMT')
            except ValueError:
                custom_properties[name] = value
        else:  # only int, float or boolean
            if value.lower() == 'true':
                custom_properties[name] = True
            elif value.lower() == 'false':
                custom_properties[name] = False
            # int('3.1') doesn't work so need to get float('3.14') first
            elif str(int(float(value))) == value:    # <---- Exception !
                custom_properties[name] = int(value)
            else:
                custom_properties[name] = float(value)

Any ideas what I could do to resolve this?

2 Answers 2

1

This is a bug is version 0.20.1, see Change Log in Pypi. From 0.20.2 released 2016-06-28, the bug is fixed. https://pypi.python.org/pypi/azure-servicebus

Reference issue: https://github.com/Azure/azure-sdk-for-python/issues/669

Thank you,

Sign up to request clarification or add additional context in comments.

Comments

0

I had to change Microsofts _serialization.py file to get it to work. Wrapping the offending block in a try/except block:

if '"' in value:
    value = value[1:-1]
    try:
        custom_properties[name] = datetime.strptime(
            value, '%a, %d %b %Y %H:%M:%S GMT')
    except ValueError:
        custom_properties[name] = value
else:  # only int, float or boolean
    try:
        if value.lower() == 'true':
            custom_properties[name] = True
        elif value.lower() == 'false':
            custom_properties[name] = False
        # int('3.1') doesn't work so need to get float('3.14') first
        elif str(int(float(value))) == value:
            custom_properties[name] = int(value)
        else:
            custom_properties[name] = float(value)
    except ValueError:
        custom_properties[name] = value

Seems to work so far..

So, Microsoft... Any chance of a job?...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.