Example #1
0
    def get_response_serializers(self):
        responses = super().get_response_serializers()
        definitions = self.components.with_scope(openapi.SCHEMA_DEFINITIONS)
        definitions.setdefault(GENERIC_ERROR, self.get_generic_error_schema)
        definitions.setdefault(VALIDATION_ERROR, self.get_validation_error_schema)

        if self.get_request_serializer():
            responses.setdefault(exceptions.ValidationError.status_code, openapi.Response(
                description=force_real_str(exceptions.ValidationError.default_detail),
                schema=openapi.SchemaRef(definitions, VALIDATION_ERROR)
            ))

        security = self.get_security()
        if (not security or len(security) > 0) and AllowAny not in self.view.permission_classes:
            responses.setdefault(status.HTTP_401_UNAUTHORIZED, openapi.Response(
                description="Authentication credentials were not provided.",
                schema=openapi.SchemaRef(definitions, GENERIC_ERROR)
            ))
            responses.setdefault(exceptions.PermissionDenied.status_code, openapi.Response(
                description="Permission denied.",
                schema=openapi.SchemaRef(definitions, GENERIC_ERROR)
            ))

        if not is_list_view(self.path, self.method, self.view) or '{' in self.path:
            responses.setdefault(exceptions.NotFound.status_code, openapi.Response(
                description="Not found.",
                schema=openapi.SchemaRef(definitions, GENERIC_ERROR)
            ))

        return responses
Example #2
0
    def get_response_serializers(self):
        responses = super().get_response_serializers()
        definitions = self.components.with_scope(
            openapi.SCHEMA_DEFINITIONS)  # type: openapi.ReferenceResolver

        # definitions.setdefault('GenericError', self.get_generic_error_schema)
        definitions.setdefault('ValidationError',
                               self.get_validation_error_schema)
        definitions.setdefault('TOSInvalidException',
                               self.get_tos_exception_schema)
        # definitions.setdefault('APIException', self.get_generic_error_schema)

        serializer = self.get_request_serializer(
        ) or self.get_query_serializer()

        for permission in self.view.permission_classes:
            if permission.__name__ == 'SignedLatestTOS':
                responses.setdefault(
                    TOSInvalidException.status_code,
                    openapi.Response(
                        description='TOS expired or was never signed.',
                        schema=openapi.SchemaRef(definitions,
                                                 'TOSInvalidException')))

        if serializer:
            meta = getattr(serializer.__class__, 'Meta', None)
            if meta and 'error_codes' in meta.__dict__:
                responses.setdefault(
                    exceptions.ValidationError.status_code,
                    openapi.Response(description=force_real_str(
                        exceptions.ValidationError.default_detail),
                                     schema=self.get_validation_error_schema(
                                         error_codes=meta.error_codes)))
            else:
                responses.setdefault(
                    exceptions.ValidationError.status_code,
                    openapi.Response(description=force_real_str(
                        exceptions.ValidationError.default_detail),
                                     schema=openapi.SchemaRef(
                                         definitions, 'ValidationError')))

        # security = self.get_security()
        # if security is None or len(security) > 0:
        #     # Note: 401 error codes are coerced  into 403 see rest_framework/views.py:433:handle_exception
        #     # This is b/c the API uses token auth which doesn't have WWW-Authenticate header
        #     responses.setdefault(status.HTTP_403_FORBIDDEN, openapi.Response(
        #         description="Authentication credentials were invalid, absent or insufficient.",
        #         schema=openapi.SchemaRef(definitions, 'GenericError')
        #     ))
        # if not is_list_view(self.path, self.method, self.view):
        #     responses.setdefault(exceptions.PermissionDenied.status_code, openapi.Response(
        #         description="Permission denied.",
        #         schema=openapi.SchemaRef(definitions, 'APIException')
        #     ))
        #     responses.setdefault(exceptions.NotFound.status_code, openapi.Response(
        #         description="Object does not exist.",
        #         schema=openapi.SchemaRef(definitions, 'APIException')
        #     ))

        return responses
