Proposal: Add an async email validation function using dnspython’s async resolver #164
Copy link
Copy link
Open
Description
I maintain a high-volume lead-gen API that validates thousands of emails per request. To keep latency low, we can’t rely on the library’s check_deliverability=True option because it triggers blocking DNS lookups. Instead, we run the library with deliverability checks disabled and perform our own async DNS queries via dns.asyncresolver.
It would be a real improvement if the library exposed a first-class async deliverability path. Below is a minimal prototype showing what that could look like:
from email_validator import validate_email, EmailNotValidError, ValidatedEmail
import dns.asyncresolver
dns_resolver = dns.asyncresolver.Resolver()
async def _resolve_mail_hosts(domain: str):
try: return await dns_resolver.resolve(domain, "MX")
except Exception:
for record_type in ("A", "AAAA"):
try: return await dns_resolver.resolve(domain, record_type)
except Exception: continue
return None
async def aio_validate_email(email: str) -> ValidatedEmail:
email_info = validate_email(email, check_deliverability=False)
if await _resolve_mail_hosts(email_info.domain) is None: raise EmailNotValidError
return email_infoMy plan is to open a PR that adds an async validator fully compatible with your existing Pydantic models, plus tests and documentation. Before I invest the time, are you open to adding async support to the project?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
JoshData commentedon Dec 13, 2025
I actually did some work on that several years ago and it's on the async branch. But I stopped because 1) it was a complex change that I was afraid to commit to supporting and 2) I don't have much experience using async so I wasn't sure if it really worked for practical purposes.
VGBijpuria commentedon Dec 14, 2025
My current role gives me the time and opportunity to meaningfully support the open-source projects I rely on, and this is one I use heavily. In the lead gen API I maintain, I had to build an async deliverability path myself to avoid blocking DNS lookups at scale. While that implementation isn’t suitable to drop directly into a general purpose library, but it has given me practical experience with what does and doesn’t work in real async workloads.
I agree that for the majority of users that are just validating login or signup emails, the existing synchronous path is perfectly adequate. I just don’t think that subset should be used to judge the usefulness of async support overall. High-volume lead generation, enrichment pipelines, and bulk data hygiene jobs operate under very different constraints, and in those cases a blocking deliverability check becomes a real bottleneck. They are small niches, but together I believe they are a considerable sum.
If it would be helpful, I’d be happy to assist by reviewing the existing async branch and sharing responsibility for testing and ongoing support. I’m going to continue maintaining the internal async fork for my own use either way, so I wanted to check whether there’s interest in aligning that work with the main project rather than keeping them separate.
JoshData commentedon Dec 14, 2025
Thanks for the offer.
Right now I'm not in a position to commit to any answer about what would be helpful since I don't have enough time to prioritize this project. 😢
VGBijpuria commentedon Dec 15, 2025
Totally understandable.
Given the constraints, I’ll plan to fork your async branch into a separate library when I have time, rather than trying to fit it into this repo right now.
If things change in the future and it makes sense to align again, I’m happy to revisit. Thanks for your time.
JoshData commentedon Dec 15, 2025
Thanks