6
6
7
7
8
8
class HTTPMethod (str , Enum ):
9
+ """HTTP methods enumeration for route definitions.
10
+
11
+ This enum defines the supported HTTP methods that can be used
12
+ with route decorators in the PySpring framework.
13
+ """
9
14
GET = "GET"
10
15
POST = "POST"
11
16
PUT = "PUT"
@@ -14,6 +19,36 @@ class HTTPMethod(str, Enum):
14
19
15
20
16
21
class RouteRegistration (BaseModel ):
22
+ """Model representing a route registration with all FastAPI-compatible parameters.
23
+
24
+ This class encapsulates all the information needed to register a route,
25
+ including the HTTP method, path, handler function, and various FastAPI
26
+ configuration options.
27
+
28
+ Attributes:
29
+ class_name (str): Name of the controller class containing the route
30
+ method (HTTPMethod): HTTP method for the route
31
+ path (str): URL path pattern for the route
32
+ func (Callable): The handler function for the route
33
+ response_model (Any, optional): Pydantic model for response serialization
34
+ status_code (int, optional): Default HTTP status code for successful responses
35
+ tags (List[Union[str, Enum]], optional): OpenAPI tags for documentation
36
+ dependencies (List[Any], optional): FastAPI dependencies
37
+ summary (str, optional): Short summary for OpenAPI documentation
38
+ description (str, optional): Detailed description for OpenAPI documentation
39
+ response_description (str): Description of successful response
40
+ responses (Dict[Union[int, str], Dict[str, Any]], optional): Additional response definitions
41
+ deprecated (bool, optional): Whether the endpoint is deprecated
42
+ operation_id (str, optional): Unique operation ID for OpenAPI
43
+ response_model_include (Set[str], optional): Fields to include in response model
44
+ response_model_exclude (Set[str], optional): Fields to exclude from response model
45
+ response_model_by_alias (bool): Whether to use field aliases in response
46
+ response_model_exclude_unset (bool): Whether to exclude unset fields
47
+ response_model_exclude_defaults (bool): Whether to exclude default values
48
+ response_model_exclude_none (bool): Whether to exclude None values
49
+ include_in_schema (bool): Whether to include in OpenAPI schema
50
+ name (str, optional): Custom name for the route
51
+ """
17
52
class_name : str
18
53
method : HTTPMethod
19
54
path : str
@@ -38,26 +73,73 @@ class RouteRegistration(BaseModel):
38
73
name : Optional [str ] = None
39
74
40
75
def __eq__ (self , other : Any ) -> bool :
76
+ """Check equality based on HTTP method and path.
77
+
78
+ Two route registrations are considered equal if they have
79
+ the same HTTP method and path, regardless of other attributes.
80
+
81
+ Args:
82
+ other (Any): Object to compare with
83
+
84
+ Returns:
85
+ bool: True if equal, False otherwise
86
+ """
41
87
if not isinstance (other , RouteRegistration ):
42
88
return False
43
89
return self .method == other .method and self .path == other .path
44
90
45
91
def __hash__ (self ) -> int :
92
+ """Generate hash based on HTTP method and path.
93
+
94
+ This allows RouteRegistration objects to be used in sets
95
+ and as dictionary keys.
96
+
97
+ Returns:
98
+ int: Hash value based on method and path
99
+ """
46
100
return hash ((self .method , self .path ))
47
101
48
102
49
103
class RouteMapping :
104
+ """Registry for storing and managing route registrations by controller class.
105
+
106
+ This class maintains a mapping of controller class names to their
107
+ associated route registrations, enabling efficient route lookup
108
+ and management within the PySpring framework.
109
+
110
+ Attributes:
111
+ routes (dict[str, set[RouteRegistration]]): Mapping of class names to route sets
112
+ """
50
113
routes : dict [str , set [RouteRegistration ]] = {}
51
114
52
115
@classmethod
53
116
def register_route (cls , route_registration : RouteRegistration ) -> None :
117
+ """Register a route for a specific controller class.
118
+
119
+ Adds the given route registration to the routes mapping,
120
+ creating a new set for the class if it doesn't exist.
121
+
122
+ Args:
123
+ route_registration (RouteRegistration): The route to register
124
+ """
54
125
optional_routes = cls .routes .get (route_registration .class_name , None )
55
126
if optional_routes is None :
56
127
cls .routes [route_registration .class_name ] = set ()
57
128
cls .routes [route_registration .class_name ].add (route_registration )
58
129
59
130
60
131
def _create_route_decorator (method : HTTPMethod ):
132
+ """Create a route decorator factory for a specific HTTP method.
133
+
134
+ This function generates decorator factories that can be used to create
135
+ route decorators with FastAPI-compatible parameters.
136
+
137
+ Args:
138
+ method (HTTPMethod): The HTTP method for routes created by this decorator
139
+
140
+ Returns:
141
+ Callable: A decorator factory function that accepts route parameters
142
+ """
61
143
def decorator_factory (
62
144
path : str ,
63
145
* ,
@@ -80,7 +162,41 @@ def decorator_factory(
80
162
include_in_schema : bool = True ,
81
163
name : Optional [str ] = None ,
82
164
):
165
+ """Create a route decorator with the specified parameters.
166
+
167
+ Args:
168
+ path (str): URL path pattern for the route
169
+ response_model (Any, optional): Pydantic model for response serialization
170
+ status_code (int, optional): Default HTTP status code
171
+ tags (List[Union[str, Enum]], optional): OpenAPI tags
172
+ dependencies (List[Any], optional): FastAPI dependencies
173
+ summary (str, optional): Route summary for documentation
174
+ description (str, optional): Route description for documentation
175
+ response_description (str): Description of successful response
176
+ responses (Dict[Union[int, str], Dict[str, Any]], optional): Additional responses
177
+ deprecated (bool, optional): Whether the endpoint is deprecated
178
+ operation_id (str, optional): Unique operation ID
179
+ response_model_include (Set[str], optional): Fields to include in response
180
+ response_model_exclude (Set[str], optional): Fields to exclude from response
181
+ response_model_by_alias (bool): Whether to use field aliases
182
+ response_model_exclude_unset (bool): Whether to exclude unset fields
183
+ response_model_exclude_defaults (bool): Whether to exclude defaults
184
+ response_model_exclude_none (bool): Whether to exclude None values
185
+ include_in_schema (bool): Whether to include in OpenAPI schema
186
+ name (str, optional): Custom name for the route
187
+
188
+ Returns:
189
+ Callable: A decorator function that registers the route
190
+ """
83
191
def decorator (func : Callable ):
192
+ """Decorate a function to register it as a route.
193
+
194
+ Args:
195
+ func (Callable): The handler function to decorate
196
+
197
+ Returns:
198
+ Callable: The wrapped function
199
+ """
84
200
class_name = func .__qualname__ .split ("." )[0 ]
85
201
route_registration = RouteRegistration (
86
202
class_name = class_name ,
@@ -119,8 +235,49 @@ def wrapper(*args: Any, **kwargs: Any):
119
235
return decorator_factory
120
236
121
237
238
+ # Route decorator factories for different HTTP methods
122
239
GetMapping = _create_route_decorator (HTTPMethod .GET )
240
+ """Decorator factory for creating GET route handlers.
241
+
242
+ Example:
243
+ @GetMapping("/users")
244
+ def get_users(self):
245
+ return {"users": []}
246
+ """
247
+
123
248
PostMapping = _create_route_decorator (HTTPMethod .POST )
249
+ """Decorator factory for creating POST route handlers.
250
+
251
+ Example:
252
+ @PostMapping("/users", response_model=UserResponse)
253
+ def create_user(self, user: UserCreate):
254
+ return create_new_user(user)
255
+ """
256
+
124
257
PutMapping = _create_route_decorator (HTTPMethod .PUT )
258
+ """Decorator factory for creating PUT route handlers.
259
+
260
+ Example:
261
+ @PutMapping("/users/{user_id}")
262
+ def update_user(self, user_id: int, user: UserUpdate):
263
+ return update_existing_user(user_id, user)
264
+ """
265
+
125
266
DeleteMapping = _create_route_decorator (HTTPMethod .DELETE )
267
+ """Decorator factory for creating DELETE route handlers.
268
+
269
+ Example:
270
+ @DeleteMapping("/users/{user_id}")
271
+ def delete_user(self, user_id: int):
272
+ delete_existing_user(user_id)
273
+ return {"message": "User deleted"}
274
+ """
275
+
126
276
PatchMapping = _create_route_decorator (HTTPMethod .PATCH )
277
+ """Decorator factory for creating PATCH route handlers.
278
+
279
+ Example:
280
+ @PatchMapping("/users/{user_id}")
281
+ def partial_update_user(self, user_id: int, user: UserPatch):
282
+ return patch_existing_user(user_id, user)
283
+ """
0 commit comments