kinto 19.5.0__py3-none-any.whl → 19.6.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kinto might be problematic. Click here for more details.
- kinto/core/__init__.py +3 -3
- kinto/core/cornice/__init__.py +93 -0
- kinto/core/cornice/cors.py +144 -0
- kinto/core/cornice/errors.py +40 -0
- kinto/core/cornice/pyramidhook.py +373 -0
- kinto/core/cornice/renderer.py +89 -0
- kinto/core/cornice/resource.py +205 -0
- kinto/core/cornice/service.py +641 -0
- kinto/core/cornice/util.py +138 -0
- kinto/core/cornice/validators/__init__.py +94 -0
- kinto/core/cornice/validators/_colander.py +142 -0
- kinto/core/cornice/validators/_marshmallow.py +182 -0
- kinto/core/cornice_swagger/__init__.py +92 -0
- kinto/core/cornice_swagger/converters/__init__.py +21 -0
- kinto/core/cornice_swagger/converters/exceptions.py +6 -0
- kinto/core/cornice_swagger/converters/parameters.py +90 -0
- kinto/core/cornice_swagger/converters/schema.py +249 -0
- kinto/core/cornice_swagger/swagger.py +725 -0
- kinto/core/cornice_swagger/templates/index.html +73 -0
- kinto/core/cornice_swagger/templates/index_script_template.html +21 -0
- kinto/core/cornice_swagger/util.py +42 -0
- kinto/core/cornice_swagger/views.py +78 -0
- kinto/core/openapi.py +2 -3
- kinto/core/resource/viewset.py +1 -1
- kinto/core/testing.py +1 -1
- kinto/core/utils.py +3 -2
- kinto/core/views/batch.py +1 -1
- kinto/core/views/openapi.py +1 -1
- kinto/plugins/flush.py +1 -1
- kinto/plugins/openid/views.py +1 -1
- kinto/views/contribute.py +2 -1
- {kinto-19.5.0.dist-info → kinto-19.6.0.dist-info}/METADATA +2 -4
- {kinto-19.5.0.dist-info → kinto-19.6.0.dist-info}/RECORD +37 -16
- {kinto-19.5.0.dist-info → kinto-19.6.0.dist-info}/LICENSE +0 -0
- {kinto-19.5.0.dist-info → kinto-19.6.0.dist-info}/WHEEL +0 -0
- {kinto-19.5.0.dist-info → kinto-19.6.0.dist-info}/entry_points.txt +0 -0
- {kinto-19.5.0.dist-info → kinto-19.6.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Converts from colander request chema to Swagger parameters."""
|
|
2
|
+
|
|
3
|
+
from kinto.core.cornice_swagger.converters.exceptions import NoSuchConverter
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ParameterConverter(object):
|
|
7
|
+
_in = None
|
|
8
|
+
|
|
9
|
+
def convert(self, schema_node, definition_handler):
|
|
10
|
+
"""
|
|
11
|
+
Convert node schema into a parameter object.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
converted = {"name": schema_node.name, "in": self._in, "required": schema_node.required}
|
|
15
|
+
if schema_node.description:
|
|
16
|
+
converted["description"] = schema_node.description
|
|
17
|
+
|
|
18
|
+
if schema_node.default:
|
|
19
|
+
converted["default"] = schema_node.default
|
|
20
|
+
|
|
21
|
+
schema = definition_handler(schema_node)
|
|
22
|
+
# Parameters shouldn't have a title
|
|
23
|
+
schema.pop("title", None)
|
|
24
|
+
converted.update(schema)
|
|
25
|
+
|
|
26
|
+
if schema.get("type") == "array":
|
|
27
|
+
converted["items"] = {"type": schema["items"]["type"]}
|
|
28
|
+
|
|
29
|
+
return converted
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class PathParameterConverter(ParameterConverter):
|
|
33
|
+
_in = "path"
|
|
34
|
+
|
|
35
|
+
def convert(self, schema_node, definition_handler):
|
|
36
|
+
converted = super(PathParameterConverter, self).convert(schema_node, definition_handler)
|
|
37
|
+
# Extract regex pattern from name
|
|
38
|
+
template = converted["name"].split(":", 1)
|
|
39
|
+
if len(template) == 2:
|
|
40
|
+
converted["name"] = template[0]
|
|
41
|
+
converted["pattern"] = template[1]
|
|
42
|
+
|
|
43
|
+
return converted
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class QueryParameterConverter(ParameterConverter):
|
|
47
|
+
_in = "query"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class HeaderParameterConverter(ParameterConverter):
|
|
51
|
+
_in = "header"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class BodyParameterConverter(ParameterConverter):
|
|
55
|
+
_in = "body"
|
|
56
|
+
|
|
57
|
+
def convert(self, schema_node, definition_handler):
|
|
58
|
+
converted = {"name": schema_node.name, "in": self._in, "required": schema_node.required}
|
|
59
|
+
if schema_node.description:
|
|
60
|
+
converted["description"] = schema_node.description
|
|
61
|
+
|
|
62
|
+
schema_node.title = schema_node.__class__.__name__
|
|
63
|
+
schema = definition_handler(schema_node)
|
|
64
|
+
converted["schema"] = schema
|
|
65
|
+
|
|
66
|
+
return converted
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ParameterConversionDispatcher(object):
|
|
70
|
+
converters = {
|
|
71
|
+
"body": BodyParameterConverter,
|
|
72
|
+
"path": PathParameterConverter,
|
|
73
|
+
"querystring": QueryParameterConverter,
|
|
74
|
+
"GET": QueryParameterConverter,
|
|
75
|
+
"header": HeaderParameterConverter,
|
|
76
|
+
"headers": HeaderParameterConverter,
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
def __init__(self, definition_handler):
|
|
80
|
+
self.definition_handler = definition_handler
|
|
81
|
+
|
|
82
|
+
def __call__(self, location, schema_node):
|
|
83
|
+
converter_class = self.converters.get(location)
|
|
84
|
+
if converter_class is None:
|
|
85
|
+
raise NoSuchConverter()
|
|
86
|
+
|
|
87
|
+
converter = converter_class()
|
|
88
|
+
converted = converter.convert(schema_node, self.definition_handler)
|
|
89
|
+
|
|
90
|
+
return converted
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module handles the conversion between colander object schemas and swagger
|
|
3
|
+
object schemas by converting types and node validators.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import colander
|
|
7
|
+
|
|
8
|
+
from kinto.core.cornice_swagger.converters.exceptions import NoSuchConverter
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def convert_length_validator_factory(max_key, min_key):
|
|
12
|
+
def validator_converter(validator):
|
|
13
|
+
converted = None
|
|
14
|
+
|
|
15
|
+
if isinstance(validator, colander.Length):
|
|
16
|
+
converted = {}
|
|
17
|
+
if validator.max is not None:
|
|
18
|
+
converted[max_key] = validator.max
|
|
19
|
+
if validator.min is not None:
|
|
20
|
+
converted[min_key] = validator.min
|
|
21
|
+
|
|
22
|
+
return converted
|
|
23
|
+
|
|
24
|
+
return validator_converter
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def convert_oneof_validator_factory():
|
|
28
|
+
def validator_converter(validator):
|
|
29
|
+
converted = None
|
|
30
|
+
|
|
31
|
+
if isinstance(validator, colander.OneOf):
|
|
32
|
+
converted = {"enum": list(validator.choices)}
|
|
33
|
+
return converted
|
|
34
|
+
|
|
35
|
+
return validator_converter
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def convert_range_validator(validator):
|
|
39
|
+
converted = None
|
|
40
|
+
|
|
41
|
+
if isinstance(validator, colander.Range):
|
|
42
|
+
converted = {}
|
|
43
|
+
|
|
44
|
+
if validator.max is not None:
|
|
45
|
+
converted["maximum"] = validator.max
|
|
46
|
+
if validator.min is not None:
|
|
47
|
+
converted["minimum"] = validator.min
|
|
48
|
+
|
|
49
|
+
return converted
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def convert_regex_validator(validator):
|
|
53
|
+
converted = None
|
|
54
|
+
|
|
55
|
+
if isinstance(validator, colander.Regex):
|
|
56
|
+
converted = {}
|
|
57
|
+
|
|
58
|
+
if hasattr(colander, "url") and validator is colander.url:
|
|
59
|
+
converted["format"] = "url"
|
|
60
|
+
elif isinstance(validator, colander.Email):
|
|
61
|
+
converted["format"] = "email"
|
|
62
|
+
else:
|
|
63
|
+
converted["pattern"] = validator.match_object.pattern
|
|
64
|
+
|
|
65
|
+
return converted
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class ValidatorConversionDispatcher(object):
|
|
69
|
+
def __init__(self, *converters):
|
|
70
|
+
self.converters = converters
|
|
71
|
+
|
|
72
|
+
def __call__(self, schema_node, validator=None):
|
|
73
|
+
if validator is None:
|
|
74
|
+
validator = schema_node.validator
|
|
75
|
+
|
|
76
|
+
converted = {}
|
|
77
|
+
if validator is not None:
|
|
78
|
+
for converter in (self.convert_all_validator,) + self.converters:
|
|
79
|
+
ret = converter(validator)
|
|
80
|
+
if ret is not None:
|
|
81
|
+
converted = ret
|
|
82
|
+
break
|
|
83
|
+
|
|
84
|
+
return converted
|
|
85
|
+
|
|
86
|
+
def convert_all_validator(self, validator):
|
|
87
|
+
if isinstance(validator, colander.All):
|
|
88
|
+
converted = {}
|
|
89
|
+
for v in validator.validators:
|
|
90
|
+
ret = self(None, v)
|
|
91
|
+
converted.update(ret)
|
|
92
|
+
return converted
|
|
93
|
+
else:
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class TypeConverter(object):
|
|
98
|
+
type = ""
|
|
99
|
+
|
|
100
|
+
def __init__(self, dispatcher):
|
|
101
|
+
self.dispatcher = dispatcher
|
|
102
|
+
|
|
103
|
+
def convert_validator(self, schema_node):
|
|
104
|
+
return {}
|
|
105
|
+
|
|
106
|
+
def convert_type(self, schema_node):
|
|
107
|
+
converted = {"type": self.type}
|
|
108
|
+
|
|
109
|
+
if schema_node.title:
|
|
110
|
+
converted["title"] = schema_node.title
|
|
111
|
+
if schema_node.description:
|
|
112
|
+
converted["description"] = schema_node.description
|
|
113
|
+
if schema_node.missing not in (colander.required, colander.drop, colander.null):
|
|
114
|
+
converted["default"] = schema_node.missing
|
|
115
|
+
if "example" in schema_node.__dict__:
|
|
116
|
+
converted["example"] = schema_node.example
|
|
117
|
+
|
|
118
|
+
return converted
|
|
119
|
+
|
|
120
|
+
def __call__(self, schema_node):
|
|
121
|
+
converted = self.convert_type(schema_node)
|
|
122
|
+
converted.update(self.convert_validator(schema_node))
|
|
123
|
+
|
|
124
|
+
return converted
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class BaseStringTypeConverter(TypeConverter):
|
|
128
|
+
type = "string"
|
|
129
|
+
format = None
|
|
130
|
+
|
|
131
|
+
def convert_type(self, schema_node):
|
|
132
|
+
converted = super(BaseStringTypeConverter, self).convert_type(schema_node)
|
|
133
|
+
|
|
134
|
+
if self.format is not None:
|
|
135
|
+
converted["format"] = self.format
|
|
136
|
+
|
|
137
|
+
return converted
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class BooleanTypeConverter(TypeConverter):
|
|
141
|
+
type = "boolean"
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class DateTypeConverter(BaseStringTypeConverter):
|
|
145
|
+
format = "date"
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class DateTimeTypeConverter(BaseStringTypeConverter):
|
|
149
|
+
format = "date-time"
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class NumberTypeConverter(TypeConverter):
|
|
153
|
+
type = "number"
|
|
154
|
+
|
|
155
|
+
convert_validator = ValidatorConversionDispatcher(
|
|
156
|
+
convert_range_validator,
|
|
157
|
+
convert_oneof_validator_factory(),
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class IntegerTypeConverter(NumberTypeConverter):
|
|
162
|
+
type = "integer"
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class StringTypeConverter(BaseStringTypeConverter):
|
|
166
|
+
convert_validator = ValidatorConversionDispatcher(
|
|
167
|
+
convert_length_validator_factory("maxLength", "minLength"),
|
|
168
|
+
convert_regex_validator,
|
|
169
|
+
convert_oneof_validator_factory(),
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class TimeTypeConverter(BaseStringTypeConverter):
|
|
174
|
+
format = "time"
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class ObjectTypeConverter(TypeConverter):
|
|
178
|
+
type = "object"
|
|
179
|
+
|
|
180
|
+
def convert_type(self, schema_node):
|
|
181
|
+
converted = super(ObjectTypeConverter, self).convert_type(schema_node)
|
|
182
|
+
|
|
183
|
+
properties = {}
|
|
184
|
+
required = []
|
|
185
|
+
|
|
186
|
+
for sub_node in schema_node.children:
|
|
187
|
+
properties[sub_node.name] = self.dispatcher(sub_node)
|
|
188
|
+
if sub_node.required:
|
|
189
|
+
required.append(sub_node.name)
|
|
190
|
+
|
|
191
|
+
if len(properties) > 0:
|
|
192
|
+
converted["properties"] = properties
|
|
193
|
+
|
|
194
|
+
if len(required) > 0:
|
|
195
|
+
converted["required"] = required
|
|
196
|
+
|
|
197
|
+
if schema_node.typ.unknown == "preserve":
|
|
198
|
+
converted["additionalProperties"] = {}
|
|
199
|
+
|
|
200
|
+
return converted
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class ArrayTypeConverter(TypeConverter):
|
|
204
|
+
type = "array"
|
|
205
|
+
|
|
206
|
+
convert_validator = ValidatorConversionDispatcher(
|
|
207
|
+
convert_length_validator_factory("maxItems", "minItems"),
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
def convert_type(self, schema_node):
|
|
211
|
+
converted = super(ArrayTypeConverter, self).convert_type(schema_node)
|
|
212
|
+
|
|
213
|
+
converted["items"] = self.dispatcher(schema_node.children[0])
|
|
214
|
+
|
|
215
|
+
return converted
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class TypeConversionDispatcher(object):
|
|
219
|
+
def __init__(self, custom_converters={}, default_converter=None):
|
|
220
|
+
self.converters = {
|
|
221
|
+
colander.Boolean: BooleanTypeConverter,
|
|
222
|
+
colander.Date: DateTypeConverter,
|
|
223
|
+
colander.DateTime: DateTimeTypeConverter,
|
|
224
|
+
colander.Float: NumberTypeConverter,
|
|
225
|
+
colander.Integer: IntegerTypeConverter,
|
|
226
|
+
colander.Mapping: ObjectTypeConverter,
|
|
227
|
+
colander.Sequence: ArrayTypeConverter,
|
|
228
|
+
colander.String: StringTypeConverter,
|
|
229
|
+
colander.Time: TimeTypeConverter,
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
self.converters.update(custom_converters)
|
|
233
|
+
self.default_converter = default_converter
|
|
234
|
+
|
|
235
|
+
def __call__(self, schema_node):
|
|
236
|
+
schema_type = schema_node.typ
|
|
237
|
+
schema_type = type(schema_type)
|
|
238
|
+
|
|
239
|
+
converter_class = self.converters.get(schema_type)
|
|
240
|
+
if converter_class is None:
|
|
241
|
+
if self.default_converter:
|
|
242
|
+
converter_class = self.default_converter
|
|
243
|
+
else:
|
|
244
|
+
raise NoSuchConverter
|
|
245
|
+
|
|
246
|
+
converter = converter_class(self)
|
|
247
|
+
converted = converter(schema_node)
|
|
248
|
+
|
|
249
|
+
return converted
|