or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Email Validator

1

2

A robust email address syntax and deliverability validation library for Python 3.8+. This library validates that a string is of the form `name@example.com` and optionally checks that the domain name is set up to receive email, providing friendly error messages and normalized email addresses.

3

4

## Package Information

5

6

- **Package Name**: email-validator

7

- **Language**: Python

8

- **Installation**: `pip install email-validator`

9

10

## Core Imports

11

12

```python

13

from email_validator import validate_email, EmailNotValidError

14

```

15

16

Import validation exceptions:

17

18

```python

19

from email_validator import EmailSyntaxError, EmailUndeliverableError

20

```

21

22

Import helper functions and types:

23

24

```python

25

from email_validator import ValidatedEmail, caching_resolver, __version__

26

```

27

28

## Basic Usage

29

30

```python

31

from email_validator import validate_email, EmailNotValidError

32

33

email = "user@example.com"

34

35

try:

36

# Validate email address with deliverability checking

37

validated_email = validate_email(email)

38

39

# Use the normalized form for storage/comparison

40

normalized = validated_email.normalized

41

print(f"Valid email: {normalized}")

42

43

# Access additional information

44

print(f"Local part: {validated_email.local_part}")

45

print(f"Domain: {validated_email.domain}")

46

print(f"ASCII email: {validated_email.ascii_email}")

47

48

except EmailNotValidError as e:

49

print(f"Invalid email: {e}")

50

```

51

52

## Architecture

53

54

The email-validator library provides a single main validation function that performs comprehensive email address validation in multiple stages:

55

56

1. **Input Processing**: Handles both string and bytes input, converting to Unicode as needed

57

2. **Syntax Parsing**: Splits email into display name, local part, and domain components

58

3. **Local Part Validation**: Validates local part syntax with support for internationalization and quoted strings

59

4. **Domain Validation**: Validates domain syntax supporting both domain names and IP literals

60

5. **Deliverability Checking**: Optional DNS-based validation to verify domain can receive email

61

6. **Normalization**: Returns normalized forms suitable for storage and comparison

62

63

## Capabilities

64

65

### Email Validation

66

67

Core email validation functionality that validates email address syntax and optionally checks deliverability.

68

69

```python { .api }

70

def validate_email(

71

email: Union[str, bytes],

72

/, # prior arguments are positional-only

73

*, # subsequent arguments are keyword-only

74

allow_smtputf8: Optional[bool] = None,

75

allow_empty_local: Optional[bool] = None,

76

allow_quoted_local: Optional[bool] = None,

77

allow_domain_literal: Optional[bool] = None,

78

allow_display_name: Optional[bool] = None,

79

strict: Optional[bool] = None,

80

check_deliverability: Optional[bool] = None,

81

test_environment: Optional[bool] = None,

82

globally_deliverable: Optional[bool] = None,

83

timeout: Optional[int] = None,

84

dns_resolver: Optional[object] = None

85

) -> ValidatedEmail:

86

"""

87

Validate an email address and return normalized information.

88

89

Parameters:

90

- email: Email address to validate (str or bytes)

91

- allow_smtputf8: Allow internationalized email addresses (default: True)

92

- allow_empty_local: Allow empty local part like @example.com (default: False)

93

- allow_quoted_local: Allow quoted local parts with special characters (default: False)

94

- allow_domain_literal: Allow bracketed IP addresses in domain (default: False)

95

- allow_display_name: Allow display name format like "Name <email>" (default: False)

96

- strict: Enable additional syntax checks like length limits (default: False)

97

- check_deliverability: Perform DNS checks on domain (default: True)

98

- test_environment: Allow test domains and disable DNS checks (default: False)

99

- globally_deliverable: Require globally routable domains (default: True)

100

- timeout: DNS query timeout in seconds (default: 15)

101

- dns_resolver: Custom DNS resolver instance (default: None)

102

103

Returns:

104

ValidatedEmail: Object containing normalized email and metadata

105

106

Raises:

107

EmailSyntaxError: Email syntax is invalid

108

EmailUndeliverableError: Domain fails deliverability checks

109

"""

110

```

111

112

### Command-Line Interface

113

114

The email-validator package provides a command-line interface for testing and batch validation of email addresses.

115

116

