django-cfg 1.1.82__py3-none-any.whl → 1.2.1__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.
Files changed (244) hide show
  1. django_cfg/__init__.py +20 -448
  2. django_cfg/apps/accounts/README.md +3 -3
  3. django_cfg/apps/accounts/admin/__init__.py +0 -2
  4. django_cfg/apps/accounts/admin/activity.py +2 -9
  5. django_cfg/apps/accounts/admin/filters.py +0 -42
  6. django_cfg/apps/accounts/admin/inlines.py +8 -8
  7. django_cfg/apps/accounts/admin/otp.py +5 -5
  8. django_cfg/apps/accounts/admin/registration_source.py +1 -8
  9. django_cfg/apps/accounts/admin/user.py +12 -20
  10. django_cfg/apps/accounts/managers/user_manager.py +2 -129
  11. django_cfg/apps/accounts/migrations/0006_remove_twilioresponse_otp_secret_and_more.py +46 -0
  12. django_cfg/apps/accounts/models.py +3 -123
  13. django_cfg/apps/accounts/serializers/otp.py +40 -44
  14. django_cfg/apps/accounts/serializers/profile.py +0 -2
  15. django_cfg/apps/accounts/services/otp_service.py +98 -186
  16. django_cfg/apps/accounts/signals.py +25 -15
  17. django_cfg/apps/accounts/utils/auth_email_service.py +84 -0
  18. django_cfg/apps/accounts/views/otp.py +35 -36
  19. django_cfg/apps/agents/README.md +129 -0
  20. django_cfg/apps/agents/__init__.py +68 -0
  21. django_cfg/apps/agents/admin/__init__.py +17 -0
  22. django_cfg/apps/agents/admin/execution_admin.py +460 -0
  23. django_cfg/apps/agents/admin/registry_admin.py +360 -0
  24. django_cfg/apps/agents/admin/toolsets_admin.py +482 -0
  25. django_cfg/apps/agents/apps.py +29 -0
  26. django_cfg/apps/agents/core/__init__.py +20 -0
  27. django_cfg/apps/agents/core/agent.py +281 -0
  28. django_cfg/apps/agents/core/dependencies.py +154 -0
  29. django_cfg/apps/agents/core/exceptions.py +66 -0
  30. django_cfg/apps/agents/core/models.py +106 -0
  31. django_cfg/apps/agents/core/orchestrator.py +391 -0
  32. django_cfg/apps/agents/examples/__init__.py +3 -0
  33. django_cfg/apps/agents/examples/simple_example.py +161 -0
  34. django_cfg/apps/agents/integration/__init__.py +14 -0
  35. django_cfg/apps/agents/integration/middleware.py +80 -0
  36. django_cfg/apps/agents/integration/registry.py +345 -0
  37. django_cfg/apps/agents/integration/signals.py +50 -0
  38. django_cfg/apps/agents/management/__init__.py +3 -0
  39. django_cfg/apps/agents/management/commands/__init__.py +3 -0
  40. django_cfg/apps/agents/management/commands/create_agent.py +365 -0
  41. django_cfg/apps/agents/management/commands/orchestrator_status.py +191 -0
  42. django_cfg/apps/agents/managers/__init__.py +23 -0
  43. django_cfg/apps/agents/managers/execution.py +236 -0
  44. django_cfg/apps/agents/managers/registry.py +254 -0
  45. django_cfg/apps/agents/managers/toolsets.py +496 -0
  46. django_cfg/apps/agents/migrations/0001_initial.py +286 -0
  47. django_cfg/apps/agents/migrations/__init__.py +5 -0
  48. django_cfg/apps/agents/models/__init__.py +15 -0
  49. django_cfg/apps/agents/models/execution.py +215 -0
  50. django_cfg/apps/agents/models/registry.py +220 -0
  51. django_cfg/apps/agents/models/toolsets.py +305 -0
  52. django_cfg/apps/agents/patterns/__init__.py +24 -0
  53. django_cfg/apps/agents/patterns/content_agents.py +234 -0
  54. django_cfg/apps/agents/toolsets/__init__.py +15 -0
  55. django_cfg/apps/agents/toolsets/cache_toolset.py +285 -0
  56. django_cfg/apps/agents/toolsets/django_toolset.py +220 -0
  57. django_cfg/apps/agents/toolsets/file_toolset.py +324 -0
  58. django_cfg/apps/agents/toolsets/orm_toolset.py +319 -0
  59. django_cfg/apps/agents/urls.py +46 -0
  60. django_cfg/apps/knowbase/README.md +150 -0
  61. django_cfg/apps/knowbase/__init__.py +27 -0
  62. django_cfg/apps/knowbase/admin/__init__.py +23 -0
  63. django_cfg/apps/knowbase/admin/archive_admin.py +857 -0
  64. django_cfg/apps/knowbase/admin/chat_admin.py +386 -0
  65. django_cfg/apps/knowbase/admin/document_admin.py +650 -0
  66. django_cfg/apps/knowbase/admin/external_data_admin.py +685 -0
  67. django_cfg/apps/knowbase/apps.py +81 -0
  68. django_cfg/apps/knowbase/config/README.md +176 -0
  69. django_cfg/apps/knowbase/config/__init__.py +51 -0
  70. django_cfg/apps/knowbase/config/constance_fields.py +186 -0
  71. django_cfg/apps/knowbase/config/constance_settings.py +200 -0
  72. django_cfg/apps/knowbase/config/settings.py +450 -0
  73. django_cfg/apps/knowbase/examples/__init__.py +3 -0
  74. django_cfg/apps/knowbase/examples/external_data_usage.py +191 -0
  75. django_cfg/apps/knowbase/management/__init__.py +0 -0
  76. django_cfg/apps/knowbase/management/commands/__init__.py +0 -0
  77. django_cfg/apps/knowbase/management/commands/knowbase_stats.py +158 -0
  78. django_cfg/apps/knowbase/management/commands/setup_knowbase.py +59 -0
  79. django_cfg/apps/knowbase/managers/__init__.py +22 -0
  80. django_cfg/apps/knowbase/managers/archive.py +426 -0
  81. django_cfg/apps/knowbase/managers/base.py +32 -0
  82. django_cfg/apps/knowbase/managers/chat.py +141 -0
  83. django_cfg/apps/knowbase/managers/document.py +203 -0
  84. django_cfg/apps/knowbase/managers/external_data.py +471 -0
  85. django_cfg/apps/knowbase/migrations/0001_initial.py +427 -0
  86. django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +434 -0
  87. django_cfg/apps/knowbase/migrations/__init__.py +5 -0
  88. django_cfg/apps/knowbase/mixins/__init__.py +15 -0
  89. django_cfg/apps/knowbase/mixins/config.py +108 -0
  90. django_cfg/apps/knowbase/mixins/creator.py +81 -0
  91. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +199 -0
  92. django_cfg/apps/knowbase/mixins/external_data_mixin.py +813 -0
  93. django_cfg/apps/knowbase/mixins/service.py +362 -0
  94. django_cfg/apps/knowbase/models/__init__.py +41 -0
  95. django_cfg/apps/knowbase/models/archive.py +599 -0
  96. django_cfg/apps/knowbase/models/base.py +58 -0
  97. django_cfg/apps/knowbase/models/chat.py +157 -0
  98. django_cfg/apps/knowbase/models/document.py +267 -0
  99. django_cfg/apps/knowbase/models/external_data.py +376 -0
  100. django_cfg/apps/knowbase/serializers/__init__.py +68 -0
  101. django_cfg/apps/knowbase/serializers/archive_serializers.py +386 -0
  102. django_cfg/apps/knowbase/serializers/chat_serializers.py +137 -0
  103. django_cfg/apps/knowbase/serializers/document_serializers.py +94 -0
  104. django_cfg/apps/knowbase/serializers/external_data_serializers.py +256 -0
  105. django_cfg/apps/knowbase/serializers/public_serializers.py +74 -0
  106. django_cfg/apps/knowbase/services/__init__.py +40 -0
  107. django_cfg/apps/knowbase/services/archive/__init__.py +42 -0
  108. django_cfg/apps/knowbase/services/archive/archive_service.py +541 -0
  109. django_cfg/apps/knowbase/services/archive/chunking_service.py +791 -0
  110. django_cfg/apps/knowbase/services/archive/exceptions.py +52 -0
  111. django_cfg/apps/knowbase/services/archive/extraction_service.py +508 -0
  112. django_cfg/apps/knowbase/services/archive/vectorization_service.py +362 -0
  113. django_cfg/apps/knowbase/services/base.py +53 -0
  114. django_cfg/apps/knowbase/services/chat_service.py +239 -0
  115. django_cfg/apps/knowbase/services/document_service.py +144 -0
  116. django_cfg/apps/knowbase/services/embedding/__init__.py +43 -0
  117. django_cfg/apps/knowbase/services/embedding/async_processor.py +244 -0
  118. django_cfg/apps/knowbase/services/embedding/batch_processor.py +250 -0
  119. django_cfg/apps/knowbase/services/embedding/batch_result.py +61 -0
  120. django_cfg/apps/knowbase/services/embedding/models.py +229 -0
  121. django_cfg/apps/knowbase/services/embedding/processors.py +148 -0
  122. django_cfg/apps/knowbase/services/embedding/utils.py +176 -0
  123. django_cfg/apps/knowbase/services/prompt_builder.py +191 -0
  124. django_cfg/apps/knowbase/services/search_service.py +293 -0
  125. django_cfg/apps/knowbase/signals/__init__.py +21 -0
  126. django_cfg/apps/knowbase/signals/archive_signals.py +211 -0
  127. django_cfg/apps/knowbase/signals/chat_signals.py +37 -0
  128. django_cfg/apps/knowbase/signals/document_signals.py +143 -0
  129. django_cfg/apps/knowbase/signals/external_data_signals.py +157 -0
  130. django_cfg/apps/knowbase/tasks/__init__.py +39 -0
  131. django_cfg/apps/knowbase/tasks/archive_tasks.py +316 -0
  132. django_cfg/apps/knowbase/tasks/document_processing.py +341 -0
  133. django_cfg/apps/knowbase/tasks/external_data_tasks.py +341 -0
  134. django_cfg/apps/knowbase/tasks/maintenance.py +195 -0
  135. django_cfg/apps/knowbase/urls.py +43 -0
  136. django_cfg/apps/knowbase/utils/__init__.py +12 -0
  137. django_cfg/apps/knowbase/utils/chunk_settings.py +261 -0
  138. django_cfg/apps/knowbase/utils/text_processing.py +375 -0
  139. django_cfg/apps/knowbase/utils/validation.py +99 -0
  140. django_cfg/apps/knowbase/views/__init__.py +28 -0
  141. django_cfg/apps/knowbase/views/archive_views.py +469 -0
  142. django_cfg/apps/knowbase/views/base.py +49 -0
  143. django_cfg/apps/knowbase/views/chat_views.py +181 -0
  144. django_cfg/apps/knowbase/views/document_views.py +183 -0
  145. django_cfg/apps/knowbase/views/public_views.py +129 -0
  146. django_cfg/apps/leads/admin.py +70 -0
  147. django_cfg/apps/newsletter/admin.py +234 -0
  148. django_cfg/apps/newsletter/admin_filters.py +124 -0
  149. django_cfg/apps/support/admin.py +196 -0
  150. django_cfg/apps/support/admin_filters.py +71 -0
  151. django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
  152. django_cfg/apps/urls.py +5 -4
  153. django_cfg/cli/README.md +1 -1
  154. django_cfg/cli/commands/create_project.py +2 -2
  155. django_cfg/cli/commands/info.py +1 -1
  156. django_cfg/config.py +44 -0
  157. django_cfg/core/config.py +29 -82
  158. django_cfg/core/environment.py +1 -1
  159. django_cfg/core/generation.py +19 -107
  160. django_cfg/{integration.py → core/integration.py} +18 -16
  161. django_cfg/core/validation.py +1 -1
  162. django_cfg/management/__init__.py +1 -1
  163. django_cfg/management/commands/__init__.py +1 -1
  164. django_cfg/management/commands/auto_generate.py +482 -0
  165. django_cfg/management/commands/migrator.py +19 -101
  166. django_cfg/management/commands/test_email.py +1 -1
  167. django_cfg/middleware/README.md +0 -158
  168. django_cfg/middleware/__init__.py +0 -2
  169. django_cfg/middleware/user_activity.py +3 -3
  170. django_cfg/models/api.py +145 -0
  171. django_cfg/models/base.py +287 -0
  172. django_cfg/models/cache.py +4 -4
  173. django_cfg/models/constance.py +25 -88
  174. django_cfg/models/database.py +9 -9
  175. django_cfg/models/drf.py +3 -36
  176. django_cfg/models/email.py +163 -0
  177. django_cfg/models/environment.py +276 -0
  178. django_cfg/models/limits.py +1 -1
  179. django_cfg/models/logging.py +366 -0
  180. django_cfg/models/revolution.py +41 -2
  181. django_cfg/models/security.py +125 -0
  182. django_cfg/models/services.py +1 -1
  183. django_cfg/modules/__init__.py +2 -56
  184. django_cfg/modules/base.py +78 -52
  185. django_cfg/modules/django_currency/service.py +2 -2
  186. django_cfg/modules/django_email.py +2 -2
  187. django_cfg/modules/django_health.py +267 -0
  188. django_cfg/modules/django_llm/llm/client.py +91 -19
  189. django_cfg/modules/django_llm/translator/translator.py +2 -2
  190. django_cfg/modules/django_logger.py +2 -2
  191. django_cfg/modules/django_ngrok.py +2 -2
  192. django_cfg/modules/django_tasks.py +68 -3
  193. django_cfg/modules/django_telegram.py +3 -3
  194. django_cfg/modules/django_twilio/sendgrid_service.py +2 -2
  195. django_cfg/modules/django_twilio/service.py +2 -2
  196. django_cfg/modules/django_twilio/simple_service.py +2 -2
  197. django_cfg/modules/django_twilio/twilio_service.py +2 -2
  198. django_cfg/modules/django_unfold/__init__.py +69 -0
  199. django_cfg/modules/{unfold → django_unfold}/callbacks.py +23 -22
  200. django_cfg/modules/django_unfold/dashboard.py +278 -0
  201. django_cfg/modules/django_unfold/icons/README.md +145 -0
  202. django_cfg/modules/django_unfold/icons/__init__.py +12 -0
  203. django_cfg/modules/django_unfold/icons/constants.py +2851 -0
  204. django_cfg/modules/django_unfold/icons/generate_icons.py +486 -0
  205. django_cfg/modules/django_unfold/models/__init__.py +42 -0
  206. django_cfg/modules/django_unfold/models/config.py +601 -0
  207. django_cfg/modules/django_unfold/models/dashboard.py +206 -0
  208. django_cfg/modules/django_unfold/models/dropdown.py +40 -0
  209. django_cfg/modules/django_unfold/models/navigation.py +73 -0
  210. django_cfg/modules/django_unfold/models/tabs.py +25 -0
  211. django_cfg/modules/{unfold → django_unfold}/system_monitor.py +2 -2
  212. django_cfg/modules/django_unfold/utils.py +140 -0
  213. django_cfg/registry/__init__.py +23 -0
  214. django_cfg/registry/core.py +61 -0
  215. django_cfg/registry/exceptions.py +11 -0
  216. django_cfg/registry/modules.py +12 -0
  217. django_cfg/registry/services.py +26 -0
  218. django_cfg/registry/third_party.py +52 -0
  219. django_cfg/routing/__init__.py +19 -0
  220. django_cfg/routing/callbacks.py +198 -0
  221. django_cfg/routing/routers.py +48 -0
  222. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +8 -9
  223. django_cfg/templatetags/__init__.py +0 -0
  224. django_cfg/templatetags/django_cfg.py +33 -0
  225. django_cfg/urls.py +33 -0
  226. django_cfg/utils/path_resolution.py +1 -1
  227. django_cfg/utils/smart_defaults.py +7 -61
  228. django_cfg/utils/toolkit.py +663 -0
  229. {django_cfg-1.1.82.dist-info → django_cfg-1.2.1.dist-info}/METADATA +83 -86
  230. django_cfg-1.2.1.dist-info/RECORD +441 -0
  231. django_cfg/archive/django_sample.zip +0 -0
  232. django_cfg/models/unfold.py +0 -271
  233. django_cfg/modules/unfold/__init__.py +0 -29
  234. django_cfg/modules/unfold/dashboard.py +0 -318
  235. django_cfg/pyproject.toml +0 -370
  236. django_cfg/routers.py +0 -83
  237. django_cfg-1.1.82.dist-info/RECORD +0 -278
  238. /django_cfg/{exceptions.py → core/exceptions.py} +0 -0
  239. /django_cfg/modules/{unfold → django_unfold}/models.py +0 -0
  240. /django_cfg/modules/{unfold → django_unfold}/tailwind.py +0 -0
  241. /django_cfg/{version_check.py → utils/version_check.py} +0 -0
  242. {django_cfg-1.1.82.dist-info → django_cfg-1.2.1.dist-info}/WHEEL +0 -0
  243. {django_cfg-1.1.82.dist-info → django_cfg-1.2.1.dist-info}/entry_points.txt +0 -0
  244. {django_cfg-1.1.82.dist-info → django_cfg-1.2.1.dist-info}/licenses/LICENSE +0 -0
