|
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