{"id":18084838,"url":"https://github.com/jwodder/outgoing","last_synced_at":"2025-07-23T08:05:37.263Z","repository":{"id":57449893,"uuid":"342399977","full_name":"jwodder/outgoing","owner":"jwodder","description":"Common interface for multiple e-mail methods","archived":false,"fork":false,"pushed_at":"2025-03-31T20:17:06.000Z","size":236,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-23T08:04:08.580Z","etag":null,"topics":["available-on-pypi","e-mail","email","mailbox","mbox","python","send-mail","sendmail","smtp"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jwodder.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-02-25T22:49:00.000Z","updated_at":"2025-01-23T14:38:48.000Z","dependencies_parsed_at":"2023-09-30T18:27:41.726Z","dependency_job_id":"40602308-09c4-4ea9-82fe-f6079b2e7437","html_url":"https://github.com/jwodder/outgoing","commit_stats":{"total_commits":162,"total_committers":1,"mean_commits":162.0,"dds":0.0,"last_synced_commit":"71edff470830c41d98bc900480f0e95b92dbb262"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/jwodder/outgoing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Foutgoing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Foutgoing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Foutgoing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Foutgoing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jwodder","download_url":"https://codeload.github.com/jwodder/outgoing/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jwodder%2Foutgoing/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266640819,"owners_count":23960808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["available-on-pypi","e-mail","email","mailbox","mbox","python","send-mail","sendmail","smtp"],"created_at":"2024-10-31T15:08:23.709Z","updated_at":"2025-07-23T08:05:37.049Z","avatar_url":"https://github.com/jwodder.png","language":"Python","readme":"|repostatus| |ci-status| |coverage| |pyversions| |license|\n\n.. |repostatus| image:: https://www.repostatus.org/badges/latest/active.svg\n    :target: https://www.repostatus.org/#active\n    :alt: Project Status: Active — The project has reached a stable, usable\n          state and is being actively developed.\n\n.. |ci-status| image:: https://github.com/jwodder/outgoing/actions/workflows/test.yml/badge.svg\n    :target: https://github.com/jwodder/outgoing/actions/workflows/test.yml\n    :alt: CI Status\n\n.. |coverage| image:: https://codecov.io/gh/jwodder/outgoing/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/jwodder/outgoing\n\n.. |pyversions| image:: https://img.shields.io/pypi/pyversions/outgoing.svg\n    :target: https://pypi.org/project/outgoing/\n\n.. |license| image:: https://img.shields.io/github/license/jwodder/outgoing.svg\n    :target: https://opensource.org/licenses/MIT\n    :alt: MIT License\n\n`GitHub \u003chttps://github.com/jwodder/outgoing\u003e`_\n| `PyPI \u003chttps://pypi.org/project/outgoing/\u003e`_\n| `Documentation \u003chttps://outgoing.readthedocs.io\u003e`_\n| `Issues \u003chttps://github.com/jwodder/outgoing/issues\u003e`_\n| `Changelog \u003chttps://github.com/jwodder/outgoing/blob/master/CHANGELOG.md\u003e`_\n\n``outgoing`` provides a common interface to multiple different e-mail sending\nmethods (SMTP, sendmail, mbox, etc.).  Just construct a sender from a\nconfiguration file or object, pass it an ``EmailMessage`` instance, and let the\nmagical internet daemons take care of the rest.\n\n``outgoing`` itself provides support for only basic sending methods; additional\nmethods are provided by extension packages.\n\nSee `the documentation \u003chttps://outgoing.readthedocs.io\u003e`_ for more\ninformation.\n\n\nInstallation\n============\n``outgoing`` requires Python 3.8 or higher.  Just use `pip\n\u003chttps://pip.pypa.io\u003e`_ for Python 3 (You have pip, right?) to install\n``outgoing`` and its dependencies::\n\n    python3 -m pip install outgoing\n\n\nExamples\n========\n\nA sample configuration file:\n\n.. code:: toml\n\n    [outgoing]\n    method = \"smtp\"\n    host = \"mx.example.com\"\n    ssl = \"starttls\"\n    username = \"myname\"\n    password = { file = \"~/secrets/smtp-password\" }\n\n\nSending an e-mail based on a configuration file:\n\n.. code:: python\n\n    from email.message import EmailMessage\n    import outgoing\n\n    # Construct an EmailMessage object the standard Python way:\n    msg = EmailMessage()\n    msg[\"Subject\"] = \"Meet me\"\n    msg[\"To\"] = \"my.beloved@love.love\"\n    msg[\"From\"] = \"me@here.qq\"\n    msg.set_content(\n        \"Oh my beloved!\\n\"\n        \"\\n\"\n        \"Wilt thou dine with me on the morrow?\\n\"\n        \"\\n\"\n        \"We're having hot pockets.\\n\"\n        \"\\n\"\n        \"Love, Me\\n\"\n    )\n\n    # Construct a sender object based on the default config file (assuming it's\n    # populated)\n    with outgoing.from_config_file() as sender:\n        # Now send that letter!\n        sender.send(msg)\n\n\nAs an alternative to using a configuration file, you can specify an explicit\nconfiguration by passing the configuration structure to the\n``outgoing.from_dict()`` method, like so:\n\n.. code:: python\n\n    from email.message import EmailMessage\n    import outgoing\n\n    # Construct an EmailMessage object using the eletter library\n    # \u003chttps://github.com/jwodder/eletter\u003e:\n    from eletter import compose\n\n    msg1 = compose(\n        subject=\"No.\",\n        to=[\"me@here.qq\"],\n        from_=\"my.beloved@love.love\",\n        text=(\n            \"Hot pockets?  Thou disgusteth me.\\n\"\n            \"\\n\"\n            \"Pineapple pizza or RIOT.\\n\"\n        ),\n    )\n\n    msg2 = compose(\n        subject=\"I'd like to place an order.\",\n        to=[\"pete@za.aa\"],\n        from_=\"my.beloved@love.love\",\n        text=\"I need the usual.  Twelve Hawaiian Abominations to go, please.\\n\",\n    )\n\n    SENDING_CONFIG = {\n        \"method\": \"smtp\",\n        \"host\": \"smtp.love.love\",\n        \"username\": \"my.beloved\",\n        \"password\": {\"env\": \"SMTP_PASSWORD\"},\n        \"ssl\": \"starttls\",\n    }\n\n    with outgoing.from_dict(SENDING_CONFIG) as sender:\n        sender.send(msg1)\n        sender.send(msg2)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwodder%2Foutgoing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjwodder%2Foutgoing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjwodder%2Foutgoing/lists"}