@@ -83,13 +83,16 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
83
83
 
84
84
  # Add default django-cfg zones if enabled
85
85
  try:
86
- from django_cfg.modules.base import BaseModule
87
- base_module = BaseModule()
86
+ from django_cfg.modules.base import BaseCfgModule
87
+ base_module = BaseCfgModule()
88
88
 
89
89
  support_enabled = base_module.is_support_enabled()
90
90
  accounts_enabled = base_module.is_accounts_enabled()
91
91
  newsletter_enabled = base_module.is_newsletter_enabled()
92
92
  leads_enabled = base_module.is_leads_enabled()
93
+ knowbase_enabled = base_module.is_knowbase_enabled()
94
+ agents_enabled = base_module.is_agents_enabled()
95
+ tasks_enabled = base_module.is_tasks_enabled()
93
96
 
94
97
  # Add Support zone if enabled
95
98
  default_support_zone = 'cfg_support'
@@ -138,6 +141,42 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
138
141
  auth_required=False,
139
142
  version="v1",
140
143
  )
144
+
145
+ # Add Knowbase zone if enabled
146
+ default_knowbase_zone = 'cfg_knowbase'
147
+ if knowbase_enabled and default_knowbase_zone not in zones:
148
+ zones[default_knowbase_zone] = ZoneConfig(
149
+ apps=["django_cfg.apps.knowbase"],
150
+ title="Knowbase API",
151
+ description="Knowledge base, AI chat, embeddings, and search API",
152
+ public=False,
153
+ auth_required=True,
154
+ version="v1",
155
+ )
156
+
157
+ # Add Agents zone if enabled
158
+ default_agents_zone = 'cfg_agents'
159
+ if agents_enabled and default_agents_zone not in zones:
160
+ zones[default_agents_zone] = ZoneConfig(
161
+ apps=["django_cfg.apps.agents"],
162
+ title="Agents API",
163
+ description="Agent definitions, executions, workflows, and tools API",
164
+ public=False,
165
+ auth_required=True,
166
+ version="v1",
167
+ )
168
+
169
+ # Add Tasks zone if enabled
170
+ default_tasks_zone = 'cfg_tasks'
171
+ if tasks_enabled and default_tasks_zone not in zones:
172
+ zones[default_tasks_zone] = ZoneConfig(
173
+ apps=["django_cfg.apps.tasks"],
174
+ title="Tasks API",
175
+ description="Tasks, workflows, and automation API",
176
+ public=False,
177
+ auth_required=True,
178
+ version="v1",
179
+ )
141
180
  except Exception:
