Git Product home page Git Product logo

python-sparkpost's Introduction

image

Sign up for a SparkPost account and visit our Developer Hub for even more content.

SparkPost Python API client

Build Status

Documentation Status

Coverage Status

The official Python package for using the SparkPost API.

Documentation

Installation

Install from PyPI using pip:

$ pip install sparkpost

Python 2.7 or later is required.

Get a key

Go to API & SMTP in the SparkPost app and create an API key. We recommend using the SPARKPOST_API_KEY environment variable:

from sparkpost import SparkPost
sp = SparkPost() # uses environment variable

Alternatively, you can pass the API key to the SparkPost class:

from sparkpost import SparkPost
sp = SparkPost('YOUR API KEY')

For SparkPost EU and Enterprise accounts, pass in a second parameter to set the API host.

from sparkpost import SparkPost
sp = SparkPost('YOUR API KEY', 'https://api.eu.sparkpost.com')

Send a message

Here at SparkPost, our messages are known as transmissions. Let's use the underlying transmissions API to send a friendly test message:

from sparkpost import SparkPost

sp = SparkPost()

response = sp.transmissions.send(
    use_sandbox=True,
    recipients=['[email protected]'],
    html='<p>Hello world</p>',
    from_email='[email protected]',
    subject='Hello from python-sparkpost'
)

print(response)
# outputs {u'total_accepted_recipients': 1, u'id': u'47960765679942446', u'total_rejected_recipients': 0}

Django Integration

The SparkPost python library comes with an email backend for Django. Put the following configuration in settings.py file.

SPARKPOST_API_KEY = 'API_KEY'
SPARKPOST_BASE_URI = 'api.sparkpost.com'
EMAIL_BACKEND = 'sparkpost.django.email_backend.SparkPostEmailBackend'

Replace API_KEY with an actual API key that you've generated in Get a Key section. Check out the full documentation on the Django email backend.

If you are using an EU account, set SPARKPOST_BASE_URI to api.eu.sparkpost.com. The default value is api.sparkpost.com.

Using with Google Cloud

There are a few simple modifications necessary to enable the use of the underlying requests library that python-sparkpost uses. First, add the requests and requests-toolbelt to your project's requirements.txt:

requests
requests-toolbelt

Then create or update your appengine_config.py file to include the following:

import requests
import requests_toolbelt.adapters.appengine

requests_toolbelt.adapters.appengine.monkeypatch()

Then deploy your app and you should be able to send using python-sparkpost on Google Cloud.

Contribute

  1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
  2. Fork the repository on GitHub and make your changes in a branch on your fork
  3. Write a test which shows that the bug was fixed or that the feature works as expected.
  4. Send a pull request. Make sure to add yourself to AUTHORS.

python-sparkpost's People

Contributors

amatissart avatar avigoldman avatar avinassh avatar aydrian avatar bartdag avatar bizob2828 avatar btx avatar darrensmith223 avatar deems avatar duanehutchins avatar ewandennis avatar haos616 avatar hugoarts avatar jarcoal avatar jgzamora avatar jkeyes avatar kai5263499 avatar mathiasose avatar orval avatar pegler avatar pl-jankowskimichal avatar puttu avatar rajumsys avatar rdawemsys avatar richleland avatar svisser avatar thiagogds avatar tuck1s avatar wooyek avatar ypcrumble 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

Watchers

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

python-sparkpost's Issues

Update docs to show from_email formats

You can supply a friendly from in the existing from_email field. For example the following are both valid:

sp.transmissions.send(..., from_email='[email protected]', ...)
sp.transmissions.send(..., from_email='Test Email <[email protected]>', ...)

The _extract_recipients (see this line) method handles converting either of these into the proper format for the API. We just need to document it.

make test returning errors

When you run make test it doesn't make it past the flake8 validation. If you bypass that and run venv/bin/activate; py.test --cov sparkpost test/, import errors are returned. We must get tests running and passing before moving forward.

Support email attachments

Sending attachment isn't supported at this moment. We need to add that support for attachment in python (including in Django backend).

Transmissions thoughts

@bizob2828 reviewed the transmissions real quick - just a couple of thoughts/questions around the _translate_keys method:

  • When the incoming values in kwargs fallback to None, how does that pass through to the API? I'm wondering if we should just never add them to the model if they are being passed on.
  • What are your thoughts on removing email_rfc822? I really don't think we should encourage users to go this route. It's just not user-friendly.

