Esempio n. 1
0
 def test_fetch(self):
     # add a database without http auth
     client = CouchAsyncHTTPClient('http://172.16.200.51:5984/', self.io_loop)
     resp = yield client.fetch(
         'newcmdb',
         method="PUT",
         raise_error=False,
         allow_nonstandard_methods=True
     )
     self.assertEqual(resp.body, '{"error":"unauthorized","reason":"You are not a server admin."}')
Esempio n. 2
0
 def test_fetch_del(self):
     # delete a database with http auth
     client = CouchAsyncHTTPClient('http://172.16.200.51:5984/', self.io_loop)
     resp = yield client.fetch(
         'newcmdb',
         method="DELETE",
         raise_error=False,
         auth_username='******',
         auth_password='******',
         allow_nonstandard_methods=True
     )
     self.assertEqual(resp.body, '{"ok":true}\n')
Esempio n. 3
0
class TestHttpClient(AsyncTestCase):
    @classmethod
    def setUpClass(cls):
        cls.database = 'couch-test'

    def setUp(self):
        super(TestHttpClient, self).setUp()  # setup io_loop
        self.client = CouchAsyncHTTPClient('http://127.0.0.1:5984/', self.io_loop)

    @gen_test(timeout=3)
    def test_get(self):
        resp = yield self.client.get(self.database, 'not exist', raise_error=False)
        self.assertEqual(resp.body, '{"error":"not_found","reason":"missing"}')

    @gen_test(timeout=3)
    def test_put(self):
        client = CouchAsyncHTTPClient('http://172.16.200.51:5984/', self.io_loop)
        resp = yield client.put('cmdb', 'foo_bar', {"foo": "bar"}, raise_error=False)
        print(resp.body)

    @gen_test(timeout=3)
    def test_fetch(self):
        # add a database without http auth
        client = CouchAsyncHTTPClient('http://172.16.200.51:5984/', self.io_loop)
        resp = yield client.fetch(
            'newcmdb',
            method="PUT",
            raise_error=False,
            allow_nonstandard_methods=True
        )
        self.assertEqual(resp.body, '{"error":"unauthorized","reason":"You are not a server admin."}')

    @gen_test(timeout=3)
    def test_fetch_auth(self):
        # add a database with http auth
        client = CouchAsyncHTTPClient('http://172.16.200.51:5984/', self.io_loop)
        resp = yield client.fetch(
            'newcmdb',
            method="PUT",
            raise_error=False,
            auth_username='******',
            auth_password='******',
            allow_nonstandard_methods=True
        )
        self.assertEqual(resp.body, '{"ok":true}\n')

    @gen_test(timeout=3)
    def test_fetch_del(self):
        # delete a database with http auth
        client = CouchAsyncHTTPClient('http://172.16.200.51:5984/', self.io_loop)
        resp = yield client.fetch(
            'newcmdb',
            method="DELETE",
            raise_error=False,
            auth_username='******',
            auth_password='******',
            allow_nonstandard_methods=True
        )
        self.assertEqual(resp.body, '{"ok":true}\n')
Esempio n. 4
0
 def test_put(self):
     client = CouchAsyncHTTPClient('http://172.16.200.51:5984/', self.io_loop)
     resp = yield client.put('cmdb', 'foo_bar', {"foo": "bar"}, raise_error=False)
     print(resp.body)
Esempio n. 5
0
 def setUp(self):
     super(TestHttpClient, self).setUp()  # setup io_loop
     self.client = CouchAsyncHTTPClient('http://127.0.0.1:5984/', self.io_loop)
Esempio n. 6
0
 def __init__(self, url='http://localhost:5984', io_loop=None):
     self.base_url = url[:-1] if url.endswith('/') else url
     self.io_loop = io_loop or ioloop.IOLoop.instance()
     self.client = CouchAsyncHTTPClient(self.base_url, self.io_loop)