142
181
  pass
143
182
 
@@ -0,0 +1,125 @@
1
+ """
2
+ Security Configuration Model
3
+
4
+ Django security settings with Pydantic 2.
5
+ """
6
+
7
+ from typing import List, Dict, Any
8
+ from pydantic import Field, field_validator
9
+ from .base import BaseConfig
10
+
11
+
12
+ class SecurityConfig(BaseConfig):
13
+ """
14
+ 🔒 Security Configuration - Django security settings
15
+
16
+ Handles CORS, CSRF, SSL, sessions, and other security configurations
17
+ with environment-aware defaults.
18
+ """
19
+
20
+ # CORS settings
21
+ cors_enabled: bool = Field(default=True, description="Enable CORS support")
22
+ cors_allow_all_origins: bool = Field(default=False, description="Allow all origins (dev only)")
23
+ cors_allowed_origins: List[str] = Field(default_factory=list, description="Allowed CORS origins")
24
+ cors_allow_credentials: bool = Field(default=True, description="Allow CORS credentials")
25
+
26
+ # CSRF settings
27
+ csrf_enabled: bool = Field(default=True, description="Enable CSRF protection")
28
+ csrf_trusted_origins: List[str] = Field(default_factory=list, description="CSRF trusted origins")
29
+ csrf_cookie_secure: bool = Field(default=False, description="Secure CSRF cookies")
30
+
31
+ # SSL/HTTPS settings
32
+ ssl_redirect: bool = Field(default=False, description="Redirect HTTP to HTTPS")
33
+ hsts_enabled: bool = Field(default=False, description="Enable HTTP Strict Transport Security")
34
+ hsts_max_age: int = Field(default=31536000, description="HSTS max age in seconds")
35
+
36
+ # Session settings
37
+ session_cookie_secure: bool = Field(default=False, description="Secure session cookies")
38
+ session_cookie_age: int = Field(default=86400, description="Session cookie age in seconds")
39
+
40
+ # Production domains for auto-configuration
41
+ production_domains: List[str] = Field(
42
+ default_factory=lambda: [
43
+ "https://carapis.com",
44
+ "https://api2.carapis.com",
45
+ "https://djangocfg.com",
46
+ ],
47
+ description="Production domains for security configuration"
48
+ )
49
+
50
+ @field_validator('hsts_max_age')
51
+ @classmethod
52
+ def validate_hsts_max_age(cls, v: int) -> int:
53
+ """Validate HSTS max age."""
54
+ if v < 0:
55
+ raise ValueError("HSTS max age must be non-negative")
56
+ return v
57
+
58
+ def configure_for_production(self) -> None:
59
+ """Configure security settings for production."""
60
+ self.cors_allow_all_origins = False
61
+ self.cors_allowed_origins = self.production_domains
62
+ self.csrf_cookie_secure = True
63
+ self.csrf_trusted_origins = self.production_domains
64
+ self.ssl_redirect = True
65
+ self.hsts_enabled = True
66
+ self.session_cookie_secure = True
67
+
68
+ def configure_for_development(self) -> None:
69
+ """Configure security settings for development."""
70
+ self.cors_allow_all_origins = True
71
+ self.cors_allowed_origins = []
72
+ self.csrf_cookie_secure = False
73
+ self.csrf_trusted_origins = []
74
+ self.ssl_redirect = False
75
+ self.hsts_enabled = False
76
+ self.session_cookie_secure = False
77
+
78
+ def to_django_settings(self) -> Dict[str, Any]:
79
+ """Convert to Django security settings."""
80
+ settings = {}
81
+
82
+ # CORS settings
83
+ if self.cors_enabled:
84
+ settings.update({
85
+ 'CORS_ALLOW_ALL_ORIGINS': self.cors_allow_all_origins,
86
+ 'CORS_ALLOWED_ORIGINS': self.cors_allowed_origins,
87
+ 'CORS_ALLOW_CREDENTIALS': self.cors_allow_credentials,
88
+ })
89
+
90
+ # Add corsheaders to middleware if not present
91
+ # This will be handled by the main ConfigToolkit
92
+
93
+ # CSRF settings
94
+ settings.update({
95
+ 'CSRF_TRUSTED_ORIGINS': self.csrf_trusted_origins,
96
+ 'CSRF_COOKIE_SECURE': self.csrf_cookie_secure,
97
+ })
98
+
99
+ # SSL/HTTPS settings
100
+ if self.ssl_redirect:
101
+ settings['SECURE_SSL_REDIRECT'] = True
102
+
103
+ if self.hsts_enabled:
104
+ settings.update({
105
+ 'SECURE_HSTS_SECONDS': self.hsts_max_age,
106
+ 'SECURE_HSTS_INCLUDE_SUBDOMAINS': True,
107
+ 'SECURE_HSTS_PRELOAD': True,
108
+ })
109
+
110
+ # Session settings
111
+ settings.update({
112
+ 'SESSION_COOKIE_SECURE': self.session_cookie_secure,
113
+ 'SESSION_COOKIE_AGE': self.session_cookie_age,
114
+ 'SESSION_COOKIE_HTTPONLY': True,
115
+ 'SESSION_COOKIE_SAMESITE': 'Lax',
116
+ })
117
+
118
+ # Additional security headers
119
+ settings.update({
120
+ 'SECURE_CONTENT_TYPE_NOSNIFF': True,
121
+ 'SECURE_BROWSER_XSS_FILTER': True,
122
+ 'X_FRAME_OPTIONS': 'DENY',
123
+ })
124
+
125
+ return settings
@@ -12,7 +12,7 @@ from typing import Dict, Optional, Any, Literal, List
12
12
  from pydantic import BaseModel, Field, field_validator, model_validator, EmailStr
