Repository: sendgrid/sendgrid-python

Issue:
Using .add_header()  raises a TypeError
### Issue Summary
.add_header() cannot be used because python raises a TypeError exception.

### Steps to Reproduce
1. Create an instance of Mail `mail = Mail(  Email(from_email), subject, Email(to_emails), Content('text/html', message) )`
2. Add a header to the instance
`mail.add_header( {'Reply-To' : 'user@server.ext, user@server.ext'} )`
3. Send the Request
`response = sg.client.mail.send.post(request_body=mail.get())`

### Stack Trace
[File "mail.py", line 63](https://github.com/sendgrid/sendgrid-python/blob/master/sendgrid/helpers/mail/mail.py#L63), in **get**
> headers.update(key**.get()**)

TypeError: get expected at least 1 arguments, got 0

Discussion:

Patch:
diff --git a/sendgrid/helpers/mail/mail.py b/sendgrid/helpers/mail/mail.py
index 48d25f1..661c036 100644
--- a/sendgrid/helpers/mail/mail.py
+++ b/sendgrid/helpers/mail/mail.py
@@ -117,7 +117,11 @@ class Mail(object):
     def add_header(self, header):
         if self.headers is None:
             self.headers = []
-        self.headers.append(header)
+        if isinstance(header, dict):
+            (k,v) = list(header.items())[0]
+            self.headers.append(Header(k,v))
+        else:
+            self.headers.append(header)
 
     def add_category(self, category):
         if self.categories is None:


Test patch:
diff --git a/test/test_mail.py b/test/test_mail.py
index e0dc945..9b482dc 100644
--- a/test/test_mail.py
+++ b/test/test_mail.py
@@ -100,6 +100,8 @@ class UnitTests(unittest.TestCase):
         mail.add_header(Header("X-Test1", "test1"))
         mail.add_header(Header("X-Test3", "test2"))
 
+        mail.add_header({"X-Test4" : "test4"})
+
         mail.add_category(Category("May"))
         mail.add_category(Category("2016"))
 
@@ -131,4 +133,4 @@ class UnitTests(unittest.TestCase):
 
         mail.set_reply_to(Email("test@example.com"))
 
-        self.assertEqual(json.dumps(mail.get(), sort_keys=True), '{"asm": {"group_id": 99, "groups_to_display": [4, 5, 6, 7, 8]}, "attachments": [{"content": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12", "content_id": "Balance Sheet", "disposition": "attachment", "filename": "balance_001.pdf", "type": "application/pdf"}, {"content": "BwdW", "content_id": "Banner", "disposition": "inline", "filename": "banner.png", "type": "image/png"}], "batch_id": "sendgrid_batch_id", "categories": ["May", "2016"], "content": [{"type": "text/plain", "value": "some text here"}, {"type": "text/html", "value": "<html><body>some text here</body></html>"}], "custom_args": {"campaign": "welcome", "weekday": "morning"}, "from": {"email": "test@example.com", "name": "Example User"}, "headers": {"X-Test1": "test1", "X-Test3": "test2"}, "ip_pool_name": "24", "mail_settings": {"bcc": {"email": "test@example.com", "enable": true}, "bypass_list_management": {"enable": true}, "footer": {"enable": true, "html": "<html><body>Footer Text</body></html>", "text": "Footer Text"}, "sandbox_mode": {"enable": true}, "spam_check": {"enable": true, "post_to_url": "https://spamcatcher.sendgrid.com", "threshold": 1}}, "personalizations": [{"bcc": [{"email": "test@example.com"}, {"email": "test@example.com"}], "cc": [{"email": "test@example.com", "name": "Example User"}, {"email": "test@example.com", "name": "Example User"}], "custom_args": {"type": "marketing", "user_id": "343"}, "headers": {"X-Mock": "true", "X-Test": "test"}, "send_at": 1443636843, "subject": "Hello World from the Personalized SendGrid Python Library", "substitutions": {"%city%": "Denver", "%name%": "Example User"}, "to": [{"email": "test@example.com", "name": "Example User"}, {"email": "test@example.com", "name": "Example User"}]}, {"bcc": [{"email": "test@example.com"}, {"email": "test@example.com"}], "cc": [{"email": "test@example.com", "name": "Example User"}, {"email": "test@example.com", "name": "Example User"}], "custom_args": {"type": "marketing", "user_id": "343"}, "headers": {"X-Mock": "true", "X-Test": "test"}, "send_at": 1443636843, "subject": "Hello World from the Personalized SendGrid Python Library", "substitutions": {"%city%": "Denver", "%name%": "Example User"}, "to": [{"email": "test@example.com", "name": "Example User"}, {"email": "test@example.com", "name": "Example User"}]}], "reply_to": {"email": "test@example.com"}, "sections": {"%section1%": "Substitution Text for Section 1", "%section2%": "Substitution Text for Section 2"}, "send_at": 1443636842, "subject": "Hello World from the SendGrid Python Library", "template_id": "13b8f94f-bcae-4ec6-b752-70d6cb59f932", "tracking_settings": {"click_tracking": {"enable": true, "enable_text": true}, "ganalytics": {"enable": true, "utm_campaign": "some campaign", "utm_content": "some content", "utm_medium": "some medium", "utm_source": "some source", "utm_term": "some term"}, "open_tracking": {"enable": true, "substitution_tag": "Optional tag to replace with the open image in the body of the message"}, "subscription_tracking": {"enable": true, "html": "<html><body>html to insert into the text/html portion of the message</body></html>", "substitution_tag": "Optional tag to replace with the open image in the body of the message", "text": "text to insert into the text/plain portion of the message"}}}')
+        self.assertEqual(json.dumps(mail.get(), sort_keys=True), '{"asm": {"group_id": 99, "groups_to_display": [4, 5, 6, 7, 8]}, "attachments": [{"content": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3JhcyBwdW12", "content_id": "Balance Sheet", "disposition": "attachment", "filename": "balance_001.pdf", "type": "application/pdf"}, {"content": "BwdW", "content_id": "Banner", "disposition": "inline", "filename": "banner.png", "type": "image/png"}], "batch_id": "sendgrid_batch_id", "categories": ["May", "2016"], "content": [{"type": "text/plain", "value": "some text here"}, {"type": "text/html", "value": "<html><body>some text here</body></html>"}], "custom_args": {"campaign": "welcome", "weekday": "morning"}, "from": {"email": "test@example.com", "name": "Example User"}, "headers": {"X-Test1": "test1", "X-Test3": "test2", "X-Test4": "test4"}, "ip_pool_name": "24", "mail_settings": {"bcc": {"email": "test@example.com", "enable": true}, "bypass_list_management": {"enable": true}, "footer": {"enable": true, "html": "<html><body>Footer Text</body></html>", "text": "Footer Text"}, "sandbox_mode": {"enable": true}, "spam_check": {"enable": true, "post_to_url": "https://spamcatcher.sendgrid.com", "threshold": 1}}, "personalizations": [{"bcc": [{"email": "test@example.com"}, {"email": "test@example.com"}], "cc": [{"email": "test@example.com", "name": "Example User"}, {"email": "test@example.com", "name": "Example User"}], "custom_args": {"type": "marketing", "user_id": "343"}, "headers": {"X-Mock": "true", "X-Test": "test"}, "send_at": 1443636843, "subject": "Hello World from the Personalized SendGrid Python Library", "substitutions": {"%city%": "Denver", "%name%": "Example User"}, "to": [{"email": "test@example.com", "name": "Example User"}, {"email": "test@example.com", "name": "Example User"}]}, {"bcc": [{"email": "test@example.com"}, {"email": "test@example.com"}], "cc": [{"email": "test@example.com", "name": "Example User"}, {"email": "test@example.com", "name": "Example User"}], "custom_args": {"type": "marketing", "user_id": "343"}, "headers": {"X-Mock": "true", "X-Test": "test"}, "send_at": 1443636843, "subject": "Hello World from the Personalized SendGrid Python Library", "substitutions": {"%city%": "Denver", "%name%": "Example User"}, "to": [{"email": "test@example.com", "name": "Example User"}, {"email": "test@example.com", "name": "Example User"}]}], "reply_to": {"email": "test@example.com"}, "sections": {"%section1%": "Substitution Text for Section 1", "%section2%": "Substitution Text for Section 2"}, "send_at": 1443636842, "subject": "Hello World from the SendGrid Python Library", "template_id": "13b8f94f-bcae-4ec6-b752-70d6cb59f932", "tracking_settings": {"click_tracking": {"enable": true, "enable_text": true}, "ganalytics": {"enable": true, "utm_campaign": "some campaign", "utm_content": "some content", "utm_medium": "some medium", "utm_source": "some source", "utm_term": "some term"}, "open_tracking": {"enable": true, "substitution_tag": "Optional tag to replace with the open image in the body of the message"}, "subscription_tracking": {"enable": true, "html": "<html><body>html to insert into the text/html portion of the message</body></html>", "substitution_tag": "Optional tag to replace with the open image in the body of the message", "text": "text to insert into the text/plain portion of the message"}}}')