Giter Site home page Giter Site logo

sendgrid / sendgrid-python Goto Github PK

View Code? Open in Web Editor NEW
1.5K 226.0 707.0 2.16 MB

The Official Twilio SendGrid Python API Library

Home Page: https://sendgrid.com

License: MIT License

Python 99.62% Shell 0.01% HTML 0.09% Dockerfile 0.05% Makefile 0.21% Procfile 0.01%
python sendgrid email transactional-emails

sendgrid-python's Introduction

SendGrid Logo

BuildStatus Docker Badge MIT licensed Twitter Follow GitHub contributors Open Source Helpers

This library allows you to quickly and easily use the SendGrid Web API v3 via Python.

Version 3.X.X+ of this library provides full support for all SendGrid Web API v3 endpoints, including the new v3 /mail/send.

This library represents the beginning of a new path for SendGrid. We want this library to be community driven and SendGrid led. We need your help to realize this goal. To help make sure we are building the right things in the right order, we ask that you create issues and pull requests or simply upvote or comment on existing issues or pull requests.

If you need help using SendGrid, please check the Twilio SendGrid Support Help Center.

Please browse the rest of this README for further detail.

Table of Contents

Installation

Prerequisites

  • Python version 2.7+
  • The SendGrid service, starting at the free level

Setup Environment Variables

Mac

Update the development environment with your SENDGRID_API_KEY (more info here), for example:

echo "export SENDGRID_API_KEY='YOUR_API_KEY'" > sendgrid.env
echo "sendgrid.env" >> .gitignore
source ./sendgrid.env

SendGrid also supports local environment file .env. Copy or rename .env_sample into .env and update SENDGRID_API_KEY with your key.

Windows

Temporarily set the environment variable(accessible only during the current cli session):

set SENDGRID_API_KEY=YOUR_API_KEY

Permanently set the environment variable(accessible in all subsequent cli sessions):

setx SENDGRID_API_KEY "YOUR_API_KEY"

Install Package

pip install sendgrid

Dependencies

Quick Start

Hello Email

The following is the minimum needed code to send an email with the /mail/send Helper (here is a full example):

With Mail Helper Class

import sendgrid
import os
from sendgrid.helpers.mail import *

sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
from_email = Email("[email protected]")
to_email = To("[email protected]")
subject = "Sending with SendGrid is Fun"
content = Content("text/plain", "and easy to do anywhere, even with Python")
mail = Mail(from_email, to_email, subject, content)
response = sg.client.mail.send.post(request_body=mail.get())
print(response.status_code)
print(response.body)
print(response.headers)

The Mail constructor creates a personalization object for you. Here is an example of how to add it.

Without Mail Helper Class

The following is the minimum needed code to send an email without the /mail/send Helper (here is a full example):

import sendgrid
import os

sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
data = {
  "personalizations": [
    {
      "to": [
        {
          "email": "[email protected]"
        }
      ],
      "subject": "Sending with SendGrid is Fun"
    }
  ],
  "from": {
    "email": "[email protected]"
  },
  "content": [
    {
      "type": "text/plain",
      "value": "and easy to do anywhere, even with Python"
    }
  ]
}
response = sg.client.mail.send.post(request_body=data)
print(response.status_code)
print(response.body)
print(response.headers)

General v3 Web API Usage (With Fluent Interface)

import sendgrid
import os

sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
response = sg.client.suppression.bounces.get()
print(response.status_code)
print(response.body)
print(response.headers)

General v3 Web API Usage (Without Fluent Interface)

import sendgrid
import os

sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
response = sg.client._("suppression/bounces").get()
print(response.status_code)
print(response.body)
print(response.headers)

Processing Inbound Email

Please see our helper for utilizing our Inbound Parse webhook.

Usage

Use Cases

Examples of common API use cases, such as how to send an email with a transactional template.

Announcements

All updates to this library are documented in our CHANGELOG and releases.

How to Contribute

We encourage contribution to our libraries (you might even score some nifty swag), please see our CONTRIBUTING guide for details.

Quick links:

Troubleshooting

Please see our troubleshooting guide for common library issues.

About

sendgrid-python is maintained and funded by Twilio SendGrid, Inc. The names and logos for sendgrid-python are trademarks of Twilio SendGrid, Inc.

Support

If you need support, please check the Twilio SendGrid Support Help Center.

License

The MIT License (MIT)

sendgrid-python's People

Contributors