13
13
  from pathlib import Path
14
14
 
15
- from django_cfg.exceptions import ConfigurationError, ValidationError
15
+ from django_cfg.core.exceptions import ConfigurationError, ValidationError
16
16
 
17
17
 
18
18
  class EmailConfig(BaseModel):
@@ -6,61 +6,7 @@ All modules automatically receive configuration from the DjangoConfig instance
6
6
  without requiring manual parameter passing.
7
7
  """
8
8
 
9
- from typing import TYPE_CHECKING, Optional, Any
10
- import importlib
11
- import os
12
-
13
- if TYPE_CHECKING:
14
- from django_cfg.core.config import DjangoConfig
15
-
16
-
17
- class BaseModule:
18
- """
19
- Base class for auto-configuring django_cfg modules.
20
-
21
- All modules inherit from this to automatically receive
22
- configuration from the DjangoConfig instance.
23
- """
24
-
25
- _config_instance: Optional["DjangoConfig"] = None
26
-
27
- @classmethod
28
- def get_config(cls) -> "DjangoConfig":
29
- """Get the DjangoConfig instance automatically."""
30
- if cls._config_instance is None:
31
- cls._config_instance = cls._discover_config()
32
- return cls._config_instance
33
-
34
- @classmethod
35
- def _discover_config(cls) -> "DjangoConfig":
36
- """Discover the DjangoConfig instance from Django settings."""
37
- try:
38
- # Try to get config from Django settings module
39
- settings_module = os.environ.get("DJANGO_SETTINGS_MODULE")
40
- if settings_module:
41
- settings_mod = importlib.import_module(settings_module)
42
- if hasattr(settings_mod, "config"):
43
- return settings_mod.config
44
-
45
- # Fallback: try to create minimal config from Django settings
46
- from django.conf import settings
47
- from django_cfg import DjangoConfig
48
-
49
- return DjangoConfig(
50
- project_name=getattr(settings, "PROJECT_NAME", "Django Project"),
51
- secret_key=settings.SECRET_KEY,
52
- debug=settings.DEBUG,
53
- allowed_hosts=settings.ALLOWED_HOSTS,
54
- )
55
-
56
- except Exception as e:
57
- raise RuntimeError(f"Could not discover DjangoConfig instance: {e}")
58
-
59
- @classmethod
60
- def reset_config(cls):
61
- """Reset the cached config instance (useful for testing)."""
62
- cls._config_instance = None
63
-
9
+ from .base import BaseCfgModule
64
10
 
65
11
  # Export the base module
66
- __all__ = ["BaseModule"]
12
+ __all__ = ["BaseCfgModule"]
@@ -4,56 +4,69 @@ Base Module for Django CFG
4
4
  Provides base functionality for all auto-configuring modules.
5
5
  """
