Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
P

python-email-validator

> 数据库
Open source

A robust email syntax and deliverability validation library for Python.

1.4K stars0 likes0 views
WebsiteGitHub

About

A robust email syntax and deliverability validation library for Python.

email-validator: Validate Email Addresses

A robust email address syntax and deliverability validation library for Python 3.10+ by Joshua Tauberer.

This library validates that a string is of the form [email protected] and optionally checks that the domain name is set up to receive email. This is the sort of validation you would want when you are identifying users by their email address like on a registration form.

Key features:

  • Checks that an email address has the correct syntax --- great for email-based registration/login forms or validating data.
  • Gives friendly English error messages when validation fails that you can display to end-users.
  • Checks deliverability (optional): Does the domain name resolve? (You can override the default DNS resolver to add query caching.)
  • Supports internationalized domain names (like @ツ.life), internationalized local parts (like ツ@example.com), and optionally parses display names (e.g. "My Name" <[email protected]>).
  • Rejects addresses with invalid or unsafe Unicode characters, obsolete email address syntax that you'd find unexpected, special use domain names like @localhost, and domains without a dot by default. This is an opinionated library!
  • Normalizes email addresses (important for internationalized and quoted-string addresses! see below).
  • Python type annotations are used.

This is an opinionated library. You should definitely also consider using the less-opinionated pyIsEmail if it works better for you. View the CHANGELOG / Release Notes for the version history of changes in the library. Occasionally this README is ahead of the latest published package --- see the CHANGELOG for details.


Installation

This package is on PyPI, so:

pip install email-validator

(You might need to use pip3 depending on your local environment.)

Quick Start

If you're validating a user's email address before creating a user account in your application, you might do this:

…

This validates the address and gives you its normalized form. You should put the normalized form in your database and always normalize before checking if an address is in your database. When using this in a login form, set check_deliverability to False to avoid unnecessary DNS queries.

Usage

Overview

The module provides a function validate_email(email_address) which takes an email address and:

  • Raises a EmailNotValidError with a helpful, human-readable error message explaining why the email address is not valid, or
  • Returns an object with a normalized form of the email address (which you should use!) and other information about it.

When an email address is not valid, validate_email raises either an EmailSyntaxError if the form of the address is invalid or an EmailUndeliverableError if the domain name fails DNS checks. Both exception classes are subclasses of EmailNotValidError, which in turn is a subclass of ValueError.

But when an email address is valid, an object is returned containing a normalized form of the email address (which you should use!) and other information.

The validator doesn't, by default, permit obsoleted forms of email addresses that no one uses anymore even though they are still valid and deliverable, since they will probably give you grief if you're using email for login. (See later in the document about how to allow some obsolete forms.)

The validator optionally checks that the domain name in the email address has a DNS MX record indicating that it can receive email. (Except a Null MX record. If there is no MX record, a fallback A/AAAA-record is permitted, unless a reject-all SPF record is present.) DNS is slow and sometimes unavailable or unreliable, so consider whether these checks are useful for your use case and turn them off if they aren't. There is nothing to be gained by trying to actually contact an SMTP server, so that's not done here. For privacy, security, and practicality reasons, servers are good at not giving away whether an address is deliverable or not: email addresses that appear to accept mail at first can bounce mail after a delay, and bounced mail may indicate a temporary failure of a good email address (sometimes an intentional failure, like greylisting).

Options

The validate_email function also accepts the following keyword arguments (defaults are as shown below):

check_deliverability=True: If true, DNS queries are made to check that the domain name in the email address (the part after the @-sign) can receive mail, as described above. Set to False to skip this DNS-based check. It is recommended to pass False when performing validation for login pages (but not account creation pages) since re-validation of a previously validated domain in your database by querying DNS at every login is probably undesirable. You can also set email_validator.CHECK_DELIVERABILITY to False to turn this off for all calls by default.

dns_resolver=None: Pass an instance of dns.resolver.Resolver to control the DNS resolver including setting a timeout and a cache. The caching_resolver function shown below is a helper function to construct a dns.resolver.Resolver with a LRUCache. Reuse the same resolver instance across calls to validate_email to make use of the cache.

test_environment=False: If True, DNS-based deliverability checks are disabled and test and **.test domain names are permitted (see below). You can also set email_validator.TEST_ENVIRONMENT to True to turn it on for all calls by default.

allow_smtputf8=True: Set to False to prohibit internationalized addresses that would require the SMTPUTF8 extension. You can also set email_validator.ALLOW_SMTPUTF8 to False to turn it off for all calls by default.

allow_quoted_local=False: Set to True to allow obscure and potentially problematic email addresses in which the part of the address before the @-sign contains spaces, @-signs, or other surprising characters when the local part is surrounded in quotes (so-called quoted-string local parts). In the object returned by validate_email, the normalized local part removes any unnecessary backslash-escaping and even removes the surrounding quotes if the address would be valid without them. You can also set email_validator.ALLOW_QUOTED_LOCAL to True to turn this on for all calls by default.

