def do_POST_restart(self) -> None:
        """Handle a ``POST`` request to ``/restart`` path.

        Used to restart postgres (or schedule a restart), mainly by ``patronictl restart``.

        The request body should be a JSON dictionary, and it can contain the following keys:

            * ``schedule``: timestamp at which the restart should occur;
            * ``role``: restart only nodes which role is ``role``. Can be either:

                * ``primary`; or
                * ``replica``.

            * ``postgres_version``: restart only nodes which PostgreSQL version is less than ``postgres_version``, e.g.
                ``15.2``;
            * ``timeout``: if restart takes longer than ``timeout`` return an error and fail over to a replica;
            * ``restart_pending``: if we should restart only when have ``pending restart`` flag;

        Response HTTP status codes:

            * ``200``: if successfully performed an immediate restart; or
            * ``202``: if successfully scheduled a restart for later; or
            * ``500``: if the cluster is in maintenance mode; or
            * ``400``: if

                * ``role`` value is invalid; or
                * ``postgres_version`` value is invalid; or
                * ``timeout`` is not a number, or lesser than ``0``; or
                * request contains an unknown key; or
                * exception is faced while performing an immediate restart.

            * ``409``: if another restart was already previously scheduled; or
            * ``503``: if any issue was found while performing an immediate restart; or
            * HTTP status returned by :func:`parse_schedule`, if any error was observed while parsing the schedule.

        .. note::
            If it's not able to parse the request body, then the request is silently discarded.
        """
        status_code = 500
        data = PostgresqlState.RESTART_FAILED
        request = self._read_json_content(body_is_optional=True)
        cluster = self.server.patroni.dcs.get_cluster()
        if request is None:
            # failed to parse the json
            return
        if request:
            logger.debug("received restart request: {0}".format(request))

        if global_config.from_cluster(cluster).is_paused and 'schedule' in request:
            self.write_response(status_code, "Can't schedule restart in the paused state")
            return

        for k in request:
            if k == 'schedule':
                (_, data, request[k]) = self.parse_schedule(request[k], "restart")
                if _:
                    status_code = _
                    break
            elif k == 'role':
                if request[k] not in (PostgresqlRole.PRIMARY, PostgresqlRole.STANDBY_LEADER, PostgresqlRole.REPLICA):
                    status_code = 400
                    data = "PostgreSQL role should be either primary, standby_leader, or replica"
                    break
            elif k == 'postgres_version':
                try:
                    postgres_version_to_int(request[k])
                except PostgresException as e:
                    status_code = 400
                    data = e.value
                    break
            elif k == 'timeout':
                request[k] = parse_int(request[k], 's')
                if request[k] is None or request[k] <= 0:
                    status_code = 400
                    data = "Timeout should be a positive number of seconds"
                    break
            elif k != 'restart_pending':
                status_code = 400
                data = "Unknown filter for the scheduled restart: {0}".format(k)
                break
        else:
            if 'schedule' not in request:
                try:
                    status, data = self.server.patroni.ha.restart(request)
                    status_code = 200 if status else 503
                except Exception:
                    logger.exception('Exception during restart')
                    status_code = 400
            else:
                if self.server.patroni.ha.schedule_future_restart(request):
                    data = "Restart scheduled"
                    status_code = 202
                else:
                    data = "Another restart is already scheduled"
                    status_code = 409
        # pyright thinks ``data`` can be ``None`` because ``parse_schedule`` call may return ``None``. However, if
        # that's the case, ``data`` will be overwritten when the ``for`` loop ends
        if TYPE_CHECKING:  # pragma: no cover
            assert isinstance(data, str)
        self.write_response(status_code, data)
Handle a ``POST`` request to ``/restart`` path.

        Used to restart postgres (or schedule a restart), mainly by ``patronictl restart``.

        The request body should be a JSON dictionary, and it can contain the following keys:

            * ``schedule``: timestamp at which the restart should occur;
            * ``role``: restart only nodes which role is ``role``. Can be either:

                * ``primary`; or
                * ``replica``.

            * ``postgres_version``: restart only nodes which PostgreSQL version is less than ``postgres_version``, e.g.
                ``15.2``;
            * ``timeout``: if restart takes longer than ``timeout`` return an error and fail over to a replica;
            * ``restart_pending``: if we should restart only when have ``pending restart`` flag;

        Response HTTP status codes:

            * ``200``: if successfully performed an immediate restart; or
            * ``202``: if successfully scheduled a restart for later; or
            * ``500``: if the cluster is in maintenance mode; or
            * ``400``: if

                * ``role`` value is invalid; or
                * ``postgres_version`` value is invalid; or
                * ``timeout`` is not a number, or lesser than ``0``; or
                * request contains an unknown key; or
                * exception is faced while performing an immediate restart.

            * ``409``: if another restart was already previously scheduled; or
            * ``503``: if any issue was found while performing an immediate restart; or
            * HTTP status returned by :func:`parse_schedule`, if any error was observed while parsing the schedule.

        .. note::
            If it's not able to parse the request body, then the request is silently discarded.
        
patroni/api.py