6
6
 
7
- from typing import Any, Optional
7
+ from typing import Any, Optional, TYPE_CHECKING
8
8
  from abc import ABC
9
+ import importlib
10
+ import os
9
11
 
12
+ if TYPE_CHECKING:
13
+ from django_cfg.core.config import DjangoConfig
10
14
 
11
- class BaseModule(ABC):
15
+
16
+ class BaseCfgModule(ABC):
12
17
  """
13
18
  Base class for all django_cfg modules.
14
19
 
15
20
  Provides common functionality and configuration access.
21
+ Auto-discovers configuration from Django settings.
16
22
  """
17
23
 
24
+ _config_instance: Optional["DjangoConfig"] = None
25
+
18
26
  def __init__(self):
19
27
  """Initialize the base module."""
20
28
  self._config = None
21
29
 
22
- def get_config(self) -> Optional[Any]:
23
- """
24
- Get the current Django configuration instance.
25
-
26
- Returns:
27
- The current DjangoConfig instance or None
28
- """
29
- if self._config is None:
30
+ @classmethod
31
+ def get_config(cls) -> Optional["DjangoConfig"]:
32
+ """Get the DjangoConfig instance automatically."""
33
+ if cls._config_instance is None:
30
34
  try:
31
- # Try to get config from the current context first
32
- from django_cfg.core.config import get_current_config
33
- self._config = get_current_config()
34
-
35
- # If that fails, try to import directly from Django settings
36
- if self._config is None:
37
- try:
38
- from django.conf import settings
39
- if hasattr(settings, 'DJANGO_SETTINGS_MODULE'):
40
- # Import the config module directly
41
- import importlib
42
- settings_module_name = settings.DJANGO_SETTINGS_MODULE
43
- if settings_module_name:
44
- # Get the config module (usually api.config)
45
- config_module_name = settings_module_name.replace('.settings', '.config')
46
- config_module = importlib.import_module(config_module_name)
47
- if hasattr(config_module, 'config'):
48
- self._config = config_module.config
49
- except Exception:
50
- pass
51
-
52
- except (ImportError, AttributeError):
53
- # Fallback - config might not be available yet
54
- pass
55
-
56
- return self._config
35
+ cls._config_instance = cls._discover_config()
36
+ except Exception:
37
+ # Return None if config discovery fails (e.g., during Django startup)
38
+ return None
39
+ return cls._config_instance
40
+
41
+ @classmethod
42
+ def _discover_config(cls) -> "DjangoConfig":
43
+ """Discover the DjangoConfig instance from Django settings."""
44
+ try:
45
+ # Try to get config from Django settings module
46
+ settings_module = os.environ.get("DJANGO_SETTINGS_MODULE")
47
+ if settings_module:
48
+ settings_mod = importlib.import_module(settings_module)
49
+ if hasattr(settings_mod, "config"):
50
+ return settings_mod.config
51
+
52
+ # Fallback: try to create minimal config from Django settings
53
+ from django.conf import settings
54
+ from django_cfg.core.config import DjangoConfig
55
+
56
+ return DjangoConfig(
57
+ project_name=getattr(settings, "PROJECT_NAME", "Django Project"),
58
+ secret_key=settings.SECRET_KEY,
59
+ debug=settings.DEBUG,
60
+ allowed_hosts=settings.ALLOWED_HOSTS,
61
+ )
62
+
63
+ except Exception as e:
64
+ raise RuntimeError(f"Could not discover DjangoConfig instance: {e}")
65
+
66
+ @classmethod
67
+ def reset_config(cls):
68
+ """Reset the cached config instance (useful for testing)."""
69
+ cls._config_instance = None
57
70
 
