11from functools import wraps
22from http import HTTPStatus
33from json import dumps as json_encode
4+ from typing import Any , Callable
45
56from django .core .exceptions import ImproperlyConfigured
67from django .http import HttpRequest , HttpResponse
78from django .template .loader import render_to_string
89
9- from .helpers import deep_transform_callables , validate_type
10+ from .helpers import deep_transform_callables
1011from .prop_classes import DeferredProp , IgnoreOnFirstLoadProp , MergeableProp
1112from .settings import settings
1213
1516 # a mock module
1617 import requests
1718except ImportError :
18- requests = None
19+ requests = None # type: ignore[assignment]
1920
2021
2122INERTIA_REQUEST_ENCRYPT_HISTORY = "_inertia_encrypt_history"
2627
2728
2829class InertiaRequest (HttpRequest ):
29- def __init__ (self , request ):
30+ def __init__ (self , request : HttpRequest ):
3031 super ().__init__ ()
3132 self .__dict__ .update (request .__dict__ )
3233
3334 @property
34- def inertia (self ):
35+ def inertia (self ) -> dict [ str , Any ] :
3536 inertia_attr = self .__dict__ .get ("inertia" )
3637 return (
3738 inertia_attr .all () if inertia_attr and hasattr (inertia_attr , "all" ) else {}
3839 )
3940
40- def is_a_partial_render (self , component ) :
41+ def is_a_partial_render (self , component : str ) -> bool :
4142 return (
4243 "X-Inertia-Partial-Data" in self .headers
4344 and self .headers .get ("X-Inertia-Partial-Component" , "" ) == component
4445 )
4546
46- def partial_keys (self ):
47+ def partial_keys (self ) -> list [ str ] :
4748 return self .headers .get ("X-Inertia-Partial-Data" , "" ).split ("," )
4849
49- def reset_keys (self ):
50+ def reset_keys (self ) -> list [ str ] :
5051 return self .headers .get ("X-Inertia-Reset" , "" ).split ("," )
5152
52- def is_inertia (self ):
53+ def is_inertia (self ) -> bool :
5354 return "X-Inertia" in self .headers
5455
55- def should_encrypt_history (self ):
56- return validate_type (
57- getattr (
58- self ,
59- INERTIA_REQUEST_ENCRYPT_HISTORY ,
60- settings .INERTIA_ENCRYPT_HISTORY ,
61- ),
62- expected_type = bool ,
63- name = "encrypt_history" ,
56+ def should_encrypt_history (self ) -> bool :
57+ should_encrypt = getattr (
58+ self , INERTIA_REQUEST_ENCRYPT_HISTORY , settings .INERTIA_ENCRYPT_HISTORY
6459 )
60+ if not isinstance (should_encrypt , bool ):
61+ raise TypeError (
62+ f"Expected bool for encrypt_history, got { type (should_encrypt ).__name__ } "
63+ )
64+ return should_encrypt
6565
6666
6767class BaseInertiaResponseMixin :
68- def page_data (self ):
69- clear_history = validate_type (
70- self .request .session .pop (INERTIA_SESSION_CLEAR_HISTORY , False ),
71- expected_type = bool ,
72- name = "clear_history" ,
73- )
68+ request : InertiaRequest
69+ component : str
70+ props : dict [str , Any ]
71+ template_data : dict [str , Any ]
72+
73+ def page_data (self ) -> dict [str , Any ]:
74+ clear_history = self .request .session .pop (INERTIA_SESSION_CLEAR_HISTORY , False )
75+ if not isinstance (clear_history , bool ):
76+ raise TypeError (
77+ f"Expected bool for clear_history, got { type (clear_history ).__name__ } "
78+ )
7479
7580 _page = {
7681 "component" : self .component ,
@@ -91,7 +96,7 @@ def page_data(self):
9196
9297 return _page
9398
94- def build_props (self ):
99+ def build_props (self ) -> Any :
95100 _props = {
96101 ** (self .request .inertia ),
97102 ** self .props ,
@@ -107,18 +112,18 @@ def build_props(self):
107112
108113 return deep_transform_callables (_props )
109114
110- def build_deferred_props (self ):
115+ def build_deferred_props (self ) -> dict [ str , Any ] | None :
111116 if self .request .is_a_partial_render (self .component ):
112117 return None
113118
114- _deferred_props = {}
119+ _deferred_props : dict [ str , Any ] = {}
115120 for key , prop in self .props .items ():
116121 if isinstance (prop , DeferredProp ):
117122 _deferred_props .setdefault (prop .group , []).append (key )
118123
119124 return _deferred_props
120125
121- def build_merge_props (self ):
126+ def build_merge_props (self ) -> list [ str ] :
122127 return [
123128 key
124129 for key , prop in self .props .items ()
@@ -129,7 +134,7 @@ def build_merge_props(self):
129134 )
130135 ]
131136
132- def build_first_load (self , data ) :
137+ def build_first_load (self , data : Any ) -> str :
133138 context , template = self .build_first_load_context_and_template (data )
134139
135140 try :
@@ -151,7 +156,9 @@ def build_first_load(self, data):
151156 using = None ,
152157 )
153158
154- def build_first_load_context_and_template (self , data ):
159+ def build_first_load_context_and_template (
160+ self , data : Any
161+ ) -> tuple [dict [str , Any ], str ]:
155162 if settings .INERTIA_SSR_ENABLED :
156163 try :
157164 response = requests .post (
@@ -178,14 +185,14 @@ class InertiaResponse(BaseInertiaResponseMixin, HttpResponse):
178185
179186 def __init__ (
180187 self ,
181- request ,
182- component ,
183- props = None ,
184- template_data = None ,
185- headers = None ,
186- * args ,
187- ** kwargs ,
188- ):
188+ request : HttpRequest ,
189+ component : str ,
190+ props : dict [ str , Any ] | None = None ,
191+ template_data : dict [ str , Any ] | None = None ,
192+ headers : dict [ str , Any ] | None = None ,
193+ * args : Any ,
194+ ** kwargs : Any ,
195+ ) -> None :
189196 self .request = InertiaRequest (request )
190197 self .component = component
191198 self .props = props or {}
@@ -208,19 +215,30 @@ def __init__(
208215 else :
209216 content = self .build_first_load (data )
210217
211- super ().__init__ (
212- * args ,
213- content = content ,
214- headers = _headers ,
215- ** kwargs ,
216- )
218+ if args :
219+ super ().__init__ (
220+ * args ,
221+ headers = _headers ,
222+ ** kwargs ,
223+ )
224+ else :
225+ super ().__init__ (
226+ content = content ,
227+ headers = _headers ,
228+ ** kwargs ,
229+ )
217230
218231
219- def render (request , component , props = None , template_data = None ):
232+ def render (
233+ request : HttpRequest ,
234+ component : str ,
235+ props : dict [str , Any ] | None = None ,
236+ template_data : dict [str , Any ] | None = None ,
237+ ) -> InertiaResponse :
220238 return InertiaResponse (request , component , props or {}, template_data or {})
221239
222240
223- def location (location ) :
241+ def location (location : str ) -> HttpResponse :
224242 return HttpResponse (
225243 "" ,
226244 status = HTTPStatus .CONFLICT ,
@@ -230,18 +248,27 @@ def location(location):
230248 )
231249
232250
233- def encrypt_history (request , value = True ):
251+ def encrypt_history (request : HttpRequest , value : bool = True ) -> None :
234252 setattr (request , INERTIA_REQUEST_ENCRYPT_HISTORY , value )
235253
236254
237- def clear_history (request ) :
255+ def clear_history (request : HttpRequest ) -> None :
238256 request .session [INERTIA_SESSION_CLEAR_HISTORY ] = True
239257
240258
241- def inertia (component ):
242- def decorator (func ):
259+ def inertia (
260+ component : str ,
261+ ) -> Callable [
262+ [Callable [..., HttpResponse | InertiaResponse | dict [str , Any ]]],
263+ Callable [..., HttpResponse ],
264+ ]:
265+ def decorator (
266+ func : Callable [..., HttpResponse | InertiaResponse | dict [str , Any ]],
267+ ) -> Callable [..., HttpResponse ]:
243268 @wraps (func )
244- def process_inertia_response (request , * args , ** kwargs ):
269+ def process_inertia_response (
270+ request : HttpRequest , * args : Any , ** kwargs : Any
271+ ) -> HttpResponse :
245272 props = func (request , * args , ** kwargs )
246273
247274 # if a response is returned, return it
0 commit comments