Skip to content

Commit ce1241a

Browse files
committed
Added some Route Handler args resolver
1 parent fa0cb01 commit ce1241a

File tree

15 files changed

+974
-635
lines changed

15 files changed

+974
-635
lines changed

ellar/common/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,14 @@
3232
File,
3333
Form,
3434
Header,
35+
Host,
36+
Http,
3537
Path,
3638
Provide,
3739
Query,
3840
Req,
41+
Res,
42+
Session,
3943
Ws,
4044
WsBody,
4145
)
@@ -81,4 +85,8 @@
8185
"on_startup",
8286
"template_filter",
8387
"template_global",
88+
"Res",
89+
"Session",
90+
"Host",
91+
"Http",
8492
]

ellar/common/decorators/controller.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def Controller(
100100
:param description: OPENAPI description
101101
:param external_doc_description: OPENAPI External Doc Description
102102
:param external_doc_url: OPENAPI External Document URL
103-
:param name: route name prefix for url reversing, eg name:route_name default=''
103+
:param name: route name prefix for url reversing, eg name:route_name default=controller_name
104104
:param version: default URL versioning for all defined route in a controller
105105
:param guards: default guard for all routes defined under this controller
106106
:param include_in_schema: include controller in OPENAPI schema
@@ -114,7 +114,7 @@ def Controller(
114114
assert _prefix == "" or str(_prefix).startswith(
115115
"/"
116116
), "Controller Prefix must start with '/'"
117-
117+
# TODO: replace with a ControllerTypeDict and OpenAPITypeDict
118118
kwargs = AttributeDict(
119119
openapi=AttributeDict(
120120
tag=tag,

ellar/common/routing/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88
File,
99
Form,
1010
Header,
11+
Host,
12+
Http,
1113
Path,
1214
Provide,
1315
Query,
1416
Req,
17+
Res,
18+
Session,
1519
Ws,
1620
WsBody,
1721
)
@@ -58,4 +62,8 @@
5862
"head",
5963
"http_route",
6064
"ws_route",
65+
"Res",
66+
"Session",
67+
"Host",
68+
"Http",
6169
]

ellar/common/routing/params.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
from pydantic.error_wrappers import ErrorWrapper
44
from pydantic.fields import Undefined
5+
from starlette.responses import Response
56

6-
from ellar.core.connection import Request, WebSocket
7+
from ellar.core.connection import HTTPConnection, Request, WebSocket
78
from ellar.core.context import IExecutionContext
89
from ellar.core.params import params
910
from ellar.core.params.resolvers import (
11+
BaseRequestRouteParameterResolver,
1012
NonFieldRouteParameterResolver,
1113
ParameterInjectable,
1214
)
@@ -368,6 +370,49 @@ async def resolve(
368370
return {self.parameter_name: ctx}, []
369371

370372

373+
class _HostRequestParam(BaseRequestRouteParameterResolver):
374+
lookup_connection_field = None
375+
376+
async def get_value(self, ctx: IExecutionContext) -> t.Any:
377+
connection = ctx.switch_to_http_connection()
378+
if connection.client:
379+
return connection.client.host
380+
381+
382+
class _SessionRequestParam(BaseRequestRouteParameterResolver):
383+
lookup_connection_field = "session"
384+
385+
386+
class _ConnectionParam(NonFieldRouteParameterResolver):
387+
async def resolve(
388+
self, ctx: IExecutionContext, **kwargs: t.Any
389+
) -> t.Tuple[t.Dict, t.List]:
390+
try:
391+
connection = ctx.switch_to_http_connection()
392+
return {self.parameter_name: connection}, []
393+
except Exception as ex:
394+
return {}, [ErrorWrapper(ex, loc=self.parameter_name or "connection")]
395+
396+
397+
class _ResponseRequestParam(NonFieldRouteParameterResolver):
398+
async def resolve(
399+
self, ctx: IExecutionContext, **kwargs: t.Any
400+
) -> t.Tuple[t.Dict, t.List]:
401+
try:
402+
response = ctx.get_response()
403+
return {self.parameter_name: response}, []
404+
except Exception as ex:
405+
return {}, [ErrorWrapper(ex, loc=self.parameter_name or "response")]
406+
407+
408+
def Http() -> HTTPConnection:
409+
"""
410+
Route Function Parameter for retrieving Current Request Instance
411+
:return: Request
412+
"""
413+
return t.cast(Request, _ConnectionParam())
414+
415+
371416
def Req() -> Request:
372417
"""
373418
Route Function Parameter for retrieving Current Request Instance
@@ -398,3 +443,28 @@ def Provide(service: t.Optional[t.Type[T]] = None) -> T:
398443
:return: T
399444
"""
400445
return t.cast(T, ParameterInjectable(service))
446+
447+
448+
def Session() -> t.Dict:
449+
"""
450+
Route Function Parameter for resolving registered `HTTPConnection.sessions`
451+
Ensure SessionMiddleware is registered to application middlewares
452+
:return: Dict
453+
"""
454+
return t.cast(t.Dict, _SessionRequestParam())
455+
456+
457+
def Host() -> str:
458+
"""
459+
Route Function Parameter for resolving registered `HTTPConnection.client.host`
460+
:return: str
461+
"""
462+
return t.cast(str, _HostRequestParam())
463+
464+
465+
def Res() -> Response:
466+
"""
467+
Route Function Parameter for resolving registered Response
468+
:return: Response
469+
"""
470+
return t.cast(Response, _ResponseRequestParam())

ellar/core/params/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@
55
WebsocketEndpointArgsModel,
66
)
77
from .params import Body, Cookie, File, Form, Header, Param, ParamTypes, Path, Query
8-
from .resolvers import NonFieldRouteParameterResolver
8+
from .resolvers import (
9+
BaseRequestRouteParameterResolver,
10+
BaseRouteParameterResolver,
11+
NonFieldRouteParameterResolver,
12+
)
913

1014
__all__ = [
1115
"WebsocketEndpointArgsModel",
1216
"RequestEndpointArgsModel",
1317
"ExtraEndpointArg",
1418
"EndpointArgsModel",
1519
"NonFieldRouteParameterResolver",
20+
"BaseRequestRouteParameterResolver",
21+
"BaseRouteParameterResolver",
1622
"Body",
1723
"Cookie",
1824
"File",

0 commit comments

Comments
 (0)