58
71
  def set_config(self, config: Any) -> None:
59
72
  """
@@ -73,13 +86,12 @@ class BaseModule(ABC):
73
86
  default: The default value to return if the key is not found
74
87
  """
75
88
  try:
76
- # Try to get config if not already set
77
- if self._config is None:
78
- self._config = self.get_config()
89
+ # Get config using class method
90
+ config = self.get_config()
79
91
 
80
92
  # If config is available, get the key
81
- if self._config is not None:
82
- result = getattr(self._config, key, default)
93
+ if config is not None:
94
+ result = getattr(config, key, default)
83
95
  return bool(result)
84
96
 
85
97
  # Fallback to default if no config available
@@ -125,25 +137,39 @@ class BaseModule(ABC):
125
137
  """
126
138
  return self._get_config_key('enable_leads', False)
127
139
 
140
+ def is_agents_enabled(self) -> bool:
141
+ """
142
+ Check if django-cfg Agents is enabled.
143
+
144
+ Returns:
145
+ True if Agents is enabled, False otherwise
146
+ """
147
+ return self._get_config_key('enable_agents', False)
148
+
149
+ def is_knowbase_enabled(self) -> bool:
150
+ """
151
+ Check if django-cfg Knowbase is enabled.
152
+
153
+ Returns:
154
+ True if Knowbase is enabled, False otherwise
155
+ """
156
+ return self._get_config_key('enable_knowbase', False)
157
+
128
158
  def is_tasks_enabled(self) -> bool:
129
159
  """
