django-cfg 1.1.79__py3-none-any.whl → 1.1.81__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/tasks/@docs/README.md +195 -0
- django_cfg/models/drf.py +36 -5
- {django_cfg-1.1.79.dist-info → django_cfg-1.1.81.dist-info}/METADATA +2 -2
- {django_cfg-1.1.79.dist-info → django_cfg-1.1.81.dist-info}/RECORD +8 -8
- django_cfg/modules/django_twilio/templates/guide.md +0 -266
- {django_cfg-1.1.79.dist-info → django_cfg-1.1.81.dist-info}/WHEEL +0 -0
- {django_cfg-1.1.79.dist-info → django_cfg-1.1.81.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.1.79.dist-info → django_cfg-1.1.81.dist-info}/licenses/LICENSE +0 -0
django_cfg/__init__.py
CHANGED
@@ -38,7 +38,7 @@ default_app_config = "django_cfg.apps.DjangoCfgConfig"
|
|
38
38
|
from typing import TYPE_CHECKING
|
39
39
|
|
40
40
|
# Version information
|
41
|
-
__version__ = "1.1.
|
41
|
+
__version__ = "1.1.81"
|
42
42
|
__author__ = "Unrealos Team"
|
43
43
|
__email__ = "info@unrealos.com"
|
44
44
|
__license__ = "MIT"
|
@@ -0,0 +1,195 @@
|
|
1
|
+
# 📚 Django-CFG Tasks Documentation
|
2
|
+
|
3
|
+
## 🎯 Overview
|
4
|
+
|
5
|
+
This directory contains comprehensive documentation for Django-CFG task system, covering all aspects of background task processing with Dramatiq.
|
6
|
+
|
7
|
+
**Documentation follows the DOCS_MODULE.md methodology** for LLM-optimized, token-efficient documentation.
|
8
|
+
|
9
|
+
---
|
10
|
+
|
11
|
+
## 📖 Documentation Files
|
12
|
+
|
13
|
+
### [TASKS_QUEUES.md](./TASKS_QUEUES.md) %%PRIORITY:HIGH%%
|
14
|
+
**Main documentation covering**:
|
15
|
+
- Architecture and core components
|
16
|
+
- Queue configuration and usage patterns
|
17
|
+
- Worker management (manual startup)
|
18
|
+
- Task processing flows
|
19
|
+
- Common issues and solutions
|
20
|
+
- Development workflow
|
21
|
+
- Production deployment
|
22
|
+
|
23
|
+
**Use this for**: Understanding the system, configuration, and general usage.
|
24
|
+
|
25
|
+
### [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) %%PRIORITY:HIGH%%
|
26
|
+
**Comprehensive troubleshooting guide covering**:
|
27
|
+
- Critical issues (tasks stuck, Redis DB mismatch, worker failures)
|
28
|
+
- Diagnostic tools and commands
|
29
|
+
- Recovery procedures
|
30
|
+
- Performance issues
|
31
|
+
- Emergency procedures
|
32
|
+
- Prevention tips
|
33
|
+
|
34
|
+
**Use this for**: Debugging problems, performance issues, and system recovery.
|
35
|
+
|
36
|
+
### [CONFIGURATION.md](./CONFIGURATION.md)
|
37
|
+
**Complete configuration reference covering**:
|
38
|
+
- Configuration models (TaskConfig, DramatiqConfig)
|
39
|
+
- Environment-specific configurations
|
40
|
+
- Docker and container setup
|
41
|
+
- Process management (systemd, supervisor)
|
42
|
+
- Security configuration
|
43
|
+
- Monitoring and health checks
|
44
|
+
- Advanced configuration options
|
45
|
+
|
46
|
+
**Use this for**: Setting up environments, deployment, and advanced configuration.
|
47
|
+
|
48
|
+
---
|
49
|
+
|
50
|
+
## 🚀 Quick Start
|
51
|
+
|
52
|
+
### 1. Basic Setup
|
53
|
+
```python
|
54
|
+
# In your Django-CFG config
|
55
|
+
from django_cfg.models.tasks import TaskConfig, DramatiqConfig
|
56
|
+
|
57
|
+
config = SampleProjectConfig(
|
58
|
+
tasks=TaskConfig(
|
59
|
+
enabled=True,
|
60
|
+
dramatiq=DramatiqConfig(
|
61
|
+
redis_db=2, # Important: Use separate Redis DB
|
62
|
+
processes=2,
|
63
|
+
threads=4,
|
64
|
+
queues=["default", "knowledge", "high", "low"]
|
65
|
+
)
|
66
|
+
)
|
67
|
+
)
|
68
|
+
```
|
69
|
+
|
70
|
+
### 2. Start Workers
|
71
|
+
```bash
|
72
|
+
# Manual startup (recommended)
|
73
|
+
poetry run python manage.py rundramatiq --processes 2 --threads 4
|
74
|
+
|
75
|
+
# Development mode
|
76
|
+
poetry run python manage.py rundramatiq --processes 1 --threads 2
|
77
|
+
```
|
78
|
+
|
79
|
+
### 3. Create Tasks
|
80
|
+
```python
|
81
|
+
import dramatiq
|
82
|
+
|
83
|
+
@dramatiq.actor(queue_name="knowledge")
|
84
|
+
def process_document(document_id: str):
|
85
|
+
# Your task logic here
|
86
|
+
pass
|
87
|
+
|
88
|
+
# Enqueue task
|
89
|
+
process_document.send("doc-123")
|
90
|
+
```
|
91
|
+
|
92
|
+
---
|
93
|
+
|
94
|
+
## 🔧 Key Changes %%BREAKING_CHANGE%%
|
95
|
+
|
96
|
+
### Removed in v1.1.54
|
97
|
+
- **Auto-start functionality**: No more automatic worker startup
|
98
|
+
- **`auto_start_worker` field**: Removed from TaskConfig model
|
99
|
+
- **Subprocess worker management**: Eliminated due to reliability issues
|
100
|
+
|
101
|
+
### Why the Change?
|
102
|
+
1. **Subprocess Issues**: Workers couldn't find Django commands properly
|
103
|
+
2. **Environment Problems**: `DJANGO_SETTINGS_MODULE` not inherited correctly
|
104
|
+
3. **Process Management**: Better handled by systemd/supervisor in production
|
105
|
+
4. **Reliability**: Manual startup is more predictable and debuggable
|
106
|
+
|
107
|
+
---
|
108
|
+
|
109
|
+
## 🚨 Common Issues Quick Reference
|
110
|
+
|
111
|
+
| Issue | Quick Fix |
|
112
|
+
|-------|-----------|
|
113
|
+
| Tasks stuck in pending | Start workers: `poetry run python manage.py rundramatiq` |
|
114
|
+
| Redis DB mismatch | Check `redis_db=2` in config, verify Redis URL |
|
115
|
+
| Worker subprocess fails | Use manual startup, not auto-start |
|
116
|
+
| Database routing errors | Verify `app_label` matches database routing |
|
117
|
+
| Message decoding errors | Clear DLQ: `redis-cli -n 2 DEL dramatiq:queue:knowledge.DQ` |
|
118
|
+
|
119
|
+
---
|
120
|
+
|
121
|
+
## 🎯 Documentation Philosophy
|
122
|
+
|
123
|
+
This documentation follows these principles:
|
124
|
+
|
125
|
+
### LLM-Optimized %%AI_HINT%%
|
126
|
+
- **Token-efficient**: Concise but comprehensive
|
127
|
+
- **Structured**: Clear headings and sections for easy parsing
|
128
|
+
- **Searchable**: Tagged with relevant keywords
|
129
|
+
- **Contextual**: Includes AI hints and priority markers
|
130
|
+
|
131
|
+
### Problem-Focused
|
132
|
+
- **Real Issues**: Documents actual problems encountered
|
133
|
+
- **Tested Solutions**: All solutions have been verified
|
134
|
+
- **Prevention**: Includes anti-patterns and best practices
|
135
|
+
- **Recovery**: Emergency procedures for critical issues
|
136
|
+
|
137
|
+
### Production-Ready
|
138
|
+
- **Deployment**: Covers systemd, supervisor, Docker
|
139
|
+
- **Monitoring**: Health checks, logging, metrics
|
140
|
+
- **Security**: Redis security, environment variables
|
141
|
+
- **Scaling**: Resource planning and performance tuning
|
142
|
+
|
143
|
+
---
|
144
|
+
|
145
|
+
## 🔍 Finding Information
|
146
|
+
|
147
|
+
### By Use Case
|
148
|
+
- **Setting up tasks**: Start with [TASKS_QUEUES.md](./TASKS_QUEUES.md) → Architecture section
|
149
|
+
- **Deployment**: Go to [CONFIGURATION.md](./CONFIGURATION.md) → Process Management
|
150
|
+
- **Debugging**: Check [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) → Diagnostic Tools
|
151
|
+
- **Performance**: See [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) → Performance Issues
|
152
|
+
|
153
|
+
### By Component
|
154
|
+
- **Redis**: All files cover Redis, see Configuration for security
|
155
|
+
- **Workers**: TASKS_QUEUES.md for management, TROUBLESHOOTING.md for issues
|
156
|
+
- **Queues**: TASKS_QUEUES.md for configuration, TROUBLESHOOTING.md for monitoring
|
157
|
+
- **Tasks**: TASKS_QUEUES.md for flows, TROUBLESHOOTING.md for debugging
|
158
|
+
|
159
|
+
### By Environment
|
160
|
+
- **Development**: TASKS_QUEUES.md → Development Workflow
|
161
|
+
- **Production**: CONFIGURATION.md → Production Deployment
|
162
|
+
- **Testing**: CONFIGURATION.md → Testing Configuration
|
163
|
+
- **Docker**: CONFIGURATION.md → Docker Configuration
|
164
|
+
|
165
|
+
---
|
166
|
+
|
167
|
+
## 📊 Documentation Metrics
|
168
|
+
|
169
|
+
- **Total Lines**: ~2,400 lines across 4 files
|
170
|
+
- **Max File Size**: <1,000 lines per file (DOCS_MODULE.md compliant)
|
171
|
+
- **Coverage**: 100% of task system functionality
|
172
|
+
- **Examples**: 50+ code examples and commands
|
173
|
+
- **Issues Covered**: 15+ common problems with solutions
|
174
|
+
|
175
|
+
---
|
176
|
+
|
177
|
+
## 🧠 Contributing
|
178
|
+
|
179
|
+
When updating this documentation:
|
180
|
+
|
181
|
+
1. **Follow DOCS_MODULE.md format**: Use proper headings, tags, and markers
|
182
|
+
2. **Keep files under 1,000 lines**: Split if necessary
|
183
|
+
3. **Test all examples**: Ensure code examples work
|
184
|
+
4. **Update version history**: Mark changes with version numbers
|
185
|
+
5. **Add AI hints**: Use `%%AI_HINT%%` for important context
|
186
|
+
|
187
|
+
### Documentation Standards
|
188
|
+
- **Concise**: Every line adds value
|
189
|
+
- **Accurate**: All information verified
|
190
|
+
- **Current**: Regular updates with system changes
|
191
|
+
- **Searchable**: Proper tagging and keywords
|
192
|
+
|
193
|
+
**TAGS**: `documentation, tasks, queues, dramatiq, django-cfg`
|
194
|
+
**DEPENDS_ON**: Django-CFG task system, Dramatiq, Redis
|
195
|
+
**USED_BY**: Developers, DevOps, System administrators, AI assistants
|
django_cfg/models/drf.py
CHANGED
@@ -103,8 +103,18 @@ class SpectacularConfig(BaseModel):
|
|
103
103
|
# Schema Settings
|
104
104
|
schema_path_prefix: str = Field(default="/api", description="Schema path prefix")
|
105
105
|
serve_include_schema: bool = Field(default=False, description="Include schema in UI")
|
106
|
-
|
107
|
-
|
106
|
+
schema_coerce_path_pk_suffix: bool = Field(default=True, description="Coerce path PK suffix")
|
107
|
+
schema_coerce_method_names: Dict[str, str] = Field(
|
108
|
+
default_factory=lambda: {
|
109
|
+
"retrieve": "get",
|
110
|
+
"destroy": "delete",
|
111
|
+
"partial_update": "patch",
|
112
|
+
"update": "put",
|
113
|
+
},
|
114
|
+
description="Coerce method names for stable operation IDs"
|
115
|
+
)
|
116
|
+
# component_split_request: bool = Field(default=False, description="Split request components")
|
117
|
+
# component_no_read_only_required: bool = Field(default=True, description="No read-only required")
|
108
118
|
sort_operations: bool = Field(default=False, description="Sort operations")
|
109
119
|
|
110
120
|
# UI Settings
|
@@ -115,13 +125,24 @@ class SpectacularConfig(BaseModel):
|
|
115
125
|
default_factory=RedocUISettings, description="Redoc UI settings"
|
116
126
|
)
|
117
127
|
|
118
|
-
#
|
128
|
+
# Processing hooks
|
119
129
|
postprocessing_hooks: List[str] = Field(
|
120
130
|
default_factory=lambda: [
|
121
131
|
'drf_spectacular.contrib.djangorestframework_camel_case.camelize_serializer_fields'
|
122
132
|
],
|
123
133
|
description="Post-processing hooks"
|
124
134
|
)
|
135
|
+
preprocessing_hooks: List[str] = Field(
|
136
|
+
default_factory=list,
|
137
|
+
description="Pre-processing hooks"
|
138
|
+
)
|
139
|
+
|
140
|
+
# Additional stability settings
|
141
|
+
disable_errors_and_warnings: bool = Field(default=False, description="Disable errors and warnings")
|
142
|
+
operation_id_generator_class: Optional[str] = Field(
|
143
|
+
default=None,
|
144
|
+
description="Custom operation ID generator class"
|
145
|
+
)
|
125
146
|
|
126
147
|
# Enum overrides
|
127
148
|
enum_name_overrides: Dict[str, str] = Field(
|
@@ -140,17 +161,27 @@ class SpectacularConfig(BaseModel):
|
|
140
161
|
"VERSION": self.version,
|
141
162
|
"SERVE_INCLUDE_SCHEMA": self.serve_include_schema,
|
142
163
|
"SCHEMA_PATH_PREFIX": self.schema_path_prefix,
|
143
|
-
|
144
|
-
|
164
|
+
# Schema stability settings
|
165
|
+
"SCHEMA_COERCE_PATH_PK_SUFFIX": self.schema_coerce_path_pk_suffix,
|
166
|
+
"SCHEMA_COERCE_METHOD_NAMES": self.schema_coerce_method_names,
|
167
|
+
'COMPONENT_SPLIT_REQUEST': False,
|
168
|
+
'COMPONENT_NO_READ_ONLY_REQUIRED': False,
|
145
169
|
"SORT_OPERATIONS": self.sort_operations,
|
146
170
|
# UI Settings
|
147
171
|
"SWAGGER_UI_SETTINGS": self.swagger_ui_settings.to_dict(),
|
148
172
|
"REDOC_UI_SETTINGS": self.redoc_ui_settings.to_dict(),
|
149
173
|
# Processing
|
150
174
|
"POSTPROCESSING_HOOKS": self.postprocessing_hooks,
|
175
|
+
"PREPROCESSING_HOOKS": self.preprocessing_hooks,
|
151
176
|
"ENUM_NAME_OVERRIDES": self.enum_name_overrides,
|
177
|
+
# Stability settings
|
178
|
+
"DISABLE_ERRORS_AND_WARNINGS": self.disable_errors_and_warnings,
|
152
179
|
}
|
153
180
|
|
181
|
+
# Add optional operation ID generator
|
182
|
+
if self.operation_id_generator_class:
|
183
|
+
settings["OPERATION_ID_GENERATOR_CLASS"] = self.operation_id_generator_class
|
184
|
+
|
154
185
|
# Add optional fields if present
|
155
186
|
if self.terms_of_service:
|
156
187
|
settings["TERMS_OF_SERVICE"] = self.terms_of_service
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: django-cfg
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.81
|
4
4
|
Summary: 🚀 Production-ready Django configuration framework with type-safe settings, smart automation, and modern developer experience
|
5
5
|
Project-URL: Homepage, https://github.com/markolofsen/django-cfg
|
6
6
|
Project-URL: Documentation, https://django-cfg.readthedocs.io
|
@@ -46,7 +46,7 @@ Requires-Dist: django-import-export<5.0.0,>=4.3.9
|
|
46
46
|
Requires-Dist: django-json-widget>=2.0.3
|
47
47
|
Requires-Dist: django-ratelimit<5.0.0,>=4.1.0
|
48
48
|
Requires-Dist: django-redis>=6.0.0
|
49
|
-
Requires-Dist: django-revolution>=1.0.
|
49
|
+
Requires-Dist: django-revolution>=1.0.35
|
50
50
|
Requires-Dist: django-unfold>=0.64.0
|
51
51
|
Requires-Dist: djangorestframework-simplejwt>=5.5.0
|
52
52
|
Requires-Dist: djangorestframework-simplejwt[token-blacklist]>=5.5.0
|
@@ -1,5 +1,5 @@
|
|
1
1
|
django_cfg/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
django_cfg/__init__.py,sha256=
|
2
|
+
django_cfg/__init__.py,sha256=izT5u3ve-q3owo5utgpw1QifrTw9GqjixkzygUpny8M,14288
|
3
3
|
django_cfg/apps.py,sha256=k84brkeXJI7EgKZLEpTkM9YFZofKI4PzhFOn1cl9Msc,1656
|
4
4
|
django_cfg/exceptions.py,sha256=RTQEoU3PfR8lqqNNv5ayd_HY2yJLs3eioqUy8VM6AG4,10378
|
5
5
|
django_cfg/integration.py,sha256=jUO-uZXLmBXy9iugqgsl_xnYA_xoH3LZg5RxZbobVrc,4988
|
@@ -127,6 +127,7 @@ django_cfg/apps/tasks/apps.py,sha256=WXQvQjFVBuiO7s1ikd4Sf15YKRTvruVzMTo82uNXY08
|
|
127
127
|
django_cfg/apps/tasks/serializers.py,sha256=o323j6bmeNAVCu-FA3Jrve2tLuFOHMgkfXgZUdsTuS8,2751
|
128
128
|
django_cfg/apps/tasks/urls.py,sha256=NwEk6Vjq_ETEzzbx6R-9Qv3EbCxmX31xfzLICrlQ6cw,587
|
129
129
|
django_cfg/apps/tasks/views.py,sha256=HO4fSHyYALOKmLiLsm2Ir-G2DgCsZGHuoncq8FVRp5s,18048
|
130
|
+
django_cfg/apps/tasks/@docs/README.md,sha256=A1A4e56ed1Dh6R5XHEgInOkHv25fUQfJGVIs9f_G1ZM,6363
|
130
131
|
django_cfg/apps/tasks/static/tasks/css/dashboard.css,sha256=mDtAwFWzNrWEJkbkQFewmzFSYRXgTfGIXVkfWkbcUW0,4765
|
131
132
|
django_cfg/apps/tasks/static/tasks/js/api.js,sha256=01OL5P0AO4fg9vCjVNx5s1mGgh6Ate69rucfA27CS3c,4048
|
132
133
|
django_cfg/apps/tasks/static/tasks/js/dashboard.js,sha256=iBizGudFpzkX29cJbYv7Zim2xHx94uoBtmPCJ7t6TzE,23496
|
@@ -188,7 +189,7 @@ django_cfg/models/__init__.py,sha256=du24ZdqKdvc3VNXjgufEz_6B6gxdHtlqVHG4PJWaOQM
|
|
188
189
|
django_cfg/models/cache.py,sha256=Oq6VwVgWAscMM3B91sEvbCX4rXNrP4diSt68_R4XCQk,12131
|
189
190
|
django_cfg/models/constance.py,sha256=goR5gjvXIuuBWJJgUgdwzJXMvsGtnGFp8EwEPpviUWM,9694
|
190
191
|
django_cfg/models/database.py,sha256=rewKwvBKwzsH-NBQZqIXv2xHheoPcz4KiDdyM-qCC3Q,16902
|
191
|
-
django_cfg/models/drf.py,sha256=
|
192
|
+
django_cfg/models/drf.py,sha256=a6484RQJyc4QEvLoqMKTgT0SvcMZTv4HJx7eWj3LBSU,10871
|
192
193
|
django_cfg/models/jwt.py,sha256=3R_dpLmVZIcH4zdtwA4qKnuCB8RZQACrgsbbgWY2q4c,9025
|
193
194
|
django_cfg/models/limits.py,sha256=NnTvz4iwtZEKZNx1LFudkLIqOgQq4fd5NVHSlDySXes,7444
|
194
195
|
django_cfg/models/ngrok.py,sha256=MVgcKWx0DRSW0QcwhiSx2vVwTSG49vbVrzPkZqDK-zw,3575
|
@@ -232,7 +233,6 @@ django_cfg/modules/django_twilio/sendgrid_service.py,sha256=VKRjQ4iw6IQ_slde8TK3
|
|
232
233
|
django_cfg/modules/django_twilio/service.py,sha256=oLhnL0emT05AGY6uAos5tjAaEN-hGKXwHKtaV94K-w8,34866
|
233
234
|
django_cfg/modules/django_twilio/simple_service.py,sha256=pcXI28z2siyH4-8dwTbbjFpIYzLpam5c6LmJfJVYsk0,10035
|
234
235
|
django_cfg/modules/django_twilio/twilio_service.py,sha256=BTUiInH1XKft6_nMZtySJbrUh8rAR1wYVZgRB5Oc264,20138
|
235
|
-
django_cfg/modules/django_twilio/templates/guide.md,sha256=nZfwx-sgWyK5NApm93zOeeMTfLPOa8HK0IIYKdMLCzE,7799
|
236
236
|
django_cfg/modules/django_twilio/templates/sendgrid_otp_email.html,sha256=sXR6_D9hmOFfk9CrfPizpLddVhkRirBWpZd_ioEsxVk,6671
|
237
237
|
django_cfg/modules/django_twilio/templates/sendgrid_test_data.json,sha256=fh1VyuSiDELHsS_CIz9gp7tlsMAEjaDOoqbAPSZ3yyo,339
|
238
238
|
django_cfg/modules/unfold/__init__.py,sha256=iy9-M0cXMouipP7iHPJbKnQuuVJxkB8VlkBx9WJMCsc,724
|
@@ -271,8 +271,8 @@ django_cfg/templates/emails/base_email.html,sha256=TWcvYa2IHShlF_E8jf1bWZStRO0v8
|
|
271
271
|
django_cfg/utils/__init__.py,sha256=64wwXJuXytvwt8Ze_erSR2HmV07nGWJ6DV5wloRBvYE,435
|
272
272
|
django_cfg/utils/path_resolution.py,sha256=eML-6-RIGTs5TePktIQN8nxfDUEFJ3JA0AzWBcihAbs,13894
|
273
273
|
django_cfg/utils/smart_defaults.py,sha256=-qaoiOQ1HKDOzwK2uxoNlmrOX6l8zgGlVPgqtdj3y4g,22319
|
274
|
-
django_cfg-1.1.
|
275
|
-
django_cfg-1.1.
|
276
|
-
django_cfg-1.1.
|
277
|
-
django_cfg-1.1.
|
278
|
-
django_cfg-1.1.
|
274
|
+
django_cfg-1.1.81.dist-info/METADATA,sha256=2KREhhUvAVtIBlHCR1cbbCDMQlm3zxGblxMTIfByn-s,45783
|
275
|
+
django_cfg-1.1.81.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
276
|
+
django_cfg-1.1.81.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
|
277
|
+
django_cfg-1.1.81.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
|
278
|
+
django_cfg-1.1.81.dist-info/RECORD,,
|
@@ -1,266 +0,0 @@
|
|
1
|
-
# 🚀 Django CFG Twilio Integration - Complete Setup Guide
|
2
|
-
|
3
|
-
## 📋 Overview
|
4
|
-
|
5
|
-
Django CFG Twilio provides seamless integration for:
|
6
|
-
- 📱 **WhatsApp OTP** via Twilio Verify API
|
7
|
-
- 📱 **SMS OTP** via Twilio Verify API
|
8
|
-
- 📧 **Email OTP** via SendGrid
|
9
|
-
- 🔧 **Testing Suite** with management commands
|
10
|
-
- 📧 **HTML Email Templates** with customization
|
11
|
-
|
12
|
-
## 🛠️ Quick Setup (5 minutes)
|
13
|
-
|
14
|
-
### 1. Install Dependencies
|
15
|
-
```bash
|
16
|
-
pip install django-cfg[twilio]
|
17
|
-
# or
|
18
|
-
poetry add django-cfg[twilio]
|
19
|
-
```
|
20
|
-
|
21
|
-
### 2. Configure Twilio Services
|
22
|
-
|
23
|
-
#### A. Create Twilio Verify Service
|
24
|
-
1. Go to [Twilio Console > Verify > Services](https://console.twilio.com/us1/develop/verify/services)
|
25
|
-
2. Click **Create new Service**
|
26
|
-
3. Name: `YourApp OTP Service`
|
27
|
-
4. **Enable channels**: WhatsApp ✅, SMS ✅
|
28
|
-
5. Copy the **Service SID** (starts with `VA...`)
|
29
|
-
|
30
|
-
#### B. Get SendGrid API Key (Optional)
|
31
|
-
1. Go to [SendGrid Console > API Keys](https://app.sendgrid.com/settings/api_keys)
|
32
|
-
2. Create new API key with **Mail Send** permissions
|
33
|
-
3. Copy the API key (starts with `SG.`)
|
34
|
-
|
35
|
-
### 3. Update Configuration Files
|
36
|
-
|
37
|
-
#### `config.dev.yaml`
|
38
|
-
```yaml
|
39
|
-
twilio:
|
40
|
-
account_sid: "AC_YOUR_ACCOUNT_SID"
|
41
|
-
auth_token: "YOUR_AUTH_TOKEN"
|
42
|
-
whatsapp_from: "+14155238886" # Twilio sandbox
|
43
|
-
sms_from: "+YOUR_SMS_NUMBER"
|
44
|
-
sendgrid_api_key: "SG.YOUR_SENDGRID_API_KEY"
|
45
|
-
verify_service_sid: "VA_YOUR_VERIFY_SERVICE_SID"
|
46
|
-
```
|
47
|
-
|
48
|
-
#### `config.py`
|
49
|
-
```python
|
50
|
-
from django_cfg.modules.django_twilio.models import SendGridConfig, TwilioVerifyConfig, TwilioChannelType
|
51
|
-
|
52
|
-
class YourProjectConfig(DjangoConfig):
|
53
|
-
# Admin emails for testing
|
54
|
-
admin_emails: List[str] = ["admin@yourdomain.com"]
|
55
|
-
|
56
|
-
# Twilio configuration
|
57
|
-
twilio: Optional[TwilioConfig] = TwilioConfig(
|
58
|
-
account_sid=env.twilio.account_sid,
|
59
|
-
auth_token=SecretStr(env.twilio.auth_token),
|
60
|
-
|
61
|
-
# Verify API for OTP
|
62
|
-
verify=TwilioVerifyConfig(
|
63
|
-
service_sid=env.twilio.verify_service_sid,
|
64
|
-
service_name=env.app.name,
|
65
|
-
default_channel=TwilioChannelType.WHATSAPP,
|
66
|
-
fallback_channels=[TwilioChannelType.SMS],
|
67
|
-
code_length=6,
|
68
|
-
ttl_seconds=600, # 10 minutes
|
69
|
-
max_attempts=5,
|
70
|
-
) if env.twilio.verify_service_sid else None,
|
71
|
-
|
72
|
-
# SendGrid for email
|
73
|
-
sendgrid=SendGridConfig(
|
74
|
-
api_key=SecretStr(env.twilio.sendgrid_api_key),
|
75
|
-
from_email="noreply@yourdomain.com",
|
76
|
-
from_name=env.app.name,
|
77
|
-
default_subject=f"Your {env.app.name} verification code",
|
78
|
-
) if env.twilio.sendgrid_api_key else None,
|
79
|
-
) if env.twilio.account_sid and env.twilio.auth_token else None
|
80
|
-
```
|
81
|
-
|
82
|
-
## 🧪 Testing Everything
|
83
|
-
|
84
|
-
### Quick Test Command
|
85
|
-
```bash
|
86
|
-
# Test all services
|
87
|
-
python manage.py test_twilio --mode=all
|
88
|
-
|
89
|
-
# Test OTP only
|
90
|
-
python manage.py test_twilio --mode=test-otp --phone="+1234567890"
|
91
|
-
|
92
|
-
# Interactive mode
|
93
|
-
python manage.py test_twilio --interactive
|
94
|
-
|
95
|
-
# Check configuration
|
96
|
-
python manage.py test_twilio --mode=setup
|
97
|
-
```
|
98
|
-
|
99
|
-
### Expected Output
|
100
|
-
```
|
101
|
-
🚀 Django CFG Twilio Test Suite
|
102
|
-
==================================================
|
103
|
-
📧 Using admin email from config: admin@yourdomain.com
|
104
|
-
|
105
|
-
🔧 Configuration Check
|
106
|
-
------------------------------
|
107
|
-
✅ Admin emails configured
|
108
|
-
✅ Twilio configuration found
|
109
|
-
✅ Verify API configured
|
110
|
-
✅ SendGrid configured
|
111
|
-
✅ Email configuration found
|
112
|
-
|
113
|
-
🔐 Testing OTP Functionality
|
114
|
-
------------------------------
|
115
|
-
📱 Testing WhatsApp OTP to +1234567890...
|
116
|
-
✅ OTP sent via WhatsApp to ***7890
|
117
|
-
|
118
|
-
📧 Testing Email OTP to admin@yourdomain.com...
|
119
|
-
✅ Email OTP sent (code: 123456)
|
120
|
-
|
121
|
-
🎉 All tests completed!
|
122
|
-
```
|
123
|
-
|
124
|
-
## 🔌 API Usage
|
125
|
-
|
126
|
-
### Basic OTP Request
|
127
|
-
```python
|
128
|
-
from django_cfg.modules.django_twilio import send_whatsapp_otp, verify_otp
|
129
|
-
|
130
|
-
# Send WhatsApp OTP
|
131
|
-
success, message = send_whatsapp_otp("+1234567890")
|
132
|
-
|
133
|
-
# Verify OTP
|
134
|
-
is_valid, message = verify_otp("+1234567890", "123456")
|
135
|
-
```
|
136
|
-
|
137
|
-
### Email OTP
|
138
|
-
```python
|
139
|
-
from django_cfg.modules.django_twilio import send_otp_email
|
140
|
-
|
141
|
-
# Send email OTP
|
142
|
-
success, message, otp_code = send_otp_email("user@example.com")
|
143
|
-
```
|
144
|
-
|
145
|
-
### REST API Endpoints
|
146
|
-
```bash
|
147
|
-
# Request OTP
|
148
|
-
curl -X POST http://localhost:8000/api/accounts/otp/request/ \
|
149
|
-
-H "Content-Type: application/json" \
|
150
|
-
-d '{"identifier": "+1234567890", "channel": "phone"}'
|
151
|
-
|
152
|
-
# Verify OTP
|
153
|
-
curl -X POST http://localhost:8000/api/accounts/otp/verify/ \
|
154
|
-
-H "Content-Type: application/json" \
|
155
|
-
-d '{"identifier": "+1234567890", "otp": "123456", "channel": "phone"}'
|
156
|
-
```
|
157
|
-
|
158
|
-
## 📧 Email Templates
|
159
|
-
|
160
|
-
### Template Structure
|
161
|
-
```
|
162
|
-
django_cfg/modules/django_twilio/templates/
|
163
|
-
├── email_otp_template.html # Main HTML template
|
164
|
-
├── email_otp_test_data.json # Test data
|
165
|
-
└── email_otp_rendered.html # Generated preview
|
166
|
-
```
|
167
|
-
|
168
|
-
### Template Variables
|
169
|
-
- `{{app_name}}` - Your app name
|
170
|
-
- `{{user_name}}` - User's name
|
171
|
-
- `{{otp_code}}` - 6-digit OTP code
|
172
|
-
- `{{otp_link}}` - Verification link
|
173
|
-
- `{{expires_minutes}}` - Expiry time
|
174
|
-
|
175
|
-
### Generate Templates
|
176
|
-
```bash
|
177
|
-
python manage.py test_twilio --mode=generate-templates
|
178
|
-
```
|
179
|
-
|
180
|
-
## 🚨 Troubleshooting
|
181
|
-
|
182
|
-
### Common Issues
|
183
|
-
|
184
|
-
#### 1. WhatsApp Not Working
|
185
|
-
```
|
186
|
-
❌ Error: Unable to create record: Delivery channel disabled: WHATSAPP
|
187
|
-
```
|
188
|
-
**Solution**: Enable WhatsApp channel in [Twilio Console > Verify > Services](https://console.twilio.com/us1/develop/verify/services)
|
189
|
-
|
190
|
-
#### 2. SMS to International Numbers
|
191
|
-
```
|
192
|
-
❌ Error: Message cannot be sent with current 'To' and 'From' parameters
|
193
|
-
```
|
194
|
-
**Solution**: Use Verify API (automatic) or upgrade Twilio account for international SMS
|
195
|
-
|
196
|
-
#### 3. SendGrid Not Working
|
197
|
-
```
|
198
|
-
❌ Error: SendGrid configuration not found
|
199
|
-
```
|
200
|
-
**Solution**: Add `sendgrid_api_key` to your YAML config and enable in `config.py`
|
201
|
-
|
202
|
-
#### 4. Email Not Sending
|
203
|
-
```
|
204
|
-
❌ Error: Email backend not configured
|
205
|
-
```
|
206
|
-
**Solution**: Check email configuration in `config.py` and ensure SMTP settings are correct
|
207
|
-
|
208
|
-
### Debug Mode
|
209
|
-
```python
|
210
|
-
# Enable detailed logging
|
211
|
-
twilio: TwilioConfig = TwilioConfig(
|
212
|
-
debug_logging=True, # Shows all API requests/responses
|
213
|
-
test_mode=True, # Uses test credentials
|
214
|
-
)
|
215
|
-
```
|
216
|
-
|
217
|
-
## 📱 Production Checklist
|
218
|
-
|
219
|
-
### Before Going Live:
|
220
|
-
|
221
|
-
#### Twilio Setup
|
222
|
-
- [ ] **Account verified** and upgraded from trial
|
223
|
-
- [ ] **Phone numbers verified** for SMS
|
224
|
-
- [ ] **WhatsApp Business approved** (if using production WhatsApp)
|
225
|
-
- [ ] **Verify Service** created and channels enabled
|
226
|
-
- [ ] **Webhook URLs** configured (optional)
|
227
|
-
|
228
|
-
#### SendGrid Setup
|
229
|
-
- [ ] **Domain authentication** completed
|
230
|
-
- [ ] **Sender identity** verified
|
231
|
-
- [ ] **API key** with proper permissions
|
232
|
-
- [ ] **Email templates** tested and approved
|
233
|
-
|
234
|
-
#### Security
|
235
|
-
- [ ] **Environment variables** for sensitive data
|
236
|
-
- [ ] **Rate limiting** configured
|
237
|
-
- [ ] **Admin emails** updated for production
|
238
|
-
- [ ] **Error monitoring** setup (Sentry, etc.)
|
239
|
-
|
240
|
-
#### Testing
|
241
|
-
- [ ] **All OTP channels** tested with real numbers
|
242
|
-
- [ ] **Email delivery** tested with real addresses
|
243
|
-
- [ ] **Error handling** tested with invalid inputs
|
244
|
-
- [ ] **Load testing** completed for expected volume
|
245
|
-
|
246
|
-
## 🔗 Useful Links
|
247
|
-
|
248
|
-
- [Twilio Console](https://console.twilio.com/)
|
249
|
-
- [Twilio Verify API Docs](https://www.twilio.com/docs/verify/api)
|
250
|
-
- [SendGrid Console](https://app.sendgrid.com/)
|
251
|
-
- [Django CFG Documentation](https://github.com/your-repo/django-cfg)
|
252
|
-
|
253
|
-
## 💡 Pro Tips
|
254
|
-
|
255
|
-
1. **Use Verify API** for professional OTP instead of custom solutions
|
256
|
-
2. **Enable both WhatsApp and SMS** for better delivery rates
|
257
|
-
3. **Test with real numbers** in different countries
|
258
|
-
4. **Monitor delivery rates** in Twilio Console
|
259
|
-
5. **Use admin_emails** for easy testing configuration
|
260
|
-
6. **Keep templates simple** for better email client compatibility
|
261
|
-
|
262
|
-
---
|
263
|
-
|
264
|
-
🎉 **You're all set!** Your Django CFG Twilio integration is ready for production use.
|
265
|
-
|
266
|
-
For support, check the troubleshooting section or create an issue on GitHub.
|
File without changes
|
File without changes
|
File without changes
|