Skip to content

Commit f2ac3cc

Browse files
Refactor MiddlewareRegistry and Introduce MiddlewareConfiguration
Updated the MiddlewareRegistry class to remove inheritance from SingleInheritanceRequired and added methods for managing middleware registration, including adding, removing, and querying middlewares. Introduced a new MiddlewareConfiguration class for configuring middleware execution order. Updated related imports and adjusted type hints in PySpringApplication for better type safety.
1 parent f01d9ec commit f2ac3cc

File tree

3 files changed

+170
-17
lines changed

3 files changed

+170
-17
lines changed

py_spring_core/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from py_spring_core.core.entities.entity_provider.entity_provider import EntityProvider
1313
from py_spring_core.core.entities.middlewares.middleware import Middleware
1414
from py_spring_core.core.entities.middlewares.middleware_registry import (
15-
MiddlewareRegistry,
15+
MiddlewareRegistry, MiddlewareConfiguration
1616
)
1717
from py_spring_core.core.entities.properties.properties import Properties
1818
from py_spring_core.core.interfaces.application_context_required import (
@@ -44,6 +44,7 @@
4444
"EventListener",
4545
"Middleware",
4646
"MiddlewareRegistry",
47+
"MiddlewareConfiguration",
4748
"GracefulShutdownHandler",
4849
"ShutdownType",
4950
]

py_spring_core/core/application/py_spring_application.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
import os
3-
from typing import Any, Callable, Iterable, Optional, Type
3+
from typing import Any, Callable, Iterable, Optional, Type, TypeVar
44

55
import uvicorn
66
from fastapi import APIRouter, FastAPI
@@ -30,6 +30,7 @@
3030
from py_spring_core.core.entities.entity_provider.entity_provider import EntityProvider
3131
from py_spring_core.core.entities.middlewares.middleware import Middleware
3232
from py_spring_core.core.entities.middlewares.middleware_registry import (
33+
MiddlewareConfiguration,
3334
MiddlewareRegistry,
3435
)
3536
from py_spring_core.core.entities.properties.properties import Properties
@@ -45,6 +46,8 @@
4546

4647
import py_spring_core.core.utils as framework_utils
4748

49+
50+
SingleInheritanceRequiredT = TypeVar("SingleInheritanceRequiredT", bound=SingleInheritanceRequired)
4851
class PySpringApplication:
4952
"""
5053
The PySpringApplication class is the main entry point for the PySpring application.
@@ -237,7 +240,7 @@ def __init_controllers(self) -> None:
237240
self.fastapi.include_router(router)
238241
logger.debug(f"[CONTROLLER INIT] Controller {name} initialized")
239242

240-
def _init_external_handler(self, base_class: Type[SingleInheritanceRequired]) -> Type[Any] | None:
243+
def _init_external_handler(self, base_class: Type[SingleInheritanceRequiredT]) -> Type[SingleInheritanceRequiredT] | None:
241244
"""Initialize an external handler (middleware registry or graceful shutdown handler).
242245
243246
Args:
@@ -276,12 +279,15 @@ def _init_external_handler(self, base_class: Type[SingleInheritanceRequired]) ->
276279
def __init_middlewares(self) -> None:
277280
handler_type = MiddlewareRegistry.__name__
278281
logger.debug(f"[{handler_type} INIT] Initialize middlewares...")
279-
registry_cls = self._init_external_handler(MiddlewareRegistry)
280-
if registry_cls is None:
282+
middeware_configuration_cls = self._init_external_handler(MiddlewareConfiguration)
283+
if middeware_configuration_cls is None:
281284
return
282-
283-
registry: MiddlewareRegistry = registry_cls()
285+
registry = MiddlewareRegistry()
286+
logger.info(f"[{handler_type} INIT] Setup middlewares for registry: {registry.__class__.__name__}")
287+
middeware_configuration_cls().configure_middlewares(registry)
288+
logger.info(f"[{handler_type} INIT] Middlewares setup for registry: {registry.__class__.__name__} completed")
284289
middleware_classes: list[Type[Middleware]] = registry.get_middleware_classes()
290+
logger.info(f"[{handler_type} INIT] Middleware classes: {', '.join([middleware_class.__name__ for middleware_class in middleware_classes])}")
285291
for middleware_class in middleware_classes:
286292
logger.debug(
287293
f"[{handler_type} INIT] Inject dependencies for middleware: {middleware_class.__name__}"
@@ -305,7 +311,7 @@ def __init_graceful_shutdown(self) -> None:
305311
self.shutdown_handler = handler_cls(
306312
timeout_seconds=shutdown_config.timeout_seconds,
307313
timeout_enabled=shutdown_config.enabled
308-
)
314+
) # type: ignore
309315
logger.debug(f"[{handler_type} INIT] Graceful shutdown initialized")
310316

311317
def __configure_uvicorn_logging(self):

py_spring_core/core/entities/middlewares/middleware_registry.py

Lines changed: 155 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
)
1010

1111