0bsearch avatar aaronmak avatar adityatandon007 avatar af4ro avatar artiemq avatar blackpioter avatar brandonmwest avatar cmccandless avatar codevbus avatar crweiner avatar dsouzarc avatar eddiezane avatar eshanholtz avatar gabrielkrell avatar heitortsergent avatar hugovk avatar iandouglas avatar jennifermah avatar liychristopher avatar manisha1997 avatar mbernier avatar meahow avatar misterdorm avatar navinpai avatar theycallmeswift avatar thinkingserious avatar tushdante avatar twilio-ci avatar twilio-dx avatar vinayak42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sendgrid-python's Issues

message.add_to no longer accepts tuples

The old add_to equivalent method would take a tuple like (email, name) when setting the recipient, but that doesn't seem to be the case now. It looks like I'll have to compile my own name <email> strings.

I see that the API has changed (a lot) since then, but I think this would still be something worth supporting. What are your thoughts?

Thanks!

A potential bug?

Hi,

I am using the python sendgrid package here: https://github.com/sendgrid/sendgrid-python

Yesterday, I updated to the latest version: 0.3.1

But when I ran my program, I got the following error:
maximum recursion depth exceeded while calling a Python object

A part of the error is :

C:\Users\ChengLu\crowdadvice\adviceapp\manager\emails.py in send_verification_email
message.add_to(user.email) ...
โ–ถ Local vars
C:\Python27\lib\site-packages\sendgrid\message.py in add_to
self.add_to(email) ...
โ–ถ Local vars
C:\Python27\lib\site-packages\sendgrid\message.py in add_to
self.add_to(email) ...
โ–ถ Local vars
C:\Python27\lib\site-packages\sendgrid\message.py in add_to
self.add_to(email) ...
โ–ถ Local vars
C:\Python27\lib\site-packages\sendgrid\message.py in add_to
self.add_to(email) ...
โ–ถ Local vars
C:\Python27\lib\site-packages\sendgrid\message.py in add_to
self.add_to(email) ...
โ–ถ Local vars
C:\Python27\lib\site-packages\sendgrid\message.py in add_to

I think there may be some problem with the function add_to() in the latest version...

BCC and CC are broken.

sg = sendgrid.SendGridClient(settings.SEND_GRID_USERNAME,
                             settings.SEND_GRID_PASSWORD,
                             raise_errors=True)
message.set_subject(subject)
message.set_replyto(self.replyto)
message.set_from(self.from_email)
if test_email_address:
    message.add_category("test")
else:
    message.add_category(category)
message.add_attachment(attachment_filename, attachement_path)

message.add_filter('clicktrack', 'enable', 1)
message.add_filter('opentrack', 'enable', 1)

message.add_to(email)
message.add_bcc('[email protected]')
status, msg = sg.send(message)

After raising the error with Ron in support, it seems the API is broken and cant send out BCC or CC anymore.

Please advice ASAP.

Many Thanks,
Houman

Tagged releases?

