def uri(proto: str, netloc: Union[List[str], Tuple[str, Union[int, str]], str], path: Optional[str] = '',
        user: Optional[str] = None) -> str:
    """Construct URI from given arguments.

    :param proto: the URI protocol.
    :param netloc: the URI host(s) and port. Can be specified in either way among

        * A :class:`list` or :class:`tuple`. The second item should be a port, and the first item should be composed of
            hosts in either of these formats:

            * ``host``; or.
            * ``host1,host2,...,hostn``.

        * A :class:`str` in either of these formats:

            * ``host:port``; or
            * ``host1,host2,...,hostn:port``.

        In all cases, each ``host`` portion of *netloc* can be either:

            * An FQDN; or
            * An IPv4 address; or
            * An IPv6 address, with or without square brackets.

    :param path: the URI path.
    :param user: the authenticating user, if any.

    :returns: constructed URI.
    """
    host, port = netloc if isinstance(netloc, (list, tuple)) else split_host_port(netloc, 0)
    # If ``host`` contains ``:`` we consider it to be an IPv6 address, so we add square brackets if they are missing
    if host and ':' in host and host[0] != '[' and host[-1] != ']':
        host = '[{0}]'.format(host)
    port = ':{0}'.format(port) if port else ''
    path = '/{0}'.format(path) if path and not path.startswith('/') else path
    user = '{0}@'.format(user) if user else ''
    return '{0}://{1}{2}{3}{4}'.format(proto, user, host, port, path)
Construct URI from given arguments.

    :param proto: the URI protocol.
    :param netloc: the URI host(s) and port. Can be specified in either way among

        * A :class:`list` or :class:`tuple`. The second item should be a port, and the first item should be composed of
            hosts in either of these formats:

            * ``host``; or.
            * ``host1,host2,...,hostn``.

        * A :class:`str` in either of these formats:

            * ``host:port``; or
            * ``host1,host2,...,hostn:port``.

        In all cases, each ``host`` portion of *netloc* can be either:

            * An FQDN; or
            * An IPv4 address; or
            * An IPv6 address, with or without square brackets.

    :param path: the URI path.
    :param user: the authenticating user, if any.

    :returns: constructed URI.
    
patroni/utils.py