12-
class MiddlewareRegistry(SingleInheritanceRequired["MiddlewareRegistry"], ABC):
12+
class MiddlewareRegistry:
1313
"""
1414
Middleware registry for managing all middlewares
1515
@@ -31,20 +31,153 @@ class MiddlewareRegistry(SingleInheritanceRequired["MiddlewareRegistry"], ABC):
3131
Response: route → MiddlewareA → MiddlewareB
3232
This stacking behavior ensures that middlewares are executed in a predictable and controllable order.
3333
"""
34-
35-
@abstractmethod
34+
35+
def __init__(self):
36+
"""
37+
Initialize the middleware registry.
38+
"""
39+
self._middlewares: list[Type[Middleware]] = []
40+
41+
def add_middleware(self, middleware_class: Type[Middleware]) -> None:
42+
"""
43+
Add middleware to the end of the list.
44+
45+
Args:
46+
middleware_class: The middleware class to add
47+
48+
Raises:
49+
ValueError: If middleware is already registered
50+
"""
51+
if middleware_class in self._middlewares:
52+
raise ValueError(f"Middleware {middleware_class.__name__} is already registered")
53+
self._middlewares.append(middleware_class)
54+
55+
def add_at_index(self, index: int, middleware_class: Type[Middleware]) -> None:
56+
"""
57+
Insert middleware at a specific index position.
58+
59+
Args:
60+
index: The position to insert at (0-based)
61+
middleware_class: The middleware class to add
62+
63+
Raises:
64+
ValueError: If middleware is already registered or index is invalid
65+
"""
66+
if middleware_class in self._middlewares:
67+
raise ValueError(f"Middleware {middleware_class.__name__} is already registered")
68+
if index < 0 or index > len(self._middlewares):
69+
raise ValueError(f"Index {index} is out of range (0-{len(self._middlewares)})")
70+
self._middlewares.insert(index, middleware_class)
71+
72+
def add_before(self, target_middleware: Type[Middleware], middleware_class: Type[Middleware]) -> None:
73+
"""
74+
Insert middleware before the target middleware.
75+
76+
Args:
77+
target_middleware: The middleware to insert before
78+
middleware_class: The middleware class to add
79+
80+
Raises:
81+
ValueError: If middleware is already registered or target not found
82+
"""
83+
if middleware_class in self._middlewares:
84+
raise ValueError(f"Middleware {middleware_class.__name__} is already registered")
85+
if target_middleware not in self._middlewares:
86+
raise ValueError(f"Target middleware {target_middleware.__name__} not found")
87+
index = self._middlewares.index(target_middleware)
88+
self._middlewares.insert(index, middleware_class)
89+
90+
def add_after(self, target_middleware: Type[Middleware], middleware_class: Type[Middleware]) -> None:
91+
"""
92+
Insert middleware after the target middleware.
93+
94+
Args:
95+
target_middleware: The middleware to insert after
96+
middleware_class: The middleware class to add
97+
98+
Raises:
99+
ValueError: If middleware is already registered or target not found
100+
"""
101+
if middleware_class in self._middlewares:
102+
raise ValueError(f"Middleware {middleware_class.__name__} is already registered")
103+
if target_middleware not in self._middlewares:
104+
raise ValueError(f"Target middleware {target_middleware.__name__} not found")
105+
index = self._middlewares.index(target_middleware)
106+
self._middlewares.insert(index + 1, middleware_class)
107+
108+
def remove_middleware(self, middleware_class: Type[Middleware]) -> None:
109+
"""
110+
Remove a middleware from the registry.
111+
112+
Args:
113+
middleware_class: The middleware class to remove
114+
115+
Raises:
116+
ValueError: If middleware is not found
117+
"""
118+
if middleware_class not in self._middlewares:
119+
raise ValueError(f"Middleware {middleware_class.__name__} not found")
120+
self._middlewares.remove(middleware_class)
121+
122+
def clear_middlewares(self) -> None:
123+
"""Remove all middlewares from the registry."""
124+
self._middlewares.clear()
125+
126+
def has_middleware(self, middleware_class: Type[Middleware]) -> bool:
127+
"""
128+
Check if a middleware is registered.
129+
130+
Args:
131+
middleware_class: The middleware class to check
132+
133+
Returns:
134+
bool: True if middleware is registered, False otherwise
135+
"""
136+
return middleware_class in self._middlewares
137+
138+
def get_middleware_count(self) -> int:
139+
"""
140+
Get the number of registered middlewares.
141+
142+
Returns:
143+
int: Number of registered middlewares
144+
"""
145+
return len(self._middlewares)
146+
147+
def get_middleware_index(self, middleware_class: Type[Middleware]) -> int:
148+
"""
149+
Get the index of a middleware in the registry.
150+
151+
Args:
152+
middleware_class: The middleware class to find
153+
154+
Returns:
155+
int: The index of the middleware
156+
157+
Raises:
158+
ValueError: If middleware is not found
159+
"""
160+
if middleware_class not in self._middlewares:
161+
raise ValueError(f"Middleware {middleware_class.__name__} not found")
162+
return self._middlewares.index(middleware_class)
163+
164+
165+
36166
def get_middleware_classes(self) -> list[Type[Middleware]]:
37167
"""
38-
Get all registered middleware classes
39-
168+
Get all registered middleware classes.
169+
40170
Returns:
41-
List[Type[Middleware]]: List of middleware classes
171+
List[Type[Middleware]]: List of middleware classes in registration order
42172
"""
43-
pass
44-
173+
return self._middlewares.copy()
174+
45175
def apply_middlewares(self, app: FastAPI) -> FastAPI:
46176
"""
47-
Apply middlewares to FastAPI application
177+
Apply middlewares to FastAPI application.
178+
179+
Iterates through all registered middlewares and applies them to the FastAPI
180+
application instance in the order they were registered.
48181
49182
Args:
50183
app: FastAPI application instance
@@ -55,3 +188,16 @@ def apply_middlewares(self, app: FastAPI) -> FastAPI:
55188
for middleware_class in self.get_middleware_classes():
56189
app.add_middleware(middleware_class)
57190
return app
191+
192+
193+
194+
class MiddlewareConfiguration(SingleInheritanceRequired["MiddlewareConfiguration"]):
195+
"""
196+
Middleware configuration for managing middleware registration and execution order.
197+
"""
198+
199+
def configure_middlewares(self, registry: MiddlewareRegistry) -> None:
200+
"""
201+
Setup middlewares for the registry.
202+
"""
203+
pass

0 commit comments

Comments
 (0)