Would you mind tagging v0.3.4 (what's currently on PyPI)? (In the event that I wanted to patch it, it would be useful to know where to base the patch off in Git.)

Set Content-Id on attachments if requested

Message.add_attachment() receives a cid parameter, but neither transport does anything with it. I think the SMTP transport should have these lines added near the end of the _getFileMIME() method:

if attach.get('cid'):
    msg.add_header('Content-Id', '<' + attach['cid'] + '>')

Message's docstring lies.

In https://github.com/sendgrid/sendgrid-python/blob/master/sendgrid/message.py#L21, the docstring claims that one of the args is from. The function's code appears to expect from_email and from_name.

Though it'd be great if it took from, however, note that from is a reserved word in Python, and this means you can't say:

sendgrid.Message(from='John Smith <[email protected]>')

โ€ฆyou have to sayโ€ฆ

sendgrid.Message(**{'from': 'John Smith <[email protected]>'})

โ€ฆwhich is slightly annoying.

set_headers method not working

The set_headers method should accept a dictionary, like the following:

message.set_headers({'X-Sent-Using': 'SendGrid-API', 'X-Transport': 'web'});

But that only raises the following error:

sendgrid.exceptions.SendGridClientError: (400, '{"message": "error", "errors": ["JSON in headers could not be parsed"]}')

I couldn't find any code related to the headers parameters on the send method as well.

Support for parsing inbound emails

The only documentation available for inbound email handling contains a simple PHP script. It would be nice if Sendgrid could provide fully-documented code for parsing their inbound emails as well.

problem sending subject/body with non-ascii characters

When I send an email with non-ascii characters in the subject or body, these appear as question marks when the email arrives. Perhaps this is due to me sending the email incorrectly, or perhaps this is a core sendgrid issue more than a sendgrid-python issue, but I have not been able to sort it out. I have tried setting the encoding of my Python script (via the Python "magic comment"), but that doesn't help.

Here is a simple script that shows what I am talking about:

import sendgrid
s = sendgrid.Sendgrid('username', 'password', secure=True)
message = sendgrid.Message('[email protected]', u'Que dรญa mรกs bueno hace', u'Que dรญa mรกs bueno hace')
message.add_to('[email protected]')
s.web.send(message)

I have also tried these two versions of the sendgrid.Message call:

message = sendgrid.Message('[email protected]', 'Que dรญa mรกs bueno hace', 'Que dรญa mรกs bueno hace')
message = sendgrid.Message('[email protected]', u'Que d\u00EDa m\u00E1s bueno hace', html=u'Que d\u00EDa m\u00E1s bueno hace')

In all three cases, the emails come through with question marks where the non-ascii characters are.

I also tried adding this filter, but it did not help:

message.add_header("Content-Type", "text/html charset=utf-8")

Am I making an obvious mistake? Thanks.

SSLError: The read operation timed out

We just have sent out 270 emails via Sendgrid's APi using this library when we got the exception

SSLError: The read operation timed out

This is not great, as its hard to say who has received it.
What can be done to fix this please?

Thanks,
Houman

Python API doesn't successfully do substitution.

Substitution doesn't appear to work. Here's my test code:

#!/usr/bin/env python

user = 'REMOVED'
password = 'REMOVED'

import os
import sys
from   datetime import datetime as dt

import sendgrid
import smtpapi

sg      = sendgrid.SendGridClient(user,password)
message = sendgrid.Mail()
message.add_to('[email protected]')
message.add_bcc('[email protected]')
message.set_subject('Tested @ '+str(dt.today()))
message.set_text('''This is a test, it is only a test. Do not adjust your expectations.
                 Hello, -world-''')
message.add_substitution('-world-','Charlie')
message.set_from('[email protected]')

print message.data

status, msg = sg.send(message)

print status
print msg

Here's the example output, using the library as currently loaded with pip install

(sendgrid)bash $ python sgt.py 
{'sub': {'-world-': ['Charlie']}}
200
{"message":"success"}

And here's the email text as delivered:


Delivered-To: [email protected]
Received: by 10.70.126.7 with SMTP id mu7csp233571pdb;
        Mon, 24 Mar 2014 14:01:52 -0700 (PDT)
X-Received: by 10.50.11.36 with SMTP id n4mr14094506igb.3.1395694911863;
        Mon, 24 Mar 2014 14:01:51 -0700 (PDT)
Return-Path: <[email protected]>
Received: from o2.bn.sendgrid.net (o2.bn.sendgrid.net. [208.115.214.177])
        by mx.google.com with SMTP id v10si22265177igb.37.2014.03.24.14.01.23
        for <[email protected]>;
        Mon, 24 Mar 2014 14:01:51 -0700 (PDT)
Received-SPF: pass (google.com: domain of [email protected] designates 208.115.214.177 as permitted sender) client-ip=208.115.214.177;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of [email protected] designates 208.115.214.177 as permitted sender) [email protected];
       dkim=pass [email protected]
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sendgrid.me; 
    h=mime-version:from:to:subject:content-type; s=smtpapi; 
    bh=vDs5hKXED7ie4mejfFMneIWc0g0=; b=QqWZms8K4AucK2a/z4Y5N3V73bF+I
    HWnS3J3f983sUw39EXkkhEaP9Imu203Gg7+zbIbQ8E6PKxl/PH9rV5FP9oueMNRP
    AeXrN0FodDb0VqG9xL/27Is7Oal6q/OuPxcRZvoiHKKqIjNnhw4OnKQa/ZqSJ/P9
    PML5sK8vIf471s=
Received: by filter-186.sjc1.sendgrid.net with SMTP id filter-186.18923.53309D22E
        Mon, 24 Mar 2014 21:01:22 +0000 (UTC)
Received: from NDIwODMy (c-67-165-251-56.hsd1.co.comcast.net [67.165.251.56])
    by localhost.localdomain (SG) with HTTP id 144f5e5d04c.3284.16d93e0
    Mon, 24 Mar 2014 21:01:22 +0000 (GMT)