Example #3
0
    def get_response_serializers(self):
        responses = super().get_response_serializers()
        definitions = self.components.with_scope(
            openapi.SCHEMA_DEFINITIONS)  # type: openapi.ReferenceResolver

        definitions.setdefault("GenericError", self.get_generic_error_schema)
        definitions.setdefault("ValidationError",
                               self.get_validation_error_schema)
        definitions.setdefault("APIException", self.get_generic_error_schema)

        if self.get_request_serializer() or self.get_query_serializer():
            responses.setdefault(
                exceptions.ValidationError.status_code,
                openapi.Response(
                    description=force_real_str(
                        exceptions.ValidationError.default_detail),
                    schema=openapi.SchemaRef(definitions, "ValidationError"),
                ),
            )

        security = self.get_security()
        if security is None or len(security) > 0:
            # Note: 401 error codes are coerced  into 403 see
            # rest_framework/views.py:433:handle_exception
            # This is b/c the API uses token auth which doesn't have WWW-Authenticate header
            responses.setdefault(
                status.HTTP_403_FORBIDDEN,
                openapi.Response(
                    description=
                    "Authentication credentials were invalid, absent or insufficient.",
                    schema=openapi.SchemaRef(definitions, "GenericError"),
                ),
            )
        if not is_list_view(self.path, self.method, self.view):
            responses.setdefault(
                exceptions.PermissionDenied.status_code,
                openapi.Response(
                    description="Permission denied.",
                    schema=openapi.SchemaRef(definitions, "APIException"),
                ),
            )
            responses.setdefault(
                exceptions.NotFound.status_code,
                openapi.Response(
                    description=("Object does not exist or caller "
                                 "has insufficient permissions to access it."),
                    schema=openapi.SchemaRef(definitions, "APIException"),
                ),
            )

        return responses
Example #4
0
    def field_to_swagger_object(self, field, swagger_object_type,
                                use_references, **kw):
        # pylint: disable=invalid-name
        if not isinstance(field, fields.AutoCompletionField):
            return NotHandled

        SwaggerType, _ = self._get_partial_types(field, swagger_object_type,
                                                 use_references, **kw)
        kwargs = {'type': openapi.TYPE_STRING, 'format': FORMAT_AUTOCOMPLETE}
        if isinstance(field.autocomplete, (list, tuple)):
            kwargs['enum'] = list(field.autocomplete)
        else:
            kwargs['format'] = FORMAT_FK_AUTOCOMPLETE
            kwargs[X_OPTIONS] = {
                'model':
                openapi.SchemaRef(self.components.with_scope(
                    openapi.SCHEMA_DEFINITIONS),
                                  field.autocomplete,
                                  ignore_unresolved=True),
                'value_field':
                field.autocomplete_property,
                'view_field':
                field.autocomplete_represent,
                'usePrefetch':
                field.use_prefetch,
            }

        return SwaggerType(**field_extra_handler(field, **kwargs))