Esempio n. 7
0
class CouchServer(object):
    """
    couchdb database operation
    """

    def __init__(self, url='http://localhost:5984', io_loop=None):
        self.base_url = url[:-1] if url.endswith('/') else url
        self.io_loop = io_loop or ioloop.IOLoop.instance()
        self.client = CouchAsyncHTTPClient(self.base_url, self.io_loop)

    @gen.coroutine
    def create(self, database):
        # if couchdb set a admin must use http auth to create/delete a database

        # because tornado AsyncHttpclient can not send a empty body with 'PUT' method
        # so here set allow_nonstandard_methods = True
        # this option send body with a '0' instead of empty
        # if couchdb implement on a windows client will get an error: [Errno 10054]
        # because couchdb send a RST packet , but it works fine on Linux
        try:
            resp = yield self.client.fetch(
                database,
                method="PUT",
                auth_username=couch_conf['user'],
                auth_password=couch_conf['passwd'],
                allow_nonstandard_methods=True
                )
            raise gen.Return(resp.body)
        except HTTPError:
            # HTTP 412: Precondition Failed
            raise ValueError('Database: {0} Exist'.format(database))

    @staticmethod
    def _get_design(root):
        design_path = os.path.join(root, 'design')
        return [os.path.join(design_path, f) for f in os.listdir(design_path)]

    @gen.coroutine
    def init(self, database):
        """
        add design document to a new database
        """
        root = os.path.join(os.path.dirname(__file__), '..')
        designs = self._get_design(root)
        for design in designs:
            design_name = os.path.basename(design).split('.')[0]
            with open(design) as f:
                doc = json_decode(f.read())
                yield self.client.fetch(
                    '{0}/_design/{1}'.format(database, design_name),
                    method="PUT",
                    body=doc,
                    auth_username=couch_conf['user'],
                    auth_password=couch_conf['passwd']
                )

    @gen.coroutine
    def delete(self, database):
        try:
            resp = yield self.client.fetch(
                database,
                method="DELETE",
                auth_username=couch_conf['user'],
                auth_password=couch_conf['passwd']
            )
            raise gen.Return(resp.body)
        except HTTPError:
            raise ValueError('Database: {0} not Exist'.format(database))

    @gen.coroutine
    def list_db(self):
        resp = yield self.client.fetch('_all_dbs', method="GET", allow_nonstandard_methods=True)
        databases = [db for db in json_decode(resp.body) if not db.startswith('_')]
        raise gen.Return(databases)
Esempio n. 8
0
class CouchBase(object):
    """
    couchdb document operation
    """

    def __init__(self, url='http://localhost:5984', io_loop=None):
        self.url = url[:-1] if url.endswith('/') else url
        self.io_loop = io_loop or ioloop.IOLoop.instance()
        self.client = CouchAsyncHTTPClient(self.url, io_loop=self.io_loop)

    @gen.coroutine
    def list_ids(self, database):
        """ only list document id which not starts with '_' """
        resp = yield self.get_doc(database, '_all_docs')
        raise gen.Return([doc['id'] for doc in resp['rows'] if not doc['id'].startswith('_')])

    @gen.coroutine
    def get_doc(self, database, doc_id):
        """
        return Document instance
        """

        resp = yield self.client.get(database, doc_id, raise_error=False)
        if resp.code == 200:
            raise gen.Return(Document(json_decode(resp.body)))
        elif resp.code == 404:
            # {"error":"not_found","reason":"no_db_file"} for db not exist
            # {"error":"not_found","reason":"missing"} for doc not exist
            raise ValueError(json_decode(resp.body)['reason'])

    @gen.coroutine
    def has_doc(self, database, doc_id):
        try:
            resp = yield self.client.head(database, doc_id)
            raise gen.Return(resp.code == 200)
        except HTTPError:
            raise gen.Return(False)

    @gen.coroutine
    def get_doc_rev(self, database, doc_id):
        try:
            resp = yield self.client.head(database, doc_id)
            raise gen.Return(resp.headers['Etag'].strip('"'))
        except HTTPError:
            raise ValueError("Document {0} not Exist".format(doc_id))

    @gen.coroutine
    def update_doc(self, database, doc_id, doc):
        resp = yield self.client.put(database, doc_id, doc)
        raise gen.Return(resp.body.decode('utf-8'))

    @gen.coroutine
    def update_doc_field(self, database, doc_id, **fields):
        doc = yield self.get_doc(database, doc_id)
        for field, value in fields.items():
            doc[field] = value
        resp = yield self.client.put(database, doc_id, doc)
        raise gen.Return(resp.body.decode('utf-8'))

    @gen.coroutine
    def del_doc(self, database, doc_id):
        rev = yield self.get_doc_rev(database, doc_id)
        resp = yield self.client.delete(database, doc_id, rev)
        # json_decode can not decode String "True" but "true"
        # should return lowercase string "true"
        raise gen.Return("true" if resp.code == 200 else "false")