django-cfg 1.4.72__py3-none-any.whl → 1.4.74__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 (31) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/api/endpoints/README.md +144 -0
  3. django_cfg/apps/api/endpoints/endpoints_status/__init__.py +13 -0
  4. django_cfg/apps/api/endpoints/urls.py +13 -6
  5. django_cfg/apps/api/endpoints/urls_list/__init__.py +10 -0
  6. django_cfg/apps/api/endpoints/urls_list/serializers.py +74 -0
  7. django_cfg/apps/api/endpoints/urls_list/views.py +231 -0
  8. django_cfg/apps/api/health/drf_views.py +9 -0
  9. django_cfg/apps/api/health/serializers.py +4 -0
  10. django_cfg/models/django/crypto_fields.py +11 -0
  11. django_cfg/modules/django_client/core/__init__.py +2 -1
  12. django_cfg/modules/django_client/core/archive/manager.py +14 -0
  13. django_cfg/modules/django_client/core/generator/__init__.py +40 -2
  14. django_cfg/modules/django_client/core/generator/proto/__init__.py +17 -0
  15. django_cfg/modules/django_client/core/generator/proto/generator.py +461 -0
  16. django_cfg/modules/django_client/core/generator/proto/messages_generator.py +260 -0
  17. django_cfg/modules/django_client/core/generator/proto/services_generator.py +295 -0
  18. django_cfg/modules/django_client/core/generator/proto/test_proto_generator.py +262 -0
  19. django_cfg/modules/django_client/core/generator/proto/type_mapper.py +153 -0
  20. django_cfg/modules/django_client/management/commands/generate_client.py +49 -3
  21. django_cfg/pyproject.toml +1 -1
  22. {django_cfg-1.4.72.dist-info → django_cfg-1.4.74.dist-info}/METADATA +1 -1
  23. {django_cfg-1.4.72.dist-info → django_cfg-1.4.74.dist-info}/RECORD +31 -20
  24. /django_cfg/apps/api/endpoints/{checker.py → endpoints_status/checker.py} +0 -0
  25. /django_cfg/apps/api/endpoints/{drf_views.py → endpoints_status/drf_views.py} +0 -0
  26. /django_cfg/apps/api/endpoints/{serializers.py → endpoints_status/serializers.py} +0 -0
  27. /django_cfg/apps/api/endpoints/{tests.py → endpoints_status/tests.py} +0 -0
  28. /django_cfg/apps/api/endpoints/{views.py → endpoints_status/views.py} +0 -0
  29. {django_cfg-1.4.72.dist-info → django_cfg-1.4.74.dist-info}/WHEEL +0 -0
  30. {django_cfg-1.4.72.dist-info → django_cfg-1.4.74.dist-info}/entry_points.txt +0 -0
  31. {django_cfg-1.4.72.dist-info → django_cfg-1.4.74.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,262 @@
1
+ """
2
+ Simple test for Proto Generator.
3
+
4
+ This script demonstrates basic proto generation functionality.
5
+ Run with: python -m django_cfg.modules.django_client.core.generator.proto.test_proto_generator
6
+ """
7
+
8
+ from django_cfg.modules.django_client.core.ir import (
9
+ IRContext,
10
+ IROperationObject,
11
+ IRParameterObject,
12
+ IRRequestBodyObject,
13
+ IRResponseObject,
14
+ IRSchemaObject,
15
+ MediaTypeObject,
16
+ )
17
+ from django_cfg.modules.django_client.core.generator.proto import ProtoGenerator
18
+
19
+
20
+ def create_test_context() -> IRContext:
21
+ """Create a simple test IR context."""
22
+
23
+ # User schema
24
+ user_schema = IRSchemaObject(
25
+ name="User",
26
+ type="object",
27
+ properties={
28
+ "id": IRSchemaObject(
29
+ name="id",
30
+ type="integer",
31
+ format="int64",
32
+ nullable=False,
33
+ ),
34
+ "username": IRSchemaObject(
35
+ name="username",
36
+ type="string",
37
+ nullable=False,
38
+ ),
39
+ "email": IRSchemaObject(
40
+ name="email",
41
+ type="string",
42
+ format="email",
43
+ nullable=True,
44
+ ),
45
+ "status": IRSchemaObject(
46
+ name="status",
47
+ type="string",
48
+ enum=["active", "inactive", "banned"],
49
+ nullable=False,
50
+ ),
51
+ "created_at": IRSchemaObject(
52
+ name="created_at",
53
+ type="string",
54
+ format="date-time",
55
+ nullable=False,
56
+ ),
57
+ },
58
+ required=["id", "username", "status", "created_at"],
59
+ )
60
+
61
+ # List users operation
62
+ list_users_op = IROperationObject(
63
+ operation_id="users_list",
64
+ method="GET",
65
+ path="/api/users/",
66
+ tags=["Users"],
67
+ description="List all users",
68
+ parameters=[
69
+ IRParameterObject(
70
+ name="page",
71
+ in_location="query",
72
+ required=False,
73
+ schema=IRSchemaObject(type="integer", format="int32"),
74
+ ),
75
+ IRParameterObject(
76
+ name="page_size",
77
+ in_location="query",
78
+ required=False,
79
+ schema=IRSchemaObject(type="integer", format="int32"),
80
+ ),
81
+ ],
82
+ request_body=None,
83
+ responses={
84
+ 200: IRResponseObject(
85
+ description="Successful response",
86
+ content={
87
+ "application/json": MediaTypeObject(
88
+ schema=IRSchemaObject(
89
+ type="array",
90
+ items=user_schema,
91
+ )
92
+ )
93
+ },
94
+ )
95
+ },
96
+ )
97
+
98
+ # Create user operation
99
+ create_user_op = IROperationObject(
100
+ operation_id="users_create",
101
+ method="POST",
102
+ path="/api/users/",
103
+ tags=["Users"],
104
+ description="Create a new user",
105
+ parameters=[],
106
+ request_body=IRRequestBodyObject(
107
+ required=True,
108
+ content={
109
+ "application/json": MediaTypeObject(
110
+ schema=IRSchemaObject(
111
+ name="UserRequest",
112
+ type="object",
113
+ properties={
114
+ "username": IRSchemaObject(
115
+ name="username",
116
+ type="string",
117
+ ),
118
+ "email": IRSchemaObject(
119
+ name="email",
120
+ type="string",
121
+ format="email",
122
+ ),
123
+ },
124
+ required=["username"],
125
+ )
126
+ )
127
+ },
128
+ ),
129
+ responses={
130
+ 201: IRResponseObject(
131
+ description="User created",
132
+ content={
133
+ "application/json": MediaTypeObject(schema=user_schema)
134
+ },
135
+ )
136
+ },
137
+ )
138
+
139
+ # Get user operation
140
+ get_user_op = IROperationObject(
141
+ operation_id="users_retrieve",
142
+ method="GET",
143
+ path="/api/users/{id}/",
144
+ tags=["Users"],
145
+ description="Get user by ID",
146
+ parameters=[
147
+ IRParameterObject(
148
+ name="id",
149
+ in_location="path",
150
+ required=True,
151
+ schema=IRSchemaObject(type="integer", format="int64"),
152
+ ),
153
+ ],
154
+ request_body=None,
155
+ responses={
156
+ 200: IRResponseObject(
157
+ description="Successful response",
158
+ content={
159
+ "application/json": MediaTypeObject(schema=user_schema)
160
+ },
161
+ ),
162
+ 404: IRResponseObject(
163
+ description="User not found",
164
+ content={},
165
+ ),
166
+ },
167
+ )
168
+
169
+ # Delete user operation (empty response)
170
+ delete_user_op = IROperationObject(
171
+ operation_id="users_delete",
172
+ method="DELETE",
173
+ path="/api/users/{id}/",
174
+ tags=["Users"],
175
+ description="Delete a user",
176
+ parameters=[
177
+ IRParameterObject(
178
+ name="id",
179
+ in_location="path",
180
+ required=True,
181
+ schema=IRSchemaObject(type="integer", format="int64"),
182
+ ),
183
+ ],
184
+ request_body=None,
185
+ responses={
186
+ 204: IRResponseObject(
187
+ description="User deleted",
188
+ content={},
189
+ )
190
+ },
191
+ )
192
+
193
+ # Create IR context
194
+ context = IRContext(
195
+ schemas={"User": user_schema},
196
+ operations={
197
+ "users_list": list_users_op,
198
+ "users_create": create_user_op,
199
+ "users_retrieve": get_user_op,
200
+ "users_delete": delete_user_op,
201
+ },
202
+ security_schemes={},
203
+ request_models={},
204
+ response_models={"User": user_schema},
205
+ patch_models={},
206
+ enum_schemas={},
207
+ operations_by_tag={"Users": [list_users_op, create_user_op, get_user_op, delete_user_op]},
208
+ )
209
+
210
+ return context
211
+
212
+
213
+ def main():
214
+ """Run basic proto generation test."""
215
+ print("🧪 Testing Proto Generator...\n")
216
+
217
+ # Create test context
218
+ context = create_test_context()
219
+
220
+ # Test 1: Combined file generation
221
+ print("📝 Test 1: Generating combined api.proto file")
222
+ generator = ProtoGenerator(
223
+ context=context,
224
+ split_files=False,
225
+ package_name="test.api.v1",
226
+ )
227
+
228
+ files = generator.generate()
229
+ print(f"✅ Generated {len(files)} file(s)")
230
+
231
+ for file in files:
232
+ print(f"\n{'=' * 60}")
233
+ print(f"File: {file.path}")
234
+ print(f"Description: {file.description}")
235
+ print(f"Size: {len(file.content)} bytes")
236
+ print(f"{'=' * 60}")
237
+ print(file.content)
238
+
239
+ # Test 2: Split files generation
240
+ print("\n\n📝 Test 2: Generating split messages.proto and services.proto")
241
+ generator_split = ProtoGenerator(
242
+ context=context,
243
+ split_files=True,
244
+ package_name="test.api.v1",
245
+ )
246
+
247
+ split_files = generator_split.generate()
248
+ print(f"✅ Generated {len(split_files)} file(s)")
249
+
250
+ for file in split_files:
251
+ print(f"\n{'=' * 60}")
252
+ print(f"File: {file.path}")
253
+ print(f"Description: {file.description}")
254
+ print(f"Size: {len(file.content)} bytes")
255
+ print(f"{'=' * 60}")
256
+ print(file.content[:500] + "..." if len(file.content) > 500 else file.content)
257
+
258
+ print("\n\n✅ All tests passed!")
259
+
260
+
261
+ if __name__ == "__main__":
262
+ main()
@@ -0,0 +1,153 @@
1
+ """
2
+ Proto Type Mapper - Maps IR types to Protocol Buffer types.
3
+
4
+ Handles type conversion from OpenAPI/IR types to proto3 types.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+
10
+ class ProtoTypeMapper:
11
+ """
12
+ Maps IR schema types to Protocol Buffer types.
13
+
14
+ Supports proto3 with proper handling of:
15
+ - Basic types (string, int32, int64, double, bool)
16
+ - Complex types (message, repeated)
17
+ - Special types (bytes for binary, google.protobuf.Timestamp for datetime)
18
+ - Nullable fields (optional in proto3)
19
+ """
20
+
21
+ # Core type mappings
22
+ TYPE_MAP = {
23
+ "string": "string",
24
+ "integer": "int64", # Default to int64 for safety
25
+ "number": "double",
26
+ "boolean": "bool",
27
+ }
28
+
29
+ # Format-specific mappings
30
+ FORMAT_MAP = {
31
+ "int32": "int32",
32
+ "int64": "int64",
33
+ "float": "float",
34
+ "double": "double",
35
+ "byte": "bytes",
36
+ "binary": "bytes",
37
+ "date": "string", # ISO 8601 date string
38
+ "date-time": "google.protobuf.Timestamp",
39
+ "password": "string",
40
+ "email": "string",
41
+ "uri": "string",
42
+ "uuid": "string",
43
+ }
44
+
45
+ def __init__(self):
46
+ self.imported_types = set() # Track which google types we need to import
47
+
48
+ def map_type(self, ir_type: str, ir_format: str | None = None) -> str:
49
+ """
50
+ Map IR type to proto type.
51
+
52
+ Args:
53
+ ir_type: IR schema type (string, integer, number, boolean, array, object)
54
+ ir_format: Optional format specifier (int32, date-time, binary, etc.)
55
+
56
+ Returns:
57
+ Proto type string (e.g., "string", "int64", "bytes")
58
+ """
59
+ # Check format first (more specific)
60
+ if ir_format and ir_format in self.FORMAT_MAP:
61
+ proto_type = self.FORMAT_MAP[ir_format]
62
+
63
+ # Track google imports
64
+ if proto_type.startswith("google.protobuf."):
65
+ self.imported_types.add(proto_type)
66
+
67
+ return proto_type
68
+
69
+ # Fall back to base type
70
+ return self.TYPE_MAP.get(ir_type, "string")
71
+
72
+ def get_field_label(self, required: bool, nullable: bool, is_repeated: bool) -> str:
73
+ """
74
+ Get proto field label (optional, repeated, or none).
75
+
76
+ In proto3:
77
+ - repeated: for arrays
78
+ - optional: for nullable or non-required fields
79
+ - (no label): for required non-repeated fields
80
+
81
+ Args:
82
+ required: Whether field is required
83
+ nullable: Whether field can be null
84
+ is_repeated: Whether field is an array
85
+
86
+ Returns:
87
+ Field label ("optional", "repeated", or "")
88
+ """
89
+ if is_repeated:
90
+ return "repeated"
91
+
92
+ if nullable or not required:
93
+ return "optional"
94
+
95
+ return ""
96
+
97
+ def get_required_imports(self) -> list[str]:
98
+ """
99
+ Get list of proto files that need to be imported.
100
+
101
+ Returns:
102
+ List of import statements (e.g., ["google/protobuf/timestamp.proto"])
103
+ """
104
+ imports = []
105
+
106
+ if "google.protobuf.Timestamp" in self.imported_types:
107
+ imports.append("google/protobuf/timestamp.proto")
108
+
109
+ if "google.protobuf.Empty" in self.imported_types:
110
+ imports.append("google/protobuf/empty.proto")
111
+
112
+ return imports
113
+
114
+ def sanitize_field_name(self, name: str) -> str:
115
+ """
116
+ Sanitize field name for proto compatibility.
117
+
118
+ Proto3 field names should be snake_case.
119
+
120
+ Args:
121
+ name: Original field name
122
+
123
+ Returns:
124
+ Sanitized field name
125
+ """
126
+ # Convert camelCase to snake_case
127
+ import re
128
+ name = re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()
129
+
130
+ # Reserved proto keywords
131
+ reserved = {
132
+ "message", "service", "rpc", "option", "import", "package",
133
+ "syntax", "enum", "repeated", "optional", "required"
134
+ }
135
+
136
+ if name in reserved:
137
+ return f"{name}_value"
138
+
139
+ return name
140
+
141
+ def get_message_name(self, name: str) -> str:
142
+ """
143
+ Get proto message name (PascalCase).
144
+
145
+ Args:
146
+ name: Original name
147
+
148
+ Returns:
149
+ Proto-compatible message name
150
+ """
151
+ # Ensure PascalCase
152
+ parts = name.replace("_", " ").replace("-", " ").split()
153
+ return "".join(word.capitalize() for word in parts)
@@ -43,6 +43,12 @@ class Command(BaseCommand):
43
43
  help="Generate Go client only",
44
44
  )
45
45
 
46
+ parser.add_argument(
47
+ "--proto",
48
+ action="store_true",
49
+ help="Generate Protocol Buffer/gRPC definitions only",
50
+ )
51
+
46
52
  parser.add_argument(
47
53
  "--no-python",
48
54
  action="store_true",
@@ -61,6 +67,12 @@ class Command(BaseCommand):
61
67
  help="Skip Go client generation",
62
68
  )
63
69
 
70
+ parser.add_argument(
71
+ "--no-proto",
72
+ action="store_true",
73
+ help="Skip Protocol Buffer generation",
74
+ )
75
+
64
76
  # Utility options
65
77
  parser.add_argument(
66
78
  "--dry-run",
@@ -205,22 +217,31 @@ class Command(BaseCommand):
205
217
  def _generate_clients(self, service, options):
206
218
  """Generate clients."""
207
219
  # Determine languages
208
- if options["python"] and not options["typescript"] and not options["go"]:
220
+ if options["python"] and not options["typescript"] and not options["go"] and not options["proto"]:
209
221
  python = True
210
222
  typescript = False
211
223
  go = False
212
- elif options["typescript"] and not options["python"] and not options["go"]:
224
+ proto = False
225
+ elif options["typescript"] and not options["python"] and not options["go"] and not options["proto"]:
213
226
  python = False
214
227
  typescript = True
215
228
  go = False
216
- elif options["go"] and not options["python"] and not options["typescript"]:
229
+ proto = False
230
+ elif options["go"] and not options["python"] and not options["typescript"] and not options["proto"]:
217
231
  python = False
218
232
  typescript = False
219
233
  go = True
234
+ proto = False
235
+ elif options["proto"] and not options["python"] and not options["typescript"] and not options["go"]:
236
+ python = False
237
+ typescript = False
238
+ go = False
239
+ proto = True
220
240
  else:
221
241
  python = not options["no_python"]
222
242
  typescript = not options["no_typescript"]
223
243
  go = not options["no_go"]
244
+ proto = not options["no_proto"]
224
245
 
225
246
  # Get groups
226
247
  groups = options.get("groups")
@@ -254,6 +275,8 @@ class Command(BaseCommand):
254
275
  self.stdout.write(" → TypeScript")
255
276
  if go:
256
277
  self.stdout.write(" → Go")
278
+ if proto:
279
+ self.stdout.write(" → Protocol Buffers (proto3)")
257
280
 
258
281
  if dry_run:
259
282
  self.stdout.write(self.style.WARNING("\n✅ Dry run completed - no files generated"))
@@ -271,6 +294,7 @@ class Command(BaseCommand):
271
294
  ArchiveManager,
272
295
  GoGenerator,
273
296
  GroupManager,
297
+ ProtoGenerator,
274
298
  PythonGenerator,
275
299
  TypeScriptGenerator,
276
300
  parse_openapi,
@@ -444,6 +468,26 @@ class Command(BaseCommand):
444
468
 
445
469
  self.stdout.write(f" ✅ Go client: {go_dir} ({len(go_files)} files)")
446
470
 
471
+ # Generate Proto files
472
+ if proto:
473
+ self.stdout.write(" → Generating Protocol Buffer definitions...")
474
+ proto_dir = clients_dir / "proto" / group_name
475
+ proto_dir.mkdir(parents=True, exist_ok=True)
476
+
477
+ proto_generator = ProtoGenerator(
478
+ ir_context,
479
+ split_files=True, # Generate separate messages.proto and services.proto
480
+ package_name=f"{group_name}.v1",
481
+ )
482
+ proto_files = proto_generator.generate()
483
+
484
+ for generated_file in proto_files:
485
+ full_path = proto_dir / generated_file.path
486
+ full_path.parent.mkdir(parents=True, exist_ok=True)
487
+ full_path.write_text(generated_file.content)
488
+
489
+ self.stdout.write(f" ✅ Proto files: {proto_dir} ({len(proto_files)} files)")
490
+
447
491
  # Archive if enabled
448
492
  if service.config.enable_archive:
449
493
  self.stdout.write(" → Archiving...")
@@ -452,6 +496,8 @@ class Command(BaseCommand):
452
496
  group_name,
453
497
  python_dir=service.config.get_group_python_dir(group_name) if python else None,
454
498
  typescript_dir=service.config.get_group_typescript_dir(group_name) if typescript else None,
499
+ go_dir=go_dir if go else None,
500
+ proto_dir=proto_dir if proto else None,
455
501
  )
456
502
  if archive_result.get('success'):
457
503
  self.stdout.write(f" ✅ Archived: {archive_result['archive_path']}")
django_cfg/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "django-cfg"
7
- version = "1.4.72"
7
+ version = "1.4.74"
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",]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-cfg
3
- Version: 1.4.72
3
+ Version: 1.4.74
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
@@ -1,5 +1,5 @@
1
1
  django_cfg/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- django_cfg/__init__.py,sha256=xDdlpsN4-YhuruB3zP6WlJ-A2Yuw9I1zYQ-lixF1BNM,1620
2
+ django_cfg/__init__.py,sha256=mqn8xhYwIioGgQ8BQp4Mon8wEhj7VR91PV9Xku-AqYk,1620
3
3
  django_cfg/apps.py,sha256=72m3uuvyqGiLx6gOfE-BD3P61jddCCERuBOYpxTX518,1605
4
4
  django_cfg/config.py,sha256=y4Z3rnYsHBE0TehpwAIPaxr---mkvyKrZGGsNwYso74,1398
5
5
  django_cfg/apps/__init__.py,sha256=JtDmEYt1OcleWM2ZaeX0LKDnRQzPOavfaXBWG4ECB5Q,26
@@ -107,16 +107,21 @@ django_cfg/apps/api/__init__.py,sha256=fHkKXld_pw5Eiqz4tNb3Z02nx-7T7PnqgMh-qjkGB
107
107
  django_cfg/apps/api/commands/__init__.py,sha256=FTmBMxSpI9rO6EljgkWn8e9pxh07ao5Y1kx2TzQmZSY,88
108
108
  django_cfg/apps/api/commands/urls.py,sha256=GSZgAsB-VIhAxq9LU5DzUtYAy-RGDRiB9P41P1jqbcc,361
109
109
  django_cfg/apps/api/commands/views.py,sha256=daSkYPRl1HYgepCCowYz7DJOZtqdp1mapUkXHZwkTpw,9827
110
+ django_cfg/apps/api/endpoints/README.md,sha256=eLqzpUWcOtBtrKL_r9zfE4mNK863lkJpbAtL_L9wGmI,3326
110
111
  django_cfg/apps/api/endpoints/__init__.py,sha256=uHjV4E24Aj0UFgv7bW1Z0kH_NFe8PItNFuS105vvRz0,108
111
- django_cfg/apps/api/endpoints/checker.py,sha256=Qu4VtsG9wRd2isqo4-Kk_gDhWlpT_fkqb7GoERvW_C8,19367
112
- django_cfg/apps/api/endpoints/drf_views.py,sha256=nAGIofRtdp4ne7dWouJuMJ984kB93kYruW3HnPfsLZg,1954
113
- django_cfg/apps/api/endpoints/serializers.py,sha256=W5Az0m1jUi8rLLIMoKVBADk6KHFyAWrwJ_gzSinktno,3656
114
- django_cfg/apps/api/endpoints/tests.py,sha256=PpOwpZ7Rm5eOtbVn-6Ha8yagvpuwusbHkB5FYYs7GHY,9993
115
- django_cfg/apps/api/endpoints/urls.py,sha256=azan8Az3-2ktL21nawKky6XK7i2ZIeegswVyGtbu9YU,373
116
- django_cfg/apps/api/endpoints/views.py,sha256=10zyQyQllrVJS44R2GAY9VV4_4Zl14a7R4dYrQmVJKw,1243
112
+ django_cfg/apps/api/endpoints/urls.py,sha256=vovwkICejTYtk0ZWOZpTOVrbi2hP_bR1YNNn4v8MPIU,726
113
+ django_cfg/apps/api/endpoints/endpoints_status/__init__.py,sha256=KjdWJjbRZ1-1LiBfR1Wch3oPV4ANwiykIKFBW3woOJQ,270
114
+ django_cfg/apps/api/endpoints/endpoints_status/checker.py,sha256=Qu4VtsG9wRd2isqo4-Kk_gDhWlpT_fkqb7GoERvW_C8,19367
115
+ django_cfg/apps/api/endpoints/endpoints_status/drf_views.py,sha256=nAGIofRtdp4ne7dWouJuMJ984kB93kYruW3HnPfsLZg,1954
116
+ django_cfg/apps/api/endpoints/endpoints_status/serializers.py,sha256=W5Az0m1jUi8rLLIMoKVBADk6KHFyAWrwJ_gzSinktno,3656
117
+ django_cfg/apps/api/endpoints/endpoints_status/tests.py,sha256=PpOwpZ7Rm5eOtbVn-6Ha8yagvpuwusbHkB5FYYs7GHY,9993
118
+ django_cfg/apps/api/endpoints/endpoints_status/views.py,sha256=10zyQyQllrVJS44R2GAY9VV4_4Zl14a7R4dYrQmVJKw,1243
119
+ django_cfg/apps/api/endpoints/urls_list/__init__.py,sha256=aspLNziW0Ys4v-Bbf0lu_1G0RgySHwg16mMTnMY2dws,165
120
+ django_cfg/apps/api/endpoints/urls_list/serializers.py,sha256=hhtAM-PkskoJI9JLF7VKMczkJIaz2IkRMAI3r9Lyoks,1955
121
+ django_cfg/apps/api/endpoints/urls_list/views.py,sha256=Z3ULXsv1Vl8m0kpL6JxTTainMD1ZQIAVOX-3FOWjqKQ,7502
117
122
  django_cfg/apps/api/health/__init__.py,sha256=ypFUiCo0I9VJpaZ_KqEPPX3-ma_MhRm5U1XYWahUaFI,93
118
- django_cfg/apps/api/health/drf_views.py,sha256=CrNQGXONwew9OV4dmpxOlTDEDKn_TM6J2Lh41PqnNHo,8796
119
- django_cfg/apps/api/health/serializers.py,sha256=Y_kn_RIn4MBRJWbsO2_DNEG_AqxnhuD7h9srhj6ggEE,1270
123
+ django_cfg/apps/api/health/drf_views.py,sha256=wW8f611YtQnarN6_x8JZwNn4zkOpp0k2JBz_OCk6qEw,9270
124
+ django_cfg/apps/api/health/serializers.py,sha256=JuFgWBRsycXsAZjZST33QO5li1z3S19l4xsLJ-ahWP8,1381
120
125
  django_cfg/apps/api/health/urls.py,sha256=eCTzgB4rv_H2W0NrixPO6qsh0pT2oUePrYAT5D35QIY,550
121
126
  django_cfg/apps/api/health/views.py,sha256=65oA6O3gaz2ECY2SiXlT3n4JpORt0nDufa_10um0nRw,8194
122
127
  django_cfg/apps/centrifugo/__init__.py,sha256=VeMqGhK9OgFikSbF3ZgBEqQJ8y7YvKzbWmXsxunJ7FI,1833
@@ -632,7 +637,7 @@ django_cfg/models/base/module.py,sha256=nxN1Y9J4l94kOfSXLQJ2eGgIGWTq8kyh7hUGvCQN
632
637
  django_cfg/models/django/__init__.py,sha256=xY_ts1oGmMROXfKHLuERqwG35dQf3EpsZxqj9DcRYwI,397
633
638
  django_cfg/models/django/axes.py,sha256=-4nk2gSfpj7lNY5vnm_2jHVLz8VAKoEd9yF2TuCR8O8,5624
634
639
  django_cfg/models/django/constance.py,sha256=E4U3HS_gFq5_q2nhI1R8inONGtD7IgvSwxOEGNGGrEI,9127
635
- django_cfg/models/django/crypto_fields.py,sha256=u8OY5BmdwB7F2fLR2fcSwOk2XSGtqGdLMFhpodr9YMY,2919
640
+ django_cfg/models/django/crypto_fields.py,sha256=HZgV0lA8T7hvx8Np0l1OQoJbM_fA1VIrSoMDwXP25RE,3426
636
641
  django_cfg/models/django/environment.py,sha256=lBCHBs1lphv9tlu1BCTfLZeH_kUame0p66A_BIjBY7M,9440
637
642
  django_cfg/models/django/openapi.py,sha256=avE3iapaCj8eyOqVUum_v2EExR3V-hwHrexqtXMHtTQ,3739
638
643
  django_cfg/models/django/revolution_legacy.py,sha256=Z4SPUS7QSv62EuPAeFFoXGEgqLmdXnVEr7Ofk1IDtVc,8918
@@ -691,16 +696,16 @@ django_cfg/modules/django_client/__init__.py,sha256=iHaGKbsyR2wMmVCWNsETC7cwB60f
691
696
  django_cfg/modules/django_client/apps.py,sha256=xfkw2aXy08xXlkFhbCiTFveMmRwlDk3SQOAWdqXraFM,1952
692
697
  django_cfg/modules/django_client/pytest.ini,sha256=yC1PeQKS4nWQD-jVo5fWF9y1Uv6rywcH0mtHREsiAp0,668
693
698
  django_cfg/modules/django_client/urls.py,sha256=0Q0uDhiRqI-jlTU_tsylg-HtRHNXARko6gGGz2-63Aw,1799
694
- django_cfg/modules/django_client/core/__init__.py,sha256=xZYmtokiVm72lInjXgolQJ_oVzThDR6F_J9ukptDniA,1097
699
+ django_cfg/modules/django_client/core/__init__.py,sha256=xAqXcFoY3H0oCBp8g7d9PzO99bOGIDdtHUKgVAOoS_c,1135
695
700
  django_cfg/modules/django_client/core/archive/__init__.py,sha256=SKeOKjRnw_NsL7_fOU_2Neo-bcDj4Hv2sVFYztJYiSI,171
696
- django_cfg/modules/django_client/core/archive/manager.py,sha256=V73TF_AynDoj8RvciCAVpBJBFgqJCArQJGO2wi0TUkw,3792
701
+ django_cfg/modules/django_client/core/archive/manager.py,sha256=2qSi1ymdjfjU-X0cWzl_hq2adt09EmOCz4z4pMQMAQw,4345
697
702
  django_cfg/modules/django_client/core/cli/__init__.py,sha256=bqY0TX3uaOyhlDmVVQ0kjoCvEPqKJFgWBYVPj974dQs,167
698
703
  django_cfg/modules/django_client/core/cli/main.py,sha256=emfSWMCLiV1qm8naC1jWL9pagRxGJKF3sXmYfaJ1Sf4,6591
699
704
  django_cfg/modules/django_client/core/config/__init__.py,sha256=aFniCFG7yC1Iaal5euPLjuQ-VubyDryc3a7cST8APTk,411
700
705
  django_cfg/modules/django_client/core/config/config.py,sha256=2OC8WZwiCH6FcYL6SCAbD7YvtnUrQcr4FT-plutFXaA,6681
701
706
  django_cfg/modules/django_client/core/config/group.py,sha256=LDITTEhPD0_p5GvwYTqzc_xxT3JaY1WBgUaCiQEWKPQ,2646
702
707
  django_cfg/modules/django_client/core/config/service.py,sha256=-TQXpy5z-GmQzDwD-tjpOWmMW31uV_7eH9AHlimnHEU,6287
703
- django_cfg/modules/django_client/core/generator/__init__.py,sha256=CadusdRjTSHdiTobtIIod21WFLXTmJntOt1uEbcXr9c,4506
708
+ django_cfg/modules/django_client/core/generator/__init__.py,sha256=JN1HpxRfO24ZgHjwX3hkW4v4O5Hcx5ewBPhxiwI2Faw,5756
704
709
  django_cfg/modules/django_client/core/generator/base.py,sha256=2dWKCbAb1heCaWsWhDn85TR9Z05nI2V3fvi3h8odG7Y,31765
705
710
  django_cfg/modules/django_client/core/generator/go/__init__.py,sha256=vY5VIxrnFXjw8pn1DBaazMohyEFOas5WI8RuQmNfFdQ,333
706
711
  django_cfg/modules/django_client/core/generator/go/client_generator.py,sha256=DpnIm0AMGqeftT-mNALvz3K5btbMm9A_1EAlCr6xFSA,4427
@@ -721,6 +726,12 @@ django_cfg/modules/django_client/core/generator/go/templates/middleware.go.j2,sh
721
726
  django_cfg/modules/django_client/core/generator/go/templates/models.go.j2,sha256=9UThdTAGbILmzxIvu_Mn5cQsxs6dGPLtEdCK-DDrvUU,631
722
727
  django_cfg/modules/django_client/core/generator/go/templates/operations_client.go.j2,sha256=Qxjr8kO1n-3FSlWfNWyBlt8ldrdh4Ym-FusC4cMQ9X0,3716
723
728
  django_cfg/modules/django_client/core/generator/go/templates/validation.go.j2,sha256=3BzI7pOuuh-19wNwuRq7GtRda-Pmaw57Jug35bdtamA,5154
729
+ django_cfg/modules/django_client/core/generator/proto/__init__.py,sha256=TBbZGr6Cim3apAO1eexEcmIQuo840lVWQpA_FD_QkLs,449
730
+ django_cfg/modules/django_client/core/generator/proto/generator.py,sha256=ewMs1Ld657hos2YYv172A_EtlfMibQy7NeDqdlBusrI,17411
731
+ django_cfg/modules/django_client/core/generator/proto/messages_generator.py,sha256=H9A3DeWUy-wJZ5dtMBrh5o1l1uwF3ZqnGdsx7vNtm-Q,9498
732
+ django_cfg/modules/django_client/core/generator/proto/services_generator.py,sha256=XYXT8f3bTktGBWLyW5hbgE2igzfc3T6caFTxdSXYZ3I,11018
733
+ django_cfg/modules/django_client/core/generator/proto/test_proto_generator.py,sha256=XG4FJJ6MJYTcb_BNTMoXwZLeL6JCn3lNrk4Z25BnBec,7725
734
+ django_cfg/modules/django_client/core/generator/proto/type_mapper.py,sha256=n5GVQHK3h_-7h3xvQaEUqWVJWy-utFOyusdRAP1e1lM,4370
724
735
  django_cfg/modules/django_client/core/generator/python/__init__.py,sha256=DOPkZBmNVX8qKZBulnE-49iMlBsMHszidzBhWG17c2E,448
725
736
  django_cfg/modules/django_client/core/generator/python/async_client_gen.py,sha256=zFviFo0PLg3Zb-0TL5AS_Ghhvl-jS180Cl-AWIAWIa0,6030
726
737
  django_cfg/modules/django_client/core/generator/python/files_generator.py,sha256=cgJVL6OZFXQFiy3trgCK5NDfGQWygQBJNaDepDQx4Vc,6420
@@ -821,7 +832,7 @@ django_cfg/modules/django_client/core/validation/rules/base.py,sha256=xVJli0eSEz
821
832
  django_cfg/modules/django_client/core/validation/rules/type_hints.py,sha256=hwjTMADillsTPruDvXZQeZMj4LVV443zxY9o0Gqgg6k,10200
822
833
  django_cfg/modules/django_client/management/__init__.py,sha256=mCTPP_bIOmqNnn0WAG2n4BuF6zwc9PTgdZr_dORfNDk,54
823
834
  django_cfg/modules/django_client/management/commands/__init__.py,sha256=CJ55pHUNYQ5h-QHUe3axeTtxzlUJv7wbEuZmGN21iCM,36
824
- django_cfg/modules/django_client/management/commands/generate_client.py,sha256=OaNiuiwA8BTDTaCTdGVsldwxithSvl-9WuLVRlGhAk8,18701
835
+ django_cfg/modules/django_client/management/commands/generate_client.py,sha256=NTxVIOLMvrxbKfqNAhVjqChaLEb33nflGAHFQMMN4aU,20642
825
836
  django_cfg/modules/django_client/management/commands/validate_openapi.py,sha256=IBKk7oRP3tMQzXjvZNIgQtMPk3k_mB2diNS7bkaSLz4,11011
826
837
  django_cfg/modules/django_client/spectacular/__init__.py,sha256=M8fG-odu2ltkG36aMMr0KDkCKGX676TwdrJO8vky2cI,345
827
838
  django_cfg/modules/django_client/spectacular/async_detection.py,sha256=S_pwGR7_2SIWHjZJyiu7SCfySF3Nr3P8eqjDyBSkkLs,5731
@@ -1105,9 +1116,9 @@ django_cfg/utils/version_check.py,sha256=WO51J2m2e-wVqWCRwbultEwu3q1lQasV67Mw2aa
1105
1116
  django_cfg/CHANGELOG.md,sha256=jtT3EprqEJkqSUh7IraP73vQ8PmKUMdRtznQsEnqDZk,2052
1106
1117
  django_cfg/CONTRIBUTING.md,sha256=DU2kyQ6PU0Z24ob7O_OqKWEYHcZmJDgzw-lQCmu6uBg,3041
1107
1118
  django_cfg/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1108
- django_cfg/pyproject.toml,sha256=kEFqwl6GaVlwLny_D3ljqIIk0c5FNHxhRRrhL0l6wOg,8164
1109
- django_cfg-1.4.72.dist-info/METADATA,sha256=HJC5pYczPM2qc1bwXuiEo_hpGwIDwgfLA4pS_qFnXjw,22624
1110
- django_cfg-1.4.72.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1111
- django_cfg-1.4.72.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
1112
- django_cfg-1.4.72.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1113
- django_cfg-1.4.72.dist-info/RECORD,,
1119
+ django_cfg/pyproject.toml,sha256=M4jxEC0_B7R_qqnCxUJMxjZaCyRx2wEAGtZ36qNROCA,8164
1120
+ django_cfg-1.4.74.dist-info/METADATA,sha256=0IuecNQP4vRHY57KvrtWxrpgPROJqP4OUiYonlLJDvY,22624
1121
+ django_cfg-1.4.74.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1122
+ django_cfg-1.4.74.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
1123
+ django_cfg-1.4.74.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1124
+ django_cfg-1.4.74.dist-info/RECORD,,