MIME-Version: 1.0
From: [email protected]
To: [email protected]
Subject: Tested @ 2014-03-24 15:01:22.550601
Date: Mon, 24 Mar 2014 21:01:22 GMT
Message-ID: <[email protected]>
Content-type: multipart/alternative; boundary="----------=_1395694883-3864-20"
X-SG-EID: YE9D3amB11oCx+ueBrCAM1haFwBHQh6mFMZpGXg8NPN2lMcCCF8zJ1OqQZMrjmtSUCY4nVrpgm1Ds0wglDqNQLgZ6kiBSundt+DWPTuwt7TCd1YHV26nuZ2AaMh1/Dq2uDQxHiUv8tcTaANBxkfG5zlqqR72ejEKGeYZBgStYtw=

This is a multi-part message in MIME format...

------------=_1395694883-3864-20
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable

This is a test, it is only a test. Do not adjust your expectations.

                 Hello,=20

------------=_1395694883-3864-20
Content-Type: text/html; charset="utf-8"
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

<html><body>
<p>This is a test, it is only a test. Do not adjust your expectations.</p>
<pre>Hello, </pre>

<img src=3D"http://u420832.sendgrid.org/wf/open?upn=3DCAmjcb10sNExu9QJmZkHE=
5aqPSBSAdaQMtST1HPHtAEcG8RgLvjpteSfqUkaoWOI4DKvQweEVbQg2r41YKk18Efg2KKp-2Fo=
OaZWryKaoUs8bLEl6OZci3h1qoBxq2WFvsbxEvBMhEfMDsLKUZ7h3PdGFUTEmjGbxCP4r5A1FOa=
8IzkLK7Btvy1cdgIIFZSFb58ldVfHNW3LjvMctd-2FtZUHQ-3D-3D" alt=3D"" width=3D"1"=
 height=3D"1" border=3D"0" style=3D"height:1px !important;width:1px !import=
ant;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !impo=
rtant;margin-right:0 !important;margin-left:0 !important;padding-top:0 !imp=
ortant;padding-bottom:0 !important;padding-right:0 !important;padding-left:=
0 !important;"/>
</body></html>

------------=_1395694883-3864-20--

Wrong mail where only text body is specified

If I specify only text body, then i recieve an email were text is None (html field).
I guess it is not problem of library since encoded url looks good to me.

Data:

{'to[]': u'<removed>', 'from': '<removed>', 'subject': u'Test subject', 'replyto': '', 'headers': '', 'fromname': 'MiuMeet Notification ', 'date': 'Wed, 19 Feb 2014 15:29:14 GMT', 'html': None, 'api_user': '', 'text': u'Test test test', 'x-smtpapi': '{}', 'api_key': '<removed>', 'toname[]': []}

Encoded url:

to%5B%5D=<removed>&from=<removed>&subject=Test+subject&replyto=&headers=&fromname=<removed>&date=Wed%2C+19+Feb+2014+15%3A29%3A14+GMT&html=None&api_user=<removed>&text=Test+test+test&x-smtpapi=%7B%7D&api_key=<removed>%3D

Exceeded 30 redirects exception.

I've solved this issue by sending request to 'https://sendgrid.com/api/mail.send.json' instead of 'https://api.sendgrid.com/api/mail.send.json'

Trimmed Traceback (most recent call last):
File "sendgrid.py", line 42, in send
r = requests.post(url=self.mailUrl, data=self._build_body(message), proxies=self.proxies)
File "requests/api.py", line 88, in post
return request('post', url, data=data, *_kwargs)
File "requests/api.py", line 44, in request
return session.request(method=method, url=url, *_kwargs)
File "sessions.py", line 396, in request
resp = self.send(prep, **send_kwargs)
File "/requests/sessions.py", line 525, in send
history = [resp for resp in gen] if allow_redirects else []
File "requests/sessions.py", line 99, in resolve_redirects
raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects)
TooManyRedirects: Exceeded 30 redirects.

Tag versions

In case a later version of the sendgrid library breaks compatibility, introduces a bug or changes behavior, it would be nice to be able to pip install a specific version of this library

Cc not really working as expected

import sendgrid

to = ['[email protected]']
cc = ['[email protected]']

message = sendgrid.Mail(to=to, subject=subject, html=content, text=content_text)
message.add_cc(cc)

What this does is, marks [email protected] as cc in the email sent to [email protected]. But never triggers an email to [email protected]. Is it just me who is seeing this behavior or anyone else too?

