A robust SMS gateway service built with FastAPI that supports multiple SMS providers with automatic failover and circuit breaker pattern implementation.
- Multi-Provider Support: Integrates with Arkesel and Mnotify SMS providers
- Strategy Pattern: Clean separation of concerns with provider-specific strategies
- Circuit Breaker Pattern: Prevents cascading failures and improves system resilience
- Automatic Failover: Automatically switches between providers if one fails
- Health Monitoring: Built-in health checks and circuit breaker status monitoring
- Async/Await: Fully asynchronous implementation for high performance
- RESTful API: Clean REST API with automatic documentation
- Environment Configuration: Flexible configuration via environment variables
- Python 3.8+
- pip
- Virtual environment (recommended)
-
Clone the repository
git clone https://github.com/aglili/gateway.git cd gateway -
Create and activate virtual environment
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies
pip install -r requirements.txt
-
Set up environment variables Create a
.envfile in the root directory:# Arkesel Configuration ARKESEL_API_KEY=your_arkesel_api_key ARKESEL_API_URL=https://sms.arkesel.com ARKESEL_SENDER_ID=your_sender_id # Mnotify Configuration MNOTIFY_API_KEY=your_mnotify_api_key MNOTIFY_API_URL=https://api.mnotify.com MNOTIFY_SENDER_ID=your_sender_id
uvicorn src.main:app --reload --host 0.0.0.0 --port 8000uvicorn src.main:app --host 0.0.0.0 --port 8000The API will be available at:
- API: http://localhost:8000
- Documentation: http://localhost:8000/docs
- Health Check: http://localhost:8000/health
POST /sms/send
Send an SMS message using the configured providers with automatic failover.
Request Body:
{
"recipient": "+233241234567",
"message": "Hello from SMS Gateway!"
}Response:
{
"success": true,
"message_id": "A59CCB70-662D-45EF-9976-1EFAD249793D",
"provider": "mnotify",
"timestamp": "2024-01-15T10:30:00",
"error": null
}GET /health
Check the overall health of the service including circuit breaker status.
Response:
{
"status": "healthy",
"timestamp": "2024-01-15T10:30:00",
"circuit_breaker_status": {
"arkesel_status": {
"state": "CLOSED",
"failure_count": 0,
"can_execute": true
},
"mnotify_status": {
"state": "CLOSED",
"failure_count": 0,
"can_execute": true
}
}
}GET /circuit-breaker-status
Get detailed circuit breaker status for all providers.
POST /circuit-breaker/reset
Manually reset all circuit breakers to CLOSED state.
The application implements a circuit breaker pattern to improve system resilience:
- CLOSED: Normal operation, requests are allowed
- OPEN: Circuit is open, requests are blocked
- HALF_OPEN: Limited requests allowed to test if service is back
Configuration:
FAILURE_THRESHOLD: Number of failures before opening circuit (default: 5)RESET_TIMEOUT: Time in seconds before attempting to close circuit (default: 30)
- API Endpoint:
https://sms.arkesel.com/api/v2/sms/send - Authentication: API key in headers
- Required Config:
ARKESEL_API_KEY,ARKESEL_SENDER_ID
- API Endpoint:
https://api.mnotify.com/api/sms/quick - Authentication: API key in URL parameters
- Required Config:
MNOTIFY_API_KEY,MNOTIFY_SENDER_ID
The service implements comprehensive error handling:
- Provider Failover: If one provider fails, automatically tries the next
- Circuit Breaker: Prevents overwhelming failing providers
- Graceful Degradation: Returns meaningful error messages
- Logging: All errors are logged for monitoring
src/
├── config/settings.py # Configuration management
├── utils/
│ ├── circuit_breaker.py # Circuit breaker implementation
│ ├── enums.py # Enums and constants
│ ├── logger.py # Logging setup
│ ├── sms_orchestrator.py # Orchestrator for managing strategies
│ ├── sms_providers.py # Original SMS provider implementations
│ └── sms_strategy.py # Strategy pattern implementation
├── main.py # FastAPI application
└── schema.py # Pydantic models
# Run with uvicorn for testing
uvicorn src.main:app --reload
# Test endpoints using curl
curl -X POST "http://localhost:8000/sms/send" \
-H "Content-Type: application/json" \
-d '{"recipient": "+233241234567", "message": "Test message"}'| Variable | Description | Default |
|---|---|---|
ARKESEL_API_KEY |
Arkesel API key | Required |
ARKESEL_API_URL |
Arkesel API URL | https://sms.arkesel.com |
ARKESEL_SENDER_ID |
Arkesel sender ID | Required |
MNOTIFY_API_KEY |
Mnotify API key | Required |
MNOTIFY_API_URL |
Mnotify API URL | https://api.mnotify.com |
MNOTIFY_SENDER_ID |
Mnotify sender ID | Required |
FAILURE_THRESHOLD |
Circuit breaker failure threshold | 5 |
RESET_TIMEOUT |
Circuit breaker reset timeout (seconds) | 30 |