22import logging
33import warnings
44
5+ from functools import lru_cache
56from six import iteritems
67
7- from openapi_core .enums import ParameterLocation , ParameterStyle
8+ from openapi_core .enums import ParameterLocation , ParameterStyle , SchemaType
89from openapi_core .exceptions import (
910 EmptyValue , InvalidValueType , InvalidParameterValue ,
1011)
1112
1213log = logging .getLogger (__name__ )
1314
15+ PARAMETER_STYLE_DESERIALIZERS = {
16+ ParameterStyle .FORM : lambda x : x .split (',' ),
17+ ParameterStyle .SIMPLE : lambda x : x .split (',' ),
18+ ParameterStyle .SPACE_DELIMITED : lambda x : x .split (' ' ),
19+ ParameterStyle .PIPE_DELIMITED : lambda x : x .split ('|' ),
20+ }
21+
1422
1523class Parameter (object ):
1624 """Represents an OpenAPI operation Parameter."""
@@ -32,7 +40,14 @@ def __init__(
3240 )
3341 self .items = items
3442 self .style = ParameterStyle (style or self .default_style )
35- self .explode = explode or self .default_explode
43+ self .explode = self .default_explode if explode is None else explode
44+
45+ @property
46+ def aslist (self ):
47+ return (
48+ self .schema and
49+ self .schema .type in [SchemaType .ARRAY , SchemaType .OBJECT ]
50+ )
3651
3752 @property
3853 def default_style (self ):
@@ -45,6 +60,16 @@ def default_style(self):
4560 def default_explode (self ):
4661 return self .style == ParameterStyle .FORM
4762
63+ def get_dererializer (self ):
64+ return PARAMETER_STYLE_DESERIALIZERS [self .style ]
65+
66+ def deserialize (self , value ):
67+ if not self .aslist or self .explode :
68+ return value
69+
70+ deserializer = self .get_dererializer ()
71+ return deserializer (value )
72+
4873 def unmarshal (self , value ):
4974 if self .deprecated :
5075 warnings .warn (
@@ -60,65 +85,65 @@ def unmarshal(self, value):
6085 if not self .schema :
6186 return value
6287
88+ deserialized = self .deserialize (value )
89+
6390 try :
64- return self .schema .unmarshal (value )
91+ return self .schema .unmarshal (deserialized )
6592 except InvalidValueType as exc :
6693 raise InvalidParameterValue (str (exc ))
6794
6895
96+ class ParameterFactory (object ):
97+
98+ def __init__ (self , dereferencer , schemas_registry ):
99+ self .dereferencer = dereferencer
100+ self .schemas_registry = schemas_registry
101+
102+ def create (self , parameter_spec , parameter_name = None ):
103+ parameter_deref = self .dereferencer .dereference (parameter_spec )
104+
105+ parameter_name = parameter_name or parameter_deref ['name' ]
106+ parameter_in = parameter_deref .get ('in' , 'header' )
107+
108+ allow_empty_value = parameter_deref .get ('allowEmptyValue' )
109+ required = parameter_deref .get ('required' , False )
110+
111+ style = parameter_deref .get ('style' )
112+ explode = parameter_deref .get ('explode' )
113+
114+ schema_spec = parameter_deref .get ('schema' , None )
115+ schema = None
116+ if schema_spec :
117+ schema , _ = self .schemas_registry .get_or_create (schema_spec )
118+
119+ return Parameter (
120+ parameter_name , parameter_in ,
121+ schema = schema , required = required ,
122+ allow_empty_value = allow_empty_value ,
123+ style = style , explode = explode ,
124+ )
125+
126+
69127class ParametersGenerator (object ):
70128
71129 def __init__ (self , dereferencer , schemas_registry ):
72130 self .dereferencer = dereferencer
73131 self .schemas_registry = schemas_registry
74132
75133 def generate (self , parameters ):
76- for parameter_name , parameter in iteritems (parameters ):
77- parameter_deref = self .dereferencer .dereference (parameter )
78-
79- parameter_in = parameter_deref .get ('in' , 'header' )
80-
81- allow_empty_value = parameter_deref .get ('allowEmptyValue' )
82- required = parameter_deref .get ('required' , False )
83-
84- schema_spec = parameter_deref .get ('schema' , None )
85- schema = None
86- if schema_spec :
87- schema , _ = self .schemas_registry .get_or_create (schema_spec )
88-
89- yield (
90- parameter_name ,
91- Parameter (
92- parameter_name , parameter_in ,
93- schema = schema , required = required ,
94- allow_empty_value = allow_empty_value ,
95- ),
96- )
134+ for parameter_name , parameter_spec in iteritems (parameters ):
135+ parameter = self .parameter_factory .create (
136+ parameter_spec , parameter_name = parameter_name )
137+
138+ yield (parameter_name , parameter )
97139
98140 def generate_from_list (self , parameters_list ):
99- for parameter in parameters_list :
100- parameter_deref = self .dereferencer .dereference (parameter )
101-
102- parameter_name = parameter_deref ['name' ]
103- parameter_in = parameter_deref .get ('in' , 'header' )
104-
105- allow_empty_value = parameter_deref .get ('allowEmptyValue' )
106- required = parameter_deref .get ('required' , False )
107-
108- style = parameter_deref .get ('style' )
109- explode = parameter_deref .get ('explode' )
110-
111- schema_spec = parameter_deref .get ('schema' , None )
112- schema = None
113- if schema_spec :
114- schema , _ = self .schemas_registry .get_or_create (schema_spec )
115-
116- yield (
117- parameter_name ,
118- Parameter (
119- parameter_name , parameter_in ,
120- schema = schema , required = required ,
121- allow_empty_value = allow_empty_value ,
122- style = style , explode = explode ,
123- ),
124- )
141+ for parameter_spec in parameters_list :
142+ parameter = self .parameter_factory .create (parameter_spec )
143+
144+ yield (parameter .name , parameter )
145+
146+ @property
147+ @lru_cache ()
148+ def parameter_factory (self ):
149+ return ParameterFactory (self .dereferencer , self .schemas_registry )
0 commit comments