Example #1
0
def _get_schema(
        schema: Optional[Union[str, Type[Schema]]]) -> Optional[Schema]:
    """Get the schema instance of a schema name or class.

    In case of OneOfSchema classes, the first dispatched schema is being returned.

    Args:
        schema:
            Either

    Returns:
        A schema instance.

    """
    if schema is None:
        return None

    # NOTE:
    # In case of a "OneOfSchema" instance, we don't really have any fields on this Schema
    # as it is just there for dispatching. The real fields are on the dispatched classes.
    # We just take the first one and go with that, as we have no way of letting the user chose
    # the dispatching-key by himself (this is a limitation of ReDoc).
    _schema: Schema = resolve_schema_instance(schema)
    if _schema_is_multiple(schema):
        type_schemas = _schema.type_schemas  # type: ignore[attr-defined]
        first_key = list(type_schemas.keys())[0]
        _schema = resolve_schema_instance(type_schemas[first_key])

    return _schema
Example #2
0
def resolve_nested_schema(self, schema):
    """Return the Open API representation of a marshmallow Schema.

    Adds the schema to the spec if it isn't already present.

    Typically will return a dictionary with the reference to the schema's
    path in the spec unless the `schema_name_resolver` returns `None`, in
    which case the returned dictoinary will contain a JSON Schema Object
    representation of the schema.

    :param schema: schema to add to the spec
    """
    schema_instance = resolve_schema_instance(schema)
    schema_key = make_schema_key(schema_instance)
    if schema_key not in self.refs:
        schema_cls = self.resolve_schema_class(schema)
        name = self.schema_name_resolver(schema_cls)
        if not name:
            try:
                json_schema = self.schema2jsonschema(schema)
            except RuntimeError:
                raise APISpecError(
                    "Name resolver returned None for schema {schema} which is "
                    "part of a chain of circular referencing schemas. Please"
                    " ensure that the schema_name_resolver passed to"
                    " MarshmallowPlugin returns a string for all circular"
                    " referencing schemas.".format(schema=schema)
                )
            if getattr(schema, "many", False):
                return {"type": "array", "items": json_schema}
            return json_schema
        name = create_schema_name(schema=schema_instance)
        if name not in self.spec.components._schemas:
            self.spec.components.schema(name, schema=schema)
    return self.get_ref_dict(schema_instance)
Example #3
0
def code_samples(
    path,
    method,
    request_schema,
    operation_spec,
    code_templates=[],
):  # pylint: disable=dangerous-default-value
    """Create a list of rendered code sample Objects

    These are not specified by OpenAPI but are specific to ReDoc."""
    if not code_templates:
        with CODE_TEMPLATES_LOCK:
            if not code_templates:
                code_templates.append(_build_code_templates())

    headers = []
    for param in operation_spec.get('parameters', []):
        if isinstance(param, dict) and param['in'] == 'header':
            headers.append(param)

    return [{
        'lang':
        language,
        'source':
        template.render(
            request_endpoint=path,
            request_method=method,
            request_schema=(resolve_schema_instance(request_schema)
                            if request_schema is not None else None),
            headers=headers,
        ).strip(),
    } for language, template in code_templates[0].items()]
Example #4
0
def code_samples(  # pylint: disable=dangerous-default-value
    path: str,
    method: HTTPMethod,
    request_schema: RequestSchema,
    operation_spec: OperationSpecType,
    code_templates=[],
) -> List[Dict[str, str]]:
    """Create a list of rendered code sample Objects

    These are not specified by OpenAPI but are specific to ReDoc."""
    if not code_templates:
        with CODE_TEMPLATES_LOCK:
            if not code_templates:
                code_templates.append(_build_code_templates())

    parameters = operation_spec.get('parameters', [])

    headers = _filter_params(parameters, 'header')
    query_params = _filter_params(parameters, 'query')

    return [{
        'lang':
        language,
        'source':
        template.render(
            request_endpoint=path,
            request_method=method,
            request_schema=(resolve_schema_instance(request_schema)
                            if request_schema is not None else None),
            endpoint_parameters=_transform_params(parameters),
            headers=headers,
            query_params=query_params,
        ).strip(),
    } for language, template in code_templates[0].items()]
Example #5
0
def schema_loads(schema, data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
    """Validate a schema and populate it with the defaults.

    Examples:

        >>> from marshmallow import Schema
        >>> from cmk.gui.plugins.openapi import fields
        >>> class Foo(Schema):
        ...      integer = fields.Integer(required=True)
        ...      hello = fields.String(enum=['World'], required=True)
        ...      default_value = fields.String(missing='was populated')

        If not all required fields are passed, a ProblemException is being raised.

            >>> schema_loads(Foo, {})
            Traceback (most recent call last):
            ...
            connexion.exceptions.ProblemException

            >>> schema_loads(Foo, {'hello': 'Bob', 'integer': 10})
            Traceback (most recent call last):
            ...
            connexion.exceptions.ProblemException

        If validation passes, missing keys are populated with default values as well.

            >>> expected = {
            ...     'default_value': 'was populated',
            ...     'hello': 'World',
            ...     'integer': 10,
            ... }
            >>> res = schema_loads(Foo, {'hello': 'World', 'integer': "10"})
            >>> assert res == expected, res

    Args:
        schema:
            A marshmallow schema class, schema instance or name of a schema.
        data:
            A dictionary with data that should be checked against the schema.

    Returns:
        A new dictionary with the values converted and the defaults populated.

    """
    if schema is None:
        return None
    schema_ = resolve_schema_instance(schema)
    result = schema_.load(data)
    if result.errors:
        raise ProblemException(
            status=400,
            title="The request could not be validated.",
            detail="There is an error in your submitted data.",
            ext={'errors': result.errors},
        )
    return result.data
Example #6
0
def code_samples(path, method, request_schema, code_templates=[]):  # pylint: disable=dangerous-default-value
    """Create a list of rendered code sample Objects

    These are not specified by OpenAPI but are specific to ReDoc."""
    if not code_templates:
        with CODE_TEMPLATES_LOCK:
            if not code_templates:
                code_templates.append(_build_code_templates())

    return [{
        'lang':
        language,
        'source':
        template.render(
            request_endpoint=path,
            request_method=method,
            request_schema=resolve_schema_instance(request_schema),
        ).strip(),
    } for language, template in code_templates[0].items()]
Example #7
0
def _schema_is_multiple(schema: Optional[Union[str, Type[Schema]]]) -> bool:
    if schema is None:
        return False
    _schema = resolve_schema_instance(schema)
    return bool(getattr(_schema, 'type_schemas', None))
Example #8
0
def _schema_is_multiple(schema: Optional[Union[str, Schema]]) -> bool:
    if schema is None:
        return False
    _schema = resolve_schema_instance(schema)
    return hasattr(_schema, 'type_schemas') and _schema.type_schemas