or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdasync-io.mdauth.mddistributed.mddns.mdemail.mdhttp.mdindex.mdlogging.mdprotocols.mdssh.mdtesting.md

email.mddocs/

0

# Email Protocols

1

2

Complete email protocol implementations including SMTP, POP3, and IMAP4 with support for both client and server operations. Twisted provides comprehensive email handling capabilities.

3

4

## Capabilities

5

6

### SMTP (Simple Mail Transfer Protocol)

7

8

SMTP server and client implementations for sending and receiving email.

9

10

```python { .api }

11

class smtp.SMTP:

12

"""

13

SMTP server protocol implementation.

14

15

Attributes:

16

- host: Server hostname

17

- portal: Authentication portal

18

- challenger: Authentication challenger

19

"""

20

host = None

21

portal = None

22

challenger = None

23

24

def greeting(self):

25

"""

26

Get server greeting message.

27

28

Returns:

29

str: SMTP greeting

30

"""

31

32

def extensions(self):

33

"""

34

Get supported SMTP extensions.

35

36

Returns:

37

dict: Extension capabilities

38

"""

39

40

def validateTo(self, user):

41

"""

42

Validate recipient address.

43

44

Args:

45

user: User address object

46

47

Returns:

48

callable: Message delivery callable

49

"""

50

51

def validateFrom(self, helo, origin):

52

"""

53

Validate sender address.

54

55

Args:

56

helo (bytes): HELO/EHLO string

57

origin: Sender address object

58

59

Returns:

60

Deferred: Validation result

61

"""

62

63

class smtp.ESMTP(smtp.SMTP):

64

"""

65

Extended SMTP server with additional features.

66

67

Supports SMTP extensions like authentication, TLS, etc.

68

"""

69

70

def ext_AUTH(self, args):

71

"""Handle AUTH extension."""

72

73

def ext_STARTTLS(self, args):

74

"""Handle STARTTLS extension."""

75

76

def ext_SIZE(self, args):

77

"""Handle SIZE extension."""

78

79

class smtp.ESMTPSender:

80

"""

81

SMTP client for sending email messages.

82

"""

83

def __init__(self, username=None, password=None, contextFactory=None, **kwargs):

84

"""

85

Args:

86

username (bytes): SMTP username

87

password (bytes): SMTP password

88

contextFactory: SSL context factory for STARTTLS

89

**kwargs: Additional connection parameters

90

"""

91

92

def sendmail(self, from_addr, to_addrs, msg, response=None):

93

"""

94

Send email message.

95

96

Args:

97

from_addr (str): Sender address

98

to_addrs (list): Recipient addresses

99

msg (bytes): Email message content

100

response: Response handler

101

102

Returns:

103

Deferred: Delivery result

104

"""

105

106

class smtp.SMTPSenderFactory:

107

"""

108

Factory for creating SMTP sender connections.

109

"""

110

def __init__(self, fromEmail, toEmail, file, deferred, retries=5, timeout=None):

111

"""

112

Args:

113

fromEmail (str): Sender address

114

toEmail (str): Recipient address

115

file: File-like object with message content

116

deferred: Deferred to fire when complete

117

retries (int): Number of retry attempts

118

timeout (int): Connection timeout

119

"""

120

121

def buildProtocol(self, addr):

122

"""

123

Build SMTP sender protocol.

124

125

Args:

126

addr: Connection address

127

128

Returns:

129

ESMTPSender: SMTP sender instance

130

"""

131

132

class smtp.SMTPFactory:

133

"""

134

SMTP server factory.

135

"""

136

def __init__(self):

137

self.deliveryClass = smtp.SMTPDelivery

138

self.portal = None

139

self.challenger = None

140

141

def buildProtocol(self, addr):

142

"""

143

Build SMTP server protocol.

144

145

Args:

146

addr: Connection address

147

148

Returns:

149

SMTP: SMTP server instance

150

"""

151

```

152

153

**SMTP Usage Example**:

154

155