allow_domain_literal=False: Set to True to allow bracketed IPv4 and "IPv6:"-prefixed IPv6 addresses in the domain part of the email address. No deliverability checks are performed for these addresses. In the object returned by validate_email, the normalized domain will use the condensed IPv6 format, if applicable. The object's domain_address attribute will hold the parsed ipaddress.IPv4Address or ipaddress.IPv6Address object if applicable. You can also set email_validator.ALLOW_DOMAIN_LITERAL to True to turn this on for all calls by default.

allow_display_name=False: Set to True to allow a display name and bracketed address in the input string, like My Name <[email protected]>. It's implemented in the spirit but not the letter of RFC 5322 3.4, so it may be stricter or more relaxed than what you want. The display name, if present, is provided in the returned object's display_name field after being unquoted and unescaped. You can also set email_validator.ALLOW_DISPLAY_NAME to True to turn this on for all calls by default.

allow_empty_local=False: Set to True to allow an empty local part (i.e. @example.com), e.g. for validating Postfix aliases.

strict=False: Set to True to perform additional syntax checks (currently only a local part length check). This should be used by mail service providers at address creation to ensure email addresses meet broad compatibility requirements.

DNS timeout and cache

When validating many email addresses or to control the timeout (the default is 15 seconds), create a caching dns.resolver.Resolver to reuse in each call. The caching_resolver function returns one easily for you:

from email_validator import validate_email, caching_resolver

resolver = caching_resolver(timeout=10)

while True:
  validate_email(email, dns_resolver=resolver)

Test addresses

This library rejects email addresses that use the Special Use Domain Names invalid, localhost, test, and some others by raising EmailSyntaxError. This is to protect your system from abuse: You probably don't want a user to be able to cause an email to be sent to localhost (although they might be able to still do so via a malicious MX record). However, in your non-production test environments you may want to use @test or @myname.test email addresses. There are three ways you can allow this:

  1. Add test_environment=True to the call to validate_email (see above).
  2. Set email_validator.TEST_ENVIRONMENT to True globally.
  3. Remove the special-use domain name that you want to use from email_validator.SPECIAL_USE_DOMAIN_NAMES, e.g.:
import email_validator
email_validator.SPECIAL_USE_DOMAIN_NAMES.remove("test")

It is tempting to use @example.com/net/org in tests. They are not in this library's SPECIAL_USE_DOMAIN_NAMES list so you can, but shouldn't, use them. These domains are reserved to IANA for use in documentation so there is no risk of accidentally emailing someone at those domains. But beware that this library will nevertheless reject these domain names if DNS-based deliverability checks are not disabled because these domains do not resolve to domains that accept email. In tests, consider using your own domain name or @test or @myname.test instead.

Internationalized email addresses

The email protocol SMTP and the domain name system DNS have historically only allowed English (ASCII) characters in email addresses and domain names, respectively. Each has adapted to internationalization in a separate way, creating two separate aspects to email address internationalization.

(If your mail submission library doesn't support Unicode at all, then immediately prior to mail submission you must replace the email address with its ASCII-ized form. This library gives you back the ASCII-ized form in the ascii_email field in the returned object.)

Internationalized domain names (IDN)

The first is internationalized domain names (RFC 5891), a.k.a IDNA 2008. The DNS system has not been updated with Unicode support. Instead, internationalized domain names are converted into a special IDNA ASCII "Punycode" form starting with xn--. When an email address has non-ASCII characters in its domain part, the domain part is replaced with its IDNA ASCII equivalent form in the process of mail transmission. Your mail submission library probably does this for you transparently. (Compliance around the web is not very good though.) This library conforms to IDNA 2008 using the idna module by Kim Davies.

Internationalized local parts

The second sort of internationalization is internationalization in the local part of the address (before the @-sign). In non-internationalized email addresses, only English lett

GitHub Issues· 0 open

View all on GitHub

No open issues yet, or sync has not completed.

Highlights

  • •Checks that an email address has the correct syntax --- great for
  • •Gives friendly English error messages when validation fails that you
  • •Checks deliverability (optional): Does the domain name resolve?
  • •Supports internationalized domain names (like @ツ.life),
  • •Rejects addresses with invalid or unsafe Unicode characters,
  • •Normalizes email addresses (important for internationalized
  • •Python type annotations are used.
  • •Raises a EmailNotValidError with a helpful, human-readable error
  • •Returns an object with a normalized form of the email address (which

> Tags

Pythondnsemailnormalizationsyntax

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category数据库
PricingOpen source

> Related tools

P
PostgreSQL
功能强大的开源关系型数据库
R
Redis
内存数据结构存储,常用作缓存与队列
M
MySQL
广泛使用的开源关系型数据库