core-framework 0.12.4__tar.gz → 0.12.6__tar.gz

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 (129) hide show
  1. {core_framework-0.12.4 → core_framework-0.12.6}/PKG-INFO +1 -1
  2. {core_framework-0.12.4 → core_framework-0.12.6}/core/__init__.py +1 -1
  3. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/__init__.py +15 -0
  4. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/backends.py +5 -5
  5. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/decorators.py +7 -6
  6. core_framework-0.12.6/core/auth/helpers.py +104 -0
  7. core_framework-0.12.6/core/auth/middleware.py +473 -0
  8. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/tokens.py +17 -3
  9. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/views.py +27 -7
  10. {core_framework-0.12.4 → core_framework-0.12.6}/core/cli/main.py +6 -4
  11. {core_framework-0.12.4 → core_framework-0.12.6}/core/dependencies.py +3 -1
  12. {core_framework-0.12.4 → core_framework-0.12.6}/core/permissions.py +8 -6
  13. {core_framework-0.12.4 → core_framework-0.12.6}/core/tenancy.py +3 -2
  14. {core_framework-0.12.4 → core_framework-0.12.6}/pyproject.toml +1 -1
  15. core_framework-0.12.4/core/auth/middleware.py +0 -355
  16. {core_framework-0.12.4 → core_framework-0.12.6}/.gitignore +0 -0
  17. {core_framework-0.12.4 → core_framework-0.12.6}/README.md +0 -0
  18. {core_framework-0.12.4 → core_framework-0.12.6}/core/app.py +0 -0
  19. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/base.py +0 -0
  20. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/hashers.py +0 -0
  21. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/models.py +0 -0
  22. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/permissions.py +0 -0
  23. {core_framework-0.12.4 → core_framework-0.12.6}/core/auth/schemas.py +0 -0
  24. {core_framework-0.12.4 → core_framework-0.12.6}/core/choices.py +0 -0
  25. {core_framework-0.12.4 → core_framework-0.12.6}/core/cli/__init__.py +0 -0
  26. {core_framework-0.12.4 → core_framework-0.12.6}/core/config.py +0 -0
  27. {core_framework-0.12.4 → core_framework-0.12.6}/core/database.py +0 -0
  28. {core_framework-0.12.4 → core_framework-0.12.6}/core/datetime.py +0 -0
  29. {core_framework-0.12.4 → core_framework-0.12.6}/core/deployment/__init__.py +0 -0
  30. {core_framework-0.12.4 → core_framework-0.12.6}/core/deployment/docker.py +0 -0
  31. {core_framework-0.12.4 → core_framework-0.12.6}/core/deployment/kubernetes.py +0 -0
  32. {core_framework-0.12.4 → core_framework-0.12.6}/core/deployment/pm2.py +0 -0
  33. {core_framework-0.12.4 → core_framework-0.12.6}/core/exceptions.py +0 -0
  34. {core_framework-0.12.4 → core_framework-0.12.6}/core/fields.py +0 -0
  35. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/__init__.py +0 -0
  36. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/avro.py +0 -0
  37. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/base.py +0 -0
  38. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/config.py +0 -0
  39. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/confluent/__init__.py +0 -0
  40. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/confluent/consumer.py +0 -0
  41. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/confluent/producer.py +0 -0
  42. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/decorators.py +0 -0
  43. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/__init__.py +0 -0
  44. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/admin.py +0 -0
  45. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/broker.py +0 -0
  46. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/consumer.py +0 -0
  47. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/kafka/producer.py +0 -0
  48. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/rabbitmq/__init__.py +0 -0
  49. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/rabbitmq/broker.py +0 -0
  50. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/rabbitmq/consumer.py +0 -0
  51. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/rabbitmq/producer.py +0 -0
  52. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/redis/__init__.py +0 -0
  53. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/redis/broker.py +0 -0
  54. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/redis/consumer.py +0 -0
  55. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/redis/producer.py +0 -0
  56. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/registry.py +0 -0
  57. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/topics.py +0 -0
  58. {core_framework-0.12.4 → core_framework-0.12.6}/core/messaging/workers.py +0 -0
  59. {core_framework-0.12.4 → core_framework-0.12.6}/core/middleware.py +0 -0
  60. {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/__init__.py +0 -0
  61. {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/analyzer.py +0 -0
  62. {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/cli.py +0 -0
  63. {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/engine.py +0 -0
  64. {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/migration.py +0 -0
  65. {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/operations.py +0 -0
  66. {core_framework-0.12.4 → core_framework-0.12.6}/core/migrations/state.py +0 -0
  67. {core_framework-0.12.4 → core_framework-0.12.6}/core/models.py +0 -0
  68. {core_framework-0.12.4 → core_framework-0.12.6}/core/querysets.py +0 -0
  69. {core_framework-0.12.4 → core_framework-0.12.6}/core/relations.py +0 -0
  70. {core_framework-0.12.4 → core_framework-0.12.6}/core/routing.py +0 -0
  71. {core_framework-0.12.4 → core_framework-0.12.6}/core/serializers.py +0 -0
  72. {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/__init__.py +0 -0
  73. {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/base.py +0 -0
  74. {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/config.py +0 -0
  75. {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/decorators.py +0 -0
  76. {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/registry.py +0 -0
  77. {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/scheduler.py +0 -0
  78. {core_framework-0.12.4 → core_framework-0.12.6}/core/tasks/worker.py +0 -0
  79. {core_framework-0.12.4 → core_framework-0.12.6}/core/validators.py +0 -0
  80. {core_framework-0.12.4 → core_framework-0.12.6}/core/views.py +0 -0
  81. {core_framework-0.12.4 → core_framework-0.12.6}/docs/01-quickstart.md +0 -0
  82. {core_framework-0.12.4 → core_framework-0.12.6}/docs/02-viewsets.md +0 -0
  83. {core_framework-0.12.4 → core_framework-0.12.6}/docs/03-authentication.md +0 -0
  84. {core_framework-0.12.4 → core_framework-0.12.6}/docs/04-messaging.md +0 -0
  85. {core_framework-0.12.4 → core_framework-0.12.6}/docs/05-multi-service.md +0 -0
  86. {core_framework-0.12.4 → core_framework-0.12.6}/docs/06-tasks.md +0 -0
  87. {core_framework-0.12.4 → core_framework-0.12.6}/docs/07-deployment.md +0 -0
  88. {core_framework-0.12.4 → core_framework-0.12.6}/docs/08-complete-example.md +0 -0
  89. {core_framework-0.12.4 → core_framework-0.12.6}/docs/09-settings.md +0 -0
  90. {core_framework-0.12.4 → core_framework-0.12.6}/docs/10-migrations.md +0 -0
  91. {core_framework-0.12.4 → core_framework-0.12.6}/docs/11-permissions.md +0 -0
  92. {core_framework-0.12.4 → core_framework-0.12.6}/docs/12-auth-backends.md +0 -0
  93. {core_framework-0.12.4 → core_framework-0.12.6}/docs/13-validators.md +0 -0
  94. {core_framework-0.12.4 → core_framework-0.12.6}/docs/14-querysets.md +0 -0
  95. {core_framework-0.12.4 → core_framework-0.12.6}/docs/15-routing.md +0 -0
  96. {core_framework-0.12.4 → core_framework-0.12.6}/docs/16-serializers.md +0 -0
  97. {core_framework-0.12.4 → core_framework-0.12.6}/docs/17-datetime.md +0 -0
  98. {core_framework-0.12.4 → core_framework-0.12.6}/docs/18-dependencies.md +0 -0
  99. {core_framework-0.12.4 → core_framework-0.12.6}/docs/19-views.md +0 -0
  100. {core_framework-0.12.4 → core_framework-0.12.6}/docs/20-fields.md +0 -0
  101. {core_framework-0.12.4 → core_framework-0.12.6}/docs/21-tenancy.md +0 -0
  102. {core_framework-0.12.4 → core_framework-0.12.6}/docs/22-replicas.md +0 -0
  103. {core_framework-0.12.4 → core_framework-0.12.6}/docs/23-soft-delete.md +0 -0
  104. {core_framework-0.12.4 → core_framework-0.12.6}/docs/24-relations.md +0 -0
  105. {core_framework-0.12.4 → core_framework-0.12.6}/docs/25-exceptions.md +0 -0
  106. {core_framework-0.12.4 → core_framework-0.12.6}/docs/26-choices.md +0 -0
  107. {core_framework-0.12.4 → core_framework-0.12.6}/docs/27-workers.md +0 -0
  108. {core_framework-0.12.4 → core_framework-0.12.6}/docs/28-avro.md +0 -0
  109. {core_framework-0.12.4 → core_framework-0.12.6}/docs/29-topics.md +0 -0
  110. {core_framework-0.12.4 → core_framework-0.12.6}/docs/30-changelog-0.12.2.md +0 -0
  111. {core_framework-0.12.4 → core_framework-0.12.6}/docs/31-middleware.md +0 -0
  112. {core_framework-0.12.4 → core_framework-0.12.6}/docs/32-migration-guide-0.12.2.md +0 -0
  113. {core_framework-0.12.4 → core_framework-0.12.6}/docs/33-changelog-0.12.3.md +0 -0
  114. {core_framework-0.12.4 → core_framework-0.12.6}/docs/99-faq-troubleshooting.md +0 -0
  115. {core_framework-0.12.4 → core_framework-0.12.6}/docs/GUIDE.md +0 -0
  116. {core_framework-0.12.4 → core_framework-0.12.6}/docs/README.md +0 -0
  117. {core_framework-0.12.4 → core_framework-0.12.6}/example/__init__.py +0 -0
  118. {core_framework-0.12.4 → core_framework-0.12.6}/example/app.py +0 -0
  119. {core_framework-0.12.4 → core_framework-0.12.6}/example/auth.py +0 -0
  120. {core_framework-0.12.4 → core_framework-0.12.6}/example/models.py +0 -0
  121. {core_framework-0.12.4 → core_framework-0.12.6}/example/schemas.py +0 -0
  122. {core_framework-0.12.4 → core_framework-0.12.6}/example/views.py +0 -0
  123. {core_framework-0.12.4 → core_framework-0.12.6}/libs/__init__.py +0 -0
  124. {core_framework-0.12.4 → core_framework-0.12.6}/main.py +0 -0
  125. {core_framework-0.12.4 → core_framework-0.12.6}/tests/__init__.py +0 -0
  126. {core_framework-0.12.4 → core_framework-0.12.6}/tests/conftest.py +0 -0
  127. {core_framework-0.12.4 → core_framework-0.12.6}/tests/test_models.py +0 -0
  128. {core_framework-0.12.4 → core_framework-0.12.6}/tests/test_querysets.py +0 -0
  129. {core_framework-0.12.4 → core_framework-0.12.6}/tests/test_serializers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: core-framework
3
- Version: 0.12.4
3
+ Version: 0.12.6
4
4
  Summary: Core Framework - Django-inspired, FastAPI-powered. Alta performance, baixo acoplamento, produtividade extrema.
5
5
  Project-URL: Homepage, https://github.com/SorPuti/core-framework
6
6
  Project-URL: Documentation, https://github.com/SorPuti/core-framework#readme
@@ -278,7 +278,7 @@ from core.exceptions import (
278
278
  MissingDependency,
279
279
  )
280
280
 
281
- __version__ = "0.12.4"
281
+ __version__ = "0.12.6"
282
282
  __all__ = [
283
283
  # Models
284
284
  "Model",
@@ -121,9 +121,18 @@ from core.auth.views import (
121
121
  from core.auth.middleware import (
122
122
  AuthenticationMiddleware,
123
123
  OptionalAuthenticationMiddleware,
124
+ JWTAuthBackend,
125
+ AuthenticatedUser,
124
126
  ensure_auth_middleware,
125
127
  )
126
128
 
129
+ # Helper functions for consistent user access
130
+ from core.auth.helpers import (
131
+ get_request_user,
132
+ is_authenticated,
133
+ set_request_user,
134
+ )
135
+
127
136
  __all__ = [
128
137
  # Base
129
138
  "AuthBackend",
@@ -196,5 +205,11 @@ __all__ = [
196
205
  # Middleware
197
206
  "AuthenticationMiddleware",
198
207
  "OptionalAuthenticationMiddleware",
208
+ "JWTAuthBackend",
209
+ "AuthenticatedUser",
199
210
  "ensure_auth_middleware",
211
+ # Helpers
212
+ "get_request_user",
213
+ "is_authenticated",
214
+ "set_request_user",
200
215
  ]
@@ -161,14 +161,14 @@ class ModelBackend(AuthBackend):
161
161
 
162
162
  async def login(self, request: "Request", user: Any) -> None:
163
163
  """Executa ações pós-login."""
164
- # Armazena usuário no request.state
165
- request.state.user = user
164
+ # Armazena usuário no request.state (for backward compatibility)
165
+ from core.auth.helpers import set_request_user
166
+ set_request_user(request, user)
166
167
 
167
168
  async def logout(self, request: "Request", user: Any) -> None:
168
169
  """Executa ações de logout."""
169
- # Remove usuário do request.state
170
- if hasattr(request.state, "user"):
171
- request.state.user = None
170
+ from core.auth.helpers import set_request_user
171
+ set_request_user(request, None)
172
172
 
173
173
 
174
174
  class TokenAuthBackend(AuthBackend):
@@ -24,6 +24,7 @@ from typing import Any, TYPE_CHECKING
24
24
  from fastapi import Depends, HTTPException, Request, status
25
25
 
26
26
  from core.permissions import Permission as PermissionBase
27
+ from core.auth.helpers import get_request_user
27
28
 
28
29
  if TYPE_CHECKING:
29
30
  pass
@@ -70,7 +71,7 @@ class HasPermission(PermissionBase):
70
71
  request: Request,
71
72
  view: Any = None,
72
73
  ) -> bool:
73
- user = getattr(request.state, "user", None)
74
+ user = get_request_user(request)
74
75
 
75
76
  if user is None:
76
77
  return False
@@ -135,7 +136,7 @@ class IsInGroup(PermissionBase):
135
136
  request: Request,
136
137
  view: Any = None,
137
138
  ) -> bool:
138
- user = getattr(request.state, "user", None)
139
+ user = get_request_user(request)
139
140
 
140
141
  if user is None:
141
142
  return False
@@ -179,7 +180,7 @@ class IsSuperuser(PermissionBase):
179
180
  request: Request,
180
181
  view: Any = None,
181
182
  ) -> bool:
182
- user = getattr(request.state, "user", None)
183
+ user = get_request_user(request)
183
184
 
184
185
  if user is None:
185
186
  return False
@@ -207,7 +208,7 @@ class IsStaff(PermissionBase):
207
208
  request: Request,
208
209
  view: Any = None,
209
210
  ) -> bool:
210
- user = getattr(request.state, "user", None)
211
+ user = get_request_user(request)
211
212
 
212
213
  if user is None:
213
214
  return False
@@ -235,7 +236,7 @@ class IsActive(PermissionBase):
235
236
  request: Request,
236
237
  view: Any = None,
237
238
  ) -> bool:
238
- user = getattr(request.state, "user", None)
239
+ user = get_request_user(request)
239
240
 
240
241
  if user is None:
241
242
  return False
@@ -371,7 +372,7 @@ def login_required():
371
372
  ...
372
373
  """
373
374
  async def check(request: Request):
374
- user = getattr(request.state, "user", None)
375
+ user = get_request_user(request)
375
376
 
376
377
  if user is None:
377
378
  raise HTTPException(
@@ -0,0 +1,104 @@
1
+ """
2
+ Helper functions for authentication.
3
+
4
+ Provides consistent user access across the framework, supporting both:
5
+ - request.user (Starlette AuthenticationMiddleware pattern - preferred)
6
+ - request.state.user (legacy pattern - backward compatibility)
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import logging
12
+ from typing import Any, TYPE_CHECKING
13
+
14
+ if TYPE_CHECKING:
15
+ from starlette.requests import Request
16
+
17
+ logger = logging.getLogger("core.auth")
18
+
19
+
20
+ def get_request_user(request: "Request") -> Any | None:
21
+ """
22
+ Get authenticated user from request.
23
+
24
+ Checks both patterns for compatibility:
25
+ 1. request.user (Starlette AuthenticationMiddleware - preferred)
26
+ 2. request.state.user (legacy pattern)
27
+
28
+ Args:
29
+ request: The Starlette/FastAPI request object
30
+
31
+ Returns:
32
+ The authenticated user model or None if not authenticated
33
+
34
+ Example:
35
+ from core.auth.helpers import get_request_user
36
+
37
+ async def my_view(request: Request):
38
+ user = get_request_user(request)
39
+ if user is None:
40
+ raise HTTPException(401, "Not authenticated")
41
+ """
42
+ # Pattern 1: request.user (Starlette AuthenticationMiddleware)
43
+ user = getattr(request, "user", None)
44
+ if user is not None:
45
+ # Check if it's an authenticated user (has is_authenticated = True)
46
+ if getattr(user, "is_authenticated", False):
47
+ # If it's our AuthenticatedUser wrapper, return the underlying model
48
+ if hasattr(user, "_user"):
49
+ return user._user
50
+ return user
51
+
52
+ # Pattern 2: request.state.user (legacy)
53
+ user = getattr(request.state, "user", None) if hasattr(request, "state") else None
54
+
55
+ return user
56
+
57
+
58
+ def is_authenticated(request: "Request") -> bool:
59
+ """
60
+ Check if request has an authenticated user.
61
+
62
+ Args:
63
+ request: The Starlette/FastAPI request object
64
+
65
+ Returns:
66
+ True if authenticated, False otherwise
67
+ """
68
+ # Pattern 1: request.user with is_authenticated
69
+ user = getattr(request, "user", None)
70
+ if user is not None and getattr(user, "is_authenticated", False):
71
+ return True
72
+
73
+ # Pattern 2: request.state.user
74
+ if hasattr(request, "state"):
75
+ user = getattr(request.state, "user", None)
76
+ if user is not None:
77
+ return True
78
+
79
+ return False
80
+
81
+
82
+ def set_request_user(request: "Request", user: Any | None) -> None:
83
+ """
84
+ Set the authenticated user on the request.
85
+
86
+ Sets both patterns for maximum compatibility:
87
+ - request.state.user (for dependencies and legacy code)
88
+
89
+ Note: request.user is set by Starlette's AuthenticationMiddleware
90
+ via scope["user"] and cannot be set directly.
91
+
92
+ Args:
93
+ request: The Starlette/FastAPI request object
94
+ user: The user model or None
95
+ """
96
+ if hasattr(request, "state"):
97
+ request.state.user = user
98
+
99
+
100
+ __all__ = [
101
+ "get_request_user",
102
+ "is_authenticated",
103
+ "set_request_user",
104
+ ]