```python

156

from twisted.mail import smtp

157

from twisted.internet import reactor, defer, endpoints

158

from twisted.cred import portal, checkers

159

160

# SMTP Client - Send email

161

@defer.inlineCallbacks

162

def send_email():

163

sender_factory = smtp.SMTPSenderFactory(

164

fromEmail="sender@example.com",

165

toEmail="recipient@example.com",

166

file=io.StringIO("Subject: Test\n\nHello, World!"),

167

deferred=defer.Deferred()

168

)

169

170

endpoint = endpoints.TCP4ClientEndpoint(reactor, "smtp.example.com", 25)

171

yield endpoint.connect(sender_factory)

172

173

# SMTP Server

174

class MyDelivery:

175

"""Custom message delivery handler."""

176

177

def receivedHeader(self, helo, origin, recipients):

178

return "Received: from %s" % (helo,)

179

180

def validateTo(self, user):

181

# Validate recipient

182

if user.dest.local == "postmaster":

183

return lambda: MyMessage()

184

raise smtp.SMTPBadRcpt(user)

185

186

def validateFrom(self, helo, origin):

187

# Validate sender

188

return origin

189

190

class MyMessage:

191

"""Message storage handler."""

192

193

def eomReceived(self):

194

# Called when message is complete

195

print("Message received")

196

return defer.succeed("250 Message accepted")

197

198

# Set up SMTP server

199

factory = smtp.SMTPFactory()

200

factory.delivery = MyDelivery()

201

factory.portal = portal.Portal(realm, [checker])

202

203

endpoint = endpoints.TCP4ServerEndpoint(reactor, 25)

204

endpoint.listen(factory)

205

```

206

207

### POP3 (Post Office Protocol)

208

209

POP3 server and client for retrieving email from mailboxes.

210

211

```python { .api }

212

class pop3.POP3:

213

"""

214

POP3 server protocol implementation.

215

216

Attributes:

217

- mbox: Mailbox object

218

- portal: Authentication portal

219

"""

220

mbox = None

221

portal = None

222

223

def authenticateUserAPOP(self, user, digest):

224

"""

225

Authenticate using APOP.

226

227

Args:

228

user (bytes): Username

229

digest (bytes): APOP digest

230

231

Returns:

232

Deferred: Authentication result

233

"""

234

235

def authenticateUserPASS(self, user, password):

236

"""

237

Authenticate using USER/PASS.

238

239

Args:

240

user (bytes): Username

241

password (bytes): Password

242

243

Returns:

244

Deferred: Authentication result

245

"""

246

247

class pop3.POP3Client:

248

"""

249

POP3 client protocol implementation.

250

"""

251

def login(self, username, password):

252

"""

253

Login to POP3 server.

254

255

Args:

256

username (bytes): Username

257

password (bytes): Password

258

259

Returns:

260

Deferred: Login result

261

"""

262

263

def listMessages(self):

264

"""

265

List messages in mailbox.

266

267

Returns:

268

Deferred[list]: List of (message_num, size) tuples

269

"""

270

271

def getMessage(self, index):

272

"""

273

Retrieve message by index.

274

275

Args:

276

index (int): Message index

277

278

Returns:

279

Deferred[list]: Message lines

280

"""

281

282

def deleteMessage(self, index):

283

"""

284

Mark message for deletion.

285

286

Args:

287

index (int): Message index

288

289

Returns:

290

Deferred: Deletion result

291

"""

292

293

def quit(self):

294

"""

295

Quit POP3 session.

296

297

Returns:

298

Deferred: Quit result

299

"""

300

301

class pop3.POP3Factory:

302

"""

303

POP3 server factory.

304

"""

305

def __init__(self):

306

self.portal = None

307

308

def buildProtocol(self, addr):

309

"""

310

Build POP3 server protocol.

311

312

Args:

313

addr: Connection address

314

315

Returns:

316

POP3: POP3 server instance

317

"""

318

319

class pop3.POP3ClientFactory:

320

"""

321

POP3 client factory.

322

"""

323

def __init__(self, username, password, **kwargs):

324

"""

325

Args:

326

username (str): POP3 username

327

password (str): POP3 password

328

**kwargs: Additional parameters

329

"""

330

```

331

332

**POP3 Usage Example**:

333

334

