|
19 | 19 | ##### |
20 | 20 |
|
21 | 21 | Openapi-core is a Python library that adds client-side and server-side support |
22 | | -for the `OpenAPI Specification v3.0.0 <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md>`__. |
| 22 | +for the `OpenAPI Specification v3 <https://github.com/OAI/OpenAPI-Specification>`__. |
| 23 | + |
| 24 | +Key features |
| 25 | +************ |
| 26 | + |
| 27 | +* **Validation** of requests and responses |
| 28 | +* Schema **casting** and **unmarshalling** |
| 29 | +* Media type and parameters **deserialization** |
| 30 | +* **Security** providers (API keys, Cookie, Basic and Bearer HTTP authentications) |
| 31 | +* Custom **deserializers** and **formats** |
| 32 | +* **Integration** with libraries and frameworks |
| 33 | + |
| 34 | + |
| 35 | +Documentation |
| 36 | +############# |
| 37 | + |
| 38 | +Check documentation to see more details about the features. All documentation is in the "docs" directory and online at `openapi-core.readthedocs.io <https://openapi-core.readthedocs.io>`__ |
| 39 | + |
23 | 40 |
|
24 | 41 | Installation |
25 | 42 | ############ |
@@ -81,7 +98,7 @@ and unmarshal request data from validation result |
81 | 98 | # get security data |
82 | 99 | validated_security = result.security |
83 | 100 |
|
84 | | -Request object should be instance of OpenAPIRequest class (See `Integrations`_). |
| 101 | +Request object should be instance of OpenAPIRequest class (See `Integrations <https://openapi-core.readthedocs.io/en/latest/integrations.html>`__). |
85 | 102 |
|
86 | 103 | Response |
87 | 104 | ******** |
@@ -111,303 +128,7 @@ and unmarshal response data from validation result |
111 | 128 | # get data |
112 | 129 | validated_data = result.data |
113 | 130 |
|
114 | | -Response object should be instance of OpenAPIResponse class (See `Integrations`_). |
115 | | - |
116 | | -Security |
117 | | -******** |
118 | | - |
119 | | -openapi-core supports security for authentication and authorization process. Security data for security schemas are accessible from `security` attribute of `RequestValidationResult` object. |
120 | | - |
121 | | -For given security specification: |
122 | | - |
123 | | -.. code-block:: yaml |
124 | | -
|
125 | | - security: |
126 | | - - BasicAuth: [] |
127 | | - - ApiKeyAuth: [] |
128 | | - components: |
129 | | - securitySchemes: |
130 | | - BasicAuth: |
131 | | - type: http |
132 | | - scheme: basic |
133 | | - ApiKeyAuth: |
134 | | - type: apiKey |
135 | | - in: header |
136 | | - name: X-API-Key |
137 | | -
|
138 | | -you can access your security data the following: |
139 | | - |
140 | | -.. code-block:: python |
141 | | -
|
142 | | - result = validator.validate(request) |
143 | | -
|
144 | | - # get basic auth decoded credentials |
145 | | - result.security['BasicAuth'] |
146 | | -
|
147 | | - # get api key |
148 | | - result.security['ApiKeyAuth'] |
149 | | -
|
150 | | -Supported security types: |
151 | | - |
152 | | -* http – for Basic and Bearer HTTP authentications schemes |
153 | | -* apiKey – for API keys and cookie authentication |
154 | | - |
155 | | - |
156 | | -Customizations |
157 | | -############## |
158 | | - |
159 | | -Spec validation |
160 | | -*************** |
161 | | - |
162 | | -By default, spec dict is validated on spec creation time. Disabling the validation can improve the performance. |
163 | | - |
164 | | -.. code-block:: python |
165 | | -
|
166 | | - from openapi_core import create_spec |
167 | | -
|
168 | | - spec = create_spec(spec_dict, validate_spec=False) |
169 | | -
|
170 | | -Deserializers |
171 | | -************* |
172 | | - |
173 | | -Pass custom defined media type deserializers dictionary with supported mimetypes as a key to `RequestValidator` or `ResponseValidator` constructor: |
174 | | - |
175 | | -.. code-block:: python |
176 | | -
|
177 | | - def protobuf_deserializer(message): |
178 | | - feature = route_guide_pb2.Feature() |
179 | | - feature.ParseFromString(message) |
180 | | - return feature |
181 | | -
|
182 | | - custom_media_type_deserializers = { |
183 | | - 'application/protobuf': protobuf_deserializer, |
184 | | - } |
185 | | -
|
186 | | - validator = ResponseValidator( |
187 | | - spec, custom_media_type_deserializers=custom_media_type_deserializers) |
188 | | -
|
189 | | - result = validator.validate(request, response) |
190 | | -
|
191 | | -Formats |
192 | | -******* |
193 | | - |
194 | | -OpenAPI defines a ``format`` keyword that hints at how a value should be interpreted, e.g. a ``string`` with the type ``date`` should conform to the RFC 3339 date format. |
195 | | - |
196 | | -Openapi-core comes with a set of built-in formatters, but it's also possible to add support for custom formatters for `RequestValidator` and `ResponseValidator`. |
197 | | - |
198 | | -Here's how you could add support for a ``usdate`` format that handles dates of the form MM/DD/YYYY: |
199 | | - |
200 | | -.. code-block:: python |
201 | | -
|
202 | | - from datetime import datetime |
203 | | - import re |
204 | | -
|
205 | | - class USDateFormatter: |
206 | | - def validate(self, value) -> bool: |
207 | | - return bool(re.match(r"^\d{1,2}/\d{1,2}/\d{4}$", value)) |
208 | | -
|
209 | | - def unmarshal(self, value): |
210 | | - return datetime.strptime(value, "%m/%d/%y").date |
211 | | -
|
212 | | -
|
213 | | - custom_formatters = { |
214 | | - 'usdate': USDateFormatter(), |
215 | | - } |
216 | | -
|
217 | | - validator = ResponseValidator(spec, custom_formatters=custom_formatters) |
218 | | -
|
219 | | - result = validator.validate(request, response) |
220 | | -
|
221 | | -Integrations |
222 | | -############ |
223 | | - |
224 | | -Django |
225 | | -****** |
226 | | - |
227 | | -For Django 2.2 you can use DjangoOpenAPIRequest a Django request factory: |
228 | | - |
229 | | -.. code-block:: python |
230 | | -
|
231 | | - from openapi_core.validation.request.validators import RequestValidator |
232 | | - from openapi_core.contrib.django import DjangoOpenAPIRequest |
233 | | -
|
234 | | - openapi_request = DjangoOpenAPIRequest(django_request) |
235 | | - validator = RequestValidator(spec) |
236 | | - result = validator.validate(openapi_request) |
237 | | -
|
238 | | -You can use DjangoOpenAPIResponse as a Django response factory: |
239 | | - |
240 | | -.. code-block:: python |
241 | | -
|
242 | | - from openapi_core.validation.response.validators import ResponseValidator |
243 | | - from openapi_core.contrib.django import DjangoOpenAPIResponse |
244 | | -
|
245 | | - openapi_response = DjangoOpenAPIResponse(django_response) |
246 | | - validator = ResponseValidator(spec) |
247 | | - result = validator.validate(openapi_request, openapi_response) |
248 | | -
|
249 | | -Falcon |
250 | | -****** |
251 | | - |
252 | | -This section describes integration with `Falcon <https://falconframework.org>`__ web framework. |
253 | | - |
254 | | -Middleware |
255 | | -========== |
256 | | - |
257 | | -Falcon API can be integrated by `FalconOpenAPIMiddleware` middleware. |
258 | | - |
259 | | -.. code-block:: python |
260 | | -
|
261 | | - from openapi_core.contrib.falcon.middlewares import FalconOpenAPIMiddleware |
262 | | -
|
263 | | - openapi_middleware = FalconOpenAPIMiddleware.from_spec(spec) |
264 | | - api = falcon.API(middleware=[openapi_middleware]) |
265 | | -
|
266 | | -Low level |
267 | | -========= |
268 | | - |
269 | | -For Falcon you can use FalconOpenAPIRequest a Falcon request factory: |
270 | | - |
271 | | -.. code-block:: python |
272 | | -
|
273 | | - from openapi_core.validation.request.validators import RequestValidator |
274 | | - from openapi_core.contrib.falcon import FalconOpenAPIRequestFactory |
275 | | -
|
276 | | - openapi_request = FalconOpenAPIRequestFactory.create(falcon_request) |
277 | | - validator = RequestValidator(spec) |
278 | | - result = validator.validate(openapi_request) |
279 | | -
|
280 | | -You can use FalconOpenAPIResponse as a Falcon response factory: |
281 | | - |
282 | | -.. code-block:: python |
283 | | -
|
284 | | - from openapi_core.validation.response.validators import ResponseValidator |
285 | | - from openapi_core.contrib.falcon import FalconOpenAPIResponseFactory |
286 | | -
|
287 | | - openapi_response = FalconOpenAPIResponseFactory.create(falcon_response) |
288 | | - validator = ResponseValidator(spec) |
289 | | - result = validator.validate(openapi_request, openapi_response) |
290 | | -
|
291 | | -Flask |
292 | | -***** |
293 | | - |
294 | | -Decorator |
295 | | -========= |
296 | | - |
297 | | -Flask views can be integrated by `FlaskOpenAPIViewDecorator` decorator. |
298 | | - |
299 | | -.. code-block:: python |
300 | | -
|
301 | | - from openapi_core.contrib.flask.decorators import FlaskOpenAPIViewDecorator |
302 | | -
|
303 | | - openapi = FlaskOpenAPIViewDecorator.from_spec(spec) |
304 | | -
|
305 | | - @app.route('/home') |
306 | | - @openapi |
307 | | - def home(): |
308 | | - pass |
309 | | -
|
310 | | -If you want to decorate class based view you can use the decorators attribute: |
311 | | - |
312 | | -.. code-block:: python |
313 | | -
|
314 | | - class MyView(View): |
315 | | - decorators = [openapi] |
316 | | -
|
317 | | -View |
318 | | -==== |
319 | | - |
320 | | -As an alternative to the decorator-based integration, Flask method based views can be integrated by inheritance from `FlaskOpenAPIView` class. |
321 | | - |
322 | | -.. code-block:: python |
323 | | -
|
324 | | - from openapi_core.contrib.flask.views import FlaskOpenAPIView |
325 | | -
|
326 | | - class MyView(FlaskOpenAPIView): |
327 | | - pass |
328 | | -
|
329 | | - app.add_url_rule('/home', view_func=MyView.as_view('home', spec)) |
330 | | -
|
331 | | -Request parameters |
332 | | -================== |
333 | | - |
334 | | -In Flask, all unmarshalled request data are provided as Flask request object's openapi.parameters attribute |
335 | | - |
336 | | -.. code-block:: python |
337 | | -
|
338 | | - from flask.globals import request |
339 | | -
|
340 | | - @app.route('/browse/<id>/') |
341 | | - @openapi |
342 | | - def home(): |
343 | | - browse_id = request.openapi.parameters.path['id'] |
344 | | - page = request.openapi.parameters.query.get('page', 1) |
345 | | -
|
346 | | -Low level |
347 | | -========= |
348 | | - |
349 | | -You can use FlaskOpenAPIRequest a Flask/Werkzeug request factory: |
350 | | - |
351 | | -.. code-block:: python |
352 | | -
|
353 | | - from openapi_core.validation.request.validators import RequestValidator |
354 | | - from openapi_core.contrib.flask import FlaskOpenAPIRequest |
355 | | -
|
356 | | - openapi_request = FlaskOpenAPIRequest(flask_request) |
357 | | - validator = RequestValidator(spec) |
358 | | - result = validator.validate(openapi_request) |
359 | | -
|
360 | | -You can use FlaskOpenAPIResponse as a Flask/Werkzeug response factory: |
361 | | - |
362 | | -.. code-block:: python |
363 | | -
|
364 | | - from openapi_core.validation.response.validators import ResponseValidator |
365 | | - from openapi_core.contrib.flask import FlaskOpenAPIResponse |
366 | | -
|
367 | | - openapi_response = FlaskOpenAPIResponse(flask_response) |
368 | | - validator = ResponseValidator(spec) |
369 | | - result = validator.validate(openapi_request, openapi_response) |
370 | | -
|
371 | | -Pyramid |
372 | | -******* |
373 | | - |
374 | | -See `pyramid_openapi3 <https://github.com/niteoweb/pyramid_openapi3>`_ project. |
375 | | - |
376 | | -Bottle |
377 | | -******* |
378 | | - |
379 | | -See `bottle-openapi-3 <https://github.com/cope-systems/bottle-openapi-3>`_ project. |
380 | | - |
381 | | - |
382 | | -Requests |
383 | | -******** |
384 | | - |
385 | | -This section describes integration with `Requests <https://requests.readthedocs.io>`__ library. |
386 | | - |
387 | | -Low level |
388 | | -========= |
389 | | - |
390 | | -For Requests you can use RequestsOpenAPIRequest a Requests request factory: |
391 | | - |
392 | | -.. code-block:: python |
393 | | -
|
394 | | - from openapi_core.validation.request.validators import RequestValidator |
395 | | - from openapi_core.contrib.requests import RequestsOpenAPIRequest |
396 | | -
|
397 | | - openapi_request = RequestsOpenAPIRequest(requests_request) |
398 | | - validator = RequestValidator(spec) |
399 | | - result = validator.validate(openapi_request) |
400 | | -
|
401 | | -You can use RequestsOpenAPIResponse as a Requests response factory: |
402 | | - |
403 | | -.. code-block:: python |
404 | | -
|
405 | | - from openapi_core.validation.response.validators import ResponseValidator |
406 | | - from openapi_core.contrib.requests import RequestsOpenAPIResponse |
407 | | -
|
408 | | - openapi_response = RequestsOpenAPIResponse(requests_response) |
409 | | - validator = ResponseValidator(spec) |
410 | | - result = validator.validate(openapi_request, openapi_response) |
| 131 | +Response object should be instance of OpenAPIResponse class (See `Integrations <https://openapi-core.readthedocs.io/en/latest/integrations.html>`__). |
411 | 132 |
|
412 | 133 | Related projects |
413 | 134 | ################ |
|
0 commit comments