[Checkins] SVN: zope.sendmail/trunk/src/zope/sendmail/README.txt Add some documentation.

Marius Gedminas marius at pov.lt
Thu Oct 25 11:13:47 EDT 2007


Log message for revision 81092:
  Add some documentation.
  
  Warning: the code examples haven't been actually tested.  It might be a good
  idea to convert them to doctests, if that can be done without decreasing
  readability.
  
  

Changed:
  A   zope.sendmail/trunk/src/zope/sendmail/README.txt

-=-
Added: zope.sendmail/trunk/src/zope/sendmail/README.txt
===================================================================
--- zope.sendmail/trunk/src/zope/sendmail/README.txt	                        (rev 0)
+++ zope.sendmail/trunk/src/zope/sendmail/README.txt	2007-10-25 15:13:46 UTC (rev 81092)
@@ -0,0 +1,135 @@
+Using zope.sendmail
+===================
+
+This package is useful when your Zope 3 application wants to send email.  It
+integrates with the transaction mechanism and queues your emails to be sent on
+successful commits only.
+
+
+API
+---
+
+An application that wants to send an email can do so by getting the appropriate
+IMailDelivery utility.  The standard library's email module is useful for
+formatting the message according to RFC-2822::
+
+    import email.MIMEText
+    import email.Header
+    from zope.sendmail.interfaces import IMailDelivery
+    from zope.component import getUtility
+
+    def send_email(sender, recipient, subject, body):
+        msg = email.MIMEText.MIMEText(body.encode('UTF-8'), 'plain', 'UTF-8')
+        msg["From"] = sender
+        msg["To"] = recipient
+        msg["Subject"] = email.Header.Header(subject, 'UTF-8')
+        mailer = getUtility(IMailDelivery, 'my-app.mailer')
+        mailer.send(sender, [recipient], msg.as_string())
+
+In real-world code you may need to do extra work to format the 'From' and 'To'
+headers correctly, if the addresses contain a real-name part with non-ASCII
+characters.  You can find a recipe for that in this blog post:
+http://mg.pov.lt/blog/unicode-emails-in-python.html
+
+
+Configuration
+-------------
+
+The code above used a named IMailDelivery utility.  It is your responsibility
+to define one, as Zope 3 doesn't provide one by default.  You can define
+an IMailDelivery utility in your site.zcml with a configuration directive::
+
+    <configure xmlns="http://namespaces.zope.org/zope"
+               xmlns:mail="http://namespaces.zope.org/mail"
+
+        <mail:queuedDelivery
+            name="my-app.mailer"
+            permission="zope.Public"
+            mailer="smtp"
+            queuepath="var/mailqueue"
+            />
+
+    </configure>
+
+The ``mail:queuedDelivery`` directive stores every email in a queue (a standard
+Maildir folder on the file system in a given directory) and sends them only on
+successful transaction commits.  I'll explain the ``mailer`` parameter later.
+
+There's an alternative directive, ``mail:directDelivery``, that ignores
+transactions and tries to send the emails directly.  It is useful for (manual)
+testing, but don't use it in production if you don't want to send multiple
+copies of the same emails to your customers whenever ZODB retries a transaction
+after a ConflictError.
+
+
+Mailers
+-------
+
+The ``mailer`` argument of the ``mail:queuedDelivery`` utility chooses the
+appropriate IMailer utility that will be used to deliver email.  There
+are alternative ways of doing that, for example, SMTP or piping the message to
+an external program.  Currently ``zope.sendmail`` supports only plain SMTP.
+[#]_
+
+.. [#] There was once a mailer utility that invoked /usr/sbin/sendmail, but
+       it had security issues related to the difficulty of quoting command-line
+       arguments in a portable way.
+
+If the same system that runs your Zope 3 server also has an SMTP server on
+port 25, you can use the default ``smtp`` mailer.  If you want to use a
+different SMTP server, define your own utility like this::
+
+    <configure xmlns="http://namespaces.zope.org/zope"
+               xmlns:mail="http://namespaces.zope.org/mail"
+
+        <mail:smtpMailer
+            name="my-app.smtp"
+            hostname="mail.my-app.com"
+            port="25"
+            /> 
+            
+        <mail:queuedDelivery
+            name="my-app.mailer"
+            permission="zope.Public"
+            mailer="my-app.smtp"
+            queuepath="var/mailqueue"
+            />
+
+    </configure>
+
+
+Testing
+-------
+
+Obviously, you don't want your automated unit/functional test runs to send
+real emails.  You'll have to define a fake email delivery utility in your
+test layer.  Something like this will do the trick::
+
+    class FakeMailDelivery(object):
+        implements(IMailDelivery)
+
+        def send(self, source, dest, body):
+            print "*** Sending email from %s to %s:" % (source, dest)
+            print body
+            return 'fake-message-id at example.com'
+
+Register it with the standard ``utility`` directive::
+
+    <utility name="my-app.mailer" factory="my-app.testing.FakeMailDelivery" />
+
+
+Problems with zope.sendmail
+---------------------------
+
+* The API is a bit inconvenient to use (e.g. you have to do the message
+  formatting by yourself).
+
+* The configuration should be done in zope.conf, not in ZCML.
+
+* If the SMTP server rejects a message (for example, when the sender or
+  recipient address is malformed), that email stays in the queue forever
+  (TODO: file a bug at https://bugs.launchpad.net/zope3/+filebug)
+
+* The IMailSentEvent and IMailErrorEvent events aren't used and can't be used
+  (you don't want to send emails during the commit phase).
+


Property changes on: zope.sendmail/trunk/src/zope/sendmail/README.txt
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Checkins mailing list