```python { .api }

117

def main(dns_resolver: Optional[object] = None) -> None:

118

"""

119

Command-line interface for email validation.

120

121

Usage:

122

python -m email_validator user@example.com

123

python -m email_validator < email_list.txt

124

125

Environment Variables:

126

ALLOW_SMTPUTF8, ALLOW_EMPTY_LOCAL, ALLOW_QUOTED_LOCAL,

127

ALLOW_DOMAIN_LITERAL, ALLOW_DISPLAY_NAME, GLOBALLY_DELIVERABLE,

128

CHECK_DELIVERABILITY, TEST_ENVIRONMENT, DEFAULT_TIMEOUT

129

"""

130

```

131

132

### DNS Resolver Utilities

133

134

Helper function for creating cached DNS resolvers for improved performance when validating many email addresses.

135

136

```python { .api }

137

def caching_resolver(

138

*,

139

timeout: Optional[int] = None,

140

cache: Optional[object] = None,

141

dns_resolver: Optional[object] = None

142

) -> object:

143

"""

144

Create a DNS resolver with caching for improved performance.

145

146

Parameters:

147

- timeout: DNS query timeout in seconds (default: 15)

148

- cache: Cache instance to use (default: LRUCache)

149

- dns_resolver: Base resolver to configure (default: system resolver)

150

151

Returns:

152

dns.resolver.Resolver: Configured resolver with caching

153

"""

154

```

155

156

## Types

157

158

```python { .api }

159

class ValidatedEmail:

160

"""

161

Result object containing normalized email address and validation metadata.

162

"""

163

164

# Core email components

165

original: str # Original input email address

166

normalized: str # Normalized email address (recommended for use)

167

local_part: str # Local part after normalization

168

domain: str # Domain part after normalization

169

170

# ASCII representations

171

ascii_email: Optional[str] # ASCII-only form if available

172

ascii_local_part: Optional[str] # ASCII-only local part if available

173

ascii_domain: str # ASCII-only domain part

174

175

# Metadata

176

smtputf8: bool # True if SMTPUTF8 extension required

177

display_name: Optional[str] # Display name if present

178

domain_address: Optional[object] # IPv4Address/IPv6Address for domain literals

179

180

# Deliverability information (if checked)

181

mx: Optional[List[Tuple[int, str]]] # MX records as (priority, domain) tuples

182

mx_fallback_type: Optional[str] # Fallback record type ('A' or 'AAAA')

183

spf: Optional[str] # SPF record if found during deliverability check

184

185

def as_dict(self) -> Dict[str, Any]:

186

"""Convert to dictionary representation."""

187

188

def __repr__(self) -> str:

189

"""String representation showing normalized email."""

190

```

191

192

## Exceptions

193

194

```python { .api }

195

class EmailNotValidError(ValueError):

196

"""

197

Base exception for all email validation failures.

198

Contains human-readable error message explaining why validation failed.

199

"""

200

201

class EmailSyntaxError(EmailNotValidError):

202

"""

203

Exception raised when email address has invalid syntax.

204

Includes detailed explanation of syntax problems.

205

"""

206

207

class EmailUndeliverableError(EmailNotValidError):

208

"""

209

Exception raised when email domain fails deliverability checks.

210

Indicates DNS resolution problems or undeliverable domains.

211

"""

212

```

213

214

## Configuration Constants

215

216

Global configuration constants that set default behavior for all validation calls:

217

218

```python { .api }

219

# Validation behavior defaults

220

ALLOW_SMTPUTF8: bool = True # Allow internationalized addresses

221

ALLOW_EMPTY_LOCAL: bool = False # Allow empty local parts

222

ALLOW_QUOTED_LOCAL: bool = False # Allow quoted local parts

223

ALLOW_DOMAIN_LITERAL: bool = False # Allow IP address domains

224

ALLOW_DISPLAY_NAME: bool = False # Allow display name format

225

STRICT: bool = False # Enable strict validation mode

226

227

# Deliverability defaults

228

CHECK_DELIVERABILITY: bool = True # Perform DNS deliverability checks

229

GLOBALLY_DELIVERABLE: bool = True # Require globally routable domains

230

TEST_ENVIRONMENT: bool = False # Enable test environment mode

231

DEFAULT_TIMEOUT: int = 15 # DNS query timeout in seconds

232

233

# Special domain handling

234

SPECIAL_USE_DOMAIN_NAMES: List[str] # List of rejected special-use domains

235

236

# Version information

237

__version__: str # Package version string

238

```

239

240

## Usage Examples

241

242

### Basic Email Validation

243

244

