django-cfg 1.4.6__py3-none-any.whl → 1.4.8__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/apps/payments/views/api/api_keys.py +8 -8
- django_cfg/apps/payments/views/serializers/__init__.py +2 -2
- django_cfg/apps/payments/views/serializers/api_keys.py +11 -21
- django_cfg/cli/commands/create_project.py +30 -19
- django_cfg/models/django/revolution.py +26 -13
- django_cfg/pyproject.toml +6 -2
- {django_cfg-1.4.6.dist-info → django_cfg-1.4.8.dist-info}/METADATA +2 -2
- {django_cfg-1.4.6.dist-info → django_cfg-1.4.8.dist-info}/RECORD +11 -11
- {django_cfg-1.4.6.dist-info → django_cfg-1.4.8.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.6.dist-info → django_cfg-1.4.8.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.6.dist-info → django_cfg-1.4.8.dist-info}/licenses/LICENSE +0 -0
@@ -16,7 +16,7 @@ from drf_spectacular.utils import extend_schema, extend_schema_view
|
|
16
16
|
from .base import PaymentBaseViewSet, NestedPaymentViewSet, ReadOnlyPaymentViewSet
|
17
17
|
from ...models import APIKey
|
18
18
|
from ..serializers.api_keys import (
|
19
|
-
|
19
|
+
APIKeyDetailSerializer,
|
20
20
|
APIKeyCreateSerializer,
|
21
21
|
APIKeyListSerializer,
|
22
22
|
APIKeyUpdateSerializer,
|
@@ -39,16 +39,16 @@ class APIKeyViewSet(PaymentBaseViewSet):
|
|
39
39
|
"""
|
40
40
|
|
41
41
|
queryset = APIKey.objects.all()
|
42
|
-
serializer_class =
|
42
|
+
serializer_class = APIKeyDetailSerializer
|
43
43
|
permission_classes = [permissions.IsAdminUser] # Admin only for global access
|
44
44
|
filterset_fields = ['is_active', 'user']
|
45
45
|
search_fields = ['name', 'user__username', 'user__email']
|
46
46
|
ordering_fields = ['created_at', 'updated_at', 'last_used_at', 'expires_at', 'total_requests']
|
47
|
-
|
47
|
+
|
48
48
|
serializer_classes = {
|
49
49
|
'list': APIKeyListSerializer,
|
50
50
|
'create': APIKeyCreateSerializer,
|
51
|
-
'retrieve':
|
51
|
+
'retrieve': APIKeyDetailSerializer,
|
52
52
|
'update': APIKeyUpdateSerializer,
|
53
53
|
'partial_update': APIKeyUpdateSerializer,
|
54
54
|
}
|
@@ -209,20 +209,20 @@ class UserAPIKeyViewSet(NestedPaymentViewSet):
|
|
209
209
|
"""
|
210
210
|
|
211
211
|
queryset = APIKey.objects.all()
|
212
|
-
serializer_class =
|
212
|
+
serializer_class = APIKeyDetailSerializer
|
213
213
|
permission_classes = [permissions.IsAuthenticated]
|
214
214
|
filterset_fields = ['is_active']
|
215
215
|
search_fields = ['name']
|
216
216
|
ordering_fields = ['created_at', 'updated_at', 'last_used_at', 'expires_at']
|
217
|
-
|
217
|
+
|
218
218
|
# Nested ViewSet configuration
|
219
219
|
parent_lookup_field = 'user_pk'
|
220
220
|
parent_model_field = 'user'
|
221
|
-
|
221
|
+
|
222
222
|
serializer_classes = {
|
223
223
|
'list': APIKeyListSerializer,
|
224
224
|
'create': APIKeyCreateSerializer,
|
225
|
-
'retrieve':
|
225
|
+
'retrieve': APIKeyDetailSerializer,
|
226
226
|
'update': APIKeyUpdateSerializer,
|
227
227
|
'partial_update': APIKeyUpdateSerializer,
|
228
228
|
}
|
@@ -41,7 +41,7 @@ from .currencies import (
|
|
41
41
|
|
42
42
|
# API Key serializers
|
43
43
|
from .api_keys import (
|
44
|
-
|
44
|
+
APIKeyDetailSerializer,
|
45
45
|
APIKeyCreateSerializer,
|
46
46
|
APIKeyListSerializer,
|
47
47
|
APIKeyUpdateSerializer,
|
@@ -85,7 +85,7 @@ __all__ = [
|
|
85
85
|
'CurrencyConversionSerializer',
|
86
86
|
|
87
87
|
# API Key serializers
|
88
|
-
'
|
88
|
+
'APIKeyDetailSerializer',
|
89
89
|
'APIKeyCreateSerializer',
|
90
90
|
'APIKeyListSerializer',
|
91
91
|
'APIKeyUpdateSerializer',
|
@@ -7,6 +7,7 @@ DRF serializers for API key operations with service integration.
|
|
7
7
|
from rest_framework import serializers
|
8
8
|
from typing import Dict, Any
|
9
9
|
from django.contrib.auth import get_user_model
|
10
|
+
from drf_spectacular.utils import extend_schema_serializer, extend_schema_field, OpenApiTypes
|
10
11
|
|
11
12
|
from ...models import APIKey
|
12
13
|
from django_cfg.modules.django_logging import get_logger
|
@@ -43,19 +44,19 @@ class APIKeyListSerializer(serializers.ModelSerializer):
|
|
43
44
|
read_only_fields = fields
|
44
45
|
|
45
46
|
|
46
|
-
class
|
47
|
+
class APIKeyDetailSerializer(serializers.ModelSerializer):
|
47
48
|
"""
|
48
49
|
Complete API key serializer with full details.
|
49
|
-
|
50
|
+
|
50
51
|
Used for API key detail views (no key value for security).
|
51
52
|
"""
|
52
|
-
|
53
|
+
|
53
54
|
user = serializers.StringRelatedField(read_only=True)
|
54
55
|
key_preview = serializers.CharField(read_only=True)
|
55
56
|
is_expired = serializers.BooleanField(read_only=True)
|
56
57
|
is_valid = serializers.BooleanField(read_only=True)
|
57
58
|
days_until_expiry = serializers.IntegerField(read_only=True)
|
58
|
-
|
59
|
+
|
59
60
|
class Meta:
|
60
61
|
model = APIKey
|
61
62
|
fields = [
|
@@ -73,18 +74,7 @@ class APIKeySerializer(serializers.ModelSerializer):
|
|
73
74
|
'created_at',
|
74
75
|
'updated_at',
|
75
76
|
]
|
76
|
-
read_only_fields =
|
77
|
-
'id',
|
78
|
-
'user',
|
79
|
-
'key_preview',
|
80
|
-
'is_expired',
|
81
|
-
'is_valid',
|
82
|
-
'days_until_expiry',
|
83
|
-
'total_requests',
|
84
|
-
'last_used_at',
|
85
|
-
'created_at',
|
86
|
-
'updated_at',
|
87
|
-
]
|
77
|
+
read_only_fields = fields # All fields are read-only to prevent TypeScript split
|
88
78
|
|
89
79
|
|
90
80
|
class APIKeyCreateSerializer(serializers.Serializer):
|
@@ -153,7 +143,7 @@ class APIKeyCreateSerializer(serializers.Serializer):
|
|
153
143
|
|
154
144
|
def to_representation(self, instance: APIKey) -> Dict[str, Any]:
|
155
145
|
"""Return API key data with full key value (only on creation)."""
|
156
|
-
data =
|
146
|
+
data = APIKeyDetailSerializer(instance, context=self.context).data
|
157
147
|
|
158
148
|
# Add full key value only on creation (security: shown only once)
|
159
149
|
data['key'] = instance.key
|
@@ -288,7 +278,7 @@ class APIKeyActionSerializer(serializers.Serializer):
|
|
288
278
|
return {
|
289
279
|
'success': True,
|
290
280
|
'message': message,
|
291
|
-
'api_key':
|
281
|
+
'api_key': APIKeyDetailSerializer(api_key, context=self.context).data
|
292
282
|
}
|
293
283
|
else:
|
294
284
|
return {
|
@@ -341,7 +331,7 @@ class APIKeyValidationSerializer(serializers.Serializer):
|
|
341
331
|
return {
|
342
332
|
'success': True,
|
343
333
|
'valid': True,
|
344
|
-
'api_key':
|
334
|
+
'api_key': APIKeyDetailSerializer(api_key, context=self.context).data,
|
345
335
|
'message': 'API key is valid'
|
346
336
|
}
|
347
337
|
else:
|
@@ -364,12 +354,12 @@ class APIKeyValidationSerializer(serializers.Serializer):
|
|
364
354
|
class APIKeyValidationResponseSerializer(serializers.Serializer):
|
365
355
|
"""
|
366
356
|
API key validation response serializer.
|
367
|
-
|
357
|
+
|
368
358
|
Defines the structure of API key validation response for OpenAPI schema.
|
369
359
|
"""
|
370
360
|
success = serializers.BooleanField(help_text="Whether the validation was successful")
|
371
361
|
valid = serializers.BooleanField(help_text="Whether the API key is valid")
|
372
|
-
api_key =
|
362
|
+
api_key = APIKeyDetailSerializer(allow_null=True, read_only=True, required=False, help_text="API key details if valid")
|
373
363
|
message = serializers.CharField(help_text="Validation message")
|
374
364
|
error = serializers.CharField(required=False, help_text="Error message if validation failed")
|
375
365
|
error_code = serializers.CharField(required=False, help_text="Error code if validation failed")
|
@@ -63,27 +63,31 @@ def extract_template(archive_path: Path, target_path: Path) -> None:
|
|
63
63
|
if not root_folder:
|
64
64
|
raise ValueError("Archive structure is invalid")
|
65
65
|
|
66
|
-
# Path to
|
67
|
-
|
66
|
+
# Path to examples directory: django-cfg-main/examples/
|
67
|
+
examples_prefix = f"{root_folder}/examples/"
|
68
68
|
|
69
|
-
# Extract
|
69
|
+
# Extract files from examples/ folder (preserving django/ and docker/ subdirectories)
|
70
70
|
extracted_files = 0
|
71
71
|
for member in members:
|
72
|
-
# Skip if not in
|
73
|
-
if not member.startswith(
|
72
|
+
# Skip if not in examples path
|
73
|
+
if not member.startswith(examples_prefix):
|
74
74
|
continue
|
75
75
|
|
76
|
-
#
|
77
|
-
|
78
|
-
continue
|
79
|
-
|
80
|
-
# Calculate relative path (remove template_prefix)
|
81
|
-
relative_path = member[len(template_prefix):]
|
76
|
+
# Calculate relative path (remove examples_prefix, keep django/ and docker/)
|
77
|
+
relative_path = member[len(examples_prefix):]
|
82
78
|
|
83
79
|
# Skip empty paths (directory markers)
|
84
80
|
if not relative_path:
|
85
81
|
continue
|
86
82
|
|
83
|
+
# Skip docker volumes directory
|
84
|
+
if relative_path.startswith("docker/volumes/"):
|
85
|
+
continue
|
86
|
+
|
87
|
+
# Skip .gitignore files
|
88
|
+
if relative_path.endswith(".gitignore"):
|
89
|
+
continue
|
90
|
+
|
87
91
|
# Target file path
|
88
92
|
target_file = target_path / relative_path
|
89
93
|
|
@@ -142,16 +146,20 @@ def create_project(path: str, force: bool):
|
|
142
146
|
django-cfg create-project --force
|
143
147
|
"""
|
144
148
|
|
145
|
-
# Determine
|
146
|
-
|
149
|
+
# Determine parent path and project folder name
|
150
|
+
parent_path = Path(path).resolve()
|
147
151
|
|
148
|
-
#
|
149
|
-
|
152
|
+
# Create django-project folder inside the specified path
|
153
|
+
target_path = parent_path / "django-project"
|
154
|
+
|
155
|
+
# Check if django-project directory already exists
|
156
|
+
if target_path.exists():
|
150
157
|
if not force:
|
151
|
-
click.echo(f"❌ Directory '{target_path}'
|
158
|
+
click.echo(f"❌ Directory '{target_path}' already exists. Use --force to overwrite.", err=True)
|
152
159
|
return
|
153
160
|
else:
|
154
|
-
click.echo(f"⚠️ Directory
|
161
|
+
click.echo(f"⚠️ Directory '{target_path}' exists and will be overwritten...")
|
162
|
+
shutil.rmtree(target_path)
|
155
163
|
|
156
164
|
temp_archive = None
|
157
165
|
|
@@ -176,12 +184,15 @@ def create_project(path: str, force: bool):
|
|
176
184
|
# Show next steps
|
177
185
|
click.echo()
|
178
186
|
click.echo("📋 Next steps:")
|
179
|
-
|
180
|
-
click.echo(f" cd {target_path}")
|
187
|
+
click.echo(f" cd {target_path}/django")
|
181
188
|
click.echo(" poetry install # or: pip install -r requirements.txt")
|
182
189
|
click.echo(" python manage.py migrate")
|
183
190
|
click.echo(" python manage.py createsuperuser")
|
184
191
|
click.echo(" python manage.py runserver")
|
192
|
+
click.echo()
|
193
|
+
click.echo("🐳 Docker deployment:")
|
194
|
+
click.echo(f" cd {target_path}/docker")
|
195
|
+
click.echo(" docker-compose up -d")
|
185
196
|
|
186
197
|
click.echo()
|
187
198
|
click.echo("💡 Features included:")
|
@@ -3,6 +3,19 @@ Django Revolution Configuration with DRF Integration
|
|
3
3
|
|
4
4
|
Extended configuration model that includes DRF parameters for automatic
|
5
5
|
integration with django_revolution's create_drf_config.
|
6
|
+
|
7
|
+
TypeScript Client Generation Issue & Solution:
|
8
|
+
----------------------------------------------
|
9
|
+
Problem: @hey-api/openapi-ts splits types with mixed readonly/writable fields into
|
10
|
+
Readable/Writable versions (e.g., ApiKeyDetailReadable, ApiKeyDetailWritable),
|
11
|
+
but references inside other types still use the base name (e.g., ApiKeyDetail),
|
12
|
+
causing "Cannot find name 'ApiKeyDetail'" errors.
|
13
|
+
|
14
|
+
Solution: Make all fields in detail serializers read-only to prevent splitting:
|
15
|
+
class Meta:
|
16
|
+
read_only_fields = fields # All fields read-only prevents TS split
|
17
|
+
|
18
|
+
This ensures TypeScript generator creates a single type without Readable/Writable suffix.
|
6
19
|
"""
|
7
20
|
|
8
21
|
from typing import Dict, Any, Optional
|
@@ -104,7 +117,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
|
|
104
117
|
description="Support tickets and messages API",
|
105
118
|
public=False,
|
106
119
|
auth_required=True,
|
107
|
-
version="v1",
|
120
|
+
# version="v1",
|
108
121
|
)
|
109
122
|
|
110
123
|
# Add Accounts zone if enabled
|
@@ -116,9 +129,9 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
|
|
116
129
|
description="User management, OTP, profiles, and activity tracking API",
|
117
130
|
public=False,
|
118
131
|
auth_required=True,
|
119
|
-
version="v1",
|
132
|
+
# version="v1",
|
120
133
|
)
|
121
|
-
|
134
|
+
|
122
135
|
# Add Newsletter zone if enabled
|
123
136
|
default_newsletter_zone = 'cfg_newsletter'
|
124
137
|
if newsletter_enabled and default_newsletter_zone not in zones:
|
@@ -128,9 +141,9 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
|
|
128
141
|
description="Email campaigns, subscriptions, and newsletter management API",
|
129
142
|
public=False,
|
130
143
|
auth_required=True,
|
131
|
-
version="v1",
|
144
|
+
# version="v1",
|
132
145
|
)
|
133
|
-
|
146
|
+
|
134
147
|
# Add Leads zone if enabled
|
135
148
|
default_leads_zone = 'cfg_leads'
|
136
149
|
if leads_enabled and default_leads_zone not in zones:
|
@@ -140,9 +153,9 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
|
|
140
153
|
description="Lead collection, contact forms, and CRM integration API",
|
141
154
|
public=True, # Leads can be public for contact forms
|
142
155
|
auth_required=False,
|
143
|
-
version="v1",
|
156
|
+
# version="v1",
|
144
157
|
)
|
145
|
-
|
158
|
+
|
146
159
|
# Add Knowbase zone if enabled
|
147
160
|
default_knowbase_zone = 'cfg_knowbase'
|
148
161
|
if knowbase_enabled and default_knowbase_zone not in zones:
|
@@ -152,9 +165,9 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
|
|
152
165
|
description="Knowledge base, AI chat, embeddings, and search API",
|
153
166
|
public=False,
|
154
167
|
auth_required=True,
|
155
|
-
version="v1",
|
168
|
+
# version="v1",
|
156
169
|
)
|
157
|
-
|
170
|
+
|
158
171
|
# Add Agents zone if enabled
|
159
172
|
default_agents_zone = 'cfg_agents'
|
160
173
|
if agents_enabled and default_agents_zone not in zones:
|
@@ -164,9 +177,9 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
|
|
164
177
|
description="Agent definitions, executions, workflows, and tools API",
|
165
178
|
public=False,
|
166
179
|
auth_required=True,
|
167
|
-
version="v1",
|
180
|
+
# version="v1",
|
168
181
|
)
|
169
|
-
|
182
|
+
|
170
183
|
# Add Tasks zone if enabled
|
171
184
|
default_tasks_zone = 'cfg_tasks'
|
172
185
|
if tasks_enabled and default_tasks_zone not in zones:
|
@@ -176,7 +189,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
|
|
176
189
|
description="Tasks, workflows, and automation API",
|
177
190
|
public=False,
|
178
191
|
auth_required=True,
|
179
|
-
version="v1",
|
192
|
+
# version="v1",
|
180
193
|
)
|
181
194
|
|
182
195
|
# Add Payments zone if enabled
|
@@ -188,7 +201,7 @@ class ExtendedRevolutionConfig(BaseDjangoRevolutionConfig):
|
|
188
201
|
description="Payments, subscriptions, and billing API",
|
189
202
|
public=False,
|
190
203
|
auth_required=True,
|
191
|
-
version="v1",
|
204
|
+
# version="v1",
|
192
205
|
)
|
193
206
|
|
194
207
|
except Exception:
|
django_cfg/pyproject.toml
CHANGED
@@ -4,13 +4,13 @@ build-backend = "hatchling.build"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "django-cfg"
|
7
|
-
version = "1.4.
|
7
|
+
version = "1.4.8"
|
8
8
|
description = "Django AI framework with built-in agents, type-safe Pydantic v2 configuration, and 8 enterprise apps. Replace settings.py, validate at startup, 90% less code. Production-ready AI workflows for Django."
|
9
9
|
readme = "README.md"
|
10
10
|
keywords = [ "django", "configuration", "pydantic", "settings", "type-safety", "pydantic-settings", "django-environ", "startup-validation", "ide-autocomplete", "ai-agents", "enterprise-django", "django-settings", "type-safe-config",]
|
11
11
|
classifiers = [ "Development Status :: 4 - Beta", "Framework :: Django", "Framework :: Django :: 5.2", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Systems Administration", "Typing :: Typed",]
|
12
12
|
requires-python = ">=3.12,<4.0"
|
13
|
-
dependencies = [ "pydantic>=2.11.0,<3.0", "pydantic[email]>=2.11.0,<3.0", "PyYAML>=6.0,<7.0", "pydantic-yaml>=1.6.0,<2.0", "click>=8.2.0,<9.0", "questionary>=2.1.0,<3.0", "rich>=14.0.0,<15.0", "cloudflare>=4.3.0,<5.0", "loguru>=0.7.0,<1.0", "colorlog>=6.9.0,<7.0", "cachetools>=5.3.0,<7.0", "toml>=0.10.2,<0.11.0", "ngrok>=1.5.1; python_version>='3.12'", "psycopg[binary,pool]>=3.2.0,<4.0", "dj-database-url>=3.0.0,<4.0", "whitenoise>=6.8.0,<7.0", "django-cors-headers>=4.7.0,<5.0", "djangorestframework>=3.16.0,<4.0", "djangorestframework-simplejwt>=5.5.0,<6.0", "djangorestframework-simplejwt[token-blacklist]>=5.5.0,<6.0", "drf-nested-routers>=0.94.0,<1.0", "django-filter>=25.0,<26.0", "django-ratelimit>=4.1.0,<5.0.0", "drf-spectacular>=0.28.0,<1.0", "drf-spectacular-sidecar>=2025.8.0,<2026.0", "django-json-widget>=2.0.0,<3.0", "django-import-export>=4.3.0,<5.0", "django-extensions>=4.1.0,<5.0", "django-constance>=4.3.0,<5.0", "django-unfold>=0.64.0,<1.0", "django-redis>=6.0.0,<7.0", "redis>=6.4.0,<7.0", "hiredis>=2.0.0,<4.0", "dramatiq[redis]>=1.18.0,<2.0", "django-dramatiq>=0.14.0,<1.0", "pyTelegramBotAPI>=4.28.0,<5.0", "coolname>=2.2.0,<3.0", "django-admin-rangefilter>=0.13.0,<1.0", "python-json-logger>=3.3.0,<4.0", "requests>=2.32.0,<3.0", "tiktoken>=0.11.0,<1.0", "openai>=1.107.0,<2.0", "twilio>=9.8.0,<10.0", "sendgrid>=6.12.0,<7.0", "beautifulsoup4>=4.13.0,<5.0", "lxml>=6.0.0,<7.0", "pgvector>=0.4.0,<1.0", "pydantic-ai>=1.0.10,<2.0", "django-revolution>=1.0.
|
13
|
+
dependencies = [ "pydantic>=2.11.0,<3.0", "pydantic[email]>=2.11.0,<3.0", "PyYAML>=6.0,<7.0", "pydantic-yaml>=1.6.0,<2.0", "click>=8.2.0,<9.0", "questionary>=2.1.0,<3.0", "rich>=14.0.0,<15.0", "cloudflare>=4.3.0,<5.0", "loguru>=0.7.0,<1.0", "colorlog>=6.9.0,<7.0", "cachetools>=5.3.0,<7.0", "toml>=0.10.2,<0.11.0", "ngrok>=1.5.1; python_version>='3.12'", "psycopg[binary,pool]>=3.2.0,<4.0", "dj-database-url>=3.0.0,<4.0", "whitenoise>=6.8.0,<7.0", "django-cors-headers>=4.7.0,<5.0", "djangorestframework>=3.16.0,<4.0", "djangorestframework-simplejwt>=5.5.0,<6.0", "djangorestframework-simplejwt[token-blacklist]>=5.5.0,<6.0", "drf-nested-routers>=0.94.0,<1.0", "django-filter>=25.0,<26.0", "django-ratelimit>=4.1.0,<5.0.0", "drf-spectacular>=0.28.0,<1.0", "drf-spectacular-sidecar>=2025.8.0,<2026.0", "django-json-widget>=2.0.0,<3.0", "django-import-export>=4.3.0,<5.0", "django-extensions>=4.1.0,<5.0", "django-constance>=4.3.0,<5.0", "django-unfold>=0.64.0,<1.0", "django-redis>=6.0.0,<7.0", "redis>=6.4.0,<7.0", "hiredis>=2.0.0,<4.0", "dramatiq[redis]>=1.18.0,<2.0", "django-dramatiq>=0.14.0,<1.0", "pyTelegramBotAPI>=4.28.0,<5.0", "coolname>=2.2.0,<3.0", "django-admin-rangefilter>=0.13.0,<1.0", "python-json-logger>=3.3.0,<4.0", "requests>=2.32.0,<3.0", "tiktoken>=0.11.0,<1.0", "openai>=1.107.0,<2.0", "twilio>=9.8.0,<10.0", "sendgrid>=6.12.0,<7.0", "beautifulsoup4>=4.13.0,<5.0", "lxml>=6.0.0,<7.0", "pgvector>=0.4.0,<1.0", "pydantic-ai>=1.0.10,<2.0", "django-revolution>=1.0.44,<2.0", "tenacity>=9.1.2,<10.0.0", "mypy (>=1.18.2,<2.0.0)", "django-tailwind[reload] (>=4.2.0,<5.0.0)",]
|
14
14
|
[[project.authors]]
|
15
15
|
name = "Django-CFG Team"
|
16
16
|
email = "info@djangocfg.com"
|
@@ -141,6 +141,10 @@ exclude = [ "@*", "tests", "scripts", "*.log", ".env*",]
|
|
141
141
|
path = "/Users/markinmatrix/djangoipc"
|
142
142
|
develop = true
|
143
143
|
|
144
|
+
[tool.poetry.group.local.dependencies.django-revolution]
|
145
|
+
path = "/Users/markinmatrix/revolution"
|
146
|
+
develop = true
|
147
|
+
|
144
148
|
[tool.hatch.build.targets.wheel.force-include]
|
145
149
|
LICENSE = "django_cfg/LICENSE"
|
146
150
|
"CONTRIBUTING.md" = "django_cfg/CONTRIBUTING.md"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: django-cfg
|
3
|
-
Version: 1.4.
|
3
|
+
Version: 1.4.8
|
4
4
|
Summary: Django AI framework with built-in agents, type-safe Pydantic v2 configuration, and 8 enterprise apps. Replace settings.py, validate at startup, 90% less code. Production-ready AI workflows for Django.
|
5
5
|
Project-URL: Homepage, https://djangocfg.com
|
6
6
|
Project-URL: Documentation, https://djangocfg.com
|
@@ -45,7 +45,7 @@ Requires-Dist: django-import-export<5.0,>=4.3.0
|
|
45
45
|
Requires-Dist: django-json-widget<3.0,>=2.0.0
|
46
46
|
Requires-Dist: django-ratelimit<5.0.0,>=4.1.0
|
47
47
|
Requires-Dist: django-redis<7.0,>=6.0.0
|
48
|
-
Requires-Dist: django-revolution<2.0,>=1.0.
|
48
|
+
Requires-Dist: django-revolution<2.0,>=1.0.44
|
49
49
|
Requires-Dist: django-tailwind[reload]<5.0.0,>=4.2.0
|
50
50
|
Requires-Dist: django-unfold<1.0,>=0.64.0
|
51
51
|
Requires-Dist: djangorestframework-simplejwt<6.0,>=5.5.0
|
@@ -459,7 +459,7 @@ django_cfg/apps/payments/templates/admin/payments/subscription/change_list.html,
|
|
459
459
|
django_cfg/apps/payments/templatetags/__init__.py,sha256=K8PcAAZu-q6LgCbrH29BSxwsWH0GQx-PhT7J-hBATMM,24
|
460
460
|
django_cfg/apps/payments/templatetags/payment_tags.py,sha256=ooO9a5E6kWyaGoLmx2fam4dHnzb9_drhFYmgPT9em1g,11910
|
461
461
|
django_cfg/apps/payments/views/api/__init__.py,sha256=gKd8dE4i-ebCxjquFHI6UaW6KKgV0RE3RlH22c8O4pU,2005
|
462
|
-
django_cfg/apps/payments/views/api/api_keys.py,sha256=
|
462
|
+
django_cfg/apps/payments/views/api/api_keys.py,sha256=nzlRdkMjDY3-hChbSnAo3MFDqd5lulOcKgeajdQr7KQ,13854
|
463
463
|
django_cfg/apps/payments/views/api/balances.py,sha256=1x8wyGZrM_dyXfkYMtB8YkLnLMFKv4Vv_mauXP-nI5Y,13090
|
464
464
|
django_cfg/apps/payments/views/api/base.py,sha256=iUsI3L4eolTOqVZ-ZP8AgZp58_EsTkhZUcVcCxZuIis,10389
|
465
465
|
django_cfg/apps/payments/views/api/currencies.py,sha256=B1Wi9MCoSgyFISrQLiqMHXtVwxOHbTLZ3X6BMEIUW3Y,13866
|
@@ -471,8 +471,8 @@ django_cfg/apps/payments/views/overview/serializers.py,sha256=uxDlzMIrn7hhS0aNEx
|
|
471
471
|
django_cfg/apps/payments/views/overview/services.py,sha256=g7ypbE9v3dDyYvOv3nfwd9_1ZqWuH02UX6dcGCDv0fM,16259
|
472
472
|
django_cfg/apps/payments/views/overview/urls.py,sha256=6Ldh8-hrkUakZDkZ7eMXpcYrdAnR8xs2UpmyDUOk4z8,1212
|
473
473
|
django_cfg/apps/payments/views/overview/views.py,sha256=F1chPhhQYeey1Wpg7z7fKvlzqT5Nxr2dKIc5PioLc-U,7991
|
474
|
-
django_cfg/apps/payments/views/serializers/__init__.py,sha256=
|
475
|
-
django_cfg/apps/payments/views/serializers/api_keys.py,sha256=
|
474
|
+
django_cfg/apps/payments/views/serializers/__init__.py,sha256=jFDXboouH5lNIQbAz-X97DCDt3ucRzUKtLotr3nw1j0,2322
|
475
|
+
django_cfg/apps/payments/views/serializers/api_keys.py,sha256=7sG4mt9j1v7I2_dmnMTFBEiGm2UVasZV8fBdltgUgQg,14807
|
476
476
|
django_cfg/apps/payments/views/serializers/balances.py,sha256=CUUl9weGK-f_4KCGJ4Abv5VvJWq7ZpclaR49NpOlWHw,9415
|
477
477
|
django_cfg/apps/payments/views/serializers/currencies.py,sha256=bpWBTE2kHaz7nKZwwYnzkyK6HYtOgULQ87ZBECY3q6Q,11330
|
478
478
|
django_cfg/apps/payments/views/serializers/payments.py,sha256=SMRZEqga5KMFKZ-UiIcyafWmVC4nSeUZwwg9QPUG3JA,12543
|
@@ -544,7 +544,7 @@ django_cfg/cli/__init__.py,sha256=i3ksFngCqZCBvaimQcBD1P2_gr5PiM--4efLScCjvvU,15
|
|
544
544
|
django_cfg/cli/main.py,sha256=GOmMubPoMpcA0XcRJn4VG2cX9tuhE0i_ioy_d3ujzRQ,883
|
545
545
|
django_cfg/cli/utils.py,sha256=YGXWw7MjX-zAUDKrbJ4q_sxH54at2Oqhrcm7udVozU4,5810
|
546
546
|
django_cfg/cli/commands/__init__.py,sha256=EKLXDAx-QttnGmdjsmVANAfhxWplxl2V_2I0SZaJOoI,98
|
547
|
-
django_cfg/cli/commands/create_project.py,sha256=
|
547
|
+
django_cfg/cli/commands/create_project.py,sha256=A1LImURJY6GUq5PUM3L0vCgBsPFLYJE8-M91tkrptQg,7578
|
548
548
|
django_cfg/cli/commands/info.py,sha256=AaLbFFOjHwqiIzZChPxfD3ASZZs1IAD-0RJQaLo2PC0,4925
|
549
549
|
django_cfg/core/__init__.py,sha256=Gooxx3nhVT53LcCF_nburLh1r2ZC3iFv9Bf4wiVK6dI,1784
|
550
550
|
django_cfg/core/config.py,sha256=CWYqlXONdyLE71OSVMg_Htglsa9tTzankMrm_1PhnOo,679
|
@@ -661,7 +661,7 @@ django_cfg/models/base/module.py,sha256=P6YowmE-VOqp_L25Ijxj2hjjNhB9xtlm8G35DHWq
|
|
661
661
|
django_cfg/models/django/__init__.py,sha256=i0GblTO8rF1J_WjT55WjhdbWN10l0UeR6mSFqdnOfak,347
|
662
662
|
django_cfg/models/django/constance.py,sha256=IVklMTtusxWnWaU3PSatGLQfg5qY_Y89MZQjsJFwbCk,9175
|
663
663
|
django_cfg/models/django/environment.py,sha256=jdg6DXQrnuLSdfZNV4KoFlkiPl1n2jOicPU8NFzyB5U,9439
|
664
|
-
django_cfg/models/django/revolution.py,sha256=
|
664
|
+
django_cfg/models/django/revolution.py,sha256=H4FqK24I3JOCsi5-FDPwMgRhRJxlYTMPMEOC53Ixj_U,8741
|
665
665
|
django_cfg/models/infrastructure/__init__.py,sha256=If0XLyDNaR_F6rOhDJBCT5RmkOOoNcY61L70pQvaO1s,369
|
666
666
|
django_cfg/models/infrastructure/cache.py,sha256=N6LWinyokWcmuJmInn0q48TQq0Je-xXMJdZ0DbelGPU,12175
|
667
667
|
django_cfg/models/infrastructure/logging.py,sha256=6nQNQPUKEL7TAYX1KcYgsqHBKnHWoUnqhR54bxcr40s,10637
|
@@ -950,9 +950,9 @@ django_cfg/utils/version_check.py,sha256=jI4v3YMdQriUEeb_TvRl511sDghy6I75iKRDUaN
|
|
950
950
|
django_cfg/CHANGELOG.md,sha256=jtT3EprqEJkqSUh7IraP73vQ8PmKUMdRtznQsEnqDZk,2052
|
951
951
|
django_cfg/CONTRIBUTING.md,sha256=DU2kyQ6PU0Z24ob7O_OqKWEYHcZmJDgzw-lQCmu6uBg,3041
|
952
952
|
django_cfg/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
|
953
|
-
django_cfg/pyproject.toml,sha256=
|
954
|
-
django_cfg-1.4.
|
955
|
-
django_cfg-1.4.
|
956
|
-
django_cfg-1.4.
|
957
|
-
django_cfg-1.4.
|
958
|
-
django_cfg-1.4.
|
953
|
+
django_cfg/pyproject.toml,sha256=uWYBJ80rrhJ9oyJnQboOMe-WSoTd8D1Es1AbNCaY3Gw,8329
|
954
|
+
django_cfg-1.4.8.dist-info/METADATA,sha256=gW5wIlTOK9GnPUWX8PVC5SI9kdii5DXizX4HReJwI4o,22542
|
955
|
+
django_cfg-1.4.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
956
|
+
django_cfg-1.4.8.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
|
957
|
+
django_cfg-1.4.8.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
|
958
|
+
django_cfg-1.4.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|