Skip to content

Commit db91704

Browse files
docs: improve and expand example documentation across adapters and helpers
1 parent 98d940c commit db91704

20 files changed

Lines changed: 1115 additions & 826 deletions

docs/examples/adapters/email.md

Lines changed: 92 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,84 @@
11
# Email Adapter Examples
22

3-
This page demonstrates how to use ArchiPy's email adapter functionality for sending emails with proper error handling and logging.
3+
This page demonstrates how to use ArchiPy's email adapter for sending emails with proper error
4+
handling and logging.
45

56
## Basic Usage
67

8+
### Configuration
9+
10+
Configure email settings via environment variables or a config object:
11+
712
```python
13+
from archipy.configs.base_config import BaseConfig
14+
15+
# Using environment variables:
16+
# EMAIL__SMTP_SERVER=smtp.example.com
17+
# EMAIL__SMTP_PORT=587
18+
# EMAIL__USERNAME=your-username
19+
# EMAIL__PASSWORD=your-password
20+
21+
# Or directly (useful for testing):
22+
from archipy.configs.config_template import EmailConfig
23+
24+
custom_config = EmailConfig(
25+
SMTP_SERVER="smtp.example.com",
26+
SMTP_PORT=587,
27+
USERNAME="your-username",
28+
PASSWORD="your-password", # noqa: S106
29+
)
30+
```
31+
32+
### Initializing the Adapter
833
import logging
934

10-
from archipy.adapters.email import EmailAdapter
11-
from archipy.models.errors import InternalError, InvalidArgumentError
35+
from archipy.adapters.email.adapters import EmailAdapter
36+
from archipy.models.errors import InternalError
1237

1338
# Configure logging
1439
logger = logging.getLogger(__name__)
1540

16-
# Configure email adapter
41+
# Use global configuration (reads from BaseConfig.global_config().EMAIL)
1742
try:
18-
email_adapter = EmailAdapter(
19-
host="smtp.example.com",
20-
port=587,
21-
username="your-username",
22-
password="your-password",
23-
use_tls=True
24-
)
25-
except Exception as e:
43+
email_adapter = EmailAdapter()
44+
except InternalError as e:
2645
logger.error(f"Failed to configure email adapter: {e}")
27-
raise InternalError() from e
46+
raise
2847
else:
2948
logger.info("Email adapter configured successfully")
49+
50+
# Or pass a custom config
51+
from archipy.configs.config_template import EmailConfig
52+
53+
custom_config = EmailConfig(
54+
SMTP_SERVER="smtp.example.com",
55+
SMTP_PORT=587,
56+
USERNAME="your-username",
57+
PASSWORD="your-password", # noqa: S106
58+
)
59+
email_adapter = EmailAdapter(config=custom_config)
3060
```
3161
3262
## Sending Simple Emails
3363
3464
```python
3565
import logging
3666
37-
from archipy.adapters.email import EmailAdapter
67+
from archipy.adapters.email.adapters import EmailAdapter
3868
from archipy.models.errors import InternalError
3969
4070
# Configure logging
4171
logger = logging.getLogger(__name__)
4272
43-
email_adapter = EmailAdapter(
44-
host="smtp.example.com",
45-
port=587,
46-
username="your-username",
47-
password="your-password",
48-
use_tls=True
49-
)
73+
email_adapter = EmailAdapter()
5074
51-
# Send an email
75+
# Send a plain-text email
5276
try:
5377
email_adapter.send_email(
78+
to_email="recipient@example.com",
5479
subject="Test Email",
5580
body="This is a test email from ArchiPy",
56-
recipients=["recipient@example.com"],
57-
from_email="sender@example.com"
5881
)
59-
except InvalidArgumentError as e:
60-
logger.error(f"Invalid email parameters: {e}")
61-
raise
6282
except InternalError as e:
6383
logger.error(f"Failed to send email: {e}")
6484
raise
@@ -71,29 +91,22 @@ else:
7191
```python
7292
import logging
7393

74-
from archipy.adapters.email import EmailAdapter
94+
from archipy.adapters.email.adapters import EmailAdapter
7595
from archipy.models.errors import InternalError
7696

7797
# Configure logging
7898
logger = logging.getLogger(__name__)
7999

80-
email_adapter = EmailAdapter(
81-
host="smtp.example.com",
82-
port=587,
83-
username="your-username",
84-
password="your-password",
85-
use_tls=True
86-
)
100+
email_adapter = EmailAdapter()
87101

88-
# Send email with CC and BCC
102+
# Single recipient or list for to_email, cc, and bcc
89103
try:
90104
email_adapter.send_email(
105+
to_email=["primary@example.com"],
91106
subject="Important Notification",
92107
body="This message has CC and BCC recipients",
93-
recipients=["primary@example.com"],
94108
cc=["cc1@example.com", "cc2@example.com"],
95-
bcc=["bcc@example.com"],
96-
from_email="sender@example.com"
109+
bcc="bcc@example.com",
97110
)
98111
except InternalError as e:
99112
logger.error(f"Failed to send email with CC/BCC: {e}")
@@ -107,19 +120,13 @@ else:
107120
```python
108121
import logging
109122

