15 KiB
Notification Simulator API
Overview
The Notification Simulator API provides mock endpoints that simulate external email and SMS services for testing purposes. It's integrated with the external API notification system and allows you to test notification workflows without relying on third-party services.
Key Features:
- ✅ Email Simulator: Sends real emails via Django SMTP
- ✅ SMS Simulator: Prints formatted SMS messages to terminal
- ✅ Request Tracking: Logs all requests with counters and history
- ✅ Health Check: Monitor simulator status and statistics
- ✅ Easy Configuration: Simple
.envconfiguration to enable/disable
Architecture
PX360 Application
↓
NotificationService.send_email_via_api()
↓
HTTP POST to Simulator API
↓
┌─────────────┬─────────────┐
│ Email Sim. │ SMS Sim. │
│ Sends │ Prints to │
│ Real Email │ Terminal │
└─────────────┴─────────────┘
Endpoints
1. Email Simulator
Endpoint: POST /api/simulator/send-email
Request Body:
{
"to": "recipient@example.com",
"subject": "Email subject",
"message": "Plain text message",
"html_message": "<html>Optional HTML content</html>"
}
Response (Success):
{
"success": true,
"message": "Email sent successfully",
"data": {
"to": "recipient@example.com",
"subject": "Email subject",
"message_length": 100,
"has_html": true
}
}
Behavior:
- Validates required fields (
to,subject,message) - Sends real email using Django's SMTP backend
- Prints formatted output to terminal
- Logs request to file and history
2. SMS Simulator
Endpoint: POST /api/simulator/send-sms
Request Body:
{
"to": "+966501234567",
"message": "SMS message text"
}
Response (Success):
{
"success": true,
"message": "SMS sent successfully",
"data": {
"to": "+966501234567",
"message_length": 20
}
}
Behavior:
- Validates required fields (
to,message) - Prints formatted SMS to terminal with box drawing
- Logs request to file and history
Terminal Output Example:
══════════════════════════════════════════════════════════════════════
📱 SMS SIMULATOR
══════════════════════════════════════════════════════════════════════
Request #: 1
══════════════════════════════════════════════════════════════════════
To: +966501234567
Time: 2026-01-12 18:05:00
══════════════════════════════════════════════════════════════════════
Message:
Your verification code is 123456
══════════════════════════════════════════════════════════════════════
3. Health Check
Endpoint: GET /api/simulator/health
Response:
{
"status": "healthy",
"timestamp": "2026-01-12T18:05:00.000000",
"statistics": {
"total_requests": 5,
"email_requests": 3,
"sms_requests": 2
},
"recent_requests": [
{
"id": 5,
"channel": "sms",
"timestamp": "2026-01-12T18:05:00.000000",
"status": "sent",
"payload": {...}
}
]
}
4. Reset Simulator
Endpoint: GET /api/simulator/reset
Response:
{
"success": true,
"message": "Simulator reset successfully"
}
Behavior: Clears all counters and request history.
Configuration
Enable Simulator
Add these settings to your .env file:
# Enable external API notifications
EMAIL_API_ENABLED=true
SMS_API_ENABLED=true
# Point to simulator endpoints
EMAIL_API_URL=http://localhost:8000/api/simulator/send-email
SMS_API_URL=http://localhost:8000/api/simulator/send-sms
# Simulator authentication (any value works)
EMAIL_API_KEY=simulator-test-key
SMS_API_KEY=simulator-test-key
# Authentication method
EMAIL_API_AUTH_METHOD=bearer
SMS_API_AUTH_METHOD=bearer
Email Configuration
The email simulator uses Django's SMTP backend. Configure your SMTP settings in .env:
# Email Configuration
EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USE_TLS=True
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-app-password
DEFAULT_FROM_EMAIL=noreply@px360.sa
Important: For Gmail, use an App Password instead of your regular password.
Usage Examples
Example 1: Send Email via Simulator
from apps.notifications.services import NotificationService
# Send email - will be sent via SMTP
log = NotificationService.send_email_via_api(
message='Your account has been created successfully!',
email='user@example.com',
subject='Welcome to PX360'
)
print(f"Email status: {log.status}")
Terminal Output:
======================================================================
📧 EMAIL SIMULATOR - Request #1
======================================================================
To: user@example.com
Subject: Welcome to PX360
Message: Your account has been created successfully!
HTML: No
======================================================================
Example 2: Send SMS via Simulator
from apps.notifications.services import NotificationService
# Send SMS - will be printed to terminal
log = NotificationService.send_sms_via_api(
message='Your verification code is 123456',
phone='+966501234567'
)
print(f"SMS status: {log.status}")
Terminal Output:
══════════════════════════════════════════════════════════════════════
📱 SMS SIMULATOR
══════════════════════════════════════════════════════════════════════
Request #: 1
══════════════════════════════════════════════════════════════════════
To: +966501234567
Time: 2026-01-12 18:05:00
══════════════════════════════════════════════════════════════════════
Message:
Your verification code is 123456
══════════════════════════════════════════════════════════════════════
Example 3: Send HTML Email
from apps.notifications.services import NotificationService
# Send email with HTML content
log = NotificationService.send_email_via_api(
message='Please view this email in HTML mode.',
email='user@example.com',
subject='Welcome',
html_message='<h1>Welcome!</h1><p>Your account is ready.</p>'
)
Example 4: Check Simulator Status
# Using curl
curl http://localhost:8000/api/simulator/health
# Using requests
import requests
response = requests.get('http://localhost:8000/api/simulator/health')
print(response.json())
Example 5: Reset Simulator
# Using curl
curl http://localhost:8000/api/simulator/reset
# Using requests
import requests
response = requests.get('http://localhost:8000/api/simulator/reset')
print(response.json())
Testing Workflow
Step 1: Start Development Server
python manage.py runserver
Step 2: Enable Simulator
Update .env file with simulator URLs (see Configuration section).
Step 3: Run Python Script
# test_simulator.py
from apps.notifications.services import NotificationService
# Test email
print("Testing email...")
email_log = NotificationService.send_email_via_api(
message='Test email from simulator',
email='your-email@example.com',
subject='Simulator Test'
)
print(f"Email: {email_log.status}")
# Test SMS
print("\nTesting SMS...")
sms_log = NotificationService.send_sms_via_api(
message='Test SMS from simulator',
phone='+966501234567'
)
print(f"SMS: {sms_log.status}")
# Check health
import requests
health = requests.get('http://localhost:8000/api/simulator/health').json()
print(f"\nStatistics: {health['statistics']}")
Step 4: Verify Results
- Email: Check your email inbox (or mailcatcher if using console backend)
- SMS: Check terminal for formatted SMS output
- Logs: Check
logs/px360.logfor detailed logs
Integration with External API Service
The simulator is fully integrated with the external API notification service. When you enable the simulator URLs in .env, the NotificationService automatically uses the simulator endpoints.
Switching Between Simulator and Real APIs
Using Simulator (for development/testing):
EMAIL_API_ENABLED=true
EMAIL_API_URL=http://localhost:8000/api/simulator/send-email
SMS_API_ENABLED=true
SMS_API_URL=http://localhost:8000/api/simulator/send-sms
Using Real APIs (for production):
EMAIL_API_ENABLED=true
EMAIL_API_URL=https://api.yourservice.com/send-email
SMS_API_ENABLED=true
SMS_API_URL=https://api.yourservice.com/send-sms
No code changes required! Just update the URLs in .env.
Request Logging
All simulator requests are logged to:
- Terminal: Immediate feedback during development
- File Log:
logs/px360.log- permanent record - Request History: In-memory last 10 requests (accessible via health check)
Log Format
[INFO] [Simulator] EMAIL Request #1: sent
[INFO] [Email Simulator] Sending email to user@example.com: Test Subject
[INFO] [Email Simulator] Email sent successfully to user@example.com
Error Handling
The simulator handles various error scenarios gracefully:
Missing Fields
Request:
{
"to": "user@example.com"
// Missing "subject" and "message"
}
Response:
{
"success": false,
"error": "Missing required fields: subject, message"
}
Invalid JSON
Request: Malformed JSON
Response:
{
"success": false,
"error": "Invalid JSON format"
}
Email Sending Errors
If Django SMTP fails to send the email, the error is caught and returned:
Response:
{
"success": false,
"error": "SMTP error details..."
}
Troubleshooting
Issue: Email not received
Possible Causes:
- SMTP not configured correctly
- Email in spam folder
- Invalid recipient address
Solutions:
- Check
.envemail settings - Check
logs/px360.logfor errors - Use mailcatcher for local testing:
pip install mailcatcher mailcatcher # Update .env: EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend # EMAIL_HOST=localhost, EMAIL_PORT=1025
Issue: SMS not showing in terminal
Possible Causes:
- Server not running in terminal
- Output redirected to file
Solutions:
- Ensure
python manage.py runserveris running in visible terminal - Check
logs/px360.logfor SMS logs
Issue: Simulator endpoints returning 404
Possible Causes:
- Simulator app not in INSTALLED_APPS
- URL not included in main urls.py
- Server not restarted after adding app
Solutions:
- Check
config/settings/base.pyincludes'apps.simulator' - Check
config/urls.pyincludes simulator URLs - Restart server:
python manage.py runserver
Issue: Health check shows 0 requests
Possible Causes:
- Simulator not enabled in
.env - Requests using wrong URLs
Solutions:
- Check
EMAIL_API_ENABLEDandSMS_API_ENABLEDaretrue - Verify URLs point to
localhost:8000/api/simulator/...
Advanced Usage
Custom SMS Formatting
You can modify the SMS output format in apps/simulator/views.py. Look for the sms_simulator function and adjust the print statements.
Request Middleware
Add custom middleware to intercept all simulator requests:
# Create apps/simulator/middleware.py
class SimulatorLoggingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if '/api/simulator/' in request.path:
# Custom logging logic
pass
return self.get_response(request)
Batch Testing
Test multiple notifications at once:
from apps.notifications.services import NotificationService
test_data = [
{'email': 'user1@example.com', 'subject': 'Test 1'},
{'email': 'user2@example.com', 'subject': 'Test 2'},
]
for data in test_data:
NotificationService.send_email_via_api(
message=f'Test email for {data["email"]}',
email=data['email'],
subject=data['subject']
)
Performance Considerations
- Email Sending: Each email makes an SMTP request (network latency)
- SMS Printing: Instant, no network overhead
- Request History: Limited to last 10 requests to prevent memory issues
- Logging: Rotating file handler prevents disk space issues
Security Considerations
- No Authentication Required: Simulator endpoints are public by design
- CSRF Exempt: All endpoints exempt from CSRF checks
- Production Use: Disable simulator in production by not using simulator URLs
- Sensitive Data: Simulator logs may contain PII (phone numbers, emails)
Best Practices
- Development Only: Use simulator only in development/testing environments
- Environment-Specific Config: Keep simulator URLs only in
.env.localor.env.development - Regular Resets: Reset simulator counters between test runs
- Log Monitoring: Check logs for any unexpected errors
- Test Coverage: Include simulator tests in your test suite
Related Documentation
Support
For issues or questions:
- Check logs:
logs/px360.log - Verify
.envconfiguration - Test endpoints with curl/Postman
- Check simulator health:
GET /api/simulator/health
License
Part of the PX360 project. See project LICENSE for details.