Example #5
0
    def _serializer_to_swagger_object(
        self, serializer, swagger_object_type, use_references, **kwargs
    ):
        if self.method not in ViewInspector.body_methods:
            return NotHandled

        if not any(
            isinstance(field, Base64FieldMixin) for field in serializer.fields.values()
        ):
            return NotHandled

        SwaggerType, ChildSwaggerType = self._get_partial_types(
            serializer, swagger_object_type, use_references, **kwargs
        )

        ref_name = get_serializer_ref_name(serializer)
        ref_name = f"{ref_name}Data" if ref_name else None

        def make_schema_definition():
            properties = OrderedDict()
            required = []
            for property_name, child in serializer.fields.items():
                prop_kwargs = {"read_only": bool(child.read_only) or None}
                prop_kwargs = filter_none(prop_kwargs)

                child_schema = self.probe_field_inspectors(
                    child, ChildSwaggerType, use_references, **prop_kwargs
                )
                properties[property_name] = child_schema

                if child.required and not getattr(child_schema, "read_only", False):
                    required.append(property_name)

            result = SwaggerType(
                type=openapi.TYPE_OBJECT,
                properties=properties,
                required=required or None,
            )
            if not ref_name and "title" in result:
                # on an inline model, the title is derived from the field name
                # but is visually displayed like the model name, which is confusing
                # it is better to just remove title from inline models
                del result.title

            # Provide an option to add manual paremeters to a schema
            # for example, to add examples
            # self.add_manual_fields(serializer, result)
            return self.process_result(result, None, None)

        if not ref_name or not use_references:
            return make_schema_definition()

        definitions = self.components.with_scope(openapi.SCHEMA_DEFINITIONS)
        definitions.setdefault(ref_name, make_schema_definition)
        return openapi.SchemaRef(definitions, ref_name)
    def field_to_swagger_object(self, field, swagger_object_type,
                                use_references, **kwargs):
        if not isinstance(field, GeometryField):
            return NotHandled

        definitions = self.components.with_scope(openapi.SCHEMA_DEFINITIONS)

        if not definitions.has('Geometry'):
            register_geojson(definitions)

        return openapi.SchemaRef(definitions, REF_NAME_GEOJSON_GEOMETRY)
    def get_response_serializers(self):
        responses = super().get_response_serializers()
        definitions = self.components.with_scope(
            openapi.SCHEMA_DEFINITIONS)  # type: openapi.ReferenceResolver

        definitions.setdefault('GenericError', self.get_generic_error_schema)
        definitions.setdefault('ValidationError',
                               self.get_validation_error_schema)
        definitions.setdefault('APIException', self.get_generic_error_schema)

        if self.get_request_serializer() or self.get_query_serializer():
            responses.setdefault(
                exceptions.ValidationError.status_code,
                openapi.Response(description=force_real_str(
                    exceptions.ValidationError.default_detail),
                                 schema=openapi.SchemaRef(
                                     definitions, 'ValidationError')))

        authenticators = self.view.get_authenticators()
        if authenticators and len(authenticators) > 0:
            responses.setdefault(
                exceptions.AuthenticationFailed.status_code,
                openapi.Response(
                    description=
                    "Authentication credentials were invalid, absent or insufficient.",
                    schema=openapi.SchemaRef(definitions, 'GenericError')))
        if not is_list_view(self.path, self.method, self.view):
            responses.setdefault(
                exceptions.PermissionDenied.status_code,
                openapi.Response(description="Permission denied.",
                                 schema=openapi.SchemaRef(
                                     definitions, 'APIException')))
            responses.setdefault(
                exceptions.NotFound.status_code,
                openapi.Response(
                    description=
                    "Object does not exist or caller has insufficient permissions to access it.",
                    schema=openapi.SchemaRef(definitions, 'APIException')))

        return responses
Example #8
0
def test_get_operation_with_serializer():
    view = View()
    route = get_route(Controller.post_with_serializer)
    View.post.route = route
    reference_resolver = openapi.ReferenceResolver('definitions',
                                                   'parameters',
                                                   force_init=True)
    auto_schema = SwaggerAutoSchema(view, 'path', route.http_method,
                                    reference_resolver, 'request', {})
    operation = auto_schema.get_operation(['test_app', 'post'])
    schema_ref = openapi.SchemaRef(
        resolver=reference_resolver,
        schema_name='User',
    )
    parameters = [
        openapi.Parameter(
            name='data',
            in_=openapi.IN_BODY,
            required=True,
            schema=schema_ref,
        ),
    ]
    responses = openapi.Responses({
        '200':
        openapi.Response(
            description='',
            schema=openapi.Schema(
                type=openapi.TYPE_OBJECT,
                properties={
                    'name': {
                        'type': 'string',
                    },
                },
            ),
        ),
    })

    assert operation == openapi.Operation(
        operation_id='Controller.post_with_serializer',
        responses=responses,
        consumes=['application/json'],
        produces=['application/json'],
        tags=['test_app'],
        parameters=parameters,
    )
    del View.post.route
