Skip to content

Commit b7a8b03

Browse files
committed
move view handlers to view class
1 parent 723cfde commit b7a8b03

File tree

4 files changed

+83
-85
lines changed

4 files changed

+83
-85
lines changed

fastapi_jsonapi/views/detail_view.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import logging
2-
from typing import TypeVar, Union
2+
from typing import TYPE_CHECKING, TypeVar, Union
33

44
from fastapi_jsonapi import BadRequest
55
from fastapi_jsonapi.schema import (
66
BaseJSONAPIItemInSchema,
77
JSONAPIResultDetailSchema,
88
)
99
from fastapi_jsonapi.views.view_base import ViewBase
10-
from fastapi_jsonapi.views.view_handlers import handle_endpoint_dependencies
10+
11+
if TYPE_CHECKING:
12+
from fastapi_jsonapi.data_layers.base import BaseDataLayer
1113

1214
logger = logging.getLogger(__name__)
1315

@@ -21,8 +23,7 @@ async def handle_get_resource_detail(
2123
object_id: Union[int, str],
2224
**extra_view_deps,
2325
):
24-
dl_kwargs = await handle_endpoint_dependencies(self, extra_view_deps)
25-
dl = self._get_data_layer_for_detail(**dl_kwargs)
26+
dl: "BaseDataLayer" = await self._get_data_layer_for_detail(extra_view_deps)
2627

2728
view_kwargs = {dl.url_id_field: object_id}
2829
db_object = await dl.get_object(view_kwargs=view_kwargs, qs=self.query_params)
@@ -40,8 +41,7 @@ async def handle_update_resource(
4041
detail="obj_id and data.id should be same",
4142
pointer="/data/id",
4243
)
43-
dl_kwargs = await handle_endpoint_dependencies(self, extra_view_deps)
44-
dl = self._get_data_layer_for_detail(**dl_kwargs)
44+
dl: "BaseDataLayer" = await self._get_data_layer_for_detail(extra_view_deps)
4545

4646
view_kwargs = {dl.url_id_field: obj_id}
4747
db_object = await dl.get_object(view_kwargs=view_kwargs, qs=self.query_params)
@@ -55,8 +55,7 @@ async def handle_delete_resource(
5555
obj_id: str,
5656
**extra_view_deps,
5757
):
58-
dl_kwargs = await handle_endpoint_dependencies(self, extra_view_deps)
59-
dl = self._get_data_layer_for_detail(**dl_kwargs)
58+
dl: "BaseDataLayer" = await self._get_data_layer_for_detail(extra_view_deps)
6059

6160
view_kwargs = {dl.url_id_field: obj_id}
6261
db_object = await dl.get_object(view_kwargs=view_kwargs, qs=self.query_params)

fastapi_jsonapi/views/list_view.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import logging
2+
from typing import TYPE_CHECKING
23

34
from fastapi_jsonapi.schema import (
45
BaseJSONAPIDataInSchema,
56
JSONAPIResultDetailSchema,
67
JSONAPIResultListSchema,
78
)
89
from fastapi_jsonapi.views.view_base import ViewBase
9-
from fastapi_jsonapi.views.view_handlers import handle_endpoint_dependencies
10+
11+
if TYPE_CHECKING:
12+
from fastapi_jsonapi.data_layers.base import BaseDataLayer
1013

1114
logger = logging.getLogger(__name__)
1215

@@ -26,8 +29,7 @@ def _calculate_total_pages(self, db_items_count: int) -> int:
2629
return total_pages
2730

2831
async def handle_get_resource_list(self, **extra_view_deps) -> JSONAPIResultListSchema:
29-
dl_kwargs = await handle_endpoint_dependencies(self, extra_view_deps)
30-
dl = self._get_data_layer_for_list(**dl_kwargs)
32+
dl: "BaseDataLayer" = await self._get_data_layer_for_list(extra_view_deps)
3133
query_params = self.query_params
3234
count, items_from_db = await dl.get_collection(qs=query_params)
3335
total_pages = self._calculate_total_pages(count)
@@ -39,8 +41,7 @@ async def handle_post_resource_list(
3941
data_create: BaseJSONAPIDataInSchema,
4042
**extra_view_deps,
4143
) -> JSONAPIResultDetailSchema:
42-
dl_kwargs = await handle_endpoint_dependencies(self, extra_view_deps)
43-
dl = self._get_data_layer_for_list(**dl_kwargs)
44+
dl: "BaseDataLayer" = await self._get_data_layer_for_list(extra_view_deps)
4445
created_object = await dl.create_object(data_create=data_create.data, view_kwargs={})
4546
created_object_id = getattr(created_object, dl.get_object_id_field_name())
4647