API Keys

Caveat to this issue: I maybe misreading the code and there is another way to do this that I am not seeing.

While working on the Java SDK I see this project and PHP SDK require the API Key to be set inside a checked in file. Example

I believe things like that should not be placed inside checked in code because it is too easy to accidentally checkin you key.

I would prefer to see a name something like "config.something.example" that gets checked in. Put "config.something" would be put in the .gitignore so ti is not checked in. The example file would have the place holder properties.

The above filenames should use something appropriate for the language. In Java it would probably be "config.properties.example".

Add tox support

Tox is a testing tool that allows local testing of various combination of Python versions and dependencies. It is similar to running the Travis build locally, which can be very helpful as the number of version combinations grows.

I'll make a pull request to demonstrate its usage.

Receiving mixed response on POST to /transmissions

Using the Python SDK, a POST to /transmissions with the BODY.recipients set to an array of strings, shown in example below, returns a mixed 200 response.

Response:

{u'total_accepted_recipients': 1, u'id': u'30010207866232273', u'rcpt_to_errors': [{u'message': u'invalid data format/type', u'code': u'1300', u'description': u'address  is not JSON'}], u'total_rejected_recipients': 1}

The example code shows this as a valid use case:
https://github.com/SparkPost/python-sparkpost/blob/master/examples/transmissions/send_transmission.py#L7

Need to research if this is a valid bug (and resolve) or user error.

Allauth forgot password

Using the django allauth package to do my auth.

Clicking the forget password and sending by email, I get below.
No idea how to debug. How do i event add stuff to the content.html?

sparkpost.exceptions.SparkPostAPIException
SparkPostAPIException: Call to https://api.sparkpost.com/api/v1/transmissions returned 422, errors:

    required field is missing: content.inline_images requires content.html

Using this works
EMAIL_HOST = 'smtp.sparkpostmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'SMTP_Injection'
EMAIL_HOST_PASSWORD = '348b25528c6b64abc0b423307314292c108d8899'
EMAIL_USE_TLS = True

Critical Error on Django Backend

I've been two days behind a bug in the Django Backend.

Some of the text-only emails were arriving in HTML and with the content of other totally different email. Only viewing the email in raw you can see the correct text content.

The problem was the backend was modifing the global settings dict.
#87 should fix this bug.

Schedule transmission

I don't see any option in the transmission api to schedule a transmission. I'm missing something?

Finish building out the base resource

  • Implement following methods:
    • GET
    • POST
    • PUT
    • DELETE
  • Add User-Agent header and set it to 'python-sparkpost' (add /version if possible)
  • Add/Update any unit tests

Docs tweaks

A few items based on some feedback:

  • Update docs to show example transmission with substitution data
  • Update docs to explain precedence of substitution data - recipient > transmission > template
  • Use transmissions instead of transmission

Provide export as .csv feature for GET responses

People may want to use the SDK to offer an easy "download as .csv" format for responses.

We should make that simple and bind it to the following SparkPost API services:

  • Templates
  • Recipient Lists
  • Suppression Lists
  • Sending Domains

SparkPostAPIException: content.inline_images requires content.html

I have a weird issue, preventing me from sending emails out with sparkpost==1.1.0 and Django==1.8.12. I traced the steps, starting with a simple:

email = EmailMessage('TEST SUBJECT', 'TEST MSG', '[email protected]', ['[email protected]'])
email.send()