Example #9
0
    def field_to_swagger_object(self, field, swagger_object_type,
                                use_references, **kw):
        # pylint: disable=unused-variable,invalid-name
        if not isinstance(field, fields.FkField):
            return NotHandled

        SwaggerType, ChildSwaggerType = self._get_partial_types(
            field, swagger_object_type, use_references, **kw)

        field_format = FORMAT_FK
        options = {
            'model':
            openapi.SchemaRef(self.components.with_scope(
                openapi.SCHEMA_DEFINITIONS),
                              field.select_model,
                              ignore_unresolved=True),
            'value_field':
            field.autocomplete_property,
            'view_field':
            field.autocomplete_represent,
            'usePrefetch':
            field.use_prefetch,
            'makeLink':
            field.make_link,
            'dependence':
            field.dependence,
            'filters':
            field.filters,
        }

        if isinstance(field, fields.DeepFkField):
            field_format = FORMAT_DEEP_FK
            options = {
                **options,
                'only_last_child': field.only_last_child,
                'parent_field_name': field.parent_field_name,
            }
            del options['dependence']

        kwargs = {
            'type': openapi.TYPE_INTEGER,
            'format': field_format,
            X_OPTIONS: options,
        }

        return SwaggerType(**field_extra_handler(field, **kwargs))
Example #10
0
    def field_to_swagger_object(self, field, swagger_object_type,
                                use_references, **kw):
        # pylint: disable=invalid-name,unused-variable
        type_info = basic_type_info.get(field.__class__, None)
        if type_info is None:
            return NotHandled

        SwaggerType, ChildSwaggerType = self._get_partial_types(
            field, swagger_object_type, use_references, **kw)
        kwargs = dict(**type_info)
        if type_info.get('format', None) == FORMAT_AUTOCOMPLETE:
            kwargs['additionalProperties'] = openapi.SchemaRef(
                self.components.with_scope(openapi.SCHEMA_DEFINITIONS),
                field.autocomplete + '/properties/id',
                ignore_unresolved=True)

        return SwaggerType(**kwargs)
Example #11
0
    def field_to_swagger_object(self, field, swagger_object_type,
                                use_references, **kw):
        # pylint: disable=unused-variable,invalid-name
        if not isinstance(field, fields.Select2Field):
            return NotHandled

        SwaggerType, ChildSwaggerType = self._get_partial_types(
            field, swagger_object_type, use_references, **kw)
        kwargs = dict(type=openapi.TYPE_INTEGER, format=FORMAT_SELECT2)
        kwargs['additionalProperties'] = dict(
            model=openapi.SchemaRef(self.components.with_scope(
                openapi.SCHEMA_DEFINITIONS),
                                    field.select_model,
                                    ignore_unresolved=True),
            value_field=field.autocomplete_property,
            view_field=field.autocomplete_represent)

        return SwaggerType(**field_extra_handler(field, **kwargs))
Example #12
0
    def field_to_swagger_object(self, field, swagger_object_type,
                                use_references, **kw):
        # pylint: disable=unused-variable,invalid-name
        if not isinstance(field, fields.AutoCompletionField):
            return NotHandled

        SwaggerType, ChildSwaggerType = self._get_partial_types(
            field, swagger_object_type, use_references, **kw)
        kwargs = dict(type=openapi.TYPE_STRING, format=FORMAT_AUTOCOMPLETE)
        if isinstance(field.autocomplete, (list, tuple)):
            kwargs['enum'] = list(field.autocomplete)
        else:
            prop = dict(model=openapi.SchemaRef(self.components.with_scope(
                openapi.SCHEMA_DEFINITIONS),
                                                field.autocomplete,
                                                ignore_unresolved=True),
                        value_field=field.autocomplete_property,
                        view_field=field.autocomplete_represent)
            kwargs['additionalProperties'] = prop

        return SwaggerType(**field_extra_handler(field, **kwargs))
