1- import sys
21from typing import (
32 Any ,
4- Dict ,
5- Generic ,
63 Optional ,
7- Tuple ,
84 Type ,
9- TypeVar ,
105 Union ,
116 no_type_check ,
127)
138
149from ninja import Schema
1510
1611from .. 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
0 commit comments