This causes to execute (.../python2.7/site-packages/sparkpost/transmissions.py", line 232):

results = self.request('POST', self.uri, data=json.dumps(payload))

The payload here (as per django_extensions) looks like this:

{'description': None, 'recipients': [{'address': {'email': '[email protected]'}}], 'campaign_id': None, 'return_path': '[email protected]', 'content': {'from': {'email': '[email protected]'}, 'attachments': [], 'text': 'TEST MSG', 'headers': {}, 'html': None, 'reply_to': None, 'use_draft_template': False, 'inline_images': [], 'template_id': None, 'subject': 'TEST SUBJECT'}, 'substitution_data': None, 'options': {'skip_suppression': None, 'open_tracking': None, 'start_time': None, 'inline_css': None, 'transactional': None, 'sandbox': None, 'click_tracking': None, 'ip_pool': None}, 'metadata': None}

Error returned:

SparkPostAPIException: Call to https://api.sparkpost.com/api/v1/transmissions returned 422, errors: required field is missing: content.inline_images requires content.html

However, when I substitute [] with None in payload at this stage, the message goes out.

Unable to install Pre-Release version of SDK

Using pip > 1.4.x there is no longer support for pre-release packages (like the SparkPost Python SDK) unless you use the --pre option on the pip command.

Adding this issue from this question on Stackoverflow:
http://stackoverflow.com/questions/29871778/sparkpost-python-sdk-install-failing/29871893

Here's the reference I found that helped me resolve this issue:
http://stackoverflow.com/questions/18230956/could-not-find-a-version-that-satisfies-the-requirement-pytz

Transmissions improvements

Right now, we have to do the following:

sp.transmission.create(
    recipients=[{'address': {'email': '[email protected]'}}],
    description='test',
    campaign='rich-testing',
    metadata={},
    substitution_data={},
    reply_to='[email protected]',
    subject='test messsage',
    envelope_from='[email protected]',
    text='test message'
)

The recipients part seems especially over-complicated to me. Maybe just allow an array of addrs but also support the more complex object.

Additionally, we should change envelope_from to from as this field is actually the From header (aka Friendly From).

Map POST/PUT Payloads to the API documentation

It is confusing for developers to use a flattened structure of their request payloads, especially when the property names vary from the API documentation on SparkPost.com/api.

Use a idiomatic structure passthrough that maps to the API docs for all first class citizens of the SparkPost API.

Sphinx docs issues

  • Transmission is failing to autoload after name change
  • Templates are missing from API tree

Preview template returns error

When running the following code

    sub_data = {'content': html}

    result = sparkpost_client.templates.preview(
        template_id='newsletter',
        substitution_data=sub_data,
        draft=False
    )

I get the following error:

required field is missing: field 'substitution_data' is required

I think it may be because, in templates.py, line 181:

data=json.dumps(substitution_data))

You can't just simply dump the json, need to append it to a new dict with the "substitution_data" key before doing that.

I'm fairly sure this is the issue because if i change my code like so:

    sub_data = {'substitution_data': {'content': html}}

    result = sparkpost_client.templates.preview(
        template_id=config.item['sparkpost_template'],
        substitution_data=sub_data,
        draft=False
    )

It works.

Provide more thorough examples

Examples that are in there were quick and dirty and untested. Build a set of examples, similar to the others that exercise all the capabilities

Support CC, BCC & ReplyTo

Currently these are not supported.

Once these are added in the python library, we'll have to add the support those in the upcoming Django backend too.

Error installing local python-sparkpost package

Hey @richleland,

So I have my environment setup, and I tried to use the following command to install the SDK into a Django app:

pip install -e <path/to/python-sparkpost/>

Here's the output I'm receiving (forgive me if this is simple...my Python hasn't been touched since 1.x versions). It very well could be an environment issue, and I'm going to keep on digging, but I thought I'd share what I hit.

Here's some environment specs:
Python Version: 2.7.6
Django Version: 1.8
Latest PIP installed

Obtaining file:///Users/benjamin/GitForks/python-sparkpost
Traceback (most recent call last):
File "", line 20, in
File "/Users/benjamin/GitForks/python-sparkpost/setup.py", line 1, in
import sparkpost
File "sparkpost/init.py", line 4, in
from .metrics import Metrics
File "sparkpost/metrics.py", line 1, in
from .base import Resource
File "sparkpost/base.py", line 1, in
import requests
ImportError: No module named requests
Complete output from command python setup.py egg_info:
Traceback (most recent call last):

  File "<string>", line 20, in <module>

  File "/Users/benjamin/GitForks/python-sparkpost/setup.py", line 1, in <module>

    import sparkpost

  File "sparkpost/__init__.py", line 4, in <module>

    from .metrics import Metrics

  File "sparkpost/metrics.py", line 1, in <module>

    from .base import Resource

  File "sparkpost/base.py", line 1, in <module>

    import requests

ImportError: No module named requests

----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /Users/benjamin/GitForks/python-sparkpost

Set up tox

Install tox, create tox.ini, set up to run in multiple environments including Python3

Set up Travis to run in Python 3.5

We currently have tox tests to run against Python 2.7, 3.4, and 3.5, but Travis only runs against 2.7 and 3.4. Need to look into adding 3.5 to the list of Pythons Travis runs tests against.

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.