130
- Check if django-cfg Tasks (Dramatiq) is enabled.
160
+ Check if django-cfg Tasks is enabled.
161
+ Auto-enables if knowbase or agents are enabled.
131
162
 
132
163
  Returns:
133
164
  True if Tasks is enabled, False otherwise
134
165
  """
135
- try:
136
- config = self.get_config()
137
- if config is not None and hasattr(config, 'tasks'):
138
- tasks_config = getattr(config, 'tasks', None)
139
- if tasks_config is not None:
140
- return getattr(tasks_config, 'enabled', False)
141
- return False
142
- except Exception:
143
- return False
166
+ # Auto-enable if knowbase or agents are enabled
167
+ if self.is_knowbase_enabled() or self.is_agents_enabled():
168
+ return True
169
+ return self._get_config_key('enable_tasks', False)
144
170
 
145
171
 
146
172
  # Export the base class
147
173
  __all__ = [
148
- "BaseModule",
174
+ "BaseCfgModule",
149
175
  ]
@@ -9,7 +9,7 @@ from typing import Optional, Dict, Any, Union, List
9
9
  from datetime import datetime, date
10
10
  from pathlib import Path
11
11
 
12
- from django_cfg.modules import BaseModule
12
+ from django_cfg.modules import BaseCfgModule
13
13
  from .converter import CurrencyConverter
14
14
  from .cache import CurrencyCache
15
15
 
@@ -31,7 +31,7 @@ class CurrencyConversionError(CurrencyError):
31
31
  pass
32
32
 
33
33
 
34
- class DjangoCurrency(BaseModule):
34
+ class DjangoCurrency(BaseCfgModule):
35
35
  """
36
36
  Currency Service for django_cfg, configured via DjangoConfig.
37
37
 
@@ -11,10 +11,10 @@ from django.template.loader import render_to_string
11
11
  from django.utils.html import strip_tags
12
12
  from django.conf import settings
13
13
 
14
- from . import BaseModule
14
+ from . import BaseCfgModule
15
15
 
16
16
 
17
- class DjangoEmailService(BaseModule):
17
+ class DjangoEmailService(BaseCfgModule):
18
18
  """
19
19
  Auto-configuring email service that gets settings from DjangoConfig.
20
20