Skip to main content

PyEVP

Documentation CI Spec drift spec: draft-hardt-02 status: alpha ty License: MIT Ask DeepWiki

日本語

Python library for the Email Verification Protocol (EVP): verify tokens as a relying party, or issue them for your own email domains. With EVP, the browser obtains a token from the user's email provider proving they control an address, and your server verifies it, with no confirmation email round-trip.

Documentation: https://docs.pyevp.dev/ · Live demo: https://pyevp.dev/demo

Status: alpha. The protocol (draft-hardt-email-verification, WICG Email Verification API) is still changing. PyEVP keeps every moving part in a versioned Profile so it can follow along.

  • Browsers: Chrome, with chrome://flags/#email-verification-protocol enabled or on a site registered for the origin trial. Tested with Chrome 154. Other browsers send no token.
  • Email providers: Gmail issues tokens today. Your own domains can too, with pyevp.issuer.
  • Python: 3.11 or newer.

Install

pip install "pyevp[dns,httpx2]"   # core + the DNS and HTTP adapters

The core depends only on joserfc and idna. [dns,httpx2] adds the adapters Verifier.default() uses; httpx works too (see DNS, HTTP and caching). [all] adds the Django integration and the command line.

How it works

  1. Render a form with a nonce kept in the user's session:

    from pyevp import SessionNonces, token_input
    
    nonce = SessionNonces(session).issue()  # Flask, Starlette and Django sessions all work
    
    <input type="email" name="email" autocomplete="email">
    <input type="hidden" name="evt" autocomplete="email-verification-token" nonce="{{ nonce }}">
    

    (token_input(nonce) renders the hidden input.)

  2. When the user picks an address, the browser fills evt with <EVT>~<KB-JWT>.

  3. On submit, verify it:

    from pyevp import EVPError, SessionNonces, Verifier
    
    verifier = Verifier.default(audience="https://example.com")  # your origin
    
    try:
        result = verifier.verify_submission(
            form.get("evt"), nonces=SessionNonces(session), email=form["email"]
        )
    except EVPError as exc:
        ...  # exc.code says why, e.g. "nonce_mismatch"; fall back to email confirmation
    else:
        if result is None:
            ...  # no token: fall back to email confirmation
        else:
            result.email, result.issuer  # verified
    

    AsyncVerifier has the same API with await.

Everything that can be checked offline is checked first, and only hosts found through DNS are ever contacted, never hosts named in the token. Every rejection raises an EVPError with an error code.

More

Examples

Each example is a standalone project with its own tests:

Contributing

See CONTRIBUTING.md.

License

MIT

Metadata

Release files for PyEVP 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for PyEVP 0.2.0
File Size Uploaded
pyevp-0.2.0.tar.gz 71.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for PyEVP 0.2.0
File Interpreter ABI Platform
pyevp-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 166.2 kB

Release files / pyevp-0.2.0.tar.gz

Download URL pyevp-0.2.0.tar.gz
Size 71.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f703a269c4cdeab9c5b44818e66a9659b22bdf8bd8fc2dfee27fa4c46d8715e6
BLAKE2b-256 checksum
How to use checksums
272b502e88e015d44f85cd562474178289066e5c885c0fef78b3db355476b97f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release files / pyevp-0.2.0-py3-none-any.whl

Download URL pyevp-0.2.0-py3-none-any.whl
Size 94.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
769b166adb3750d1ad51cf204ad4e347b0a9b1e2be3bc166e129f5556f35561d
BLAKE2b-256 checksum
How to use checksums
958267dd76b0b64e7ee7a206e2f005f0213a6edb1b36aa876eed22ac2563e918
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page