```python

335

from twisted.mail import pop3

336

from twisted.internet import reactor, defer, endpoints

337

338

# POP3 Client

339

@defer.inlineCallbacks

340

def retrieve_mail():

341

factory = pop3.POP3ClientFactory("username", "password")

342

endpoint = endpoints.TCP4ClientEndpoint(reactor, "pop.example.com", 110)

343

344

protocol = yield endpoint.connect(factory)

345

yield protocol.login(b"username", b"password")

346

347

messages = yield protocol.listMessages()

348

print(f"Found {len(messages)} messages")

349

350

# Retrieve first message

351

if messages:

352

message_lines = yield protocol.getMessage(0)

353

message = b'\n'.join(message_lines)

354

print(f"Message: {message.decode()}")

355

356

yield protocol.quit()

357

358

# POP3 Server with custom mailbox

359

class MyMailbox:

360

"""Custom mailbox implementation."""

361

362

def __init__(self, messages):

363

self.messages = messages

364

365

def listMessages(self):

366

return [(i, len(msg)) for i, msg in enumerate(self.messages)]

367

368

def getMessage(self, i):

369

return self.messages[i].split(b'\n')

370

371

def deleteMessage(self, i):

372

del self.messages[i]

373

374

class MyRealm:

375

def requestAvatar(self, avatarId, mind, *interfaces):

376

# Create mailbox for user

377

messages = [b"Subject: Test\n\nHello!"]

378

mailbox = MyMailbox(messages)

379

return (pop3.IMailbox, mailbox, lambda: None)

380

381

# Set up POP3 server

382

realm = MyRealm()

383

checker = checkers.InMemoryUsernamePasswordDatabaseDontUse()

384

checker.addUser(b"testuser", b"password")

385

386

factory = pop3.POP3Factory()

387

factory.portal = portal.Portal(realm, [checker])

388

389

endpoint = endpoints.TCP4ServerEndpoint(reactor, 110)

390

endpoint.listen(factory)

391

```

392

393

### IMAP4 (Internet Message Access Protocol)

394

395

IMAP4 server and client for advanced email access and management.

396

397

```python { .api }

398

class imap4.IMAP4Server:

399

"""

400

IMAP4 server protocol implementation.

401

402

Attributes:

403

- portal: Authentication portal

404

- account: User account object

405

"""

406

portal = None

407

account = None

408

409

def authenticateLogin(self, username, password):

410

"""

411

Authenticate with LOGIN command.

412

413

Args:

414

username (bytes): Username

415

password (bytes): Password

416

417

Returns:

418

Deferred: Authentication result

419

"""

420

421

def do_SELECT(self, tag, messages):

422

"""Handle SELECT command."""

423

424

def do_EXAMINE(self, tag, messages):

425

"""Handle EXAMINE command."""

426

427

def do_FETCH(self, tag, messages):

428

"""Handle FETCH command."""

429

430

def do_SEARCH(self, tag, messages):

431

"""Handle SEARCH command."""

432

433

def do_STORE(self, tag, messages):

434

"""Handle STORE command."""

435

436

class imap4.IMAP4Client:

437

"""

438

IMAP4 client protocol implementation.

439

"""

440

def login(self, username, password):

441

"""

442

Login to IMAP4 server.

443

444

Args:

445

username (str): Username

446

password (str): Password

447

448

Returns:

449

Deferred: Login result

450

"""

451

452

def list(self, reference, name):

453

"""

454

List mailboxes.

455

456

Args:

457

reference (str): Reference name

458

name (str): Mailbox name pattern

459

460

Returns:

461

Deferred[list]: List of mailboxes

462

"""

463

464

def select(self, mailbox):

465

"""

466

Select mailbox.

467

468

Args:

469

mailbox (str): Mailbox name

470

471

Returns:

472

Deferred[dict]: Mailbox status

473

"""

474

475

def search(self, *query):

476

"""

477

Search for messages.

478

479

Args:

480

*query: Search criteria

481

482

Returns:

483

Deferred[list]: Message numbers

484

"""

485

486

def fetch(self, messages, *query):

487

"""

488

Fetch message data.

489

490

Args:

491

messages: Message set

492

*query: Fetch items

493

494

Returns:

495

Deferred[dict]: Message data

496

"""

497

498

def store(self, messages, command, flags):

499

"""

500

Store message flags.

501

502

Args:

503

messages: Message set

504

command (str): Store command

505

flags (list): Message flags

506

507

Returns:

508

Deferred: Store result

509

"""

510

511

def expunge(self):

512

"""

513

Expunge deleted messages.

514

515

Returns:

516

Deferred[list]: Expunged message numbers

517

"""

518

519

class imap4.IMAP4Factory:

520

"""

521

IMAP4 server factory.

522

"""

523

def __init__(self):

524

self.portal = None

525

self.timeOut = 30 * 60 # 30 minutes

526

527

def buildProtocol(self, addr):

528

"""

529

Build IMAP4 server protocol.

530

531

Args:

532

addr: Connection address

533

534

Returns:

535

IMAP4Server: IMAP4 server instance

536

"""

537

538

class imap4.IMAP4ClientFactory:

539

"""

540

IMAP4 client factory.

541

"""

542

def __init__(self, username, password, **kwargs):

543

"""

544

Args:

545

username (str): IMAP username

546

password (str): IMAP password

547

**kwargs: Additional parameters

548

"""

549

```