Example #13
0
    def field_to_swagger_object(self, field, swagger_object_type, use_references, **kw):
        # pylint: disable=unused-variable,invalid-name
        if not isinstance(field, fields.CommaMultiSelect):
            return NotHandled

        SwaggerType, ChildSwaggerType = self._get_partial_types(
            field, swagger_object_type, use_references, **kw
        )
        kwargs = dict(type=openapi.TYPE_STRING, format=FORMAT_MULTISELECT)
        kwargs['additionalProperties'] = dict(
            model=openapi.SchemaRef(
                self.components.with_scope(openapi.SCHEMA_DEFINITIONS),
                field.select_model, ignore_unresolved=True
            ),
            value_field=field.select_property,
            view_field=field.select_represent,
            view_separator=field.select_separator,
            usePrefetch=field.use_prefetch,
            makeLink=field.make_link
        )

        return SwaggerType(**field_extra_handler(field, **kwargs))
Example #14
0
    def field_to_swagger_object(self, field, swagger_object_type,
                                use_references, **kw):
        # pylint: disable=unused-variable,invalid-name
        if not isinstance(field, fields.CommaMultiSelect):
            return NotHandled

        SwaggerType, ChildSwaggerType = self._get_partial_types(
            field, swagger_object_type, use_references, **kw)
        kwargs = {
            'type': 'array',
            'x-collectionFormat': 'csv',
            X_OPTIONS: {
                'viewSeparator': field.select_separator,
            },
            'items': {
                "type": openapi.TYPE_INTEGER,
                "format": FORMAT_FK,
                X_OPTIONS: {
                    'model':
                    openapi.SchemaRef(
                        self.components.with_scope(openapi.SCHEMA_DEFINITIONS),
                        field.select_model,
                        ignore_unresolved=True,
                    ),
                    "value_field":
                    field.select_property,
                    "view_field":
                    field.select_represent,
                    'usePrefetch':
                    field.use_prefetch,
                    'makeLink':
                    field.make_link,
                    'dependence':
                    field.dependence,
                },
            }
        }

        return SwaggerType(**field_extra_handler(field, **kwargs))
