File: //usr/share/doc/python3-aiosmtpd/html/handlers.html
<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="./">
<head>
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Handlers — aiosmtpd 1.4.4.post2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="_static/css/theme.css?v=86f27845" />
<link rel="stylesheet" type="text/css" href="_static/aiosmtpd.css?v=4cc6bf70" />
<script src="_static/jquery.js?v=8dae8fb0"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="_static/documentation_options.js?v=ad49bbf5"></script>
<script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Authentication System" href="auth.html" />
<link rel="prev" title="The LMTP class" href="lmtp.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home">
aiosmtpd
</a>
<div class="version">
1.4.4.post2
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="intro.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="concepts.html">Concepts</a></li>
<li class="toctree-l1"><a class="reference internal" href="cli.html">Command line usage</a></li>
<li class="toctree-l1"><a class="reference internal" href="controller.html">Programmatic usage</a></li>
<li class="toctree-l1"><a class="reference internal" href="smtp.html">The SMTP Module</a></li>
<li class="toctree-l1"><a class="reference internal" href="lmtp.html">The LMTP class</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Handlers</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#from_cli"><code class="docutils literal notranslate"><span class="pre">from_cli()</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="#handler-hooks">Handler Hooks</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#common-arguments">Common Arguments</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#server"><code class="docutils literal notranslate"><span class="pre">server</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#session"><code class="docutils literal notranslate"><span class="pre">session</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#envelope"><code class="docutils literal notranslate"><span class="pre">envelope</span></code></a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#supported-hooks">Supported Hooks</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#handle_DATA"><code class="docutils literal notranslate"><span class="pre">handle_DATA()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_EHLO"><code class="docutils literal notranslate"><span class="pre">handle_EHLO()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_HELO"><code class="docutils literal notranslate"><span class="pre">handle_HELO()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_MAIL"><code class="docutils literal notranslate"><span class="pre">handle_MAIL()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_NOOP"><code class="docutils literal notranslate"><span class="pre">handle_NOOP()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_QUIT"><code class="docutils literal notranslate"><span class="pre">handle_QUIT()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_RCPT"><code class="docutils literal notranslate"><span class="pre">handle_RCPT()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_RSET"><code class="docutils literal notranslate"><span class="pre">handle_RSET()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_VRFY"><code class="docutils literal notranslate"><span class="pre">handle_VRFY()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_STARTTLS"><code class="docutils literal notranslate"><span class="pre">handle_STARTTLS()</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="#handle_exception"><code class="docutils literal notranslate"><span class="pre">handle_exception()</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#built-in-handlers">Built-in handlers</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#aiosmtpd.handlers.AsyncMessage"><code class="docutils literal notranslate"><span class="pre">AsyncMessage</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="#aiosmtpd.handlers.Debugging"><code class="docutils literal notranslate"><span class="pre">Debugging</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="#aiosmtpd.handlers.Mailbox"><code class="docutils literal notranslate"><span class="pre">Mailbox</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="#aiosmtpd.handlers.Message"><code class="docutils literal notranslate"><span class="pre">Message</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="#aiosmtpd.handlers.Proxy"><code class="docutils literal notranslate"><span class="pre">Proxy</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="#aiosmtpd.handlers.Sink"><code class="docutils literal notranslate"><span class="pre">Sink</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#the-mailbox-handler">The Mailbox Handler</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="auth.html">Authentication System</a></li>
<li class="toctree-l1"><a class="reference internal" href="proxyprotocol.html">PROXY Protocol Support</a></li>
<li class="toctree-l1"><a class="reference internal" href="migrating.html">Migrating from smtpd to aiosmtpd</a></li>
<li class="toctree-l1"><a class="reference internal" href="testing.html">Testing</a></li>
<li class="toctree-l1"><a class="reference internal" href="manpage.html">aiosmtpd</a></li>
<li class="toctree-l1"><a class="reference internal" href="NEWS.html">NEWS for aiosmtpd</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">aiosmtpd</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item active">Handlers</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/handlers.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="handlers">
<span id="id1"></span><h1>Handlers<a class="headerlink" href="#handlers" title="Link to this heading"></a></h1>
<p>Handlers are classes which can implement <a class="reference internal" href="#hooks"><span class="std std-ref">hook methods</span></a> that get
called at various points in the SMTP dialog.</p>
<p>Handlers can also be named on the <a class="reference internal" href="cli.html#cli"><span class="std std-ref">command line</span></a>,
but if the class’s constructor takes arguments,
you must define a <code class="docutils literal notranslate"><span class="pre">@classmethod</span></code> that converts the positional arguments and
returns a handler instance:</p>
<dl class="py method">
<dt class="sig sig-object py" id="from_cli">
<em class="property"><span class="pre">classmethod</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">from_cli</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">cls</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">parser</span></span></em>, <em class="sig-param"><span class="o"><span class="pre">*</span></span><span class="n"><span class="pre">args</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#from_cli" title="Link to this definition"></a></dt>
<dd><p>Convert the positional arguments, as strings passed in on the command
line, into a handler instance.</p>
<p><span class="boldital">parser</span> is the
<code class="xref py py-class docutils literal notranslate"><span class="pre">ArgumentParser</span></code> instance in use.</p>
<p>If this method does not recognize the positional arguments passed in <code class="docutils literal notranslate"><span class="pre">parser</span></code>,
it can <em>optionally</em> call <code class="xref py py-meth docutils literal notranslate"><span class="pre">parser.error</span></code>
with the error message.</p>
</dd></dl>
<p>If <code class="docutils literal notranslate"><span class="pre">from_cli()</span></code> is not defined, the handler can still be used on the command
line, but its constructor cannot accept arguments.</p>
<section id="handler-hooks">
<span id="hooks"></span><h2>Handler Hooks<a class="headerlink" href="#handler-hooks" title="Link to this heading"></a></h2>
<p>Handlers can implement hooks that get called during the SMTP dialog, or in
exceptional cases. These <em>handler hooks</em> are ALL called <strong>asynchronously</strong>
(i.e. they are coroutines).</p>
<p>All handler hooks are optional and default behaviors are
carried out by the <code class="xref py py-class docutils literal notranslate"><span class="pre">SMTP</span></code> class when a hook is omitted,
so you only need to implement the ones you care about.</p>
<p>When a handler hook is defined,
it may have additional responsibilities as described below.</p>
<section id="common-arguments">
<h3>Common Arguments<a class="headerlink" href="#common-arguments" title="Link to this heading"></a></h3>
<p>All handler hooks will be called with at least three arguments:</p>
<dl class="py attribute">
<dt class="sig sig-object py" id="server">
<span class="sig-name descname"><span class="pre">server</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><a class="reference internal" href="smtp.html#aiosmtpd.smtp.SMTP" title="aiosmtpd.smtp.SMTP"><span class="pre">SMTP</span></a></em><a class="headerlink" href="#server" title="Link to this definition"></a></dt>
<dd><p>The <code class="docutils literal notranslate"><span class="pre">SMTP</span></code> server instance</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="session">
<span class="sig-name descname"><span class="pre">session</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><a class="reference internal" href="concepts.html#Session" title="Session"><span class="pre">Session</span></a></em><a class="headerlink" href="#session" title="Link to this definition"></a></dt>
<dd><p>The <a class="reference internal" href="concepts.html#sessions-and-envelopes"><span class="std std-ref">session instance</span></a> currently being handled, and</p>
</dd></dl>
<dl class="py attribute">
<dt class="sig sig-object py" id="envelope">
<span class="sig-name descname"><span class="pre">envelope</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><a class="reference internal" href="concepts.html#Envelope" title="Envelope"><span class="pre">Envelope</span></a></em><a class="headerlink" href="#envelope" title="Link to this definition"></a></dt>
<dd><p>The <a class="reference internal" href="concepts.html#sessions-and-envelopes"><span class="std std-ref">envelope instance</span></a> of the current SMTP Transaction</p>
</dd></dl>
<p>Some handler hooks will receive additional arguments.</p>
</section>
<section id="supported-hooks">
<h3>Supported Hooks<a class="headerlink" href="#supported-hooks" title="Link to this heading"></a></h3>
<p>The following hooks are currently supported (in alphabetical order):</p>
<dl class="py method">
<dt class="sig sig-object py">
<span class="sig-name descname"><span class="pre">handle_AUTH</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">args</span></span></em><span class="sig-paren">)</span></dt>
<dd><p>Called to handle <code class="docutils literal notranslate"><span class="pre">AUTH</span></code> command if you need custom AUTH behavior.</p>
<p>For more information, please read the documentation for <a class="reference internal" href="auth.html#auth"><span class="std std-ref">Authentication System</span></a>.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_DATA">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_DATA</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="headerlink" href="#handle_DATA" title="Link to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Response message to be sent to the client</p>
</dd>
</dl>
<p>Called during <code class="docutils literal notranslate"><span class="pre">DATA</span></code> after the entire message (<a class="reference external" href="https://tools.ietf.org/html/rfc5321#section-2.3.9">“SMTP content”</a> as described in
RFC 5321) has been received.</p>
<p>The content is available in <code class="docutils literal notranslate"><span class="pre">envelope.original_content</span></code> as type <code class="docutils literal notranslate"><span class="pre">bytes</span></code>,
normalized according to the transparency rules
as defined in <span class="target" id="index-0"></span><a class="rfc reference external" href="https://datatracker.ietf.org/doc/html/rfc5321.html#section-4.5.2"><strong>RFC 5321, §4.5.2</strong></a>.</p>
<p>In addition, the <code class="docutils literal notranslate"><span class="pre">envelope.content</span></code> attribute will also contain the contents;
the type depends on whether <a class="reference internal" href="smtp.html#aiosmtpd.smtp.SMTP" title="aiosmtpd.smtp.SMTP"><code class="xref py py-class docutils literal notranslate"><span class="pre">SMTP</span></code></a> was instantiated with
<code class="docutils literal notranslate"><span class="pre">decode_data=False</span></code> or <code class="docutils literal notranslate"><span class="pre">decode_data=True</span></code>.
See <a class="reference internal" href="concepts.html#Envelope.content" title="Envelope.content"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Envelope.content</span></code></a> for more info.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_EHLO</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">hostname</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">responses</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span></span></span></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>hostname</strong> (<em>str</em>) – The host name given by the client in the <code class="docutils literal notranslate"><span class="pre">EHLO</span></code> command</p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Response message to be sent to the client</p>
</dd>
</dl>
<p>This hook is called during <code class="docutils literal notranslate"><span class="pre">EHLO</span></code>.</p>
<p>This hook may push <em>additional</em> <code class="docutils literal notranslate"><span class="pre">250-<command></span></code> responses to the client by doing
<code class="docutils literal notranslate"><span class="pre">await</span> <span class="pre">server.push(status)</span></code> before returning <code class="docutils literal notranslate"><span class="pre">"250</span> <span class="pre">HELP"</span></code> as the final response.</p>
<blockquote>
<div><div class="admonition important">
<p class="admonition-title">Important</p>
<p>If the handler sets the <code class="docutils literal notranslate"><span class="pre">session.host_name</span></code> attribute to a false-y value
(or leave it as the default <code class="docutils literal notranslate"><span class="pre">None</span></code> value)
it will signal later steps that <code class="docutils literal notranslate"><span class="pre">HELO</span></code> failed
and need to be performed again.</p>
<p>This also applies to the <a class="reference internal" href="#handle_EHLO" title="handle_EHLO"><code class="xref py py-meth docutils literal notranslate"><span class="pre">handle_EHLO()</span></code></a> hook below.</p>
</div>
</div></blockquote>
<div class="deprecated">
<p><span class="versionmodified deprecated">Deprecated since version 1.3: </span>Use the <a class="reference internal" href="#handle_EHLO" title="handle_EHLO"><code class="xref py py-meth docutils literal notranslate"><span class="pre">5-argument</span> <span class="pre">form</span></code></a> instead.
Support for the 4-argument form <strong>will be removed in version 2.0</strong></p>
</div>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_EHLO">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_EHLO</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">hostname</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">responses</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><span class="pre">str</span><span class="p"><span class="pre">]</span></span></span></span><a class="headerlink" href="#handle_EHLO" title="Link to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>hostname</strong> (<em>str</em>) – The host name given by the client in the <code class="docutils literal notranslate"><span class="pre">EHLO</span></code> command</p></li>
<li><p><strong>responses</strong> (<em>List</em><em>[</em><em>str</em><em>]</em>) – The ‘planned’ responses to the <code class="docutils literal notranslate"><span class="pre">EHLO</span></code> command
<em>including</em> the last <code class="docutils literal notranslate"><span class="pre">250</span> <span class="pre">HELP</span></code> response.</p></li>
</ul>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>List of response messages to be sent to the client</p>
</dd>
</dl>
<p>Called during <code class="docutils literal notranslate"><span class="pre">EHLO</span></code>.</p>
<p>The hook MUST return a list containing the desired responses.
The returned list should end with <code class="docutils literal notranslate"><span class="pre">250</span> <span class="pre">HELP</span></code></p>
<p>This hook MUST also set the :attr:<code class="docutils literal notranslate"><span class="pre">session.host_name</span></code> attribute.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>It is strongly recommended to not change element <code class="docutils literal notranslate"><span class="pre">[0]</span></code> of the list
(containing the hostname of the SMTP server).</p>
</div>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_HELO">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_HELO</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">hostname</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="headerlink" href="#handle_HELO" title="Link to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>hostname</strong> (<em>str</em>) – The host name given by client during <code class="docutils literal notranslate"><span class="pre">HELO</span></code></p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Response message to be sent to the client</p>
</dd>
</dl>
<p>This hook is called during <code class="docutils literal notranslate"><span class="pre">HELO</span></code>.</p>
<p>If implemented,
this hook MUST also set the :attr:<code class="docutils literal notranslate"><span class="pre">session.host_name</span></code> attribute
before returning <code class="docutils literal notranslate"><span class="pre">'250</span> <span class="pre">{}'.format(server.hostname)</span></code> as the status.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_MAIL">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_MAIL</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">address</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">mail_options</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="headerlink" href="#handle_MAIL" title="Link to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>address</strong> (<em>str</em>) – The parsed email address given by the client in the <code class="docutils literal notranslate"><span class="pre">MAIL</span> <span class="pre">FROM</span></code> command</p></li>
<li><p><strong>mail_options</strong> (<em>List</em><em>[</em><em>str</em><em>]</em>) – Additional ESMTP MAIL options provided by the client</p></li>
</ul>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Response message to be sent to the client</p>
</dd>
</dl>
<p>Called during <code class="docutils literal notranslate"><span class="pre">MAIL</span> <span class="pre">FROM</span></code>.</p>
<p>If implemented,
this hook MUST also set the <code class="xref py py-attr docutils literal notranslate"><span class="pre">envelope.mail_from</span></code> attribute
and it MAY extend <code class="xref py py-attr docutils literal notranslate"><span class="pre">envelope.mail_options</span></code> (which is always a Python list).</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_NOOP">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_NOOP</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">arg</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="headerlink" href="#handle_NOOP" title="Link to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>arg</strong> (<em>str</em>) – All characters following the <code class="docutils literal notranslate"><span class="pre">NOOP</span></code> command</p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Response message to be sent to the client</p>
</dd>
</dl>
<p>Called during <code class="docutils literal notranslate"><span class="pre">NOOP</span></code>.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py">
<span class="sig-name descname"><span class="pre">handle_PROXY</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">proxy_data</span></span></em><span class="sig-paren">)</span></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>server</strong> (<a class="reference internal" href="smtp.html#aiosmtpd.smtp.SMTP" title="aiosmtpd.smtp.SMTP"><em>SMTP</em></a>) – The <code class="xref py py-class docutils literal notranslate"><span class="pre">SMTP</span></code> instance invoking the hook.</p></li>
<li><p><strong>session</strong> (<a class="reference internal" href="concepts.html#Session" title="Session"><em>Session</em></a>) – The Session data <em>so far</em> (see Important note below)</p></li>
<li><p><strong>envelope</strong> (<a class="reference internal" href="concepts.html#Envelope" title="Envelope"><em>Envelope</em></a>) – The Envelope data <em>so far</em> (see Important note below)</p></li>
<li><p><strong>proxy_data</strong> (<a class="reference internal" href="proxyprotocol.html#aiosmtpd.proxy_protocol.ProxyData" title="aiosmtpd.proxy_protocol.ProxyData"><em>ProxyData</em></a>) – The result of parsing the PROXY Header</p></li>
</ul>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Truthy or Falsey, indicating if the connection may continue or not, respectively</p>
</dd>
</dl>
<p>Called during PROXY Protocol Handshake.</p>
<p>See <a class="reference internal" href="proxyprotocol.html#proxyprotocol"><span class="std std-ref">PROXY Protocol Support</span></a> for more information.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_QUIT">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_QUIT</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="headerlink" href="#handle_QUIT" title="Link to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Response message to be sent to the client</p>
</dd>
</dl>
<p>Called during <code class="docutils literal notranslate"><span class="pre">QUIT</span></code>.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_RCPT">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_RCPT</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">address</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">rcpt_options</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="headerlink" href="#handle_RCPT" title="Link to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>address</strong> (<em>str</em>) – The parsed email address given by the client in the <code class="docutils literal notranslate"><span class="pre">RCPT</span> <span class="pre">TO</span></code> command</p></li>
<li><p><strong>rcpt_options</strong> (<em>List</em><em>[</em><em>str</em><em>]</em>) – Additional ESMTP RCPT options provided by the client</p></li>
</ul>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Response message to be sent to the client</p>
</dd>
</dl>
<p>Called during <code class="docutils literal notranslate"><span class="pre">RCPT</span> <span class="pre">TO</span></code>.</p>
<p>If implemented,
this hook SHOULD append the address to <code class="docutils literal notranslate"><span class="pre">envelope.rcpt_tos</span></code>
and it MAY extend <code class="docutils literal notranslate"><span class="pre">envelope.rcpt_options</span></code> (both of which are always Python lists).</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_RSET">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_RSET</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="headerlink" href="#handle_RSET" title="Link to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Returns<span class="colon">:</span></dt>
<dd class="field-odd"><p>Response message to be sent to the client</p>
</dd>
</dl>
<p>Called during <code class="docutils literal notranslate"><span class="pre">RSET</span></code>.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_VRFY">
<em class="property"><span class="pre">async</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">handle_VRFY</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">address</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="headerlink" href="#handle_VRFY" title="Link to this definition"></a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Parameters<span class="colon">:</span></dt>
<dd class="field-odd"><p><strong>address</strong> (<em>str</em>) – The parsed email address given by the client in the <code class="docutils literal notranslate"><span class="pre">VRFY</span></code> command</p>
</dd>
<dt class="field-even">Returns<span class="colon">:</span></dt>
<dd class="field-even"><p>Response message to be sent to the client</p>
</dd>
</dl>
<p>Called during <code class="docutils literal notranslate"><span class="pre">VRFY</span></code>.</p>
</dd></dl>
<p>In addition to the SMTP command hooks, the following hooks can also be
implemented by handlers. These have different APIs, and are called
<strong>synchronously</strong> (i.e. they are <strong>not</strong> coroutines).</p>
<dl class="py method">
<dt class="sig sig-object py" id="handle_STARTTLS">
<span class="sig-name descname"><span class="pre">handle_STARTTLS</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">server</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">session</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">envelope</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#handle_STARTTLS" title="Link to this definition"></a></dt>
<dd><p>If implemented, and if SSL is supported, this method gets called
during the TLS handshake phase of <code class="docutils literal notranslate"><span class="pre">connection_made()</span></code>. It should return
True if the handshake succeeded, and False otherwise.</p>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="handle_exception">
<span class="sig-name descname"><span class="pre">handle_exception</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">error</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#handle_exception" title="Link to this definition"></a></dt>
<dd><p>If implemented, this method is called when any error occurs during the
handling of a connection (e.g. if an <code class="docutils literal notranslate"><span class="pre">smtp_<command>()</span></code> method raises an
exception). The exception object is passed in. This method <em>must</em> return
a status string, such as <code class="docutils literal notranslate"><span class="pre">'542</span> <span class="pre">Internal</span> <span class="pre">server</span> <span class="pre">error'</span></code>. If the method
returns <code class="docutils literal notranslate"><span class="pre">None</span></code> or raises an exception, an exception will be logged, and a
<code class="docutils literal notranslate"><span class="pre">451</span></code> code will be returned to the client.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>If client connection is lost, this handler will NOT be called.</p>
</div>
</dd></dl>
</section>
</section>
<section id="built-in-handlers">
<h2>Built-in handlers<a class="headerlink" href="#built-in-handlers" title="Link to this heading"></a></h2>
<p>The following built-in handlers can be imported from <a class="reference internal" href="#module-aiosmtpd.handlers" title="aiosmtpd.handlers"><code class="xref py py-mod docutils literal notranslate"><span class="pre">aiosmtpd.handlers</span></code></a>:</p>
<dl class="py class" id="module-aiosmtpd.handlers">
<dt class="sig sig-object py" id="aiosmtpd.handlers.AsyncMessage">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">aiosmtpd.handlers.</span></span><span class="sig-name descname"><span class="pre">AsyncMessage</span></span><a class="headerlink" href="#aiosmtpd.handlers.AsyncMessage" title="Link to this definition"></a></dt>
<dd><p>A subclass of the <a class="reference internal" href="#aiosmtpd.handlers.Message" title="aiosmtpd.handlers.Message"><code class="xref py py-class docutils literal notranslate"><span class="pre">Message</span></code></a> handler,
it is also an <span class="xref std std-term">abstract base class</span> (it must be subclassed).</p>
<p>The only difference with <a class="reference internal" href="#aiosmtpd.handlers.Message" title="aiosmtpd.handlers.Message"><code class="xref py py-class docutils literal notranslate"><span class="pre">Message</span></code></a> is that
<code class="xref py py-func docutils literal notranslate"><span class="pre">handle_message()</span></code> is called <em>asynchronously</em>.</p>
<p>This class <strong>cannot</strong> be used on the command line.</p>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="aiosmtpd.handlers.Debugging">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">aiosmtpd.handlers.</span></span><span class="sig-name descname"><span class="pre">Debugging</span></span><a class="headerlink" href="#aiosmtpd.handlers.Debugging" title="Link to this definition"></a></dt>
<dd><p>This class prints the contents of the received messages to a given output stream.
Programmatically, you can pass the stream to print to into the constructor.</p>
<p>When specified on the command line,
the (optional) positional argument
must either be the string <code class="docutils literal notranslate"><span class="pre">stdout</span></code> or <code class="docutils literal notranslate"><span class="pre">stderr</span></code>
indicating which stream to use.
Examples:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aiosmtpd</span> <span class="o">-</span><span class="n">c</span> <span class="n">aiosmtpd</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">Debugging</span>
<span class="n">aiosmtpd</span> <span class="o">-</span><span class="n">c</span> <span class="n">aiosmtpd</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">Debugging</span> <span class="n">stderr</span>
<span class="n">aiosmtpd</span> <span class="o">-</span><span class="n">c</span> <span class="n">aiosmtpd</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">Debugging</span> <span class="n">stdout</span>
</pre></div>
</div>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="aiosmtpd.handlers.Mailbox">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">aiosmtpd.handlers.</span></span><span class="sig-name descname"><span class="pre">Mailbox</span></span><a class="headerlink" href="#aiosmtpd.handlers.Mailbox" title="Link to this definition"></a></dt>
<dd><p>A subclass of the <a class="reference internal" href="#aiosmtpd.handlers.Message" title="aiosmtpd.handlers.Message"><code class="xref py py-class docutils literal notranslate"><span class="pre">Message</span></code></a> handler
which adds the messages to a <code class="xref py py-class docutils literal notranslate"><span class="pre">Maildir</span></code>.
See <a class="reference internal" href="#mailboxhandler"><span class="std std-ref">The Mailbox Handler</span></a> for details.</p>
<p>When specified on the command line,
it accepts <em>exactly</em> one positional argument which is
the <code class="docutils literal notranslate"><span class="pre">maildir</span></code> (i.e, directory where email messages will be stored.)
Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aiosmtpd</span> <span class="o">-</span><span class="n">c</span> <span class="n">aiosmtpd</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">Mailbox</span> <span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">myhome</span><span class="o">/</span><span class="n">Maildir</span>
</pre></div>
</div>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="aiosmtpd.handlers.Message">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">aiosmtpd.handlers.</span></span><span class="sig-name descname"><span class="pre">Message</span></span><a class="headerlink" href="#aiosmtpd.handlers.Message" title="Link to this definition"></a></dt>
<dd><p>This class is an <span class="xref std std-term">abstract base class</span> (it must be subclassed)
which converts the message content into a message instance.
The class used to create these instances can be passed to the constructor,
and defaults to <code class="xref py py-class docutils literal notranslate"><span class="pre">email.message.Message</span></code></p>
<p>This message instance gains a few additional headers
(e.g. <em class="mailheader">X-Peer</em>, <em class="mailheader">X-MailFrom</em>, and <em class="mailheader">X-RcptTo</em>).
You can override this behavior by overriding the <code class="xref py py-func docutils literal notranslate"><span class="pre">prepare_message()</span></code> method,
which takes a session and an envelope.
The message instance is then passed to the handler’s <code class="xref py py-func docutils literal notranslate"><span class="pre">handle_message()</span></code> method.
It is this method that must be implemented in the subclass.</p>
<p><code class="xref py py-func docutils literal notranslate"><span class="pre">prepare_message()</span></code> and <code class="xref py py-func docutils literal notranslate"><span class="pre">handle_message()`()</span></code> are both called <span class="boldital">synchronously</span>.</p>
<p>This class <strong>cannot</strong> be used on the command line.</p>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="aiosmtpd.handlers.Proxy">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">aiosmtpd.handlers.</span></span><span class="sig-name descname"><span class="pre">Proxy</span></span><a class="headerlink" href="#aiosmtpd.handlers.Proxy" title="Link to this definition"></a></dt>
<dd><p>This class is a relatively simple SMTP proxy;
it forwards messages to a remote host and port.
The constructor takes the host name and port as positional arguments.</p>
<p>This class <strong>cannot</strong> be used on the command line.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>Do not confuse this class with <a class="reference external" href="https://www.haproxy.com/blog/haproxy/proxy-protocol/">the PROXY Protocol</a>;
they are two totally different things.</p>
</div>
</dd></dl>
<dl class="py class">
<dt class="sig sig-object py" id="aiosmtpd.handlers.Sink">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">aiosmtpd.handlers.</span></span><span class="sig-name descname"><span class="pre">Sink</span></span><a class="headerlink" href="#aiosmtpd.handlers.Sink" title="Link to this definition"></a></dt>
<dd><p>This class just consumes and discards messages.
It’s essentially the “no op” handler.</p>
<p>It can be used on the command line, but accepts no positional arguments.
Example:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">aiosmtpd</span> <span class="o">-</span><span class="n">c</span> <span class="n">aiosmtpd</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">Sink</span>
</pre></div>
</div>
</dd></dl>
</section>
<section id="the-mailbox-handler">
<span id="mailboxhandler"></span><h2>The Mailbox Handler<a class="headerlink" href="#the-mailbox-handler" title="Link to this heading"></a></h2>
<p>A convenient handler is the <code class="docutils literal notranslate"><span class="pre">Mailbox</span></code> handler, which stores incoming
messages into a maildir.</p>
<p>To try it, let’s first prepare an <code class="xref py py-class docutils literal notranslate"><span class="pre">ExitStack</span></code> to automatically
clean up after we finish:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">contextlib</span> <span class="kn">import</span> <span class="n">ExitStack</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">tempfile</span> <span class="kn">import</span> <span class="n">TemporaryDirectory</span>
<span class="gp">>>> </span><span class="c1"># Clean up the temporary directory at the end</span>
<span class="gp">>>> </span><span class="n">resources</span> <span class="o">=</span> <span class="n">ExitStack</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">tempdir</span> <span class="o">=</span> <span class="n">resources</span><span class="o">.</span><span class="n">enter_context</span><span class="p">(</span><span class="n">TemporaryDirectory</span><span class="p">())</span>
</pre></div>
</div>
<p>Then, prepare the controller:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">os</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">aiosmtpd.controller</span> <span class="kn">import</span> <span class="n">Controller</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">aiosmtpd.handlers</span> <span class="kn">import</span> <span class="n">Mailbox</span>
<span class="gp">>>> </span><span class="c1">#</span>
<span class="gp">>>> </span><span class="n">maildir_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">tempdir</span><span class="p">,</span> <span class="s1">'maildir'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">controller</span> <span class="o">=</span> <span class="n">Controller</span><span class="p">(</span><span class="n">Mailbox</span><span class="p">(</span><span class="n">maildir_path</span><span class="p">))</span>
<span class="gp">>>> </span><span class="n">controller</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="gp">>>> </span><span class="c1"># Arrange for the controller to be stopped at the end</span>
<span class="gp">>>> </span><span class="n">ignore</span> <span class="o">=</span> <span class="n">resources</span><span class="o">.</span><span class="n">callback</span><span class="p">(</span><span class="n">controller</span><span class="o">.</span><span class="n">stop</span><span class="p">)</span>
</pre></div>
</div>
<p>Now we can connect to the server and send it a message…</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">smtplib</span> <span class="kn">import</span> <span class="n">SMTP</span>
<span class="gp">>>> </span><span class="n">client</span> <span class="o">=</span> <span class="n">SMTP</span><span class="p">(</span><span class="n">controller</span><span class="o">.</span><span class="n">hostname</span><span class="p">,</span> <span class="n">controller</span><span class="o">.</span><span class="n">port</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">client</span><span class="o">.</span><span class="n">sendmail</span><span class="p">(</span><span class="s1">'aperson@example.com'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'bperson@example.com'</span><span class="p">],</span> <span class="s2">"""</span><span class="se">\</span>
<span class="gp">... </span><span class="s2">From: Anne Person <anne@example.com></span>
<span class="gp">... </span><span class="s2">To: Bart Person <bart@example.com></span>
<span class="gp">... </span><span class="s2">Subject: A test</span>
<span class="gp">... </span><span class="s2">Message-ID: <ant></span>
<span class="gp">...</span>
<span class="gp">... </span><span class="s2">Hi Bart, this is Anne.</span>
<span class="gp">... </span><span class="s2">"""</span><span class="p">)</span>
<span class="go">{}</span>
</pre></div>
</div>
<p>…and a second message…</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">client</span><span class="o">.</span><span class="n">sendmail</span><span class="p">(</span><span class="s1">'cperson@example.com'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'dperson@example.com'</span><span class="p">],</span> <span class="s2">"""</span><span class="se">\</span>
<span class="gp">... </span><span class="s2">From: Cate Person <cate@example.com></span>
<span class="gp">... </span><span class="s2">To: Dave Person <dave@example.com></span>
<span class="gp">... </span><span class="s2">Subject: A test</span>
<span class="gp">... </span><span class="s2">Message-ID: <bee></span>
<span class="gp">...</span>
<span class="gp">... </span><span class="s2">Hi Dave, this is Cate.</span>
<span class="gp">... </span><span class="s2">"""</span><span class="p">)</span>
<span class="go">{}</span>
</pre></div>
</div>
<p>…and a third message.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">client</span><span class="o">.</span><span class="n">sendmail</span><span class="p">(</span><span class="s1">'eperson@example.com'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'fperson@example.com'</span><span class="p">],</span> <span class="s2">"""</span><span class="se">\</span>
<span class="gp">... </span><span class="s2">From: Elle Person <elle@example.com></span>
<span class="gp">... </span><span class="s2">To: Fred Person <fred@example.com></span>
<span class="gp">... </span><span class="s2">Subject: A test</span>
<span class="gp">... </span><span class="s2">Message-ID: <cat></span>
<span class="gp">...</span>
<span class="gp">... </span><span class="s2">Hi Fred, this is Elle.</span>
<span class="gp">... </span><span class="s2">"""</span><span class="p">)</span>
<span class="go">{}</span>
</pre></div>
</div>
<p>We open up the mailbox again, and all three messages are waiting for us.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">mailbox</span> <span class="kn">import</span> <span class="n">Maildir</span>
<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">operator</span> <span class="kn">import</span> <span class="n">itemgetter</span>
<span class="gp">>>> </span><span class="n">mailbox</span> <span class="o">=</span> <span class="n">Maildir</span><span class="p">(</span><span class="n">maildir_path</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">messages</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">mailbox</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">itemgetter</span><span class="p">(</span><span class="s1">'message-id'</span><span class="p">))</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">message</span> <span class="ow">in</span> <span class="n">messages</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">message</span><span class="p">[</span><span class="s1">'Message-ID'</span><span class="p">],</span> <span class="n">message</span><span class="p">[</span><span class="s1">'From'</span><span class="p">],</span> <span class="n">message</span><span class="p">[</span><span class="s1">'To'</span><span class="p">])</span>
<span class="go"><ant> Anne Person <anne@example.com> Bart Person <bart@example.com></span>
<span class="go"><bee> Cate Person <cate@example.com> Dave Person <dave@example.com></span>
<span class="go"><cat> Elle Person <elle@example.com> Fred Person <fred@example.com></span>
</pre></div>
</div>
<p>Cleanup when we’re done.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">resources</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="lmtp.html" class="btn btn-neutral float-left" title="The LMTP class" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="auth.html" class="btn btn-neutral float-right" title="Authentication System" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>© Copyright 2015-2024, The aiosmtpd Developers.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>