Esempio n. 1
0
    def __init__(self,
                 host='localhost',
                 port=6379,
                 db=0,
                 password=None,
                 stream_timeout=None,
                 connect_timeout=None,
                 connection_pool=None,
                 unix_socket_path=None,
                 encoding='utf-8',
                 decode_responses=False,
                 ssl=False,
                 ssl_context=None,
                 ssl_keyfile=None,
                 ssl_certfile=None,
                 ssl_cert_reqs=None,
                 ssl_ca_certs=None,
                 max_connections=None,
                 retry_on_timeout=False,
                 max_idle_time=0,
                 idle_check_interval=1,
                 client_name=None,
                 loop=None,
                 **kwargs):
        if not connection_pool:
            kwargs = {
                'db': db,
                'password': password,
                'encoding': encoding,
                'stream_timeout': stream_timeout,
                'connect_timeout': connect_timeout,
                'max_connections': max_connections,
                'retry_on_timeout': retry_on_timeout,
                'decode_responses': decode_responses,
                'max_idle_time': max_idle_time,
                'idle_check_interval': idle_check_interval,
                'client_name': client_name,
                'loop': loop
            }
            # based on input, setup appropriate connection args
            if unix_socket_path is not None:
                kwargs.update({
                    'path': unix_socket_path,
                    'connection_class': UnixDomainSocketConnection
                })
            else:
                # TCP specific options
                kwargs.update({'host': host, 'port': port})
                if ssl_context is not None:
                    kwargs['ssl_context'] = ssl_context
                elif ssl:
                    ssl_context = RedisSSLContext(ssl_keyfile, ssl_certfile,
                                                  ssl_cert_reqs,
                                                  ssl_ca_certs).get()
                    kwargs['ssl_context'] = ssl_context
            connection_pool = ConnectionPool(**kwargs)
        self.connection_pool = connection_pool
        self._use_lua_lock = None

        self.response_callbacks = self.__class__.RESPONSE_CALLBACKS.copy()
Esempio n. 2
0
    def from_url(cls, url, db=None, decode_components=False, **kwargs):
        """
        Return a connection pool configured from the given URL.

        For example::

        redis://[:password]@localhost:6379/0
        rediss://[:password]@localhost:6379/0
        unix://[:password]@/path/to/socket.sock?db=0

        Three URL schemes are supported:

        - ```redis://``
        <http://www.iana.org/assignments/uri-schemes/prov/redis>`_ creates a
        normal TCP socket connection
        - ```rediss://``
        <http://www.iana.org/assignments/uri-schemes/prov/rediss>`_ creates a
        SSL wrapped TCP socket connection
        - ``unix://`` creates a Unix Domain Socket connection

        There are several ways to specify a database number. The parse function
        will return the first specified option:
        1. A ``db`` querystring option, e.g. redis://localhost?db=0
        2. If using the redis:// scheme, the path argument of the url, e.g.
        redis://localhost/0
        3. The ``db`` argument to this function.

        If none of these options are specified, db=0 is used.

        The ``decode_components`` argument allows this function to work with
        percent-encoded URLs. If this argument is set to ``True`` all ``%xx``
        escapes will be replaced by their single-character equivalents after
        the URL has been parsed. This only applies to the ``hostname``,
        ``path``, and ``password`` components.

        Any additional querystring arguments and keyword arguments will be
        passed along to the ConnectionPool class's initializer. The querystring
        arguments ``socket_connect_timeout`` and ``socket_timeout`` if supplied
        are parsed as float values. The arguments ``socket_keepalive`` and
        ``retry_on_timeout`` are parsed to boolean values that accept
        True/False, Yes/No values to indicate state. Invalid types cause a
        ``UserWarning`` to be raised. In the case of conflicting arguments,
        querystring arguments always win.
        """
        url = urlparse(url)
        qs = url.query

        url_options = {}

        for name, value in iter(parse_qs(qs).items()):
            if value and len(value) > 0:
                parser = URL_QUERY_ARGUMENT_PARSERS.get(name)
                if parser:
                    try:
                        url_options[name] = parser(value[0])
                    except (TypeError, ValueError):
                        warnings.warn(
                            UserWarning(
                                "Invalid value for `%s` in connection URL." %
                                name))
                else:
                    url_options[name] = value[0]

        if decode_components:
            password = unquote(url.password) if url.password else None
            path = unquote(url.path) if url.path else None
            hostname = unquote(url.hostname) if url.hostname else None
        else:
            password = url.password
            path = url.path
            hostname = url.hostname

        # We only support redis:// and unix:// schemes.
        if url.scheme == 'unix':
            url_options.update({
                'password': password,
                'path': path,
                'connection_class': UnixDomainSocketConnection,
            })

        else:
            url_options.update({
                'host': hostname,
                'port': int(url.port or 6379),
                'password': password,
            })

            # If there's a path argument, use it as the db argument if a
            # querystring value wasn't specified
            if 'db' not in url_options and path:
                try:
                    url_options['db'] = int(path.replace('/', ''))
                except (AttributeError, ValueError):
                    pass

            if url.scheme == 'rediss':
                keyfile = url_options.pop('ssl_keyfile', None)
                certfile = url_options.pop('ssl_certfile', None)
                cert_reqs = url_options.pop('ssl_cert_reqs', None)
                ca_certs = url_options.pop('ssl_ca_certs', None)
                url_options['ssl_context'] = RedisSSLContext(
                    keyfile, certfile, cert_reqs, ca_certs).get()

        # last shot at the db value
        url_options['db'] = int(url_options.get('db', db or 0))

        # update the arguments from the URL values
        kwargs.update(url_options)
        return cls(**kwargs)