@@ -50,8 +51,7 @@ async def handle_post_resource_list(
5051
return self._build_detail_response(db_object)
5152

5253
async def handle_delete_resource_list(self, **extra_view_deps) -> JSONAPIResultListSchema:
53-
dl_kwargs = await handle_endpoint_dependencies(self, extra_view_deps)
54-
dl = self._get_data_layer_for_list(**dl_kwargs)
54+
dl: "BaseDataLayer" = await self._get_data_layer_for_list(extra_view_deps)
5555
query_params = self.query_params
5656
count, items_from_db = await dl.get_collection(qs=query_params)
5757
total_pages = self._calculate_total_pages(count)

fastapi_jsonapi/views/view_base.py

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import inspect
12
import logging
23
from contextvars import ContextVar
4+
from functools import partial
35
from typing import (
46
Any,
7+
Callable,
58
Dict,
69
Iterable,
710
List,
@@ -12,7 +15,9 @@
1215
)
1316

1417
from fastapi import Request
18+
from pydantic import BaseModel as PydanticBaseModel
1519
from pydantic.fields import ModelField
20+
from starlette.concurrency import run_in_threadpool
1621

1722
from fastapi_jsonapi import QueryStringManager, RoutersJSONAPI
1823
from fastapi_jsonapi.data_layers.base import BaseDataLayer
@@ -64,26 +69,84 @@ def _get_data_layer(self, schema: Type[BaseModel], **dl_kwargs):
6469
**dl_kwargs,
6570
)
6671

67-
def _get_data_layer_for_detail(self, **kwargs: Any) -> BaseDataLayer:
72+
async def _get_data_layer_for_detail(
73+
self,
74+
extra_view_deps: Dict[str, Any],
75+
) -> BaseDataLayer:
6876
"""
69-
:param kwargs: Any extra kwargs for the data layer
77+
:param extra_view_deps:
7078
:return:
7179
"""
80+
dl_kwargs = await self.handle_endpoint_dependencies(extra_view_deps)
7281
return self._get_data_layer(
7382
schema=self.jsonapi.schema_detail,
74-
**kwargs,
83+
**dl_kwargs,
7584
)
7685

77-
def _get_data_layer_for_list(self, **kwargs: Any) -> BaseDataLayer:
86+
async def _get_data_layer_for_list(
87+
self,
88+
extra_view_deps: Dict[str, Any],
89+
) -> BaseDataLayer:
7890
"""
79-
:param kwargs: Any extra kwargs for the data layer
91+
:param extra_view_deps:
8092
:return:
8193
"""
94+
dl_kwargs = await self.handle_endpoint_dependencies(extra_view_deps)
8295
return self._get_data_layer(
8396
schema=self.jsonapi.schema_list,
84-
**kwargs,
97+
**dl_kwargs,
8598
)
8699

100+
async def _run_handler(
101+
self,
102+
handler: Callable,
103+
dto: Optional[BaseModel] = None,
104+
):
105+
handler = partial(handler, self, dto) if dto is not None else partial(handler, self)
106+
107+
if inspect.iscoroutinefunction(handler):
108+
return await handler()
109+
110+
return await run_in_threadpool(handler)
111+
112+
async def _handle_config(
113+
self,
114+
method_config: HTTPMethodConfig,
115+
extra_view_deps: Dict[str, Any],
116+
) -> Dict[str, Any]:
117+
if method_config.handler is None:
118+
return {}
119+
120+
if method_config.dependencies:
121+
dto_class: Type[PydanticBaseModel] = method_config.dependencies
122+
dto = dto_class(**extra_view_deps)
123+
dl_kwargs = await self._run_handler(method_config.handler, dto)
124+
125+
return dl_kwargs
126+
127+
dl_kwargs = await self._run_handler(method_config.handler)
128+
129+
return dl_kwargs
130+
131+
async def handle_endpoint_dependencies(
132+
self,
133+
extra_view_deps: Dict[str, Any],
134+
) -> Dict:
135+
"""
136+
:return dict: this is **kwargs for DataLayer.__init___
137+
"""
138+
dl_kwargs = {}
139+
if common_method_config := self.method_dependencies.get(HTTPMethod.ALL):
140+
dl_kwargs.update(await self._handle_config(common_method_config, extra_view_deps))
141+
142+
if self.request.method not in HTTPMethod.names():
143+
return dl_kwargs
144+
145+
if method_config := self.method_dependencies.get(HTTPMethod[self.request.method]):
146+
dl_kwargs.update(await self._handle_config(method_config, extra_view_deps))
147+
148+
return dl_kwargs
149+
87150
def _build_response(self, items_from_db: List[TypeModel], item_schema: Type[BaseModel]):
88151
return self.process_includes_for_db_items(
89152
includes=self.query_params.include,

fastapi_jsonapi/views/view_handlers.py

Lines changed: 0 additions & 64 deletions
This file was deleted.

0 commit comments

Comments
 (0)