110-
from archipy.adapters.email import EmailAdapter
123+
from archipy.adapters.email.adapters import EmailAdapter
111124
from archipy.models.errors import InternalError
112125

113126
# Configure logging
114127
logger = logging.getLogger(__name__)
115128

116-
email_adapter = EmailAdapter(
117-
host="smtp.example.com",
118-
port=587,
119-
username="your-username",
120-
password="your-password",
121-
use_tls=True
122-
)
129+
email_adapter = EmailAdapter()
123130

124131
html_content = """
125132
<html>
@@ -132,11 +139,10 @@ html_content = """
132139

133140
try:
134141
email_adapter.send_email(
142+
to_email="user@example.com",
135143
subject="HTML Email",
136144
body=html_content,
137-
recipients=["user@example.com"],
138-
from_email="sender@example.com",
139-
is_html=True
145+
html=True,
140146
)
141147
except InternalError as e:
142148
logger.error(f"Failed to send HTML email: {e}")
@@ -147,33 +153,28 @@ else:
147153

148154
## Sending Emails with Attachments
149155

156+
Pass file paths as strings or `EmailAttachmentDTO` objects in the `attachments` list:
157+
150158
```python
151159
import logging
152160

153-
from archipy.adapters.email import EmailAdapter
161+
from archipy.adapters.email.adapters import EmailAdapter
154162
from archipy.models.errors import InternalError, InvalidArgumentError
155163

156164
# Configure logging
157165
logger = logging.getLogger(__name__)
158166

159-
email_adapter = EmailAdapter(
160-
host="smtp.example.com",
161-
port=587,
162-
username="your-username",
163-
password="your-password",
164-
use_tls=True
165-
)
167+
email_adapter = EmailAdapter()
166168

167169
try:
168170
email_adapter.send_email(
171+
to_email="user@example.com",
169172
subject="Email with Attachment",
170-
body="Please find the attached document",
171-
recipients=["user@example.com"],
172-
from_email="sender@example.com",
173-
attachments=["/path/to/document.pdf", "/path/to/image.png"]
173+
body="Please find the attached document.",
174+
attachments=["/path/to/document.pdf", "/path/to/image.png"],
174175
)
175176
except InvalidArgumentError as e:
176-
logger.error(f"Invalid attachment path: {e}")
177+
logger.error(f"Invalid attachment: {e}")
177178
raise
178179
except InternalError as e:
179180
logger.error(f"Failed to send email with attachments: {e}")
@@ -190,20 +191,14 @@ import logging
190191
from fastapi import FastAPI, HTTPException
191192
from pydantic import BaseModel, EmailStr
192193

193-
from archipy.adapters.email import EmailAdapter
194+
from archipy.adapters.email.adapters import EmailAdapter
194195
from archipy.models.errors import InternalError, InvalidArgumentError
195196

196197
# Configure logging
197198
logger = logging.getLogger(__name__)
198199

199200
app = FastAPI()
200-
email_adapter = EmailAdapter(
201-
host="smtp.example.com",
202-
port=587,
203-
username="your-username",
204-
password="your-password",
205-
use_tls=True
206-
)
201+
email_adapter = EmailAdapter()
207202

208203

209204
class EmailRequest(BaseModel):
@@ -216,15 +211,24 @@ class EmailRequest(BaseModel):
216211

217212
@app.post("/send-email")
218213
async def send_email(email_request: EmailRequest) -> dict[str, str]:
219-
"""Send an email via API endpoint."""
214+
"""Send an email via API endpoint.
215+
216+
Args:
217+
email_request: Email details including recipients, subject, and body.
218+
219+
Returns:
220+
Status message.
221+
222+
Raises:
223+
HTTPException: If sending fails.
224+
"""
220225
try:
221226
email_adapter.send_email(
227+
to_email=email_request.to,
222228
subject=email_request.subject,
223229
body=email_request.body,
224-
recipients=email_request.to,
225230
cc=email_request.cc,
226231
bcc=email_request.bcc,
227-
from_email="noreply@example.com"
228232
)
229233
except InvalidArgumentError as e:
230234
logger.error(f"Invalid email request: {e}")
@@ -242,8 +246,9 @@ async def send_email(email_request: EmailRequest) -> dict[str, str]:
242246
```python
243247
import logging
244248