550

551

### Email Message Handling

552

553

Utilities for parsing, creating, and manipulating email messages.

554

555

```python { .api }

556

class mail.MailService:

557

"""

558

Service for handling email delivery.

559

560

Attributes:

561

- domains: List of handled domains

562

- portals: Authentication portals

563

"""

564

domains = None

565

portals = None

566

567

def addDomain(self, domain):

568

"""

569

Add domain to handle.

570

571

Args:

572

domain (str): Domain name

573

"""

574

575

def setQueue(self, queue):

576

"""

577

Set message queue.

578

579

Args:

580

queue: Queue object for messages

581

"""

582

583

class mail.FileMessage:

584

"""

585

File-based email message storage.

586

"""

587

def __init__(self, fp, name, finalName):

588

"""

589

Args:

590

fp: File pointer

591

name (str): Temporary filename

592

finalName (str): Final filename

593

"""

594

595

def eomReceived(self):

596

"""

597

Called when end of message is received.

598

599

Returns:

600

Deferred: Processing result

601

"""

602

603

# Email address parsing

604

class smtp.Address:

605

"""

606

Email address representation.

607

608

Attributes:

609

- local: Local part of address

610

- domain: Domain part of address

611

"""

612

local = None

613

domain = None

614

615

def __init__(self, local, domain=None):

616

"""

617

Args:

618

local (str): Local part

619

domain (str): Domain part

620

"""

621

622

def __str__(self):

623

"""String representation of address."""

624

```

625

626

### Maildir Support

627

628

Maildir format support for mail storage.

629

630

```python { .api }

631

class maildir.MaildirMessage:

632

"""

633

Maildir format message.

634

"""

635

def __init__(self, file, flags=None):

636

"""

637

Args:

638

file: Message file

639

flags (str): Message flags

640

"""

641

642

class maildir.AbstractMaildirDomain:

643

"""

644

Abstract Maildir domain handler.

645

"""

646

def __init__(self, root):

647

"""

648

Args:

649

root (str): Maildir root directory

650

"""

651

652

def userDirectory(self, user):

653

"""

654

Get user's maildir directory.

655

656

Args:

657

user (str): Username

658

659

Returns:

660

str: User directory path

661

"""

662

```

663

664

**Email Message Example**:

665

666

```python

667

from twisted.mail import smtp, mail

668

from twisted.internet import defer

669

import email.mime.text

670

671

# Create and send email message

672

def create_message():

673

msg = email.mime.text.MIMEText("Hello, World!")

674

msg['From'] = "sender@example.com"

675

msg['To'] = "recipient@example.com"

676

msg['Subject'] = "Test Message"

677

return msg.as_bytes()

678

679

@defer.inlineCallbacks

680

def send_message():

681

message_data = create_message()

682

683

factory = smtp.SMTPSenderFactory(

684

fromEmail="sender@example.com",

685

toEmail="recipient@example.com",

686

file=io.BytesIO(message_data),

687

deferred=defer.Deferred()

688

)

689

690

endpoint = endpoints.TCP4ClientEndpoint(reactor, "smtp.example.com", 25)

691

yield endpoint.connect(factory)

692

print("Email sent successfully")

693

694

# Handle incoming email

695

class CustomDelivery:

696

def validateTo(self, user):

697

# Accept all messages

698

return lambda: CustomMessage(user)

699

700

def validateFrom(self, helo, origin):

701

return origin

702

703

class CustomMessage:

704

def __init__(self, user):

705

self.user = user

706

self.lines = []

707

708

def lineReceived(self, line):

709

self.lines.append(line)

710

711

def eomReceived(self):

712

# Process complete message

713

message = b'\n'.join(self.lines)

714

print(f"Received message for {self.user}: {message}")

715

return defer.succeed("250 Message accepted")

716

```