django-cfg 1.5.14__py3-none-any.whl → 1.5.20__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.

Potentially problematic release.


This version of django-cfg might be problematic. Click here for more details.

Files changed (53) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/business/accounts/serializers/profile.py +42 -0
  3. django_cfg/apps/business/support/serializers.py +3 -2
  4. django_cfg/apps/integrations/centrifugo/apps.py +2 -1
  5. django_cfg/apps/integrations/centrifugo/codegen/generators/typescript_thin/templates/rpc-client.ts.j2 +151 -12
  6. django_cfg/apps/integrations/centrifugo/management/commands/generate_centrifugo_clients.py +2 -2
  7. django_cfg/apps/integrations/centrifugo/services/__init__.py +6 -0
  8. django_cfg/apps/integrations/centrifugo/services/client/__init__.py +6 -1
  9. django_cfg/apps/integrations/centrifugo/services/client/direct_client.py +282 -0
  10. django_cfg/apps/integrations/centrifugo/services/publisher.py +371 -0
  11. django_cfg/apps/integrations/centrifugo/services/token_generator.py +122 -0
  12. django_cfg/apps/integrations/centrifugo/urls.py +8 -0
  13. django_cfg/apps/integrations/centrifugo/views/__init__.py +2 -0
  14. django_cfg/apps/integrations/centrifugo/views/testing_api.py +0 -79
  15. django_cfg/apps/integrations/centrifugo/views/token_api.py +101 -0
  16. django_cfg/apps/integrations/centrifugo/views/wrapper.py +257 -0
  17. django_cfg/apps/integrations/grpc/centrifugo/__init__.py +29 -0
  18. django_cfg/apps/integrations/grpc/centrifugo/bridge.py +277 -0
  19. django_cfg/apps/integrations/grpc/centrifugo/config.py +167 -0
  20. django_cfg/apps/integrations/grpc/centrifugo/demo.py +626 -0
  21. django_cfg/apps/integrations/grpc/centrifugo/test_publish.py +229 -0
  22. django_cfg/apps/integrations/grpc/centrifugo/transformers.py +89 -0
  23. django_cfg/apps/integrations/grpc/interceptors/__init__.py +3 -1
  24. django_cfg/apps/integrations/grpc/interceptors/centrifugo.py +541 -0
  25. django_cfg/apps/integrations/grpc/management/commands/compile_proto.py +105 -0
  26. django_cfg/apps/integrations/grpc/management/commands/generate_protos.py +55 -0
  27. django_cfg/apps/integrations/grpc/management/commands/rungrpc.py +311 -7
  28. django_cfg/apps/integrations/grpc/management/proto/__init__.py +3 -0
  29. django_cfg/apps/integrations/grpc/management/proto/compiler.py +194 -0
  30. django_cfg/apps/integrations/grpc/services/discovery.py +7 -1
  31. django_cfg/apps/integrations/grpc/utils/SERVER_LOGGING.md +164 -0
  32. django_cfg/apps/integrations/grpc/utils/streaming_logger.py +206 -5
  33. django_cfg/apps/system/dashboard/serializers/config.py +95 -9
  34. django_cfg/apps/system/dashboard/serializers/statistics.py +9 -4
  35. django_cfg/apps/system/frontend/views.py +87 -6
  36. django_cfg/core/builders/security_builder.py +1 -0
  37. django_cfg/core/generation/integration_generators/api.py +2 -0
  38. django_cfg/modules/django_client/core/generator/typescript/generator.py +26 -0
  39. django_cfg/modules/django_client/core/generator/typescript/hooks_generator.py +7 -1
  40. django_cfg/modules/django_client/core/generator/typescript/models_generator.py +5 -0
  41. django_cfg/modules/django_client/core/generator/typescript/schemas_generator.py +11 -0
  42. django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/fetchers.ts.jinja +1 -0
  43. django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/function.ts.jinja +29 -1
  44. django_cfg/modules/django_client/core/generator/typescript/templates/hooks/hooks.ts.jinja +4 -0
  45. django_cfg/modules/django_client/core/ir/schema.py +15 -1
  46. django_cfg/modules/django_client/core/parser/base.py +12 -0
  47. django_cfg/pyproject.toml +1 -1
  48. django_cfg/static/frontend/admin.zip +0 -0
  49. {django_cfg-1.5.14.dist-info → django_cfg-1.5.20.dist-info}/METADATA +1 -1
  50. {django_cfg-1.5.14.dist-info → django_cfg-1.5.20.dist-info}/RECORD +53 -37
  51. {django_cfg-1.5.14.dist-info → django_cfg-1.5.20.dist-info}/WHEEL +0 -0
  52. {django_cfg-1.5.14.dist-info → django_cfg-1.5.20.dist-info}/entry_points.txt +0 -0
  53. {django_cfg-1.5.14.dist-info → django_cfg-1.5.20.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,167 @@
1
+ """
2
+ Pydantic Configuration Models for Centrifugo Bridge.
3
+
4
+ Type-safe, validated configuration using Pydantic v2.
5
+ """
6
+
7
+ from pydantic import BaseModel, Field, field_validator
8
+ from typing import Optional, Callable, Any, Dict
9
+
10
+
11
+ class ChannelConfig(BaseModel):
12
+ """
13
+ Configuration for a single gRPC field → Centrifugo channel mapping.
14
+
15
+ Example:
16
+ ```python
17
+ ChannelConfig(
18
+ template='bot#{bot_id}#heartbeat',
19
+ rate_limit=0.1,
20
+ critical=False
21
+ )
22
+ ```
23
+
24
+ Attributes:
25
+ template: Channel name template with {variable} placeholders
26
+ rate_limit: Minimum seconds between publishes (None = no limit)
27
+ critical: Critical events bypass rate limiting
28
+ enabled: Enable/disable this specific channel
29
+ metadata: Additional metadata included in published data
30
+ """
31
+
32
+ template: str = Field(
33
+ ...,
34
+ description="Channel template with {variable} placeholders",
35
+ examples=["bot#{bot_id}#heartbeat", "user#{user_id}#notifications"]
36
+ )
37
+
38
+ rate_limit: Optional[float] = Field(
39
+ None,
40
+ description="Minimum seconds between publishes (None = no limit)",
41
+ ge=0.0,
42
+ examples=[0.1, 1.0, None]
43
+ )
44
+
45
+ critical: bool = Field(
46
+ False,
47
+ description="Critical events bypass rate limiting"
48
+ )
49
+
50
+ enabled: bool = Field(
51
+ True,
52
+ description="Enable/disable this channel"
53
+ )
54
+
55
+ metadata: Dict[str, Any] = Field(
56
+ default_factory=dict,
57
+ description="Additional metadata to include in published data"
58
+ )
59
+
60
+ # Optional custom transform function (not serialized)
61
+ transform: Optional[Callable[[str, Any], dict]] = Field(
62
+ None,
63
+ exclude=True,
64
+ description="Custom transform function(field_name, field_value) -> dict"
65
+ )
66
+
67
+ @field_validator('template')
68
+ @classmethod
69
+ def validate_template(cls, v: str) -> str:
70
+ """Ensure template contains at least one variable placeholder."""
71
+ if '{' not in v or '}' not in v:
72
+ raise ValueError(
73
+ f"Channel template must contain variables like {{bot_id}}: {v}"
74
+ )
75
+ return v
76
+
77
+ model_config = {
78
+ 'arbitrary_types_allowed': True, # Allow Callable types
79
+ 'extra': 'forbid', # Strict validation
80
+ }
81
+
82
+
83
+ class CentrifugoChannels(BaseModel):
84
+ """
85
+ Base configuration model for Centrifugo channel mappings.
86
+
87
+ Inherit from this class to define your channel mappings:
88
+
89
+ Example:
90
+ ```python
91
+ class BotChannels(CentrifugoChannels):
92
+ heartbeat: ChannelConfig = ChannelConfig(
93
+ template='bot#{bot_id}#heartbeat',
94
+ rate_limit=0.1
95
+ )
96
+
97
+ status: ChannelConfig = ChannelConfig(
98
+ template='bot#{bot_id}#status',
99
+ critical=True
100
+ )
101
+
102
+ class BotStreamingService(Servicer, CentrifugoBridgeMixin):
103
+ centrifugo_channels = BotChannels()
104
+ ```
105
+
106
+ Attributes:
107
+ enabled: Enable/disable entire Centrifugo bridge
108
+ default_rate_limit: Default rate limit for all channels
109
+ graceful_degradation: Continue if Centrifugo unavailable
110
+ """
111
+
112
+ enabled: bool = Field(
113
+ True,
114
+ description="Enable/disable entire Centrifugo bridge"
115
+ )
116
+
117
+ default_rate_limit: Optional[float] = Field(
118
+ None,
119
+ description="Default rate limit for all channels (can be overridden per channel)",
120
+ ge=0.0
121
+ )
122
+
123
+ graceful_degradation: bool = Field(
124
+ True,
125
+ description="Continue service operation if Centrifugo is unavailable"
126
+ )
127
+
128
+ def get_channel_mappings(self) -> Dict[str, ChannelConfig]:
129
+ """
130
+ Extract all ChannelConfig fields as dictionary.
131
+
132
+ Returns:
133
+ Dict mapping field names to ChannelConfig instances
134
+
135
+ Example:
136
+ ```python
137
+ channels = BotChannels()
138
+ mappings = channels.get_channel_mappings()
139
+ # {'heartbeat': ChannelConfig(...), 'status': ChannelConfig(...)}
140
+ ```
141
+ """
142
+ mappings = {}
143
+
144
+ for field_name, field_info in self.model_fields.items():
145
+ # Skip base config fields
146
+ if field_name in ('enabled', 'default_rate_limit', 'graceful_degradation'):
147
+ continue
148
+
149
+ # Get field value
150
+ field_value = getattr(self, field_name, None)
151
+
152
+ # Check if it's a ChannelConfig
153
+ if isinstance(field_value, ChannelConfig):
154
+ mappings[field_name] = field_value
155
+
156
+ return mappings
157
+
158
+ model_config = {
159
+ 'extra': 'allow', # Allow additional ChannelConfig fields
160
+ 'arbitrary_types_allowed': True,
161
+ }
162
+
163
+
164
+ __all__ = [
165
+ "ChannelConfig",
166
+ "CentrifugoChannels",
167
+ ]