# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['mailers', 'mailers.plugins']

package_data = \
{'': ['*']}

install_requires = \
['aiosmtplib>=1.1.6,<2.0.0']

setup_kwargs = {
    'name': 'mailers',
    'version': '1.2.0',
    'description': 'Email delivery for asyncio.',
    'long_description': '# Mailers for asyncio\n\n![PyPI](https://img.shields.io/pypi/v/mailers)\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/alex-oleshkevich/mailers/Lint)\n![GitHub](https://img.shields.io/github/license/alex-oleshkevich/mailers)\n![Libraries.io dependency status for latest release](https://img.shields.io/librariesio/release/pypi/mailers)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/mailers)\n![GitHub Release Date](https://img.shields.io/github/release-date/alex-oleshkevich/mailers)\n![Lines of code](https://img.shields.io/tokei/lines/github/alex-oleshkevich/mailers)\n\n## Installation\n\n```bash\npip install mailers\n```\n\n## Features\n\n* full utf-8 support\n* fully async\n* pluggable transports\n* multiple built-in transports including: SMTP, file, null, in-memory, streaming, and console.\n* plugin system\n* DKIM signing\n\n## Usage\n\nA little of theory. This library exposes two main concepts: mailers and transports. Mailers are high-level interfaces\nthat you should use to send emails while transports are low-level drivers for mailers.\n\nHere is the example:\n\n```python\nfrom mailers import create_mailer, EmailMessage\n\nmessage = EmailMessage(to=\'user@localhost\', from_address=\'from@localhost\', subject=\'Hello\', text_body=\'World!\')\nmailer = create_mailer(\'smtp://user:password@localhost:25?timeout=2\')\nawait mailer.send(message)\n```\n\nYou can also send to multiple recipients by passing an iterable int `to` argument:\n\n```python\nmessage = EmailMessage(to=[\'user@localhost\', \'user2@localhost\', \'user@localhost\'], ...)\n```\n\n## Compose messages\n\nThe arguments and methods of `EmailMessage ` class are self-explanatory so here is an kick-start example:\n\n```python\nfrom mailers import EmailMessage, Attachment\n\nmessage = EmailMessage(\n    to=\'user@localhost\',\n    from_address=\'from@example.tld\',\n    cc=\'cc@example.com\',\n    bcc=[\'bcc@example.com\'],\n    text_body=\'Hello world!\',\n    html_body=\'<b>Hello world!</b>\',\n)\n```\n\n`cc`, `bcc`, `to`, `reply_to` can be either strings or lists of strings.\n\n## Attachments\n\nUse `attach_file` and `attach_content` to add attachments. Also, you can use `Attachment` class for more control.\n\n```python\nfrom mailers import EmailMessage, Attachment\n\nmessage = EmailMessage(\n    to=\'user@localhost\',\n    from_address=\'from@example.tld\',\n    text_body=\'Hello world!\',\n    attachments=[\n        Attachment(\'CONTENTS\', \'file.txt\', \'text/plain\'),\n    ]\n)\n\n# attachments can be added on demand:\nawait message.attach_file(path=\'file.txt\')\n\n# attach using a class\nmessage.add_attachment(Attachment(\'CONTENTS\', \'file.txt\', \'text/plain\'))\n\n# or you may pass attachment contents directory\nmessage.attach_content(file_name=\'file.txt\', content=\'HERE GO ATTACHMENT CONTENTS\', mime_type=\'text/plain\')\n```\n\n## Inline attachments\n\nYou can add inline attachments (eg. images) and then reference them in HTML. For that, set `inline=True` and\nspecify `content_id=SOMEUNIQID` arguments in `attach_*` functions. Then you can reference images in HTML part like\nthat `<img src="cid:SOMEUNIQID">"`.\n\n```python\nfrom mailers import EmailMessage, Attachment\n\nmessage = EmailMessage(\n    to=\'user@localhost\',\n    from_address=\'from@example.tld\',\n    html_body=\'Render me <img src="cid:img1">\',\n)\n\nawait message.attach_file(path=\'/path/to/image.png\', inline=True, content_id=\'img1\')\n```\n\n## DKIM signing\n\nYou may wish to add DKIM signature to your messages to prevent them from being put into the spam folder. We provide a\nplugin for it.\n\nNote, you need to install [`dkimpy`](https://pypi.org/project/dkimpy/) package to start using this plugin.\n\n```python\nfrom mailers import create_mailer\nfrom mailers.plugins.dkim import DkimSignature\n\ndkim_plugin = DkimSignature(selector=\'default\', private_key_path=\'/path/to/key.pem\')\n\n# or you can put key content using private_key argument\ndkim_plugin = DkimSignature(selector=\'default\', private_key=\'PRIVATE KEY GOES here...\')\n\nmailer = create_mailer(\'smtp://\')\n```\n\nThe plugin signs "From", "To", "Subject" headers by default. Use "headers" argument to override it.\n\nIt is recommended to place DKIM plugin to the last place in the plugins list.\n\n## Plugins\n\nPlugins let you inspect and modify outgoing messages before or after they are sent. The plugin is a class that\nimplements `mailers.plugins.Plugin` protocol. Plugins are added to mailers via `plugins` argument.\n\nBelow you see an example plugin:\n\n```python\nfrom email.message import Message\n\nfrom mailers import BasePlugin, create_mailer, Mailer\n\n\nclass PrintPlugin(BasePlugin):\n\n    async def on_before_send(self, message: Message) -> None:\n        print(\'sending message %s.\' % message)\n\n    async def on_after_send(self, message: Message) -> None:\n        print(\'message has been sent %s.\' % message)\n\n\nmailer = Mailer(plugins=[PrintPlugin()])\n\n# or if you use create_mailer shortcut\nmailer = create_mailer(plugins=[PrintPlugin()])\n```\n\n## Transports\n\n### SMTP transport\n\nSend messages via third-party SMTP servers.\n\n**Class:** `mailers.transports.SMTPTransport`\n**directory** `smtp://user:pass@hostname:port?timeout=&use_tls=1`\n**Options:**\n\n* `host` (string, default "localhost") - SMTP server host\n* `port` (string, default "25") - SMTP server port\n* `user` (string) - SMTP server login\n* `password` (string) - SMTP server login password\n* `use_tls` (string, choices: "yes", "1", "on", "true") - use TLS\n* `timeout` (int) - connection timeout\n* `cert_file` (string) - path to certificate file\n* `key_file` (string) - path to key file\n\n### File transport\n\nWrite outgoing messages into a directory in EML format.\n\n**Class:** `mailers.transports.FileTransport`\n**DSN:** `file:///tmp/mails`\n**Options:**\n\n* `directory` (string) path to a directory\n\n### Null transport\n\nDiscards outgoing messages. Takes no action on send.\n\n**Class:** `mailers.transports.NullTransport`\n**DSN:** `null://`\n\n### Memory transport\n\nKeeps all outgoing messages in memory. Good for testing.\n\n**Class:** `mailers.transports.InMemoryTransport`\n**DSN:** `memory://`\n**Options:**\n\n* `storage` (list of strings) - outgoing message container\n\nYou can access the mailbox via ".mailbox" attribute.\n\nExample:\n\n```python\nfrom mailers import Mailer, InMemoryTransport, EmailMessage\n\ntransport = InMemoryTransport([])\nmailer = Mailer(transport=transport)\n\nawait mailer.send(EmailMessage(...))\nassert len(transport.mailbox) == 1  # here are all outgoing messages\n```\n\n### Streaming transport\n\nWrites all messages into a writable stream. Ok for local development.\n\n**Class:** `mailers.transports.StreamTransport`\n**DSN:** unsupported\n**Options:**\n\n* `output` (typing.IO) - a writable stream\n\nExample:\n\n```python\nimport io\nfrom mailers import Mailer, StreamTransport\n\ntransport = StreamTransport(output=io.StringIO())\nmailer = Mailer(transport=transport)\n```\n\n### Console transport\n\nThis is a preconfigured subclass of streaming transport. Writes to `sys.stderr` by default.\n\n**Class:** `mailers.transports.ConsoleTransport`\n**DSN:** `console://`\n**Options:**\n\n* `output` (typing.IO) - a writable stream\n\n### Custom transports.\n\nEach transport must implement `mailers.transports.Transport` protocol. Preferably, inherit from `BaseTransport` class:\n\n```python\nimport typing as t\nfrom email.message import Message\nfrom mailers import BaseTransport, Mailer, EmailMessage, Transport, EmailURL\n\n\nclass PrintTransport(BaseTransport):\n    @classmethod\n    def from_url(cls, url: t.Union[str, EmailURL]) -> t.Optional[Transport]:\n        # this method is optional,\n        # if your transport does not support instantiation from URL then return None here.\n        # returning None is the default behavior\n        return None\n\n    async def send(self, message: Message) -> None:\n        print(str(message))\n\n\nmailer = Mailer(transport=PrintTransport())\n```\n\nThe library will call `Transport.from_url` when it needs to instantiate the transport instance from the URL. It is ok to\nreturn `None` as call result then the transport will be instantiated using construction without any arguments passed.\n\nOnce you have defined a new transport, register a URL protocol for it:\n\n```python\nadd_protocol_handler(\'print\', PrintTransport)\nmailer = Mailer(\'print://\')\n```\n',
    'author': 'alex.oleshkevich',
    'author_email': 'alex.oleshkevich@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/alex-oleshkevich/mailers',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
