Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 353 lines (245 sloc) 11.632 kB
bab6d52 @danjac added docs stub
danjac authored
1 pyramid_mailer
2 ==================
3
c3d8289 @mmerickel Updated some documentation since taking over as maintainer.
mmerickel authored
4 **pyramid_mailer** is a package for the `Pyramid`_ framework to take the pain
3586e74 @mcdonc prep for 0.7
mcdonc authored
5 out of sending emails. It is compatible with Python 2.5, 2.6, 2.7, and
6 3.2. It has the following features:
e63fc57 @danjac docs changes
danjac authored
7
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
8 1. A wrapper around the low-level email functionality of standard
9 Python. This includes handling multipart emails with both text and HTML
10 content, and file attachments.
e63fc57 @danjac docs changes
danjac authored
11
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
12 2. The option of directly sending an email or adding it to the queue in your
3586e74 @mcdonc prep for 0.7
mcdonc authored
13 maildir.
e63fc57 @danjac docs changes
danjac authored
14
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
15 3. Wrapping email sending in the transaction manager. If you have a view that
16 sends a customer an email for example, and there is an error in that view
17 (for example, a database error) then this ensures that the email is not
18 sent.
e63fc57 @danjac docs changes
danjac authored
19
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
20 4. A ``DummyMailer`` class to help with writing unit tests, or other
21 situations where you want to avoid emails being sent accidentally from a
22 non-production install.
e63fc57 @danjac docs changes
danjac authored
23
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
24 **pyramid_mailer** uses the `repoze_sendmail`_ package for general email
623d50f @mcdonc - Drop Lamson dependency by copying Lamson's MailResponse and depende…
mcdonc authored
25 sending, queuing and transaction management, and it borrows code from Zed
26 Shaw's `Lamson`_ library for low-level multipart message encoding and
27 wrapping.
e63fc57 @danjac docs changes
danjac authored
28
bab6d52 @danjac added docs stub
danjac authored
29 Installation
30 ------------
31
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
32 Install using **pip install pyramid_mailer** or **easy_install
33 pyramid_mailer**.
bab6d52 @danjac added docs stub
danjac authored
34
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
35 If installing from source, untar/unzip, cd into the directory and do **python
36 setup.py install**.
bab6d52 @danjac added docs stub
danjac authored
37
c3d8289 @mmerickel Updated some documentation since taking over as maintainer.
mmerickel authored
38 The source repository is on `Github`_. Please report any bugs, issues or
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
39 queries there.
bab6d52 @danjac added docs stub
danjac authored
40
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
41 Getting Started (The Easier Way)
42 --------------------------------
bab6d52 @danjac added docs stub
danjac authored
43
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
44 In your application's configuration stanza (where you create a Pyramid
45 "Configurator"), use the ``config.include`` method::
e63fc57 @danjac docs changes
danjac authored
46
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
47 config.include('pyramid_mailer')
e63fc57 @danjac docs changes
danjac authored
48
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
49 Thereafter in view code, use the ``pyramid_mailer.get_mailer`` API to obtain
50 the configured mailer::
e63fc57 @danjac docs changes
danjac authored
51
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
52 from pyramid_mailer import get_mailer
53 mailer = get_mailer(request)
e63fc57 @danjac docs changes
danjac authored
54
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
55 To send a message, you must first create a
56 :class:`pyramid_mailer.message.Message` instance::
e63fc57 @danjac docs changes
danjac authored
57
72563b6 @danjac doc fix
danjac authored
58 from pyramid_mailer.message import Message
e63fc57 @danjac docs changes
danjac authored
59
60 message = Message(subject="hello world",
61 sender="admin@mysite.com",
62 recipients=["arthur.dent@gmail.com"],
63 body="hello, arthur")
64
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
65 The ``Message`` is then passed to the ``Mailer`` instance. You can either
66 send the message right away::
e63fc57 @danjac docs changes
danjac authored
67
68 mailer.send(message)
69
8cb0d3c @mcdonc add docs about queue and repoze.tm2; add makefile that grabs pyramid …
mcdonc authored
70 or add it to your mail queue (a maildir on disk)::
e63fc57 @danjac docs changes
danjac authored
71
72 mailer.send_to_queue(message)
73
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
74 Usually you provide the ``sender`` to your ``Message`` instance. Often
75 however a site might just use a single from address. If that is the case you
76 can provide the ``default_sender`` to your ``Mailer`` and this will be used
77 in throughout your application as the default if the ``sender`` is not
78 otherwise provided.
96df010 @danjac more doc changes
danjac authored
79
635d521 @danjac handle sendmail outside transaction
danjac authored
80
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
81 If you don't want to use transactions, you can side-step them by using
82 **send_immediately**::
635d521 @danjac handle sendmail outside transaction
danjac authored
83
84 mailer.send_immediately(message, fail_silently=False)
85
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
86 This will send the email immediately, outwith the transaction, so if it fails
87 you have to deal with it manually. The ``fail_silently`` flag will swallow
88 any connection errors silently - if it's not important whether the email gets
89 sent.
90
91 Getting Started (The Harder Way)
92 --------------------------------
93
94 To get started the harder way (without using ``config.include``), create an
95 instance of :class:`pyramid_mailer.mailer.Mailer`::
96
97 from pyramid_mailer.mailer import Mailer
98
99 mailer = Mailer()
100
101 The ``Mailer`` class can take a number of optional settings, detailed in
102 :ref:`configuration`. It's a good idea to create a single ``Mailer`` instance
103 for your application, and add it to your registry in your configuration
104 setup::
105
106 config = Configurator(settings=settings)
107 config.registry['mailer'] = Mailer.from_settings(settings)
108
109 or alternatively::
110
111 from pyramid_mailer import mailer_factory_from_settings
112 config.registry['mailer'] = mailer_factory_from_settings(settings)
113
114 You can then access your mailer in a view::
115
116 def my_view(request):
117 mailer = request.registry['mailer']
118
119 Note that the ``pyramid_mailer.get_mailer()`` API will not work if you
13aa9a5 @danjac spelling fix
danjac authored
120 construct and set your own mailer in this way.
635d521 @danjac handle sendmail outside transaction
danjac authored
121
e06d5ad @danjac added config to docs
danjac authored
122 .. _configuration:
123
e63fc57 @danjac docs changes
danjac authored
124 Configuration
125 -------------
126
d81998c @mcdonc better config docs
mcdonc authored
127 If you configure a ``Mailer`` using
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
128 :meth:`pyramid_mailer.mailer.Mailer.from_settings` or
129 ``config.include('pyramid_mailer')``, you can pass the settings from your
d81998c @mcdonc better config docs
mcdonc authored
130 Paste ``.ini`` file. For example::
131
132 [app:myproject]
133 mail.host = localhost
134 mail.port = 25
135
136 By default, the prefix for is assumed to be `mail.`. If you use the
137 ``config.include`` mechanism, to set another prefix, use the
138 ``pyramid_mailer.prefix`` key in the config file. For example::
139
140 [app:myproject]
141 foo.host = localhost
142 foo.port = 25
143 pyramid_mailer.prefix = foo.
144
145 If you use the :meth:`pyramid_mailer.Mailer.Mailer.from_settings` or
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
146 :func:`pyramid_mailer.mailer_factory_from_settings` API, these accept a
d81998c @mcdonc better config docs
mcdonc authored
147 prefix directly; for example::
148
149 mailer_factory_from_settings(settings, prefix='foo.')
150
151 If you don't use Paste, just pass the settings directly into your Pyramid
152 ``Configurator``::
153
154 settings = {'mail.host':'localhost', 'mail.port':'25'}
155 Configurator(settings=settings)
156 config.include('pyramid_mailer')
157
158 The available settings are listed below.
aa253cc @danjac doc changes
danjac authored
159
96df010 @danjac more doc changes
danjac authored
160 ========================= =============== =====================
161 Setting Default Description
162 ========================= =============== =====================
163 **mail.host** ``localhost`` SMTP host
164 **mail.port** ``25`` SMTP port
165 **mail.username** **None** SMTP username
166 **mail.password** **None** SMTP password
167 **mail.tls** **False** Use TLS
168 **mail.ssl** **False** Use SSL
169 **mail.keyfile** **None** SSL key file
170 **mail.certfile** **None** SSL certificate file
171 **mail.queue_path** **None** Location of maildir
172 **mail.default_sender** **None** Default from address
173 **mail.debug** **False** SMTP debug level
174 ========================= =============== =====================
e06d5ad @danjac added config to docs
danjac authored
175
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
176 **Note:** SSL will only work with **pyramid_mailer** if you are using Python
177 **2.6** or higher, as it uses the SSL additions to the ``smtplib``
178 package. While it may be possible to work around this if you have to use
179 Python 2.5 or lower, **pyramid_mailer** does not support this out of the
180 box.
6f9f516 @danjac ssl 2.5 note in docs
danjac authored
181
e63fc57 @danjac docs changes
danjac authored
182 Transactions
183 ------------
184
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
185 If you are using transaction management with your Pyramid application then
186 **pyramid_mailer** will only send the emails (or add them to the mail queue)
187 when the transactions are committed.
2fa0380 @danjac some doc changes
danjac authored
188
96df010 @danjac more doc changes
danjac authored
189 For example::
190
191 import transaction
192
193 from pyramid_mailer.mailer import Mailer
194 from pyramid_mailer.message import Message
195
196 mailer = Mailer()
197 message = Message(subject="hello arthur",
198 sender="ford.prefect@gmail.com",
199 recipients=['arthur.dent@gmail.com'],
200 body="hello from ford")
201
202
203 mailer.send(message)
204 transaction.commit()
205
206
207 The email is not actually sent until the transaction is committed.
208
8cb0d3c @mcdonc add docs about queue and repoze.tm2; add makefile that grabs pyramid …
mcdonc authored
209 When the `repoze.tm2 <http://pypi.python.org/pypi/repoze.tm2>`_ ``tm``
623d50f @mcdonc - Drop Lamson dependency by copying Lamson's MailResponse and depende…
mcdonc authored
210 middleware is in your Pyramid WSGI pipeline or if you've included the
211 ``pyramid_tm`` package in your Pyramid configuration, transactions are
212 already managed for you, so you don't need to explicitly commit or abort
213 within code that sends mail. Instead, if an exception is raised, the
214 transaction will implicitly be aborted and mail will not be sent; otherwise
215 it will be committed, and mail will be sent.
8cb0d3c @mcdonc add docs about queue and repoze.tm2; add makefile that grabs pyramid …
mcdonc authored
216
12391cc @danjac docs changes
danjac authored
217 Attachments
218 -----------
219
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
220 Attachments are added using the :class:`pyramid_mailer.message.Attachment`
221 class::
2fa0380 @danjac some doc changes
danjac authored
222
223 from pyramid_mailer.message import Attachment
224 from pyramid_mailer.message import Message
225
226 message = Message()
227
228 photo_data = open("photo.jpg", "rb").read()
229 attachment = Attachment("photo.jpg", "image/jpg", photo_data)
230
231 message.attach(attachment)
232
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
233 You can pass the data either as a string or file object, so the above code
234 could be rewritten::
aa253cc @danjac doc changes
danjac authored
235
d81998c @mcdonc better config docs
mcdonc authored
236
aa253cc @danjac doc changes
danjac authored
237 from pyramid_mailer.message import Attachment
238 from pyramid_mailer.message import Message
239
240 message = Message()
241
242 attachment = Attachment("photo.jpg", "image/jpg",
243 open("photo.jpg", "rb"))
244
245 message.attach(attachment)
246
247
12391cc @danjac docs changes
danjac authored
248
e63fc57 @danjac docs changes
danjac authored
249 Unit tests
250 ----------
251
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
252 When running unit tests you probably don't want to actually send any emails
253 inadvertently. However it's still useful to keep track of what emails would
254 be sent in your tests.
e63fc57 @danjac docs changes
danjac authored
255
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
256 Another case is if your site is in development and you want to avoid
257 accidental sending of any emails to customers.
e63fc57 @danjac docs changes
danjac authored
258
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
259 In either case, ``config.include('pyramid_mailer.testing')`` can be used to
260 make the current mailer an instance of the
261 :class:`pyramid_mailer.mailer.DummyMailer`::
262
263 from pyramid import testing
e63fc57 @danjac docs changes
danjac authored
264
265 class TestViews(unittest.TestCase):
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
266 def setUp(self):
267 self.config = testing.setUp()
268 self.config.include('pyramid_mailer.testing')
269
270 def tearDown(self):
271 testing.tearDown()
e63fc57 @danjac docs changes
danjac authored
272
273 def test_some_view(self):
274 from pyramid.testing import DummyRequest
0fa1907 @jeroenvloothuis Added missing import to test example
jeroenvloothuis authored
275 from pyramid_mailer import get_mailer
e63fc57 @danjac docs changes
danjac authored
276 request = DummyRequest()
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
277 mailer = get_mailer(request)
e63fc57 @danjac docs changes
danjac authored
278 response = some_view(request)
279
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
280 The ``DummyMailer`` instance keeps track of emails "sent" in two properties:
281 `queue` for emails send via
282 :meth:`pyramid_mailer.mailer.Mailer.send_to_queue` and `outbox` for emails
283 sent via :meth:`pyramid_mailer.mailer.Mailer.send`. Each stores the
284 individual ``Message`` instances::
e63fc57 @danjac docs changes
danjac authored
285
1dc5058 @mcdonc use assertEqual instead of assertTrue
mcdonc authored
286 self.assertEqual(len(mailer.outbox), 1)
287 self.assertEqual(mailer.outbox[0].subject, "hello world")
e63fc57 @danjac docs changes
danjac authored
288
1dc5058 @mcdonc use assertEqual instead of assertTrue
mcdonc authored
289 self.assertEqual(len(mailer.queue), 1)
290 self.assertEqual(mailer.queue[0].subject, "hello world")
e63fc57 @danjac docs changes
danjac authored
291
8cb0d3c @mcdonc add docs about queue and repoze.tm2; add makefile that grabs pyramid …
mcdonc authored
292 Queue
293 -----
294
295 When you send mail to a queue via
296 :meth:`pyramid_mailer.Mailer.send_to_queue`, the mail will be placed into a
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
297 ``maildir`` directory specified by the ``queue_path`` parameter or setting to
298 :class:`pyramid_mailer.mailer.Mailer`. A separate process will need to be
299 launched to monitor this maildir and take actions based on its state. Such a
300 program comes as part of `repoze_sendmail`_ (a dependency of the
301 ``pyramid_mailer`` package). It is known as ``qp``. ``qp`` will be
302 installed into your Python (or virtualenv) ``bin`` or ``Scripts`` directory
303 when you install ``repoze_sendmail``.
8cb0d3c @mcdonc add docs about queue and repoze.tm2; add makefile that grabs pyramid …
mcdonc authored
304
305 You'll need to arrange for ``qp`` to be a long-running process that monitors
306 the maildir state.::
307
308 $ bin/qp /path/to/mail/queue
309
310 This will attempt to use the localhost SMTP server to send any messages in
311 the queue over time. ``qp`` has other options that allow you to choose
312 different settings. Use it's ``--help`` parameter to see more::
313
314 $ bin/qp --help
e63fc57 @danjac docs changes
danjac authored
315
bab6d52 @danjac added docs stub
danjac authored
316 API
317 ---
318
05bd25b @danjac subject argument should be optional
danjac authored
319 .. module:: pyramid_mailer
320
321 .. autofunction:: mailer_factory_from_settings
322
60e3086 @mcdonc - ``pyramid_mailer.includeme`` function added for
mcdonc authored
323 .. autofunction:: get_mailer
324
bab6d52 @danjac added docs stub
danjac authored
325 .. module:: pyramid_mailer.mailer
326
327 .. autoclass:: Mailer
328 :members:
329
330 .. autoclass:: DummyMailer
331 :members:
332
333 .. module:: pyramid_mailer.message
334
335 .. autoclass:: Message
336 :members:
337
338 .. autoclass:: Attachment
339 :members:
340
341 .. module:: pyramid_mailer.exceptions
342
343 .. autoclass:: InvalidMessage
344 :members:
345
346 .. autoclass:: BadHeaders
347 :members:
348
c3d8289 @mmerickel Updated some documentation since taking over as maintainer.
mmerickel authored
349 .. _Github: https://github.com/Pylons/pyramid_mailer
bab6d52 @danjac added docs stub
danjac authored
350 .. _Pyramid: http://pypi.python.org/pypi/pyramid/
f5b9447 @danjac fix broken link in docs
danjac authored
351 .. _repoze_sendmail: http://pypi.python.org/pypi/repoze.sendmail/
bab6d52 @danjac added docs stub
danjac authored
352 .. _Lamson: http://pypi.python.org/pypi/lamson/
Something went wrong with that request. Please try again.