One ugly way I could solve this was by providing all email addresses to both to and cc. This solves the problem but each recipient will have his email in both to and cc. Is there a better way to solve this using the API?

Email to admin not delivered

We have an email address [email protected].

We can send email by hand to that address successfully, but email sent using the sendgrid-python is not delivered. Here's an example test program. Each email is addressed to both admin and charlie -- only the charlie emails are delivered. The same test with a different address [email protected] delivers the mails to both.

#!/usr/bin/env python
"""Test tool sending repeated emails to a sequence of addresses."""

import json
import os
import sys
from   datetime import datetime as dt

import sendgrid

# Initialize the connection to sendgrid
user     = 'X'
password = 'X' 

sg       = sendgrid.SendGridClient(user,password)

# multiple emails to admin 

for i in range(5):
    print "Test %d"%i
    a = "[email protected]"
    message = sendgrid.Mail()
    message.add_to(a)
    message.add_to('[email protected]')
    test_line = 'Test email '+str(i)+' @ '+str(dt.today())
    message.set_subject(test_line)
    message.set_text(test_line)
    message.set_from('[email protected]')
    print "Sending",message.text

    status, msg = sg.send(message)
    print "Status: %d msg %s"%(status, json.loads(msg)['message'])

print "done."    

AttributeError: Mail instance has no attribute '__len__'

Following the example here:

https://sendgrid.com/docs/Integrate/Code_Examples/python.html

I get:

File "c:\Python27\lib\site-packages\sendgrid\sendgrid.py", line 116, in send
return self._legacy_send(message)
File "c:\Python27\lib\site-packages\sendgrid\sendgrid.py", line 120, in _legacy_send
return self._make_request(message)
File "c:\Python27\lib\site-packages\sendgrid\sendgrid.py", line 100, in _make_request
data = urlencode(self._build_body(message), True).encode('utf-8')
File "c:\Python27\lib\urllib.py", line 1343, in urlencode
len(v)
AttributeError: Mail instance has no attribute 'len'

Unicode email address

Hi,

I'm trying to send some emails to addresses containing unicode characters. Example:
KYร–[email protected]. However, when I'm trying to send the email I'm getting:

SendGridClientError: (400, '{"message": "error", "errors": ["Invalid email address KY\[email protected]"]}')

As you can see, for some reason it's double encoding the email address somewhere so \u00d6 becomes \\u00d6

Any suggestions?

I've tried making it work in a very large number of ways (various encodings, using parse_and_add() directly etc.), but to no success so far.

bcc does not work in latest versions

I'm using the add_bcc method to specify a bcc list.

When I first installed it the version was 0.5.4
Everything was working fine till I updated to the latest version 1.1.0. After updating the bcc functionality stopped working. The emails were still being delivered to the addresses specified in the "to" field but nothing is delivered to the "bcc" addresses.

I checked and can reproduce this problem in 1.0.1 too.

