Repository: boto/boto

Issue:
boto.sqs.connection.send_message_batch does not work when message attributes are provided
If you try to send a batch of messages with boto.sqs.connection.send_message_batch and have attributes set on the batch items, you will get an error message that the message attribute 'X' must contain non-empty message attribute value.

this is because the string "Value" is missing from the p_name key for each of the cases.

for example: p_name = '%s.%i.DataType' % (base, j + 1)
is supposed to be: p_name = '%s.%i.Value.DataType' % (base, j + 1)



Discussion:

Resolving patch:
diff --git a/boto/sqs/connection.py b/boto/sqs/connection.py
--- a/boto/sqs/connection.py
+++ b/boto/sqs/connection.py
@@ -425,19 +425,19 @@ def send_message_batch(self, queue, messages):
                     params[p_name] = name
 
                     if 'data_type' in attribute:
-                        p_name = '%s.%i.DataType' % (base, j + 1)
+                        p_name = '%s.%i.Value.DataType' % (base, j + 1)
                         params[p_name] = attribute['data_type']
                     if 'string_value' in attribute:
-                        p_name = '%s.%i.StringValue' % (base, j + 1)
+                        p_name = '%s.%i.Value.StringValue' % (base, j + 1)
                         params[p_name] = attribute['string_value']
                     if 'binary_value' in attribute:
-                        p_name = '%s.%i.BinaryValue' % (base, j + 1)
+                        p_name = '%s.%i.Value.BinaryValue' % (base, j + 1)
                         params[p_name] = attribute['binary_value']
                     if 'string_list_value' in attribute:
-                        p_name = '%s.%i.StringListValue' % (base, j + 1)
+                        p_name = '%s.%i.Value.StringListValue' % (base, j + 1)
                         params[p_name] = attribute['string_list_value']
                     if 'binary_list_value' in attribute:
-                        p_name = '%s.%i.BinaryListValue' % (base, j + 1)
+                        p_name = '%s.%i.Value.BinaryListValue' % (base, j + 1)
                         params[p_name] = attribute['binary_list_value']
 
         return self.get_object('SendMessageBatch', params, BatchResults,


Test patch:
diff --git a/tests/integration/sqs/test_connection.py b/tests/integration/sqs/test_connection.py
--- a/tests/integration/sqs/test_connection.py
+++ b/tests/integration/sqs/test_connection.py
@@ -129,6 +129,17 @@ def test_1_basic(self):
                 br = queue_1.delete_message_batch(msgs)
                 deleted += len(br.results)
 
+        # try a batch write with message attributes
+        num_msgs = 10
+        attrs = {
+            'foo': {
+                'data_type': 'String',
+                'string_value': 'Hello, World!'
+            },
+        }
+        msgs = [(i, 'This is message %d' % i, 0, attrs) for i in range(num_msgs)]
+        queue_1.write_batch(msgs)
+
         # create another queue so we can test force deletion
         # we will also test MHMessage with this queue
         queue_name = 'test%d' % int(time.time())
diff --git a/tests/unit/sqs/test_connection.py b/tests/unit/sqs/test_connection.py
--- a/tests/unit/sqs/test_connection.py
+++ b/tests/unit/sqs/test_connection.py
@@ -296,15 +296,15 @@ def test_send_message_attributes(self):
             'Action': 'SendMessageBatch',
             'SendMessageBatchRequestEntry.1.DelaySeconds': 0,
             'SendMessageBatchRequestEntry.1.Id': 1,
-            'SendMessageBatchRequestEntry.1.MessageAttribute.1.DataType': 'String',
             'SendMessageBatchRequestEntry.1.MessageAttribute.1.Name': 'name1',
-            'SendMessageBatchRequestEntry.1.MessageAttribute.1.StringValue': 'foo',
+            'SendMessageBatchRequestEntry.1.MessageAttribute.1.Value.DataType': 'String',
+            'SendMessageBatchRequestEntry.1.MessageAttribute.1.Value.StringValue': 'foo',
             'SendMessageBatchRequestEntry.1.MessageBody': 'Message 1',
             'SendMessageBatchRequestEntry.2.DelaySeconds': 0,
             'SendMessageBatchRequestEntry.2.Id': 2,
-            'SendMessageBatchRequestEntry.2.MessageAttribute.1.DataType': 'Number',
             'SendMessageBatchRequestEntry.2.MessageAttribute.1.Name': 'name2',
-            'SendMessageBatchRequestEntry.2.MessageAttribute.1.StringValue': '1',
+            'SendMessageBatchRequestEntry.2.MessageAttribute.1.Value.DataType': 'Number',
+            'SendMessageBatchRequestEntry.2.MessageAttribute.1.Value.StringValue': '1',
             'SendMessageBatchRequestEntry.2.MessageBody': 'Message 2',
             'Version': '2012-11-05'
         })