def test_transcoder_class(self): # Test whether we can pass a class for a transcoder key = self.gen_key("transcoder_class") c = Connection(**self.make_connargs(transcoder=Transcoder)) c.set(key, "value") c = Couchbase.connect(**self.make_connargs(transcoder=Transcoder)) c.set(key, "value")
def __init__(self, **kwargs): self.client = Connection(timeout=60, quiet=True, **kwargs) self.session = requests.Session() self.session.auth = (kwargs['username'], kwargs['password']) self.server_nodes = [ '{}:{}'.format(kwargs['host'], kwargs.get('port', 8091)) ] self.nodes_url = 'http://{}:{}/pools/default/buckets/{}/nodes'.format( kwargs['host'], kwargs.get('port', 8091), kwargs['bucket'], )
def test_connection_errors(self): cb = Connection(password='******', bucket='meh', host='localhost', port=1, _no_connect_exceptions=True) errors = cb.errors() self.assertTrue(len(errors)) self.assertEqual(len(errors[0]), 2) cb = Connection(**self.make_connargs()) self.assertFalse(len(cb.errors()))
def test_quiet(self): connparams = self.make_connargs() cb = Connection(**connparams) self.assertRaises(NotFoundError, cb.get, 'missing_key') cb = Connection(quiet=True, **connparams) cb.delete('missing_key', quiet=True) val1 = cb.get('missing_key') self.assertFalse(val1.success) cb = Connection(quiet=False, **connparams) self.assertRaises(NotFoundError, cb.get, 'missing_key')
def skipLcbMin(self, vstr): """ Test requires a libcouchbase version of at least vstr. This may be a hex number (e.g. 0x020007) or a string (e.g. "2.0.7") """ if isinstance(vstr, basestring): components = vstr.split('.') hexstr = "0x" for comp in components: if len(comp) > 2: raise ValueError("Version component cannot be larger than 99") hexstr += "{0:02}".format(int(comp)) vernum = int(hexstr, 16) else: vernum = vstr components = [] # Get the display for x in range(0, 3): comp = (vernum & 0xff << (x*8)) >> x*8 comp = "{0:x}".format(comp) components = [comp] + components vstr = ".".join(components) rtstr, rtnum = Connection.lcb_version() if rtnum < vernum: raise SkipTest(("Test requires {0} to run (have {1})") .format(vstr, rtstr))
def skipLcbMin(self, vstr): """ Test requires a libcouchbase version of at least vstr. This may be a hex number (e.g. 0x020007) or a string (e.g. "2.0.7") """ if isinstance(vstr, basestring): components = vstr.split('.') hexstr = "0x" for comp in components: if len(comp) > 2: raise ValueError("Version component cannot be larger than 99") hexstr += "{0:02}".format(int(comp)) vernum = int(hexstr, 16) else: vernum = vstr components = [] # Get the display for x in range(0, 3): comp = (vernum & 0xff << (x*8)) >> x*8 comp = "{0:x}".format(comp) components = [comp] + components vstr = ".".join(components) rtstr, rtnum = Connection.lcb_version() if rtnum < vernum: raise SkipTest(("Test requires {0} to run (have {1})") .format(vstr, rtstr))
def test_connection_host_port(self): cb = Connection(host=self.host, port=self.port, username=self.username, password=self.password, bucket=self.bucket_prefix) # Connection didn't throw an error self.assertIsInstance(cb, Connection)
def test_sasl_bucket(self): self.skipUnlessSasl() connargs = self.make_connargs() sasl_params = self.get_sasl_params() del connargs['username'] connargs['bucket'] = sasl_params['bucket'] connargs['password'] = sasl_params['password'] cb = Connection(**connargs) self.assertIsInstance(cb, Connection)
def test_multi_hosts(self): kwargs = { 'username': self.username, 'password': self.password, 'bucket': self.bucket_prefix } cb = Connection(host=[self.host], **kwargs) self.assertTrue(cb.set("foo", "bar").success) cb = Connection(host=[(self.host, self.port)], **kwargs) self.assertTrue(cb.set("foo", "bar").success) cb = Connection(host=[('localhost', 1), (self.host, self.port)], **kwargs) self.assertTrue(cb.set("foo", "bar").success)
def __init__(self, **kwargs): self.client = Connection(timeout=60, quiet=True, **kwargs) self.session = requests.Session() self.session.auth = (kwargs['username'], kwargs['password']) self.server_nodes = ['{}:{}'.format(kwargs['host'], kwargs.get('port', 8091))] self.nodes_url = 'http://{}:{}/pools/default/buckets/{}/nodes'.format( kwargs['host'], kwargs.get('port', 8091), kwargs['bucket'], )
def test_transcoder_class(self): # Test whether we can pass a class for a transcoder key = self.gen_key("transcoder_class") c = Connection(**self.make_connargs(transcoder=TranscoderPP)) c.set(key, "value") c = Couchbase.connect(**self.make_connargs(transcoder=TranscoderPP)) c.set(key, "value")
def __init__(self): self.delay = options.delay self.key = 'K' * options.ksize self.value = b'V' * options.vsize self.wait_time = 0 self.opcount = 0 self.cb = Connection(bucket='default', host=options.hostname, unlock_gil=DO_UNLOCK_GIL) if options.transcoder: self.cb.transcoder = TC self.end_time = time() + options.duration super(Worker, self).__init__()
def test_conncache(self): cachefile = None # On Windows, the NamedTemporaryFile is deleted right when it's # created. So we need to ensure it's not deleted, and delete it # ourselves when it's closed try: cachefile = tempfile.NamedTemporaryFile(delete=False) cb = Connection(conncache=cachefile.name, **self.make_connargs()) self.assertTrue(cb.set("foo", "bar").success) cb2 = Connection(conncache=cachefile.name, **self.make_connargs()) self.assertTrue(cb2.set("foo", "bar").success) self.assertEquals("bar", cb.get("foo").value) sb = os.stat(cachefile.name) # For some reason this fails on Windows? self.assertTrue(sb.st_size > 0) finally: # On windows, we can't delete if the file is still being used cachefile.close() os.unlink(cachefile.name)
def _get_connection(self): """Connect to the Couchbase server.""" if self._connection is None: kwargs = {'bucket': self.bucket, 'host': self.host} if self.port: kwargs.update({'port': self.port}) if self.username: kwargs.update({'username': self.username}) if self.password: kwargs.update({'password': self.password}) logging.debug('couchbase settings %r', kwargs) self._connection = Connection(**kwargs) return self._connection
def _get_connection(self): """Connect to the Couchbase server.""" if self._connection is None: kwargs = {"bucket": self.bucket, "host": self.host} if self.port: kwargs.update({"port": self.port}) if self.username: kwargs.update({"username": self.username}) if self.password: kwargs.update({"password": self.password}) logging.debug("couchbase settings %r", kwargs) self._connection = Connection(**kwargs) return self._connection
def test_quiet(self): connparams = self.make_connargs() cb = Connection(**connparams) self.assertRaises(NotFoundError, cb.get, 'missing_key') cb = Connection(quiet=True, **connparams) cb.delete('missing_key', quiet=True) val1 = cb.get('missing_key') self.assertFalse(val1.success) cb = Connection(quiet=False, **connparams) self.assertRaises(NotFoundError, cb.get, 'missing_key')
def gen_info_dict(): return { "CAPS" : { "VIEWS": True, "CANCEL": True, "CONTINUOUS": True }, "COMPONENTS" : { "LCB": Connection.lcb_version(), "SDK": CB_VERSION }, "CONFIG": { "CONNCACHE": ConnectionPool.CONNCACHE, "POOL_SIZE": ConnectionPool.POOL_SIZE, "TIMEOUT": Handle.DEFAULT_TIMEOUT } }
def test_connection_errors(self): cb = Connection(username='******', password='******', bucket='meh', host='localhost', port=1, _no_connect_exceptions=True) errors = cb.errors() self.assertTrue(len(errors)) self.assertEqual(len(errors[0]), 2) cb = Connection(**self.make_connargs()) self.assertFalse(len(cb.errors()))
def test_connection_defaults(self): ctor_params = self.make_connargs() # XXX: Change these if any of the defaults change defaults = { 'timeout': 2.5, 'quiet': False, 'default_format': FMT_JSON, 'unlock_gil': True, 'transcoder': None } cb_ctor = Connection(**ctor_params) cb_connect = Couchbase.connect(**ctor_params) for option, value in defaults.items(): actual = getattr(cb_ctor, option) self.assertEqual(actual, value) actual = getattr(cb_connect, option) self.assertEqual(actual, value)
def test_multi_hosts(self): kwargs = { 'username' : self.username, 'password' : self.password, 'bucket' : self.bucket_prefix } cb = Connection(host=[self.host], **kwargs) self.assertTrue(cb.set("foo", "bar").success) cb = Connection(host=[(self.host, self.port)], **kwargs) self.assertTrue(cb.set("foo", "bar").success) cb = Connection(host=[('localhost', 1), (self.host, self.port)], **kwargs) self.assertTrue(cb.set("foo", "bar").success)
def __init__(self): self.delay = options.delay self.key = 'K' * options.ksize self.value = b'V' * options.vsize self.kv = {} for x in range(options.batch): self.kv[self.key + str(x)] = self.value self.wait_time = 0 self.opcount = 0 connopts = { "bucket": "default", "host": options.hostname, "unlock_gil": DO_UNLOCK_GIL } if options.iops: connopts["experimental_gevent_support"] = True self.cb = Connection(**connopts) if options.transcoder: self.cb.transcoder = TC self.end_time = time() + options.duration super(Worker, self).__init__()
def test_conncache(self): cachefile = None # On Windows, the NamedTemporaryFile is deleted right when it's # created. So we need to ensure it's not deleted, and delete it # ourselves when it's closed try: cachefile = tempfile.NamedTemporaryFile(delete=False) cb = Connection(conncache=cachefile.name, **self.make_connargs()) self.assertTrue(cb.set("foo", "bar").success) cb2 = Connection(conncache=cachefile.name, **self.make_connargs()) self.assertTrue(cb2.set("foo", "bar").success) self.assertEquals("bar", cb.get("foo").value) sb = os.stat(cachefile.name) # For some reason this fails on Windows? self.assertTrue(sb.st_size > 0) finally: # On windows, we can't delete if the file is still being used cachefile.close() os.unlink(cachefile.name)
def test_bucket(self): cb = Connection(**self.make_connargs()) self.assertIsInstance(cb, Connection)
#!/usr/bin/env python from couchbase.transcoder import Transcoder from couchbase.connection import Connection class ReverseTranscoder(Transcoder): def encode_key(self, key): return super(ReverseTranscoder, self).encode_key(key[::-1]) def decode_key(self, key): key = super(ReverseTranscoder, self).decode_key(key) return key[::-1] c_reversed = Connection(bucket='default', transcoder=ReverseTranscoder()) c_plain = Connection(bucket='default') c_plain.delete_multi(('ABC', 'CBA', 'XYZ', 'ZYX'), quiet=True) c_reversed.set("ABC", "This is a reversed key") rv = c_plain.get("CBA") print("Got value for reversed key '{0}'".format(rv.value)) rv = c_reversed.get("ABC") print("Got value for reversed key '{0}' again".format(rv.value)) c_plain.set("ZYX", "This is really ZYX") rv = c_reversed.get("XYZ")
def test_lcb_version(self): verstr, vernum = Connection.lcb_version() self.assertIsInstance(verstr, str) self.assertIsInstance(vernum, int)
import pprint from couchbase.connection import Connection ap = ArgumentParser() ap.add_argument('-D', '--create-design', default=False, action='store_true', help='whether to create the design') ap.add_argument('-n', '--number-of-terms', default=10, type=int, help="How many terms to generate") options = ap.parse_args() c = Connection(bucket='default') DESIGN = { '_id': '_design/search_keywords', 'language': 'javascript', 'views': { 'top_keywords': { 'map': """ function(doc) { if (typeof doc === 'number') { emit(doc, null); } } """ }
def connect(bucket=None, host='localhost', port=8091, password=None, quiet=False, config_cache=None, unlock_gil=True, timeout=2.5, transcoder=None, lockmode=LOCKMODE_EXC, **kwargs): """Connect to a bucket. :param host: the hostname or IP address of the node. This can be a list or tuple of multiple nodes; the nodes can either be simple strings, or (host, port) tuples (in which case the `port` parameter from the method arguments is ignored). :type host: string or list :param number port: port of the management API. .. note:: The value specified here is the same port used to access The couchbase REST UI (typically `8091`). If you have selcted an alternate port for your bucket, do *not* put it here. The configuration information obtained via the REST interface will automatically instruct the client (one ``connect()`` is called) about which bucket port to connect to. Note that bucket ports are typically ``112xx`` - don't use these for the `port` parameter. :param string password: the password of the bucket :param string bucket: the bucket name :param boolean quiet: the flag controlling whether to raise an exception when the client executes operations on non-existent keys. If it is `False` it will raise :exc:`couchbase.exceptions.NotFoundError` exceptions. When set to `True` the operations will return `None` silently. :param string config_cache: If set, this will refer to a file on the filesystem where cached "bootstrap" information may be stored. This path may be shared among multiple instance of the Couchbase client. Using this option may reduce overhead when using many short-lived instances of the client. In older releases this was called ``conncache`` and will be aliased. If the file does not exist, it will be created. :param boolean unlock_gil: If set (which is the default), the connection object will release the python GIL when possible, allowing other (Python) threads to function in the background. This should be set to true if you are using threads in your application (and is the default), as otherwise all threads will be blocked while couchbase functions execute. You may turn this off for some performance boost and you are certain your application is not using threads :param float timeout: Set the timeout in seconds. If an operation takes longer than this many seconds, the method will return with an error. You may set this higher if you have slow network conditions. :param transcoder: Set the transcoder object to use. This should conform to the interface in the documentation (it need not actually be a subclass). This can be either a class type to instantiate, or an initialized instance. :type transcoder: :class:`couchbase.transcoder.Transcoder` :param lockmode: The *lockmode* for threaded access. See :ref:`multiple_threads` for more information. :param boolean experimental_gevent_support: This boolean value specifies whether *experimental* support for `gevent` should be used. Experimental support is supplied by substituting the built-in libcouchbase I/O functions with their monkey-patched `gevent` equivalents. Note that `gevent.monkey_patch_all` (or similar) must have already been called in order to ensure that the cooperative socket methods are called. .. warning:: As the parameter name implies, this feature is experimental. This means it may crash or hang your application. While no known issues have been discovered at the time of writing, it has not been sufficiently tested and as such is marked as experimental. API and implementation of this feature are subject to change. :raise: :exc:`couchbase.exceptions.BucketNotFoundError` if there is no such bucket to connect to :exc:`couchbase.exceptions.ConnectError` if the socket wasn't accessible (doesn't accept connections or doesn't respond in time) :exc:`couchbase.exceptions.ArgumentError` if the bucket wasn't specified :return: instance of :class:`couchbase.connection.Connection` Initialize connection using default options:: from couchbase import Couchbase cb = Couchbase.connect(bucket='mybucket') Connect to protected bucket:: cb = Couchbase.connect(password='******', bucket='protected') Connect to a different server on the default port 8091:: cb = Couchbase.connect(host='example.com', password='******', bucket='mybucket') """ return Connection(host=host, port=port, password=password, bucket=bucket, unlock_gil=unlock_gil, timeout=timeout, transcoder=transcoder, quiet=quiet, lockmode=lockmode, config_cache=config_cache, **kwargs)
def connect(self, bucket, **kwargs): from couchbase.bucket import _depr from couchbase.connection import Connection _depr('Couchbase.connect()', 'Bucket()') return Connection(bucket, **kwargs)
def test_lcb_version(self): verstr, vernum = Connection.lcb_version() self.assertIsInstance(verstr, str) self.assertIsInstance(vernum, int)
def make_connection(self, **kwargs): return Connection(**self.make_connargs(**kwargs))
class CBGen(CBAsyncGen): NODES_UPDATE_INTERVAL = 15 def __init__(self, **kwargs): self.client = Connection(timeout=60, quiet=True, **kwargs) self.session = requests.Session() self.session.auth = (kwargs['username'], kwargs['password']) self.server_nodes = [ '{}:{}'.format(kwargs['host'], kwargs.get('port', 8091)) ] self.nodes_url = 'http://{}:{}/pools/default/buckets/{}/nodes'.format( kwargs['host'], kwargs.get('port', 8091), kwargs['bucket'], ) def start_updater(self): self.t = Thread(target=self._get_list_of_servers) self.t.daemon = True self.t.start() def _get_list_of_servers(self): while True: try: nodes = self.session.get(self.nodes_url).json() except Exception as e: logger.warn('Failed to get list of servers: {}'.format(e)) continue self.server_nodes = [n['hostname'] for n in nodes['servers']] sleep(self.NODES_UPDATE_INTERVAL) @quiet def create(self, *args, **kwargs): super(CBGen, self).create(*args, **kwargs) @quiet def read(self, *args, **kwargs): super(CBGen, self).read(*args, **kwargs) @quiet def update(self, *args, **kwargs): super(CBGen, self).update(*args, **kwargs) @quiet def cas(self, *args, **kwargs): super(CBGen, self).cas(*args, **kwargs) @quiet def delete(self, *args, **kwargs): super(CBGen, self).delete(*args, **kwargs) def query(self, ddoc, view, query): node = choice(self.server_nodes).replace('8091', '8092') url = 'http://{}/{}/_design/{}/_view/{}?{}'.format( node, self.client.bucket, ddoc, view, query.encoded) t0 = time() resp = self.session.get(url=url) latency = time() - t0 return resp.text, latency @quiet def lcb_query(self, ddoc, view, query): return tuple(self.client.query(ddoc, view, query=query))
class CBGen(CBAsyncGen): NODES_UPDATE_INTERVAL = 15 def __init__(self, **kwargs): self.client = Connection(timeout=60, quiet=True, **kwargs) self.session = requests.Session() self.session.auth = (kwargs['username'], kwargs['password']) self.server_nodes = ['{}:{}'.format(kwargs['host'], kwargs.get('port', 8091))] self.nodes_url = 'http://{}:{}/pools/default/buckets/{}/nodes'.format( kwargs['host'], kwargs.get('port', 8091), kwargs['bucket'], ) def start_updater(self): self.t = Thread(target=self._get_list_of_servers) self.t.daemon = True self.t.start() def _get_list_of_servers(self): while True: try: nodes = self.session.get(self.nodes_url).json() except Exception as e: logger.warn('Failed to get list of servers: {}'.format(e)) continue self.server_nodes = [n['hostname'] for n in nodes['servers']] sleep(self.NODES_UPDATE_INTERVAL) @quiet def create(self, *args, **kwargs): super(CBGen, self).create(*args, **kwargs) @quiet def read(self, *args, **kwargs): super(CBGen, self).read(*args, **kwargs) @quiet def update(self, *args, **kwargs): super(CBGen, self).update(*args, **kwargs) @quiet def cas(self, *args, **kwargs): super(CBGen, self).cas(*args, **kwargs) @quiet def delete(self, *args, **kwargs): super(CBGen, self).delete(*args, **kwargs) def query(self, ddoc, view, query): node = choice(self.server_nodes).replace('8091', '8092') url = 'http://{}/{}/_design/{}/_view/{}?{}'.format( node, self.client.bucket, ddoc, view, query.encoded ) t0 = time() resp = self.session.get(url=url) latency = time() - t0 return resp.text, latency @quiet def lcb_query(self, ddoc, view, query): return tuple(self.client.query(ddoc, view, query=query))
from argparse import ArgumentParser import random import pprint from couchbase.connection import Connection ap = ArgumentParser() ap.add_argument("-D", "--create-design", default=False, action="store_true", help="whether to create the design") ap.add_argument("-n", "--number-of-terms", default=10, type=int, help="How many terms to generate") options = ap.parse_args() c = Connection(bucket="default") DESIGN = { "_id": "_design/search_keywords", "language": "javascript", "views": { "top_keywords": { "map": """ function(doc) { if (typeof doc === 'number') { emit(doc, null); } } """ } },