11"""This module contains the dataclasses representing the router object."""
22
33import dataclasses
4+ from typing import Mapping
45
56from reflex import constants
67from reflex .utils import format
8+ from reflex .utils .serializers import serializer
79
810
9- @dataclasses .dataclass (frozen = True )
10- class HeaderData :
11- """An object containing headers data."""
11+ @dataclasses .dataclass (frozen = True , init = False )
12+ class _FrozenDictStrStr (Mapping [str , str ]):
13+ _data : tuple [tuple [str , str ], ...]
14+
15+ def __init__ (self , ** kwargs ):
16+ object .__setattr__ (self , "_data" , tuple (sorted (kwargs .items ())))
17+
18+ def __getitem__ (self , key : str ) -> str :
19+ return dict (self ._data )[key ]
20+
21+ def __iter__ (self ):
22+ return (x [0 ] for x in self ._data )
1223
24+ def __len__ (self ):
25+ return len (self ._data )
26+
27+
28+ @dataclasses .dataclass (frozen = True )
29+ class _HeaderData :
1330 host : str = ""
1431 origin : str = ""
1532 upgrade : str = ""
@@ -23,19 +40,54 @@ class HeaderData:
2340 sec_websocket_extensions : str = ""
2441 accept_encoding : str = ""
2542 accept_language : str = ""
43+ raw_headers : Mapping [str , str ] = dataclasses .field (
44+ default_factory = _FrozenDictStrStr
45+ )
46+
47+
48+ @dataclasses .dataclass (frozen = True , init = False )
49+ class HeaderData (_HeaderData ):
50+ """An object containing headers data."""
2651
2752 def __init__ (self , router_data : dict | None = None ):
2853 """Initialize the HeaderData object based on router_data.
2954
3055 Args:
3156 router_data: the router_data dict.
3257 """
58+ super ().__init__ ()
3359 if router_data :
60+ fields_names = [f .name for f in dataclasses .fields (self )]
3461 for k , v in router_data .get (constants .RouteVar .HEADERS , {}).items ():
35- object .__setattr__ (self , format .to_snake_case (k ), v )
36- else :
37- for k in dataclasses .fields (self ):
38- object .__setattr__ (self , k .name , "" )
62+ snake_case_key = format .to_snake_case (k )
63+ if snake_case_key in fields_names :
64+ object .__setattr__ (self , snake_case_key , v )
65+ object .__setattr__ (
66+ self ,
67+ "raw_headers" ,
68+ _FrozenDictStrStr (
69+ ** {
70+ k : v
71+ for k , v in router_data .get (
72+ constants .RouteVar .HEADERS , {}
73+ ).items ()
74+ if v
75+ }
76+ ),
77+ )
78+
79+
80+ @serializer (to = dict )
81+ def serialize_frozen_dict_str_str (obj : _FrozenDictStrStr ) -> dict :
82+ """Serialize a _FrozenDictStrStr object to a dict.
83+
84+ Args:
85+ obj: the _FrozenDictStrStr object.
86+
87+ Returns:
88+ A dict representation of the _FrozenDictStrStr object.
89+ """
90+ return dict (obj ._data )
3991
4092
4193@dataclasses .dataclass (frozen = True )
0 commit comments