Repository: frankV/flask-sendgrid

Issue:
AttributeError: module 'sendgrid' has no attribute 'SendGridClient'
This library doesn't seem to work with any versions of https://github.com/sendgrid/sendgrid-python released in the past year or so. `SendGridClient` was renamed to `SendGridAPIClient`.

Comments:

Patch:
diff --git a/README.md b/README.md
index e91d349..75ad0ea 100755
--- a/README.md
+++ b/README.md
@@ -13,22 +13,18 @@ Installation
 Usage
 -----
 
-    from flask.ext.sendgrid import FlaskSendGrid
+    from flask.ext.sendgrid import SendGrid
 
     app = Flask(__name__)
     app.config['SENDGRID_API_KEY'] = 'your api key'
     app.config['SENDGRID_DEFAULT_FROM'] = 'admin@yourdomain.com'
-    sendgrid = FlaskSendGrid(app)
+    sendgrid = SendGrid(app)
     sendgrid.send_email(
         from_email='someone@yourdomain.com',
-        subject='Subject',
-        template_id='some_id',
-        substitutions={ ':name': 'Peter Piper' },
-        to=[{'email': 'someone@somedomain.com'}, {'email': 'someoneelse@someotherdomain.com'}],
-        text='Hello World'
+        subject='Subject'
+        to_email='someoneelse@someotherdomain.com',
+        text='Body',
     )
 
-Using templates (`template_id` and `substitutions`) is purely optional.
-
 
 For additional information about mail parameters: [SendGrid Web API Mail](https://sendgrid.com/docs/API_Reference/Web_API/mail.html#parameters-mail)
diff --git a/flask_sendgrid.py b/flask_sendgrid.py
index c6178a0..84003a8 100755
--- a/flask_sendgrid.py
+++ b/flask_sendgrid.py
@@ -1,7 +1,8 @@
-import sendgrid
+from sendgrid import SendGridAPIClient
+from sendgrid.helpers.mail import Mail, Email, Content
 
 
-class FlaskSendGrid(object):
+class SendGrid(object):
     app = None
     api_key = None
     default_from = None
@@ -15,32 +16,31 @@ class FlaskSendGrid(object):
         self.api_key = app.config['SENDGRID_API_KEY']
         self.default_from = app.config['SENDGRID_DEFAULT_FROM']
 
-    def send_email(self, **opts):
-        if not opts.get('from_email', None) and not self.default_from:
-            raise ValueError('No from email or default_from was configured')
+    def send_email(self, to_email, subject, from_email=None,
+                   html=None, text=None):
+        if not any([from_email, self.default_from]):
+            raise ValueError("Missing from email and no default.")
+        if not any([html, text]):
+            raise ValueError("Missing html or text.")
 
-        client = sendgrid.SendGridClient(self.api_key)
-        message = sendgrid.Mail()
+        sg = SendGridAPIClient(apikey=self.api_key)
 
-        for _ in opts['to']:
-            message.add_to(_['email'])
+        mail = Mail(
+            from_email=Email(from_email or self.default_from),
+            subject=subject,
+            to_email=Email(to_email),
+            content=Content("text/html", html) if html
+                else Content("text/plain", text),
+        )
+
+        return sg.client.mail.send.post(request_body=mail.get())
 
         # Use a template if specified. 
         # See https://github.com/sendgrid/sendgrid-python/blob/master/examples/example_v2.py
-        if opts.get('template_id', None):
-            message.add_filter('templates', 'enable', '1')
-            message.add_filter('templates', 'template_id', opts['template_id'])
-
-            substitutions = opts.get('substitutions', dict()).items()
-            for key, value in substitutions:
-                message.add_substitution(key, value)
-
-        message.set_from(opts.get('from_email', None) or self.default_from)
-        message.set_subject(opts['subject'])
-
-        if opts.get('html', None):
-            message.set_html(opts['html'])
-        elif opts.get('text', None):
-            message.set_html(opts['text'])
+#         if opts.get('template_id', None):
+#             message.add_filter('templates', 'enable', '1')
+#             message.add_filter('templates', 'template_id', opts['template_id'])
 
-        return client.send(message)
+#             substitutions = opts.get('substitutions', dict()).items()
+#             for key, value in substitutions:
+#                 message.add_substitution(key, value)
diff --git a/setup.py b/setup.py
index ff333b5..cafcfcd 100755
--- a/setup.py
+++ b/setup.py
@@ -26,8 +26,9 @@ Usage
         sendgrid = SendGrid(app)
         sendgrid.send_email(
             from_email='someone@yourdomain.com',
-            to=[{'email': 'someoneelse@someotherdomain.com'}],
-            text='Hello World'
+            subject='Subject'
+            to_email='someoneelse@someotherdomain.com',
+            text='Body',
         )
 """
 
@@ -48,7 +49,7 @@ setup(
     py_modules=['flask_sendgrid'],
     zip_safe=False,
     platforms='any',
-    install_requires=['Flask', 'SendGrid'],
+    install_requires=['Flask', 'SendGrid~=3.0'],
     classifiers=[
         'Development Status :: 3 - Alpha',
         'Environment :: Web Environment',


Test patch:
diff --git a/tests.py b/tests.py
index 6e1b643..2e55a73 100755
--- a/tests.py
+++ b/tests.py
@@ -1,6 +1,6 @@
 import unittest
 from mock import MagicMock
-from flask_sendgrid import FlaskSendGrid
+from flask_sendgrid import SendGrid
 
 # Set up test API key for emails
 app = MagicMock()
@@ -10,18 +10,18 @@ app.config['SENDGRID_API_KEY'] = '12345'
 app.config['SENDGRID_DEFAULT_FROM'] = 'from'
 
 
-class FlaskSendGridTest(unittest.TestCase):
+class SendGridTest(unittest.TestCase):
 
     def setUp(self):
-        self.mail = FlaskSendGrid(app)
+        self.mail = SendGrid(app)
 
     def test_get_api_key(self):
         self.assertEqual(self.mail.api_key, app.config['SENDGRID_API_KEY'])
 
     def test_fails_no_key(self):
-        mail = FlaskSendGrid()
+        mail = SendGrid()
         self.assertRaises(ValueError, mail.send_email)
 
     def test_fails_no_sender(self):
-        mail = FlaskSendGrid()
+        mail = SendGrid()
         self.assertRaises(ValueError, mail.send_email, key='ABCDEFG')