Example #15
0
def register_geojson(definitions):
    Geometry = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        title="Geometry",
        description="GeoJSON geometry",
        required=['type'],
        externalDocs=OrderedDict(
            url='https://tools.ietf.org/html/rfc7946#section-3.1'),
        properties=OrderedDict(
            (('type',
              openapi.Schema(type=openapi.TYPE_STRING,
                             enum=[
                                 'Point',
                                 'MultiPoint',
                                 'LineString',
                                 'MultiLineString',
                                 'Polygon',
                                 'MultiPolygon',
                                 'Feature',
                                 'FeatureCollection',
                                 'GeometryCollection',
                             ],
                             description="The geometry type")), )))
    definitions.set('Geometry', Geometry)

    Point2D = openapi.Schema(type=openapi.TYPE_ARRAY,
                             title="Point2D",
                             description="A 2D point",
                             items=openapi.Schema(type=openapi.TYPE_NUMBER),
                             maxItems=2,
                             minItems=2)
    definitions.set('Point2D', Point2D)

    Point = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON point geometry",
        externalDocs=OrderedDict(
            url='https://tools.ietf.org/html/rfc7946#section-3.1.2'),
        allOf=[
            openapi.SchemaRef(definitions, 'Geometry'),
            openapi.Schema(type=openapi.TYPE_OBJECT,
                           required=['coordinates'],
                           properties=OrderedDict(
                               (('coordinates',
                                 openapi.SchemaRef(definitions,
                                                   'Point2D')), )))
        ])
    definitions.set('Point', Point)

    MultiPoint = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON multi-point geometry",
        externalDocs=OrderedDict(
            url='https://tools.ietf.org/html/rfc7946#section-3.1.3'),
        allOf=[
            openapi.SchemaRef(definitions, 'Geometry'),
            openapi.Schema(type=openapi.TYPE_OBJECT,
                           required=['coordinates'],
                           properties=OrderedDict(
                               (('coordinates',
                                 openapi.Schema(
                                     type=openapi.TYPE_ARRAY,
                                     items=openapi.SchemaRef(
                                         definitions, 'Point2D'),
                                 )), )))
        ])
    definitions.set('MultiPoint', MultiPoint)

    LineString = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON line-string geometry",
        externalDocs=OrderedDict(
            url='https://tools.ietf.org/html/rfc7946#section-3.1.4'),
        allOf=[
            openapi.SchemaRef(definitions, 'Geometry'),
            openapi.Schema(type=openapi.TYPE_OBJECT,
                           required=['coordinates'],
                           properties=OrderedDict(
                               (('coordinates',
                                 openapi.Schema(
                                     type=openapi.TYPE_ARRAY,
                                     items=openapi.SchemaRef(
                                         definitions, 'Point2D'),
                                     minItems=2,
                                 )), )))
        ])
    definitions.set('LineString', LineString)

    MultiLineString = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON multi-line-string geometry",
        externalDocs=OrderedDict(
            url='https://tools.ietf.org/html/rfc7946#section-3.1.5'),
        allOf=[
            openapi.SchemaRef(definitions, 'Geometry'),
            openapi.Schema(type=openapi.TYPE_OBJECT,
                           required=['coordinates'],
                           properties=OrderedDict(
                               (('coordinates',
                                 openapi.Schema(type=openapi.TYPE_ARRAY,
                                                items=openapi.Schema(
                                                    type=openapi.TYPE_ARRAY,
                                                    items=openapi.SchemaRef(
                                                        definitions,
                                                        'Point2D')))), )))
        ])
    definitions.set('MultiLineString', MultiLineString)

    Polygon = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON polygon geometry",
        externalDocs=OrderedDict(
            url='https://tools.ietf.org/html/rfc7946#section-3.1.6'),
        allOf=[
            openapi.SchemaRef(definitions, 'Geometry'),
            openapi.Schema(type=openapi.TYPE_OBJECT,
                           required=['coordinates'],
                           properties=OrderedDict(
                               (('coordinates',
                                 openapi.Schema(type=openapi.TYPE_ARRAY,
                                                items=openapi.Schema(
                                                    type=openapi.TYPE_ARRAY,
                                                    items=openapi.SchemaRef(
                                                        definitions,
                                                        'Point2D')))), )))
        ])
    definitions.set('Polygon', Polygon)

    MultiPolygon = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON multi-polygon geometry",
        externalDocs=OrderedDict(
            url='https://tools.ietf.org/html/rfc7946#section-3.1.7'),
        allOf=[
            openapi.SchemaRef(definitions, 'Geometry'),
            openapi.Schema(type=openapi.TYPE_OBJECT,
                           required=['coordinates'],
                           properties=OrderedDict(
                               (('coordinates',
                                 openapi.Schema(
                                     type=openapi.TYPE_ARRAY,
                                     items=openapi.Schema(
                                         type=openapi.TYPE_ARRAY,
                                         items=openapi.Schema(
                                             type=openapi.TYPE_ARRAY,
                                             items=openapi.SchemaRef(
                                                 definitions,
                                                 'Point2D'))))), )))
        ])
    definitions.set('MultiPolygon', MultiPolygon)

    GeometryCollection = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON multi-polygon geometry",
        externalDocs=OrderedDict(
            url='https://tools.ietf.org/html/rfc7946#section-3.1.8'),
        allOf=[
            openapi.SchemaRef(definitions, 'Geometry'),
            openapi.Schema(type=openapi.TYPE_OBJECT,
                           required=['geometries'],
                           properties=OrderedDict(
                               (('geometries',
                                 openapi.Schema(type=openapi.TYPE_ARRAY,
                                                items=openapi.SchemaRef(
                                                    definitions,
                                                    'Geometry'))), )))
        ])
    definitions.set('GeometryCollection', GeometryCollection)

    GeoJSONGeometry = openapi.Schema(
        title=REF_NAME_GEOJSON_GEOMETRY,
        type=openapi.TYPE_OBJECT,
        oneOf=[
            openapi.SchemaRef(definitions, 'Point'),
            openapi.SchemaRef(definitions, 'MultiPoint'),
            openapi.SchemaRef(definitions, 'LineString'),
            openapi.SchemaRef(definitions, 'MultiLineString'),
            openapi.SchemaRef(definitions, 'Polygon'),
            openapi.SchemaRef(definitions, 'MultiPolygon'),
            openapi.SchemaRef(definitions, 'GeometryCollection'),
        ],
        discriminator='type',
    )
    definitions.set(REF_NAME_GEOJSON_GEOMETRY, GeoJSONGeometry)
