django-cfg 1.1.78__py3-none-any.whl → 1.1.79__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/models/drf.py +4 -2
- django_cfg/modules/django_llm/llm/client.py +29 -18
- django_cfg/modules/django_llm/llm/models.py +16 -1
- {django_cfg-1.1.78.dist-info → django_cfg-1.1.79.dist-info}/METADATA +1 -1
- {django_cfg-1.1.78.dist-info → django_cfg-1.1.79.dist-info}/RECORD +9 -9
- {django_cfg-1.1.78.dist-info → django_cfg-1.1.79.dist-info}/WHEEL +0 -0
- {django_cfg-1.1.78.dist-info → django_cfg-1.1.79.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.1.78.dist-info → django_cfg-1.1.79.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.79"
|
42
42
|
__author__ = "Unrealos Team"
|
43
43
|
__email__ = "info@unrealos.com"
|
44
44
|
__license__ = "MIT"
|
django_cfg/models/drf.py
CHANGED
@@ -103,7 +103,8 @@ 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
|
-
component_split_request: bool = Field(default=
|
106
|
+
component_split_request: bool = Field(default=False, description="Split request components")
|
107
|
+
component_no_read_only_required: bool = Field(default=True, description="No read-only required")
|
107
108
|
sort_operations: bool = Field(default=False, description="Sort operations")
|
108
109
|
|
109
110
|
# UI Settings
|
@@ -139,7 +140,8 @@ class SpectacularConfig(BaseModel):
|
|
139
140
|
"VERSION": self.version,
|
140
141
|
"SERVE_INCLUDE_SCHEMA": self.serve_include_schema,
|
141
142
|
"SCHEMA_PATH_PREFIX": self.schema_path_prefix,
|
142
|
-
|
143
|
+
'COMPONENT_SPLIT_REQUEST': self.component_split_request,
|
144
|
+
'COMPONENT_NO_READ_ONLY_REQUIRED': self.component_no_read_only_required,
|
143
145
|
"SORT_OPERATIONS": self.sort_operations,
|
144
146
|
# UI Settings
|
145
147
|
"SWAGGER_UI_SETTINGS": self.swagger_ui_settings.to_dict(),
|
@@ -223,7 +223,7 @@ class LLMClient:
|
|
223
223
|
temperature: Optional[float] = None,
|
224
224
|
response_format: Optional[str] = None,
|
225
225
|
**kwargs
|
226
|
-
) ->
|
226
|
+
) -> ChatCompletionResponse:
|
227
227
|
"""
|
228
228
|
Send chat completion request.
|
229
229
|
|
@@ -260,7 +260,8 @@ class LLMClient:
|
|
260
260
|
if cached_response:
|
261
261
|
logger.debug("Cache hit for chat completion")
|
262
262
|
self.stats['cache_hits'] += 1
|
263
|
-
|
263
|
+
# Convert cached dict back to Pydantic model
|
264
|
+
return ChatCompletionResponse(**cached_response)
|
264
265
|
|
265
266
|
self.stats['cache_misses'] += 1
|
266
267
|
self.stats['total_requests'] += 1
|
@@ -307,23 +308,33 @@ class LLMClient:
|
|
307
308
|
if response_format == "json" and content:
|
308
309
|
extracted_json = self.extractor.extract_json_from_response(content)
|
309
310
|
|
310
|
-
# Create response object
|
311
|
-
completion_response =
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
311
|
+
# Create Pydantic response object
|
312
|
+
completion_response = ChatCompletionResponse(
|
313
|
+
id=response.id,
|
314
|
+
model=response.model,
|
315
|
+
created=datetime.fromtimestamp(response.created).isoformat(),
|
316
|
+
choices=[
|
317
|
+
ChatChoice(
|
318
|
+
index=choice.index,
|
319
|
+
message=choice.message.model_dump() if hasattr(choice.message, 'model_dump') else choice.message,
|
320
|
+
finish_reason=choice.finish_reason
|
321
|
+
) for choice in response.choices
|
322
|
+
] if response.choices else [],
|
323
|
+
usage=TokenUsage(
|
324
|
+
prompt_tokens=response.usage.prompt_tokens if response.usage else 0,
|
325
|
+
completion_tokens=response.usage.completion_tokens if response.usage else 0,
|
326
|
+
total_tokens=response.usage.total_tokens if response.usage else tokens_used
|
327
|
+
) if response.usage else TokenUsage(total_tokens=tokens_used),
|
328
|
+
finish_reason=response.choices[0].finish_reason if response.choices else None,
|
329
|
+
content=content,
|
330
|
+
tokens_used=tokens_used,
|
331
|
+
cost_usd=cost_usd,
|
332
|
+
processing_time=processing_time,
|
333
|
+
extracted_json=extracted_json
|
334
|
+
)
|
324
335
|
|
325
|
-
# Cache the response
|
326
|
-
self.cache.set_response(request_hash, completion_response, model)
|
336
|
+
# Cache the response (serialize to dict for caching)
|
337
|
+
self.cache.set_response(request_hash, completion_response.model_dump(), model)
|
327
338
|
|
328
339
|
# Update stats
|
329
340
|
self.stats['successful_requests'] += 1
|
@@ -2,8 +2,9 @@
|
|
2
2
|
Pydantic models for LLM client responses.
|
3
3
|
"""
|
4
4
|
|
5
|
+
import math
|
5
6
|
from typing import List, Optional, Dict, Any, Union
|
6
|
-
from pydantic import BaseModel, Field
|
7
|
+
from pydantic import BaseModel, Field, validator
|
7
8
|
from datetime import datetime
|
8
9
|
|
9
10
|
|
@@ -34,6 +35,20 @@ class ChatCompletionResponse(BaseModel):
|
|
34
35
|
cost_usd: float = Field(default=0.0, description="Cost in USD")
|
35
36
|
processing_time: float = Field(default=0.0, description="Processing time in seconds")
|
36
37
|
extracted_json: Optional[Dict[str, Any]] = Field(default=None, description="Extracted JSON if any")
|
38
|
+
|
39
|
+
@validator('cost_usd')
|
40
|
+
def validate_cost_usd(cls, v):
|
41
|
+
"""Validate cost_usd to prevent NaN values."""
|
42
|
+
if v is None or math.isnan(v) or math.isinf(v):
|
43
|
+
return 0.0
|
44
|
+
return v
|
45
|
+
|
46
|
+
@validator('processing_time')
|
47
|
+
def validate_processing_time(cls, v):
|
48
|
+
"""Validate processing_time to prevent NaN values."""
|
49
|
+
if v is None or math.isnan(v) or math.isinf(v):
|
50
|
+
return 0.0
|
51
|
+
return v
|
37
52
|
|
38
53
|
|
39
54
|
class EmbeddingResponse(BaseModel):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: django-cfg
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.79
|
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
|
@@ -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=TXttkJ3xkHyfxtP_jCR0o6gDcDPRHsfs4DY8AmG0qFs,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
|
@@ -188,7 +188,7 @@ django_cfg/models/__init__.py,sha256=du24ZdqKdvc3VNXjgufEz_6B6gxdHtlqVHG4PJWaOQM
|
|
188
188
|
django_cfg/models/cache.py,sha256=Oq6VwVgWAscMM3B91sEvbCX4rXNrP4diSt68_R4XCQk,12131
|
189
189
|
django_cfg/models/constance.py,sha256=goR5gjvXIuuBWJJgUgdwzJXMvsGtnGFp8EwEPpviUWM,9694
|
190
190
|
django_cfg/models/database.py,sha256=rewKwvBKwzsH-NBQZqIXv2xHheoPcz4KiDdyM-qCC3Q,16902
|
191
|
-
django_cfg/models/drf.py,sha256=
|
191
|
+
django_cfg/models/drf.py,sha256=vewPiWFCyROPcM52cDxFPQEstyH7_bJ22B8acQe0zDw,9549
|
192
192
|
django_cfg/models/jwt.py,sha256=3R_dpLmVZIcH4zdtwA4qKnuCB8RZQACrgsbbgWY2q4c,9025
|
193
193
|
django_cfg/models/limits.py,sha256=NnTvz4iwtZEKZNx1LFudkLIqOgQq4fd5NVHSlDySXes,7444
|
194
194
|
django_cfg/models/ngrok.py,sha256=MVgcKWx0DRSW0QcwhiSx2vVwTSG49vbVrzPkZqDK-zw,3575
|
@@ -215,10 +215,10 @@ django_cfg/modules/django_llm/__init__.py,sha256=Nirl7Ap3sv5qS5EWM0IEUl_ul-mSYac
|
|
215
215
|
django_cfg/modules/django_llm/example.py,sha256=uL3hbRHHuvmWrNzMI7uSV5wrbIck5yqcgrfRGmA76Wg,13066
|
216
216
|
django_cfg/modules/django_llm/llm/__init__.py,sha256=sLx3bbLUx1h-k5aYoljlAeIg9tDzyd5C9ZFJvccbNSA,192
|
217
217
|
django_cfg/modules/django_llm/llm/cache.py,sha256=cYcbGpVF7zLUvLVvbqKtrJJnAPwno4ubL77UBI7x4bo,5653
|
218
|
-
django_cfg/modules/django_llm/llm/client.py,sha256=
|
218
|
+
django_cfg/modules/django_llm/llm/client.py,sha256=g-AZ8K9dbLCFUd5eCmhFvyWfZB4kEIF-NO5rPVouJhc,22844
|
219
219
|
django_cfg/modules/django_llm/llm/costs.py,sha256=1L5YTlIIJTWmY0_jKC8sEMZs1YRMDeStz-r-BpyZ2Vo,7490
|
220
220
|
django_cfg/modules/django_llm/llm/extractor.py,sha256=6LCq3IZUO5zKefwNEQ4EkszLGLGEA_YFLvAUPoRBdMc,2694
|
221
|
-
django_cfg/modules/django_llm/llm/models.py,sha256=
|
221
|
+
django_cfg/modules/django_llm/llm/models.py,sha256=0bgKsjveu3wpfBTaDsFbdwMC95e08j8EQtlAuRyxVg8,6009
|
222
222
|
django_cfg/modules/django_llm/llm/models_cache.py,sha256=HjnrikmqpaM9UguaAEE7SCXlPXYsw2Qj4bKYjUHF0Zk,20819
|
223
223
|
django_cfg/modules/django_llm/llm/tokenizer.py,sha256=MMrb34Xl1u0yMUGQ4TRW40fP4NWbnOuwjBKkoOswu9g,2678
|
224
224
|
django_cfg/modules/django_llm/translator/__init__.py,sha256=_gMsHBWEfiTFQvTk4UsHcXCyQBf2ilF82ISFRBbRBSU,247
|
@@ -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.79.dist-info/METADATA,sha256=i_3vJLi7lYNsX5J1xj8UWKXvHxBnreYkfCFXSMj3DLk,45783
|
275
|
+
django_cfg-1.1.79.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
276
|
+
django_cfg-1.1.79.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
|
277
|
+
django_cfg-1.1.79.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
|
278
|
+
django_cfg-1.1.79.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|