Skip to content

Commit 0f76e5c

Browse files
committed
Dropped Controller Responses Model and removed py3.6 codes
1 parent 0f46596 commit 0f76e5c

File tree

12 files changed

+90
-674
lines changed

12 files changed

+90
-674
lines changed

ninja_extra/controllers/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from ninja_extra.constants import ROUTE_FUNCTION, THROTTLED_FUNCTION
3434
from ninja_extra.exceptions import APIException, NotFound, PermissionDenied, bad_request
3535
from ninja_extra.helper import get_function_name
36-
from ninja_extra.operation import ControllerPathView, Operation
36+
from ninja_extra.operation import Operation, PathView
3737
from ninja_extra.permissions import AllowAny, BasePermission
3838
from ninja_extra.permissions.base import OperationHolderMixin
3939
from ninja_extra.shortcuts import (
@@ -277,7 +277,7 @@ def __init__(
277277
# `controller_class` target class that the APIController wraps
278278
self._controller_class: Optional[Type["ControllerBase"]] = None
279279
# `_path_operations` a converted dict of APIController route function used by Django-Ninja library
280-
self._path_operations: Dict[str, ControllerPathView] = {}
280+
self._path_operations: Dict[str, PathView] = {}
281281
self._controller_class_route_functions: Dict[str, RouteFunction] = {}
282282
# `permission_classes` a collection of BasePermission Types
283283
# a fallback if route functions has no permissions definition
@@ -357,7 +357,7 @@ def __call__(self, cls: Type) -> Union[Type, Type["ControllerBase"]]:
357357
return cls
358358

359359
@property
360-
def path_operations(self) -> Dict[str, ControllerPathView]:
360+
def path_operations(self) -> Dict[str, PathView]:
361361
return self._path_operations
362362

363363
def set_api_instance(self, api: "NinjaExtraAPI") -> None:
@@ -410,7 +410,7 @@ def _add_operation_from_route_function(self, route_function: RouteFunction) -> N
410410
f"endpoint={get_function_name(route_function.route.view_func)}"
411411
)
412412

413-
route_function.operation = self.add_api_operation( # type: ignore
413+
route_function.operation = self.add_api_operation(
414414
view_func=route_function.as_view, **route_function.route.route_params.dict()
415415
)
416416

@@ -440,7 +440,7 @@ def add_api_operation(
440440
if self._prefix_has_route_param:
441441
path = normalize_path("/".join([i for i in (self.prefix, path) if i]))
442442
if path not in self._path_operations:
443-
path_view = ControllerPathView()
443+
path_view = PathView()
444444
self._path_operations[path] = path_view
445445
else:
446446
path_view = self._path_operations[path]
Lines changed: 11 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,22 @@
1-
import sys
21
from typing import (
32
Any,
4-
Dict,
5-
Generic,
63
Optional,
7-
Tuple,
84
Type,
9-
TypeVar,
105
Union,
116
no_type_check,
127
)
138

149
from ninja import Schema
1510

1611
from .. import status
17-
from ..schemas import DetailSchema, IdSchema, OkSchema
1812

19-
T = TypeVar("T")
20-
SCHEMA_KEY = "_schema"
2113

22-
if sys.version_info < (3, 7): # pragma: no cover
23-
from typing import GenericMeta # type: ignore[attr-defined]
24-
25-
class ControllerResponseMeta(GenericMeta):
26-
@no_type_check
27-
def __new__(mcls, name: str, bases: Tuple, namespace: Dict, **kwargs: Any):
28-
args = kwargs.get("args")
29-
if args and args[0].__name__ != "T":
30-
t = args[0]
31-
origin_schema = namespace.get(SCHEMA_KEY)
32-
if origin_schema and hasattr(origin_schema, "__generic_model__"):
33-
schema = origin_schema.__generic_model__[t]
34-
else:
35-
schema = origin_schema[t]
36-
namespace[SCHEMA_KEY] = schema
37-
res = super().__new__(mcls, name, bases, namespace, **kwargs)
38-
return res
39-
40-
class GenericControllerResponse(metaclass=ControllerResponseMeta):
41-
@no_type_check
42-
def __new__(
43-
cls: Type["ControllerResponse[T]"], *args: Any, **kwargs: Any
44-
) -> "ControllerResponse[T]":
45-
if cls._gorg is Generic or "_schema" not in cls.__dict__:
46-
raise TypeError(
47-
"Type Generic cannot be instantiated; "
48-
"it can be used only as a base class"
49-
)
50-
return object.__new__(cls)
51-
52-
else:
53-
_generic_types_cache: Dict[
54-
Tuple[Type[Any], Union[Any, Tuple[Any, ...]]], Type["ControllerResponse"]
55-
] = {}
56-
GenericControllerResponseT = TypeVar(
57-
"GenericControllerResponseT", bound="GenericControllerResponse"
58-
)
59-
60-
class ControllerResponseMeta(type):
61-
pass
62-
63-
class GenericControllerResponse(metaclass=ControllerResponseMeta):
64-
def __new__( # type:ignore[misc]
65-
cls: Type["ControllerResponse[T]"], *args: Any, **kwargs: Any
66-
) -> "ControllerResponse[T]":
67-
if "_schema" not in cls.__dict__:
68-
raise TypeError(
69-
"Type Generic cannot be instantiated; "
70-
"it can be used only as a base class"
71-
)
72-
return object.__new__(cls)
73-
74-
@no_type_check
75-
def __class_getitem__(cls: Type[GenericControllerResponseT], item: Any) -> Any:
76-
if isinstance(item, tuple):
77-
raise TypeError("Tuple Generic Model not supported")
78-
79-
_key = (cls, item)
80-
_cached_value = _generic_types_cache.get(_key)
81-
if _cached_value:
82-
return _cached_value
83-
84-
if str(type(item)) == "<class 'typing.TypeVar'>":
85-
result = super().__class_getitem__(item)
86-
else:
87-
new_schema = cls.__dict__.get(SCHEMA_KEY)
88-
if hasattr(new_schema, "__generic_model__"):
89-
new_schema = new_schema.__generic_model__[item]
90-
91-
result = type(
92-
f"{cls.__name__}[{item.__name__}]", (cls,), {SCHEMA_KEY: new_schema}
93-
)
94-
_generic_types_cache[_key] = result
95-
return result
96-
97-
98-
class ControllerResponse(GenericControllerResponse, Generic[T]):
14+
class ControllerResponse:
9915
status_code: int = status.HTTP_204_NO_CONTENT
100-
_schema: Optional[T]
16+
_schema: Optional[Any]
17+
18+
def __init__(self, *args: Any, **kwargs: Any) -> None:
19+
raise RuntimeError("Controller Response are no longer supported.")
10120

10221
@classmethod
10322
def get_schema(cls) -> Union[Schema, Type[Schema], Any]: # pragma: no cover
@@ -106,96 +25,11 @@ def get_schema(cls) -> Union[Schema, Type[Schema], Any]: # pragma: no cover
10625
def convert_to_schema(self) -> Any: # pragma: no cover
10726
raise NotImplementedError
10827

28+
@no_type_check
29+
def __class_getitem__(cls: Type["ControllerResponse"], item: Any) -> Any:
30+
raise RuntimeError("Controller Response are no longer supported.")
10931

110-
class Id(ControllerResponse[T]):
111-
"""
112-
Creates a 201 response with id information
113-
{
114-
id: int| str| UUID4| UUID1| UUID3| UUID5,
115-
}
116-
Example:
117-
Id(423) ==> 201, {id: 423}
118-
OR
119-
Id[int](424) ==> 201, {id: 424}
120-
Id[UUID4]("883a1a3d-7b10-458d-bccc-f9b7219342c9")
121-
==> 201, {id: "883a1a3d-7b10-458d-bccc-f9b7219342c9"}
122-
"""
123-
124-
_schema = IdSchema[Any]
125-
status_code: int = status.HTTP_201_CREATED
126-
127-
def __init__(self, id: T) -> None:
128-
super(Id, self).__init__()
129-
self.id = id
130-
131-
def convert_to_schema(self) -> Any:
132-
return self._schema.from_orm(self)
133-
134-
@classmethod
135-
def get_schema(cls) -> Union[Schema, Type[Schema], Any]:
136-
return cls._schema
13732

138-
139-
class Ok(ControllerResponse[T]):
140-
"""
141-
Creates a 200 response with a detail information.
142-
{
143-
detail: str| List[Dict] | List[str] | Dict,
144-
}
145-
146-
Example:
147-
Ok('Saved Successfully') ==> 200, {detail: 'Saved Successfully'}
148-
OR
149-
class ASchema(BaseModel):
150-
name: str
151-
age: int
152-
153-
OK[ASchema](ASchema(name='Eadwin', age=18)) ==> 200, {detail: {'name':'Eadwin', 'age': 18}}
154-
"""
155-
156-
status_code: int = status.HTTP_200_OK
157-
_schema = OkSchema[Any]
158-
159-
def __init__(self, message: Optional[Any] = None) -> None:
160-
super(Ok, self).__init__()
161-
self.detail = message or "Action was successful"
162-
163-
def convert_to_schema(self) -> Any:
164-
return self._schema.from_orm(self)
165-
166-
@classmethod
167-
def get_schema(cls) -> Union[Schema, Type[Schema], Any]:
168-
return cls._schema
169-
170-
171-
class Detail(ControllerResponse[T]):
172-
"""
173-
Creates a custom response with detail information
174-
{
175-
detail: str| List[Dict] | List[str] | Dict,
176-
}
177-
Example:
178-
Detail('Invalid Request', 404) ==> 404, {detail: 'Invalid Request'}
179-
OR
180-
class ErrorSchema(BaseModel):
181-
message: str
182-
183-
Detail[ErrorSchema](dict(message='Bad Request'),400) ==> 400, {detail: {'message':'Bad Request'}}
184-
"""
185-
186-
status_code: int = status.HTTP_200_OK
187-
_schema = DetailSchema[Any]
188-
189-
def __init__(
190-
self, message: Optional[Any] = None, status_code: int = status.HTTP_200_OK
191-
) -> None:
192-
super(Detail, self).__init__()
193-
self.detail = message or "Action was successful"
194-
self.status_code = status_code or self.status_code
195-
196-
def convert_to_schema(self) -> Any:
197-
return self._schema.from_orm(self)
198-
199-
@classmethod
200-
def get_schema(cls) -> Union[Schema, Type[Schema], Any]:
201-
return cls._schema
33+
Detail = ControllerResponse
34+
Ok = ControllerResponse
35+
Id = ControllerResponse

ninja_extra/controllers/route/__init__.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
ROUTE_FUNCTION,
2525
ROUTE_METHODS,
2626
)
27-
from ninja_extra.controllers.response import ControllerResponse, ControllerResponseMeta
2827
from ninja_extra.permissions import BasePermission
2928
from ninja_extra.schemas import RouteParameter
3029

@@ -78,20 +77,10 @@ def __init__(
7877
)
7978

8079
_response = response
81-
if (
82-
inspect.isclass(response) and type(response) == ControllerResponseMeta
83-
) or isinstance(response, ControllerResponse):
84-
response = cast(ControllerResponse, response)
85-
_response = {response.status_code: response.get_schema()}
86-
elif isinstance(response, list):
80+
if isinstance(response, list):
8781
_response_computed = {}
8882
for item in response:
89-
if (
90-
inspect.isclass(item) and type(item) == ControllerResponseMeta
91-
) or isinstance(item, ControllerResponse):
92-
item = cast(ControllerResponse, item)
93-
_response_computed.update({item.status_code: item.get_schema()})
94-
elif isinstance(item, dict):
83+
if isinstance(item, dict):
9584
_response_computed.update(item)
9685
elif isinstance(item, tuple):
9786
_response_computed.update({item[0]: item[1]})

ninja_extra/controllers/route/route_functions.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@
66

77
from django.http import HttpRequest, HttpResponse
88

9-
from ninja_extra.controllers.response import ControllerResponse
10-
119
from ...dependency_resolver import get_injector, service_resolver
1210
from .context import RouteContext, get_route_execution_context
1311

1412
if TYPE_CHECKING: # pragma: no cover
15-
from ninja_extra.operation import ControllerOperation
13+
from ninja_extra.operation import Operation
1614

1715
from ...controllers.base import APIController, ControllerBase
1816
from ...controllers.route import Route
@@ -31,7 +29,7 @@ def __init__(
3129
self, route: "Route", api_controller: Optional["APIController"] = None
3230
):
3331
self.route = route
34-
self.operation: Optional["ControllerOperation"] = None
32+
self.operation: Optional["Operation"] = None
3533
self.has_request_param = False
3634
self.api_controller = api_controller
3735
self.as_view = wraps(route.view_func)(self.get_view_function())
@@ -100,8 +98,8 @@ def _process_view_function_result(self, result: Any) -> Any:
10098
and creates an api response if result is ControllerResponseSchema
10199
"""
102100

103-
if result and isinstance(result, ControllerResponse):
104-
return result.status_code, result.convert_to_schema()
101+
# if result and isinstance(result, ControllerResponse):
102+
# return result.status_code, result.convert_to_schema()
105103
return result
106104

107105
def _get_controller_instance(self) -> "ControllerBase":

0 commit comments

Comments
 (0)