(I've fixed the issue temporarily by rolling back to 0.5.4)
Thanks

Improving README

What is the reason you have 2 README files (rst and md one)?

If you want README.rst to be rendered by GitHub nicely, with syntax highlighting, you can use .. code:: python instead of .. code:: for code blocks. Then you can get rid of README.md.

PyPI is supposed to render rst nicely as well, but for some reasons it doesn't work: https://pypi.python.org/pypi/sendgrid.

PyPI parser for restructured text is less forgiving than GitHub's, so whenever it encounters something it cannot parse it falls back to plain text.

For my projects, like docopt (https://pypi.python.org/pypi/docopt) I usually try the README out first with rst2html.py (to see if there are any errors), which you can install with pip install docutils. However your project is rendered nicely with rst2html.py, so I don't know what is exactly the problem. It might be that PyPI uses a different version of docutils or something.

I haven't tried it, but I think if you run python setup.py register again, it will update the documentation, you might be able play with your README to find where is the error located.

HTTP Error 400: Bad Request exception thrown by the send method

I'm getting an exception when calling the sg.send(message) method. I have tried the first example from the docs (just replaced the username and password with my own). I have also run the tests (python test/init.py), but the result was ok.

Here is the exception message:

...
File "feedsd.py", line 287, in run
sendgrid_client.send(message)
File "/usr/local/lib/python2.7/site-packages/sendgrid/sendgrid.py", line 65, in send
raise e
urllib2.HTTPError: HTTP Error 400: Bad Request

The previous version of the library was ok, this happened after I upgraded to 0.2.5. Any idea on what could be causing this?

AttributeError: 'module' object has no attribute 'SendGridClient'

I am trying to send emails via sendgrid in django. But each time it says;

sg = sendgrid.SendGridClient(settings.SENDGRID_USERNAME, settings.SENDGRID_PASSWORD, raise_errors=True)

AttributeError: 'module' object has no attribute 'SendGridClient'

However in requirements.txt file sendgrid ok and also import sendgrid.
and in setttings file it is properly configured.

DistributionNotFound

Hi.

I am integrating Sendgrid into a Google App Engine Python project.

Sendgrid is installed through pip, and from shell command line functions correctly.

I have copied the sendgrid folder into my gae project folder.

Using the same example code that works in the shell, I receive the following error:

Traceback (most recent call last):
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1535, in call
rv = self.handle_exception(request, response, e)
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1529, in call
rv = self.router.dispatch(request, response)
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1102, in call
return handler.dispatch()
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 570, in dispatch
return method(args, *kwargs)
File "C:*route
", line 260, in post
sg = sendgrid.SendGridClient('
username', 'password*')
File "C:\appname\sendgrid\sendgrid.py", line 36, in init
self.useragent = 'sendgrid/' + pkg_resources.get_distribution('sendgrid').version + ';python'
File "C:\Program Files\Google\google_appengine\lib\setuptools-0.6c11\pkg_resources.py", line 311, in get_distribution
if isinstance(dist,Requirement): dist = get_provider(dist)
File "C:\Program Files\Google\google_appengine\lib\setuptools-0.6c11\pkg_resources.py", line 197, in get_provider
return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
File "C:\Program Files\Google\google_appengine\lib\setuptools-0.6c11\pkg_resources.py", line 666, in require
needed = self.resolve(parse_requirements(requirements))
File "C:\Program Files\Google\google_appengine\lib\setuptools-0.6c11\pkg_resources.py", line 565, in resolve
raise DistributionNotFound(req) # XXX put more info here
DistributionNotFound: sendgrid

Thanks for your help.

CHANGELOG file

Hi,

I am using sendgrid==0.1.3 and I would like to know if it's safe to upgrade the package to the latest 0.5.4, any backward incompatible changes?

"Errors should never pass silently"

One of the points in Zen of Python is that Errors should never pass silently. In practice, that usually means that good APIs should force their users to deal with errors by, for example, raising exceptions; instead of allowing users to accidentally let the errors pass by assuming the user will check some error code that is returned.

So I propose to change the behavior of SendGridClient.send method to raise a custom exception, such as, for example, SendGridError, instead of returning an HTTP error code.

If SendGridClient is supposed to be an abstraction around SendGrid HTTP API, then forcing the user of the client to deal directly with HTTP codes as errors makes for a leaky abstraction.

I know that in practice it can be useful to know the exact HTTP error code, in case you want to talk to SendGrid support. So since practicality beats purity, I would set it as an attribute of the SendGridError, or added it to the exception message.

It might be sensible to make a subclass of SendGridError for some of the cases. You could have SendGridTimeout in case of timeout, or SendGridServiceUnavailable in case of 503.

For backwards compatibility, you could add a keyword argument raise_errors to .send or .__init__ methods, which would default to False until the next major version of the client.

Finally, I want to say that I really enjoy working with your client, and apart from this minor issue I am very happy with it's API.

UTF-8 characters in email address throws error

Trying to send an email with, for instance cyrillic characters, in the recipient's address (not name, subject, etc.):

File "/sendgrid/transport/web.py", line 90, in send
data = urllib.urlencode(data, 1)
File "/python27_runtime/python27_dist/lib/python2.7/urllib.py", line 1332, in urlencode
l.append(k + '=' + quote_plus(str(elt)))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 3: ordinal not in range(128)

Distributed example code incompatible with current library.

Here's the results of running the example you're distributing:

(sendgrid)bash $ python sg-example.py 
Traceback (most recent call last):
  File "sg-example.py", line 23, in <module>
    s = sendgrid.Sendgrid(sg_username, sg_password, secure=True)
AttributeError: 'module' object has no attribute 'Sendgrid'

Here's the example program:


#
# SendGrid Python Example (SendGrid Python Library)
#
# This example shows how to send email through SendGrid
# using Python and the SendGrid Python Library.  For 
# more information on the SendGrid Library, visit:
#
#     https://github.com/sendgrid/sendgrid-python
#
#

import sendgrid
import json


# MAKE A SECURE CONNECTION TO SENDGRID
# Fill in the variables below with your SendGrid 
# username and password.
#========================================================#
sg_username = "your_sendgrid_username"
sg_password = "your_sendgrid_password"
s = sendgrid.Sendgrid(sg_username, sg_password, secure=True)


# ENTER THE EMAIL INFORMATION
#========================================================#
from_address = "[email protected]"
subject = "Subject here!"
body_text = "Hello,\n\nThis is a test message from SendGrid.  We have sent this to you because you requested a test message be sent from your account.\n\nThis is a link to google.com: http://www.google.com\nThis is a link to apple.com: http://www.apple.com\nThis is a link to sendgrid.com: http://www.sendgrid.com\n\nThank you for reading this test message.\n\nLove,\nYour friends at SendGrid"
body_html = "<table style=\"border: solid 1px #000; background-color: #666; font-family: verdana, tahoma, sans-serif; color: #fff;\"> <tr> <td> <h2>Hello,</h2> <p>This is a test message from SendGrid.  We have sent this to you because you requested a test message be sent from your account.</p> <a href=\"http://www.google.com\" target=\"_blank\">This is a link to google.com</a> <p> <a href=\"http://www.apple.com\" target=\"_blank\">This is a link to apple.com</a> <p> <a href=\"http://www.sendgrid.com\" target=\"_blank\">This is a link to sendgrid.com</a> </p> <p>Thank you for reading this test message.</p> Love,<br/> Your friends at SendGrid</p> <p> <img src=\"http://sendgrid.com/wp-content/themes/sendgridNew/images/sendgrid-logo.png\" alt=\"SendGrid!\" /> </td> </tr> </table>"


# CREATE THE SENDGRID MAIL OBJECT
#========================================================#
message = sendgrid.Message(from_address, subject, body_text, body_html)


# SMTP API
#========================================================#
smtpapi = {
    "sub": {
        "%new_tag_1%": [
            "New Value 1"
        ],
        "%new_tag_2%": [
            "New Value 2"
        ]
    },
    "to": [
        "New Person 1 <[email protected]>",
        "New Person 2 <[email protected]>",
        "New Person 3 <[email protected]>"
    ],
    "category": [
        "Category 1",
        "Category 2"
    ],
    "unique_args": {
        "New Argument 2": "New Value 2",
        "New Argument 1": "New Value 1"
    }
}
message.add_header("X-SMTPAPI", json.dumps(smtpapi, separators=(',',':')))


# ADD A RECIPIENT
#========================================================#
message.add_to("[email protected]")


# USE SMTP TO SEND YOUR MESSAGE
#========================================================#
s.smtp.send(message)
# ALTERNATIVELY YOU CAN USE THE WEB API BY USING THIS:
# s.web.send(message)


print "Sent email successfully"

Port to Python3?

I just checked caniusepython3 service for my requirement.txt. Seems like sendgrid-python has not been ported to python3? Are there any plans? I will love to contribute.

Relay?

I'd like to use SendGrid with relay, and SendGrid recommends it too.

But with the this library, I don't see a way. Host is hardcoded in transport/smtp.py.

Would like to keep using this library to handle category / substitution etc.

Need an optional parameter for host in Sendgrid __init__ and pass to smpt's __init__.

Thoughts?

Thanks

Security problem when attaching file data.

According to the docs, attachments can be added to an email using two ways, either by passing the path to the file, or by passing the file content itself:

message.add_attachment("file1.doc", "/path/to/file.doc").add_attachment("file2.nfo", "File 2 content")

However, if a developer relies on that function and passes file content in their implementation and is set up to pass arbitrary attachments, an attacker can construct a file whose content is a filename that exists on the server (e.g. the string "/etc/passwd"), causing the server to attach that file instead of a file with that content.

The solution to the problem is to provide two different functions, or always expect that a file object was passed (i.e. allowing to attach data with StringIO and existing files by passing the result of open()).

Found at the InboxLove hackathon.

Despite setting the header, still getting 'Missing destination email'

Hi, Despite setting the header to an array of emails, I am still getting the exception:

sendgrid.exceptions.SendGridClientError: (400, '{"message": "error", "errors": ["Missing destination email"]}')
sg = sendgrid.SendGridClient('xx', 'xxx', raise_errors=True)
    message = sendgrid.Mail()
    message.set_subject('xxx')
    with open("../template/xx_letter.html", "r") as myfile:
        message.set_html(myfile.read())
    message.set_from('[email protected]')
    header = SMTPAPIHeader()
    header.add_category('houman test')
    test_emails = ['[email protected]', '[email protected]']
    header.set_tos(test_emails)
    message.set_headers(header.json_string())
    status, msg = sg.send(message)

From my understanding header.set_tos([emails]) should be equivalent to

headers["X-SMTPAPI"] = { 'to' : array_of_recipients }.to_json()

So why is this failing?

UPDATE:

It seems I need to add at least one "to" recipient to get this running:

message.add_to("[email protected]")

I hope after that the multiple emails specified in the header would kick in.

Yet I still get another error message.

sendgrid.exceptions.SendGridClientError: (400, '{"message": "error", "errors": ["JSON in headers is valid but incompatible"]}')

It seems smtpapi-python doesn't work seamlessly with sendgrid-python.

Many Thanks,
Hooman

The 'bcc' argument has no effect

The 'bcc' field appears to be ignored -- the specified recipients are not sent anything. The message is delivered to recipients in the 'to' field. I'm seeing this behavior on version 0.5.0.

Repro case:

import sendgrid

send_client = sendgrid.SendGridClient(SENDGRID_USERNAME, SENDGRID_APIKEY)

message = sendgrid.Mail()
message.add_to('[email protected]')
message.add_bcc('[email protected]')
message.set_subject('test')
message.set_html('test message')
message.set_from('[email protected]')

send_client.send(message)

When the values dict is compiled in SendGridClient.build_body, the x-smtpapi argument will duplicate the to recipients (they're also sent as to[] args). This duplication appears to cause the server to ignore the bcc[] args, even though they are definitely included in the HTTP request.

I'm able to work around this for my purposes by dropping the x-smtpapi key from the values dict when build_body returns since to is the only thing in it, but I doubt that's the right fix here.

X-SMTPAPI is used differently than headers. Confusing on client end

Hi!

Thanks for the Python client. I was trying to give it a go in using some of the X-SMTPAPI headers as provided in your documentation (https://sendgrid.com/docs/API_Reference/SMTP_API/index.html)

But I noticed the client does not act as you would expect. Here's how I assumed I would set these headers with the client.

 message.set_headers({
    'X-SMTPAPI': {
         "unique_args": {"foo": "bar12345"}
    }
 })

Whenever I did this and sent my message, the result was

SendGridClientError: (400, '{"message": "error", "errors": ["JSON in headers could not be parsed"]}')

I was confused, and tried json.dumps on my headers, and a variety of other things and nothing worked! I dug deeper and found _build_body and how the message is constructed here:

'x-smtpapi': message.json_string()

So it looks like you are fetching x-smtpapi from another source versus headers, and I am not to be pushing these x-smtpapi headers into the headers object.

The solution I found was adjusting message.data, which is the data smtpapi-python constructs from to create the x-smtpapi json blob.

Anyways, that's all I've got. I was hoping I could open up discussion on improving the interface here in adding x-smtpapi headers and making it less confusing.

The obvious option is to be consistent with the rest of the client and add a new method, set_xsmtpapi_header.

Thoughts?

Support for Unicode

Having trouble with emails that use unicode characters... saw a similar closed issue but I think my stack trace is a little different:

2014-03-18 18:00:34.263 return method(*args, **kwargs)
E 2014-03-18 18:00:34.263 File "/base/data/home/apps/s~sfbackend/15.374511915017788109/mailManage.py", line 273, in post
E 2014-03-18 18:00:34.263 self.send_email(params['name'],params['addr_to'],email_data['subject'],email_data['html'],email_data['text'],params['campaign'])
E 2014-03-18 18:00:34.263 File "/base/data/home/apps/s~sfbackend/15.374511915017788109/mailManage.py", line 77, in send_email
E 2014-03-18 18:00:34.263 message.add_to(addr_to) #TODO: coerced into string, but this may be an issue. Follow up on it.
E 2014-03-18 18:00:34.263 File "/base/data/home/apps/s~sfbackend/15.374511915017788109/modules/sendgrid/message.py", line 59, in add_to
E 2014-03-18 18:00:34.263 self.parse_and_add(str(to))
E 2014-03-18 18:00:34.263 UnicodeEncodeError: 'ascii' codec can't encode character u'\u017d' in position 0: ordinal not in range(128)

Email to_names with commas causes sending issue.

Attempting to send an email to someone with the name, for example

John Smith, PhD

will end up sending an email to

phd@<RANDOMTEXT>

As such, the add_to method for Message should auto-quote such names.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.