Skip to main content

A Python wrapper for the Emailnator service providing both synchronous and asynchronous APIs.

Project description

email_generator

Asynchronous and synchronous API wrapper for EmailNator. Provides a small, well-typed SDK to generate temporary Gmail-style addresses and read incoming messages. Designed for both script usage and integration into larger automation/test suites.


Features

  • Fully asynchronous core using httpx.AsyncClient.
  • Optional synchronous wrapper for blocking workflows.
  • Automatic XSRF token management (fetch, decode, refresh) via XsrfManager.
  • Async-aware initialization helpers (metaclasses / factories) so classes can expose __ainit__.
  • Async-safe singletons (AsyncSingletonMeta) where appropriate (HTTP client).
  • Configurable via YAML (config.yaml) with optional proxy support.
  • Clear, Google-style docstrings and type annotations.

Requirements

  • Python 3.11+ (works on 3.13).

  • Dependencies (typical):

    • httpx
    • PyYAML
    • pytest / pytest-asyncio for tests

Installation

pip install .
# or in editable mode for development
pip install -e .

Configuration

gmail_generator/config/config.yaml (example):

BASE_URL: https://www.emailnator.com
TIMEOUT: 15
USE_HTTP2: true
USER_AGENT: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0"
GMAIL_CONFIG:
  - dotGmail
  - plusGmail
PROXY: null

Notes

  • PROXY: null sets config.PROXY to None. Do not use the literal string "None"httpx will reject that as an invalid proxy URL.
  • Keep credentials / secrets out of the YAML in public repos.

Quickstart — Asynchronous (recommended)

Save the example below as examples/async_example.py.

# Copyright (C) 2025 unelected
#
# This file is part of account_generator.
#
# account_generator is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# account_generator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with account_generator. If not, see
# <https://www.gnu.org/licenses/>.

"""
Example usage of the asynchronous AsyncEmailGenerator.

This script demonstrates:
  1. Creating the asynchronous AsyncEmailGenerator (awaitable constructor).
  2. Generating a single temporary email address.
  3. Retrieving messages for that address.
  4. Printing results.
"""
import asyncio

from gmail_generator.asyncio.email_generator import AsyncEmailGenerator


async def generate_email_and_get_messages() -> None:
    """
    Initialize the async generator, produce an email and fetch messages.
    """
    generator = await AsyncEmailGenerator()
    email_list = await generator.generate_email()
    email = email_list[0]
    messages = await generator.get_messages(email)
    print(f"Email: {email}\nMessages: {messages}")


if __name__ == "__main__":
    asyncio.run(generate_email_and_get_messages())

Quickstart — Synchronous wrapper

Save as examples/sync_example.py.

# Copyright (C) 2025 unelected
#
# This file is part of account_generator.
#
# account_generator is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# account_generator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with account_generator. If not, see
# <https://www.gnu.org/licenses/>.

"""
Synchronous example using EmailGenerator wrapper.

This demonstrates creating the blocking wrapper and using it to generate
an email and retrieve messages in a non-async program.
"""
from gmail_generator.sync.email_generator import EmailGenerator

def main() -> None:
    gen = EmailGenerator()
    email = gen.generate_email()
    messages = gen.get_messages(email)
    print(f"Email: {email}\nMessages: {messages}")

if __name__ == "__main__":
    main()

Prefer EmailGenerator.create() (factory) over direct construction to avoid mixing event loop setups in environments that already run an event loop.


Public API overview

  • gmail_generator.asyncio.email_generator.AsyncEmailGenerator High-level async facade. Use await AsyncEmailGenerator() (if metaclass used) or await AsyncEmailGenerator.create().

  • gmail_generator.asyncio.generators.Generators Endpoint wrapper for /generate-email. Provides generate_email() and generate_bulk_emails().

  • gmail_generator.asyncio.message_getter.MessageGetter Fetch and parse messages for a given temporary email address.

  • gmail_generator.asyncio.builders.AsyncEmailnatorClient HTTP client singleton (uses AsyncSingletonMeta). Exposes get_client(), get_headers(), refresh_token().

  • gmail_generator.security.xsrf_manager.XsrfManager Encapsulates XSRF lifecycle: ensure_token(), refresh(), get_token(), get_headers().

  • gmail_generator.config.config Loads config.yaml to config object with attributes BASE_URL, TIMEOUT, USE_HTTP2, USER_AGENT, GMAIL_CONFIG, PROXY.


Behavior notes & gotchas

  • Await the constructor if using metaclass-based __ainit__: obj = await ClassName(). If you forget await, you get a coroutine object with no attributes.
  • Proxy value in YAML must be null for no proxy. String "None" will break httpx.
  • Cloudflare / Bot protection: EmailNator may be behind challenges (403/419). Temporary addresses and token flows can be blocked by anti-bot measures — the library attempts to read XSRF-TOKEN cookie, but if the site requires JavaScript challenges, consider using a Playwright-based flow or proper proxies.
  • Event loop management: Avoid calling asyncio.run() inside already-running event loops. For synchronous wrapper, use a dedicated factory that creates its own loop safely.

Error handling & common troubleshooting

  • coroutine object has no attribute '...' — forgot await on constructor.
  • RuntimeWarning: coroutine was never awaited — coroutine was created and not awaited; search for returns of coroutines.
  • ValueError: Unknown scheme for proxy URL "None"config.PROXY is the string "None", fix YAML to null or code to coerce None.
  • HTTP 419 / Page Expired — XSRF token missing or expired; check XsrfManager and cookie extraction.
  • HTTP 403 Cloudflare — site-side bot protection.

Contributing

  • Fork, branch feature/..., implement, add tests, open PR.
  • Keep changes backwards-compatible for public API unless you bump major version.
  • Follow project style: type annotations, Google-style docstrings, tests.

License

This project is licensed under GNU Affero General Public License v3 (AGPL-3.0).


Files to include in the repo

  • README.md (this file)
  • pyproject.toml / setup.cfg with dependencies and dev extras
  • gmail_generator/config/config.yaml example
  • examples/async_example.py
  • examples/sync_example.py
  • tests/ with unit & async tests

Contact

Open an issue or submit a pull request for help, bug reports, or enhancements.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

emailnator_wrapper-1.0.0.tar.gz (28.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

emailnator_wrapper-1.0.0-py3-none-any.whl (43.9 kB view details)

Uploaded Python 3

File details

Details for the file emailnator_wrapper-1.0.0.tar.gz.

File metadata

  • Download URL: emailnator_wrapper-1.0.0.tar.gz
  • Upload date:
  • Size: 28.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for emailnator_wrapper-1.0.0.tar.gz
Algorithm Hash digest
SHA256 adbc530ca21f349d1713a4152ae91fe94efbaf42a0387ce961116eae0389b58c
MD5 927bbc9d9831f164d27c4e460aa71553
BLAKE2b-256 f8410e430f76fdbbbbc4bf6bfc1a44ac9108d28f1cfe34e20eb04e008788ecdd

See more details on using hashes here.

File details

Details for the file emailnator_wrapper-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for emailnator_wrapper-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8d40e5b2cc48273efea035e6afb06da32b103932cbd587e05761e5b5e1d5825e
MD5 e410e896643e584c9bcfa6f01921fe96
BLAKE2b-256 77f07cfbc0d1023c75d4e5b94e02d79620109435bbbb6d79f5b6d18cf05b0b8f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page