```python

245

from email_validator import validate_email, EmailNotValidError

246

247

def validate_user_email(email_input):

248

try:

249

result = validate_email(email_input)

250

return result.normalized

251

except EmailNotValidError as e:

252

print(f"Invalid email: {e}")

253

return None

254

255

# Usage

256

email = validate_user_email("user@example.com")

257

if email:

258

print(f"Validated email: {email}")

259

```

260

261

### Registration Form Validation

262

263

```python

264

from email_validator import validate_email, EmailNotValidError

265

266

def validate_registration_email(email):

267

"""Validate email for new user registration with deliverability checking."""

268

try:

269

result = validate_email(

270

email,

271

check_deliverability=True, # Check DNS for registration

272

allow_quoted_local=False, # Reject confusing quoted formats

273

allow_display_name=False # Reject display name format

274

)

275

return result.normalized

276

except EmailNotValidError as e:

277

raise ValueError(f"Please enter a valid email address: {e}")

278

```

279

280

### Login Form Validation

281

282

```python

283

from email_validator import validate_email, EmailSyntaxError

284

285

def validate_login_email(email):

286

"""Validate email for login with minimal checks for performance."""

287

try:

288

result = validate_email(

289

email,

290

check_deliverability=False # Skip DNS checks for login

291

)

292

return result.normalized

293

except EmailSyntaxError as e:

294

raise ValueError("Invalid email format")

295

```

296

297

### Batch Validation with Caching

298

299

```python

300

from email_validator import validate_email, caching_resolver, EmailNotValidError

301

302

def validate_email_list(email_list):

303

"""Validate multiple emails efficiently using cached DNS resolver."""

304

# Create cached resolver for better performance

305

resolver = caching_resolver(timeout=10)

306

307

validated_emails = []

308

for email in email_list:

309

try:

310

result = validate_email(email, dns_resolver=resolver)

311

validated_emails.append(result.normalized)

312

except EmailNotValidError as e:

313

print(f"Skipping invalid email {email}: {e}")

314

315

return validated_emails

316

```

317

318

### International Email Support

319

320

```python

321

from email_validator import validate_email, EmailNotValidError

322

323

def validate_international_email(email):

324

"""Validate international email addresses with full Unicode support."""

325

try:

326

result = validate_email(

327

email,

328

allow_smtputf8=True, # Allow international characters

329

globally_deliverable=True # Ensure globally routable

330

)

331

332

print(f"Normalized: {result.normalized}")

333

print(f"ASCII form: {result.ascii_email}")

334

print(f"Requires SMTPUTF8: {result.smtputf8}")

335

336

return result.normalized

337

except EmailNotValidError as e:

338

print(f"Invalid international email: {e}")

339

return None

340

341

# Examples

342

validate_international_email("用户@example.com") # Chinese characters

343

validate_international_email("user@測試.com") # International domain

344

```

345

346

### Custom Configuration

347

348

```python

349

import email_validator

350

from email_validator import validate_email

351

352

# Modify global defaults

353

email_validator.CHECK_DELIVERABILITY = False # Disable DNS checks globally

354

email_validator.ALLOW_QUOTED_LOCAL = True # Allow quoted formats globally

355

356

# Allow test domains for development

357

email_validator.SPECIAL_USE_DOMAIN_NAMES.remove("test")

358

359

# Now all validation calls use these defaults

360

result = validate_email("developer@test") # Would normally be rejected

361

```

362

363

### Error Handling Patterns

364

365

```python

366

from email_validator import (

367

validate_email,

368

EmailNotValidError,

369

EmailSyntaxError,

370

EmailUndeliverableError

371

)

372

373

def comprehensive_email_validation(email):

374

"""Demonstrate different error handling approaches."""

375

try:

376

result = validate_email(email)

377

return {

378

'valid': True,

379

'normalized': result.normalized,

380

'metadata': {

381

'local_part': result.local_part,

382

'domain': result.domain,

383

'smtputf8': result.smtputf8,

384

'mx_records': getattr(result, 'mx', None)

385

}

386

}

387

except EmailSyntaxError as e:

388

return {

389

'valid': False,

390

'error_type': 'syntax',

391

'message': str(e)

392

}

393

except EmailUndeliverableError as e:

394

return {

395

'valid': False,

396

'error_type': 'deliverability',

397

'message': str(e)

398

}

399

except EmailNotValidError as e:

400

return {

401

'valid': False,

402

'error_type': 'general',

403

'message': str(e)

404

}

405

```