Adding support for APIStar >= 0.4.0

master
androiddrew 7 years ago
parent a7992a1bb0
commit 0a3a377f92

@ -1 +1,7 @@
# HISTORY
0.3.0 Added support for APIStar version >= 0.4.0
0.2.1 Pinned APIStar requirement to 0.3.9
APIStar 0.4.0 introduced breaking changes to the framework. Since Components have completely changed we are pinning the requirement for this release.

@ -17,22 +17,19 @@ Provides a simple interface to set up SMTP with your [APIStar](https://github.co
### Example Setup
To send mail messages from your view functions you must include the 'MAIL' dictionary in your settings, the mail_component in your component list, and the Mail component as a dependency in your view. Here we have a minimally viable app capable of sending an email message and returning a 204 response code:
To send mail messages from your view functions you must include a dictionary of mail options to the `MailComponent. Here we have a minimally viable app capable of sending an email message and returning a 204 response code:
```python
from apistar import Route
from apistar.frameworks.wsgi import WSGIApp as App
from apistar_mail import mail_component, Mail, Message
from apistar import App, Route
from apistar_mail import MailComponent, Mail, Message
settings = {
'MAIL': {
mail_options = {
'MAIL_SERVER': 'smtp.example.com',
'MAIL_USERNAME': 'me@example.com',
'MAIL_PASSWORD': 'dontcommitthistoversioncontrol',
'MAIL_PORT': 587,
'MAIL_USE_TLS': True,
'MAIL_DEFAULT_SENDER': 'me@example.com'
}
}
@ -49,17 +46,16 @@ routes = [
]
components = [
mail_component
MailComponent(**mail_options)
]
app = App(
settings=settings,
routes=routes,
components=components
)
if __name__ == '__main__':
app.main()
app.serve('127.0.0.1', 5000, debug=True)
```

@ -4,4 +4,4 @@ __author__ = """Drew Bednar"""
__email__ = 'drew@androiddrew.com'
__version__ = '0.2.1'
from .mail import mail_component, Message, Mail # NOQA: F401
from .mail import MailComponent, Message, Mail # NOQA: F401

@ -11,7 +11,7 @@ from email.mime.text import MIMEText
from email.header import Header
from email.utils import formatdate, formataddr, make_msgid, parseaddr
from apistar import Settings, Component
from apistar import Component
from .exc import MailUnicodeDecodeError, BadHeaderError
@ -415,25 +415,25 @@ class Connection:
class Mail:
"""Manages email messaging"""
def __init__(self, settings: Settings):
def __init__(self, **mail_options):
"""
Configure a new Mail manager
Args:
settings: The application settings dictionary
mail_options: A components setting dictionary
"""
mail_config = settings.get('MAIL')
self.mail_server = mail_config.get('MAIL_SERVER', 'localhost')
self.mail_user = mail_config.get('MAIL_USERNAME')
self.mail_password = mail_config.get('MAIL_PASSWORD')
self.mail_port = mail_config.get('MAIL_PORT', 25)
self.mail_use_tls = mail_config.get('MAIL_USE_TLS', False)
self.mail_use_ssl = mail_config.get('MAIL_USE_SSL', False)
self.mail_default_sender = mail_config.get('MAIL_DEFAULT_SENDER')
self.mail_debug = mail_config.get('MAIL_DEBUG', False)
self.mail_max_emails = mail_config.get('MAIL_MAX_EMAILS')
self.mail_suppress_send = mail_config.get('MAIL_SUPPRESS_SEND', False)
self.mail_ascii_attachments = mail_config.get('MAIL_ASCII_ATTACHMENTS', False)
self.mail_server = mail_options.get('MAIL_SERVER', 'localhost')
self.mail_user = mail_options.get('MAIL_USERNAME')
self.mail_password = mail_options.get('MAIL_PASSWORD')
self.mail_port = mail_options.get('MAIL_PORT', 25)
self.mail_use_tls = mail_options.get('MAIL_USE_TLS', False)
self.mail_use_ssl = mail_options.get('MAIL_USE_SSL', False)
self.mail_default_sender = mail_options.get('MAIL_DEFAULT_SENDER')
self.mail_debug = mail_options.get('MAIL_DEBUG', False)
self.mail_max_emails = mail_options.get('MAIL_MAX_EMAILS')
self.mail_suppress_send = mail_options.get('MAIL_SUPPRESS_SEND', False)
self.mail_ascii_attachments = mail_options.get('MAIL_ASCII_ATTACHMENTS', False)
def send(self, message):
"""
@ -461,4 +461,11 @@ class Mail:
return Connection(self)
mail_component = Component(Mail, preload=True)
class MailComponent(Component):
"""A component that injects an instance of `Mail` for sending emails"""
def __init__(self, **mail_options) -> None:
self.mail = Mail(**mail_options)
def resolve(self) -> Mail:
return self.mail

@ -7,7 +7,7 @@ with open('HISTORY.md') as history_file:
history = history_file.read()
requirements = [
'apistar~=0.3.9',
'apistar>=0.4',
]
test_requirements = [
@ -21,6 +21,7 @@ setup(
version='0.2.1',
description="A simple email Component for APIStar",
long_description=readme + '\n\n' + history,
long_description_content_type='text/markdown',
author="Drew Bednar",
author_email='drew@androiddrew.com',
url='https://github.com/androiddrew/apistar-mail',

@ -9,8 +9,7 @@ from apistar_mail.exc import MailUnicodeDecodeError, BadHeaderError
import pytest
settings = {
'MAIL': {
test_mail_options = {
'MAIL_SERVER': 'smtp.example.com',
'MAIL_USERNAME': 'fake@example.com',
'MAIL_PASSWORD': 'secret',
@ -18,7 +17,6 @@ settings = {
'MAIL_USE_TLS': True,
'MAIL_SUPPRESS_SEND': True,
'MAIL_DEFAULT_SENDER': 'fake@example.com'
}
}
@ -400,7 +398,7 @@ def test_message_charset():
def test_empty_subject_header():
mail = Mail(settings)
mail = Mail(**test_mail_options)
msg = Message(sender="from@example.com",
recipients=["foo@bar.com"])
msg.body = "normal ascii text"
@ -411,13 +409,13 @@ def test_empty_subject_header():
def test_message_default_sender():
msg = Message(recipients=["foo@bar.com"])
msg.body = "normal ascii text"
mail = Mail(settings)
mail = Mail(**test_mail_options)
mail.send(msg)
assert msg.sender == 'fake@example.com'
def test_mail_send_message():
mail = Mail(settings)
mail = Mail(**test_mail_options)
mail.send = MagicMock()
mail.send_message(sender="from@example.com",
recipients=["foo@bar.com"],
@ -426,7 +424,7 @@ def test_mail_send_message():
def test_message_ascii_attachments_config():
mail = Mail(settings)
mail = Mail(**test_mail_options)
mail.mail_ascii_attachments = True
msg = Message(sender="from@example.com",
subject="subject",
@ -447,7 +445,7 @@ def test_message_as_bytes():
@patch('apistar_mail.mail.smtplib.SMTP')
def test_connection_configure_host_non_ssl(mock_smtp):
mail = Mail(settings)
mail = Mail(**test_mail_options)
mail.mail_suppress_send = False
mail.mail_use_tls = True
mock_smtp.return_value = MagicMock()
@ -459,7 +457,7 @@ def test_connection_configure_host_non_ssl(mock_smtp):
@patch('apistar_mail.mail.smtplib.SMTP_SSL')
def test_connection_configure_host_ssl(mock_smtp_ssl):
mail = Mail(settings)
mail = Mail(**test_mail_options)
mail.mail_suppress_send = False
mail.mail_use_tls = False
mail.mail_use_ssl = True
@ -469,7 +467,7 @@ def test_connection_configure_host_ssl(mock_smtp_ssl):
def test_connection_send_message():
mail = Mail(settings)
mail = Mail(**test_mail_options)
with mail.connect() as conn:
conn.send = MagicMock()
conn.send_message(sender="from@example.com",
@ -480,7 +478,7 @@ def test_connection_send_message():
@patch('apistar_mail.mail.smtplib.SMTP')
def test_connection_send_single(mock_smtp):
mail = Mail(settings)
mail = Mail(**test_mail_options)
mail.mail_suppress_send = False
msg = Message(sender="from@example.com",
recipients=["foo@bar.com"],
@ -494,7 +492,7 @@ def test_connection_send_single(mock_smtp):
def test_connection_send_ascii_recipient_single():
mail = Mail(settings)
mail = Mail(**test_mail_options)
msg = Message(sender="from@example.com",
recipients=["foo@bar.com"],
body="normal ascii text")
@ -506,7 +504,7 @@ def test_connection_send_ascii_recipient_single():
def test_connection_send_non_ascii_recipient_single():
mail = Mail(settings)
mail = Mail(**test_mail_options)
with mail.connect() as conn:
with patch.object(conn, 'host') as host:
msg = Message(subject="testing",
@ -526,7 +524,7 @@ def test_connection_send_non_ascii_recipient_single():
@patch('apistar_mail.mail.smtplib.SMTP')
def test_connection_send_many(mock_smtp):
mail = Mail(settings)
mail = Mail(**test_mail_options)
mail.mail_suppress_send = False
mail.mail_max_emails = 50
mock_smtp.return_value = MagicMock(spec=SMTP)
@ -545,7 +543,7 @@ def test_connection_send_many(mock_smtp):
def test_bad_header_subject():
mail = Mail(settings)
mail = Mail(**test_mail_options)
msg = Message(subject="testing\r\n",
body="testing",
recipients=["to@example.com"])
@ -555,7 +553,7 @@ def test_bad_header_subject():
def test_bad_header_subject_whitespace():
mail = Mail(settings)
mail = Mail(**test_mail_options)
msg = Message(subject="\t\r\n",
body="testing",
recipients=["to@example.com"])
@ -570,7 +568,7 @@ def test_bad_header_subject_with_no_trailing_whitespace():
This is a bit of a strange test but we aren't changing the bad_header check from flask_mail
"""
mail = Mail(settings)
mail = Mail(**test_mail_options)
msg = Message(subject="testing\r\ntesting",
body="testing",
recipients=["to@example.com"])
@ -580,7 +578,7 @@ def test_bad_header_subject_with_no_trailing_whitespace():
def test_bad_header_subject_trailing_whitespace():
mail = Mail(settings)
mail = Mail(**test_mail_options)
msg = Message(subject="testing\r\n\t",
body="testing",
recipients=["to@example.com"])
@ -590,7 +588,7 @@ def test_bad_header_subject_trailing_whitespace():
def test_bad_header_with_a_newline():
mail = Mail(settings)
mail = Mail(**test_mail_options)
msg = Message(subject="\ntesting\r\ntesting",
body="testing",
recipients=["to@example.com"])
@ -600,7 +598,7 @@ def test_bad_header_with_a_newline():
def test_bad_header_with_newline_in_sender():
mail = Mail(settings)
mail = Mail(**test_mail_options)
msg = Message(subject="testing",
body="testing",
sender='me\n@example.com',

Loading…
Cancel
Save