<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def schema(body_schema=None, body_required=False, query_schema=None, # noqa content_types=None, default_body=None):
 """Decorator to parse and validate API body and query string. This decorator allows one to define the entire 'schema' for an API endpoint. :keyword body_schema: Callable that accepts raw data and returns the coerced (or unchanged) body content if it is valid. Otherwise, an error should be raised. :keyword body_required: `True` if some body content is required by the request. Defaults to `False`. :keyword query_schema: Callable that accepts raw data and returns the coerced (or unchanged) query string content if it is valid. Otherwise, an error should be raised. :keyword content_types: List of allowed contents types for request body contents. Defaults to `['application/json']`. :keyword default_body: Default body value to pass to the endpoint handler if `body_required` is `True` but no body was given. This can be useful for specifying complex request body defaults. """

    if not content_types:
        content_types = ['application/json']
    if not all('json' in t for t in content_types):
        raise NotImplementedError("Only 'json' body supported.")

    def deco(func):
        """Return a decorated callable."""
        def wrapped(*args, **kwargs):
            """Validate/coerce request body and parameters."""
            try:
                # validate the request body per the schema (if applicable):
                try:
                    body = bottle.request.json
                except ValueError as exc:
                    raise simpl_rest.HTTPError(
                        body=str(exc),
                        status=400,
                        exception=exc,
                        traceback=traceback.format_exc(),
                    )
                if body is None:
                    body = default_body
                if body_required and not body:
                    raise simpl_rest.HTTPError(
                        body='Request body cannot be empty.',
                        status=400,
                    )
                if body_schema:
                    try:
                        body = body_schema(body)
                    except volup.MultipleInvalid as exc:
                        raise MultiValidationError(exc.errors)

                # validate the query string per the schema (if application):
                query = bottle.request.query.dict  # pylint: disable=no-member
                if query_schema is not None:
                    try:
                        query = query_schema(query)
                    except volup.MultipleInvalid as exc:
                        raise MultiValidationError(exc.errors)
                if not query:
                    # If the query dict is empty, just set it to None.
                    query = None

                # Conditionally add 'body' or 'schema' to kwargs.
                if any([body_schema, body_required, default_body]):
                    kwargs['body'] = body
                if query_schema:
                    kwargs['query'] = query
                return func(
                    *args,
                    **kwargs
                )
            except MultiValidationError as exc:
                raise simpl_rest.HTTPError(
                    body=str(exc),
                    status=400,
                    exception=exc,
                    traceback=traceback.format_exc(),
                )
        return wrapped
    return deco