Ejemplo n.º 1
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')
Ejemplo n.º 2
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")