Example #16
0
def register_geojson(definitions):
    Geometry = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        title="Geometry",
        description="GeoJSON geometry",
        required=["type"],
        externalDocs=OrderedDict(
            url="https://tools.ietf.org/html/rfc7946#section-3.1"),
        properties=OrderedDict(((
            "type",
            openapi.Schema(
                type=openapi.TYPE_STRING,
                enum=[
                    "Point",
                    "MultiPoint",
                    "LineString",
                    "MultiLineString",
                    "Polygon",
                    "MultiPolygon",
                    "Feature",
                    "FeatureCollection",
                    "GeometryCollection",
                ],
                description="The geometry type",
            ),
        ), )),
    )
    definitions.set("Geometry", Geometry)

    Point2D = openapi.Schema(
        type=openapi.TYPE_ARRAY,
        title="Point2D",
        description="A 2D point",
        items=openapi.Schema(type=openapi.TYPE_NUMBER),
        maxItems=2,
        minItems=2,
    )
    definitions.set("Point2D", Point2D)

    Point = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON point geometry",
        externalDocs=OrderedDict(
            url="https://tools.ietf.org/html/rfc7946#section-3.1.2"),
        allOf=[
            openapi.SchemaRef(definitions, "Geometry"),
            openapi.Schema(
                type=openapi.TYPE_OBJECT,
                required=["coordinates"],
                properties=OrderedDict(
                    (("coordinates", openapi.SchemaRef(definitions,
                                                       "Point2D")), )),
            ),
        ],
    )
    definitions.set("Point", Point)

    MultiPoint = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON multi-point geometry",
        externalDocs=OrderedDict(
            url="https://tools.ietf.org/html/rfc7946#section-3.1.3"),
        allOf=[
            openapi.SchemaRef(definitions, "Geometry"),
            openapi.Schema(
                type=openapi.TYPE_OBJECT,
                required=["coordinates"],
                properties=OrderedDict(((
                    "coordinates",
                    openapi.Schema(
                        type=openapi.TYPE_ARRAY,
                        items=openapi.SchemaRef(definitions, "Point2D"),
                    ),
                ), )),
            ),
        ],
    )
    definitions.set("MultiPoint", MultiPoint)

    LineString = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON line-string geometry",
        externalDocs=OrderedDict(
            url="https://tools.ietf.org/html/rfc7946#section-3.1.4"),
        allOf=[
            openapi.SchemaRef(definitions, "Geometry"),
            openapi.Schema(
                type=openapi.TYPE_OBJECT,
                required=["coordinates"],
                properties=OrderedDict(((
                    "coordinates",
                    openapi.Schema(
                        type=openapi.TYPE_ARRAY,
                        items=openapi.SchemaRef(definitions, "Point2D"),
                        minItems=2,
                    ),
                ), )),
            ),
        ],
    )
    definitions.set("LineString", LineString)

    MultiLineString = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON multi-line-string geometry",
        externalDocs=OrderedDict(
            url="https://tools.ietf.org/html/rfc7946#section-3.1.5"),
        allOf=[
            openapi.SchemaRef(definitions, "Geometry"),
            openapi.Schema(
                type=openapi.TYPE_OBJECT,
                required=["coordinates"],
                properties=OrderedDict(((
                    "coordinates",
                    openapi.Schema(
                        type=openapi.TYPE_ARRAY,
                        items=openapi.Schema(
                            type=openapi.TYPE_ARRAY,
                            items=openapi.SchemaRef(definitions, "Point2D"),
                        ),
                    ),
                ), )),
            ),
        ],
    )
    definitions.set("MultiLineString", MultiLineString)

    Polygon = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON polygon geometry",
        externalDocs=OrderedDict(
            url="https://tools.ietf.org/html/rfc7946#section-3.1.6"),
        allOf=[
            openapi.SchemaRef(definitions, "Geometry"),
            openapi.Schema(
                type=openapi.TYPE_OBJECT,
                required=["coordinates"],
                properties=OrderedDict(((
                    "coordinates",
                    openapi.Schema(
                        type=openapi.TYPE_ARRAY,
                        items=openapi.Schema(
                            type=openapi.TYPE_ARRAY,
                            items=openapi.SchemaRef(definitions, "Point2D"),
                        ),
                    ),
                ), )),
            ),
        ],
    )
    definitions.set("Polygon", Polygon)

    MultiPolygon = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON multi-polygon geometry",
        externalDocs=OrderedDict(
            url="https://tools.ietf.org/html/rfc7946#section-3.1.7"),
        allOf=[
            openapi.SchemaRef(definitions, "Geometry"),
            openapi.Schema(
                type=openapi.TYPE_OBJECT,
                required=["coordinates"],
                properties=OrderedDict(((
                    "coordinates",
                    openapi.Schema(
                        type=openapi.TYPE_ARRAY,
                        items=openapi.Schema(
                            type=openapi.TYPE_ARRAY,
                            items=openapi.Schema(
                                type=openapi.TYPE_ARRAY,
                                items=openapi.SchemaRef(
                                    definitions, "Point2D"),
                            ),
                        ),
                    ),
                ), )),
            ),
        ],
    )
    definitions.set("MultiPolygon", MultiPolygon)

    GeometryCollection = openapi.Schema(
        type=openapi.TYPE_OBJECT,
        description="GeoJSON multi-polygon geometry",
        externalDocs=OrderedDict(
            url="https://tools.ietf.org/html/rfc7946#section-3.1.8"),
        allOf=[
            openapi.SchemaRef(definitions, "Geometry"),
            openapi.Schema(
                type=openapi.TYPE_OBJECT,
                required=["geometries"],
                properties=OrderedDict(((
                    "geometries",
                    openapi.Schema(
                        type=openapi.TYPE_ARRAY,
                        items=openapi.SchemaRef(definitions, "Geometry"),
                    ),
                ), )),
            ),
        ],
    )
    definitions.set("GeometryCollection", GeometryCollection)

    GeoJSONGeometry = openapi.Schema(
        title=REF_NAME_GEOJSON_GEOMETRY,
        type=openapi.TYPE_OBJECT,
        oneOf=[
            openapi.SchemaRef(definitions, "Point"),
            openapi.SchemaRef(definitions, "MultiPoint"),
            openapi.SchemaRef(definitions, "LineString"),
            openapi.SchemaRef(definitions, "MultiLineString"),
            openapi.SchemaRef(definitions, "Polygon"),
            openapi.SchemaRef(definitions, "MultiPolygon"),
            openapi.SchemaRef(definitions, "GeometryCollection"),
        ],
        discriminator="type",
    )
    definitions.set(REF_NAME_GEOJSON_GEOMETRY, GeoJSONGeometry)