245-
from archipy.adapters.email import EmailAdapter
246-
from archipy.models.errors import InternalError, InvalidArgumentError, ConfigurationError
249+
from archipy.adapters.email.adapters import EmailAdapter
250+
from archipy.configs.config_template import EmailConfig
251+
from archipy.models.errors import ConfigurationError, InternalError, InvalidArgumentError
247252

248253
# Configure logging
249254
logger = logging.getLogger(__name__)
@@ -253,36 +258,29 @@ def send_notification_email(recipient: str, subject: str, body: str) -> bool:
253258
"""Send a notification email with comprehensive error handling.
254259
255260
Args:
256-
recipient: Email address of the recipient
257-
subject: Email subject line
258-
body: Email body content
261+
recipient: Email address of the recipient.
262+
subject: Email subject line.
263+
body: Email body content.
259264
260265
Returns:
261-
True if email sent successfully, False otherwise
266+
True if the email was sent successfully.
262267
263268
Raises:
264-
InvalidArgumentError: If email parameters are invalid
265-
InternalError: If email service fails
266-
ConfigurationError: If email adapter is not configured
269+
ConfigurationError: If the email adapter cannot be initialised.
270+
InvalidArgumentError: If email parameters are invalid.
271+
InternalError: If the email service fails.
267272
"""
268273
try:
269-
email_adapter = EmailAdapter(
270-
host="smtp.example.com",
271-
port=587,
272-
username="your-username",
273-
password="your-password",
274-
use_tls=True
275-
)
276-
except Exception as e:
274+
email_adapter = EmailAdapter()
275+
except ConfigurationError as e:
277276
logger.error(f"Email adapter configuration failed: {e}")
278-
raise ConfigurationError() from e
277+
raise
279278

280279
try:
281280
email_adapter.send_email(
281+
to_email=recipient,
282282
subject=subject,
283283
body=body,
284-
recipients=[recipient],
285-
from_email="noreply@example.com"
286284
)
287285
except InvalidArgumentError as e:
288286
logger.error(f"Invalid email parameters: {e}")

docs/examples/adapters/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ Each adapter in ArchiPy comes with a corresponding mock implementation for testi
5050

5151
```python
5252
# Production code
53-
from archipy.adapters.redis import RedisAdapter
53+
from archipy.adapters.redis.adapters import RedisAdapter
5454

55-
redis = RedisAdapter(host="redis.example.com", port=6379)
55+
redis = RedisAdapter()
5656
redis.set("key", "value")
5757

5858
# Test code
59-
from archipy.adapters.redis import RedisMock
59+
from archipy.adapters.redis.mocks import RedisMock
6060

6161
redis_mock = RedisMock()
6262
redis_mock.set("key", "test_value")

0 commit comments

Comments
 (0)