Exemple #1
0
def test_build_index():
    engine, table = connect()
    client = CkanClient(base_location='http://catalogue.data.gov.uk/api')
    res = client.package_search("tags:spend-transactions",
            search_options={'limit': 5})
    for package_name in res['results']:
        fetch_package.description = 'metadata: %s' % package_name
        yield fetch_package, client, package_name, engine, table
Exemple #2
0
class CkanIndex(IndexBase):
    '''CKAN index.

    Where parameters not provided look them up in config.

    :param url: url for ckan API.
    :param api_key: API key.
    '''
    def __init__(self, url=None, api_key=None):
        self.status_info = ''
        if url is not None:
            self.url = url
        else:
            self.url = datapkg.CONFIG.get('index:ckan', 'ckan.url')
        if api_key is not None:
            self.api_key = api_key
        else:
            self.api_key = datapkg.CONFIG.dictget('index:ckan', 'ckan.api_key', None)
        if self.url.endswith('/'):
            self.url = self.url[:-1]
        from ckanclient import CkanClient
        service_kwds = {}
        service_kwds['base_location'] = self.url
        service_kwds['api_key'] = self.api_key
        self._print("datapkg: CKAN config: %s" % service_kwds )
        self.ckan = CkanClient(**service_kwds)

    def _print(self, msg):
        self.status_info += msg + '\n'
        logger.debug(msg)

    def list(self):
        self.ckan.package_register_get()
        self.print_status()
        if self.ckan.last_status == 200:
            if self.ckan.last_message != None:
                pkgs = [ self.cvt_to_pkg({'name': x})
                            for x in self.ckan.last_message ]
                return pkgs
            else:
                self._print("No response data. Check the resource location.")
                # TODO: convert to CKAN exception
        raise Exception(self.status_info)

    def search(self, query):
        # TODO: think this automatically limits results to 20 or so
        for pkg_name in self.ckan.package_search(query)['results']:
            yield self.get(pkg_name)
    
    def has(self, name):
        try:
            out = self.get(name)
            return True
        except Exception, inst:
            if self.ckan.last_status == 404:
                return False
            else:
                raise
Exemple #3
0
def traverse(pkg_func, query='*:*'):
    client = CkanClient(base_location=HOST, api_key=API_KEY)
    for page in count(1):
        results_page = client.package_search(query, search_options={
            'offset': page*PAGE_SIZE, 'limit': PAGE_SIZE})
        #pprint(results_page)
        if not len(results_page.get('results', [])): 
            break
        for pkg_name in results_page.get('results', []):
            print "Traversing", pkg_name
            pkg = client.package_entity_get(pkg_name)
            ret = pkg_func(client, pkg)
            if ret is not None:
                client.package_entity_put(ret, package_name=pkg_name)
Exemple #4
0
def traverse(pkg_func, query='*:*'):
    client = CkanClient(base_location=HOST, api_key=API_KEY)
    for page in count(1):
        results_page = client.package_search(query,
                                             search_options={
                                                 'offset': page * PAGE_SIZE,
                                                 'limit': PAGE_SIZE
                                             })
        #pprint(results_page)
        if not len(results_page.get('results', [])):
            break
        for pkg_name in results_page.get('results', []):
            print "Traversing", pkg_name
            pkg = client.package_entity_get(pkg_name)
            ret = pkg_func(client, pkg)
            if ret is not None:
                client.package_entity_put(ret, package_name=pkg_name)
Exemple #5
0
class TestCkanClient(CkanServerCase):
    @classmethod
    def setup_class(self):
        self.pid = self._start_ckan_server()
        self.test_base_location = 'http://127.0.0.1:5000/api'
        self._wait_for_url(url=self.test_base_location)
        self._recreate_ckan_server_testdata(config_path)
        # this is api key created for tester user by create-test-data in ckan
        test_api_key = 'tester'
        test_api_key2 = 'tester2'

        self.c = CkanClient(
            base_location=self.test_base_location,
            api_key=test_api_key,
            is_verbose=True,
        )
        self.c2 = CkanClient(
            base_location=self.test_base_location,
            api_key=test_api_key2,
            is_verbose=True,
        )

    @classmethod
    def teardown_class(self):
        self._stop_ckan_server(self.pid)

    def delete_relationships(self):
        res = self.c.package_relationship_register_get('annakarenina')
        if self.c.last_status == 200:
            if self.c.last_message:
                for rel_dict in self.c.last_message:
                    self.c.package_relationship_entity_delete( \
                        rel_dict['subject'],
                        rel_dict['type'],
                        rel_dict['object'])

    def test_01_get_locations(self):
        rest_base = self.test_base_location + '/rest'
        search_base = self.test_base_location + '/search'
        url = self.c.get_location('Base')
        assert url == self.test_base_location, url
        url = self.c.get_location('Package Register')
        assert url == rest_base + '/package'
        url = self.c.get_location('Package Entity', 'myname')
        assert url == rest_base + '/package/myname'
        url = self.c.get_location('Package Entity', 'myname', 'relationships')
        assert url == rest_base + '/package/myname/relationships'
        url = self.c.get_location('Package Entity', 'myname', 'relationships',
                                  'name2')
        assert url == rest_base + '/package/myname/relationships/name2'
        url = self.c.get_location('Package Entity', 'myname', 'child_of',
                                  'name2')
        assert url == rest_base + '/package/myname/child_of/name2'
        url = self.c.get_location('Group Register')
        assert url == rest_base + '/group'
        url = self.c.get_location('Group Entity', 'myname')
        assert url == rest_base + '/group/myname'
        url = self.c.get_location('Tag Register')
        assert url == rest_base + '/tag'
        url = self.c.get_location('Tag Entity', 'myname')
        assert url == rest_base + '/tag/myname'
        url = self.c.get_location('Tag Entity', 'myname')
        assert url == rest_base + '/tag/myname'
        url = self.c.get_location('Package Search')
        assert url == search_base + '/package'

    def test_02_get_api_version(self):
        version = self.c.api_version_get()
        status = self.c.last_status
        assert status == 200
        body = self.c.last_body
        assert 'version' in body, body
        assert int(version) > 0, version

    def test_03_package_register_get(self):
        self.c.package_register_get()
        status = self.c.last_status
        assert status == 200
        body = self.c.last_body
        assert 'annakarenina' in body, body
        assert type(self.c.last_message) == list
        assert 'annakarenina' in self.c.last_message

    def test_04_package_entity_get(self):
        # Check registered entity is found.
        self.c.package_entity_get('annakarenina')
        status = self.c.last_status
        assert status == 200, status
        body = self.c.last_body
        assert 'annakarenina' in body
        assert self.c.last_message
        message = self.c.last_message
        assert type(message) == dict
        assert message['name'] == u'annakarenina'
        assert message['title'] == u'A Novel By Tolstoy'

    def test_05_package_entity_get_404(self):
        # Check unregistered entity is not found.
        assert_raises(CkanApiError, self.c.package_entity_get, 'mycoffeecup')
        status = self.c.last_status
        assert status == 404, status

    @classmethod
    def _generate_pkg_name(self):
        pkg_name = 'ckanclienttest'
        import time
        timestr = str(time.time()).replace('.', '')
        pkg_name += timestr
        return pkg_name

    def test_06_package_register_post(self):
        pkg_name = self._generate_pkg_name()
        # Check package isn't registered.
        assert_raises(CkanApiError, self.c.package_entity_get, pkg_name)
        status = self.c.last_status
        assert status == 404, status
        # Check registration of new package.
        package = {
            'name': pkg_name,
            'url': 'orig_url',
            'download_url': 'orig_download_url',
            'tags': ['russian', 'newtag'],
            'extras': {
                'genre': 'thriller',
                'format': 'ebook'
            },
        }
        self.c.package_register_post(package)
        status = self.c.last_status
        assert status == 201, status

        # Check package is registered.
        self.c.package_entity_get(pkg_name)
        status = self.c.last_status
        assert status == 200, status
        message = self.c.last_message
        assert message
        assert 'name' in message, repr(message)
        name = message['name']
        assert name == pkg_name
        url = message['url']
        assert url == 'orig_url'
        download_url = message['download_url']
        assert download_url == 'orig_download_url'
        tags = message['tags']
        # order out is not guaranteed
        assert set(tags) == set(['newtag', 'russian']), tags
        extras = message['extras']
        assert extras == package['extras']

    def test_07_package_entity_put(self):
        # Register new package.
        pkg_name_test_07 = self._generate_pkg_name()
        package = {
            'name': pkg_name_test_07,
            'url': 'orig_url',
            'download_url': 'orig_download_url',
            'tags': ['russian'],
        }
        self.c.package_register_post(package)
        status = self.c.last_status
        assert status == 201, status

        # Check update of existing package.
        mytag = 'mytag' + pkg_name_test_07
        package = {
            'name': pkg_name_test_07,
            'url': 'new_url',
            'download_url': 'new_download_url',
            'tags': ['russian', 'tolstoy', mytag],
            'extras': {
                'genre': 'thriller',
                'format': 'ebook'
            },
        }
        self.c.package_entity_put(package)
        status = self.c.last_status
        assert status == 200

        # Check package is updated.
        self.c.package_entity_get(pkg_name_test_07)
        status = self.c.last_status
        assert status == 200, status
        message = self.c.last_message
        name = message['name']
        assert name == pkg_name_test_07
        url = message['url']
        assert url == 'new_url'
        download_url = message['download_url']
        assert download_url == 'new_download_url'
        tags = message['tags']
        # order out is not guaranteed
        assert set(tags) == set(['russian', 'tolstoy', mytag]), tags
        extras = message['extras']
        assert extras == package['extras']

    def test_08_package_entity_delete(self):
        # create a package to be deleted
        pkg_name = self._generate_pkg_name()
        self.c.package_register_post({'name': pkg_name})
        status = self.c.last_status
        assert status == 201, status

        # check it is readable
        self.c.package_entity_get(pkg_name)
        assert self.c.last_status == 200, self.c.last_status

        # delete it
        self.c.package_entity_delete(pkg_name)

        # see it is not readable by another user
        assert_raises(CkanApiError, self.c2.package_entity_get, pkg_name)
        assert self.c2.last_status == 403, self.c.last_status

        # see it is still readable by the author (therefore pkg admin)
        self.c.package_entity_get(pkg_name)
        assert self.c.last_status == 200, self.c.last_status

    def test_09_tag_register_get(self):
        self.c.tag_register_get()
        status = self.c.last_status
        assert status == 200
        body = self.c.last_body
        assert 'russian' in body
        assert type(self.c.last_message) == list
        assert 'russian' in self.c.last_message

    def test_10_pkg_search_basic(self):
        res = self.c.package_search('Novel')
        status = self.c.last_status
        assert status == 200, status
        assert_equal(list(res['results']), [u'annakarenina'])
        assert_equal(res['count'], 1)

    def test_10_pkg_search_paged(self):
        res = self.c.package_search('russian', search_options={'limit': 1})
        status = self.c.last_status
        assert status == 200, status
        all_results = list(res['results'])
        assert set(all_results) >= set([u'annakarenina', u'warandpeace'
                                        ]), all_results
        assert res['count'] >= 2, '%r %r' % (res, all_results)

    def test_10_pkg_search_options(self):
        res = self.c.package_search(None, search_options={'groups': 'roger'})
        status = self.c.last_status
        assert status == 200, status
        assert_equal(list(res['results']), [u'annakarenina'])
        assert_equal(res['count'], 1)

    def test_10_pkg_search_options_all_fields(self):
        res = self.c.package_search(None,
                                    search_options={
                                        'groups': 'roger',
                                        'all_fields': True
                                    })
        status = self.c.last_status
        assert status == 200, status
        assert_equal(res['count'], 1)
        assert_equal(list(res['results'])[0]['name'], u'annakarenina')

    def test_11_package_relationship_post(self):
        res = self.c.package_relationship_register_get('annakarenina')
        assert self.c.last_status == 200, self.c.last_status
        assert not self.c.last_message, self.c.last_body

        # create relationship
        res = self.c.package_relationship_entity_post('annakarenina',
                                                      'child_of',
                                                      'warandpeace',
                                                      'some comment')
        try:
            assert self.c.last_status == 201, self.c.last_status
        finally:
            self.delete_relationships()

    def test_12_package_relationship_get(self):
        # create relationship
        res = self.c.package_relationship_entity_post('annakarenina',
                                                      'child_of',
                                                      'warandpeace',
                                                      'some comment')

        # read relationship
        try:
            res = self.c.package_relationship_register_get('annakarenina')
            assert self.c.last_status == 200, self.c.last_status
            rels = self.c.last_message
            assert len(rels) == 1, rels
            assert rels[0]['subject'] == 'annakarenina', rels[0]
            assert rels[0]['object'] == 'warandpeace', rels[0]
            assert rels[0]['type'] == 'child_of', rels[0]
            assert rels[0]['comment'] == 'some comment', rels[0]
        finally:
            self.delete_relationships()

    def test_13_package_relationship_put(self):
        # create relationship
        res = self.c.package_relationship_entity_post('annakarenina',
                                                      'child_of',
                                                      'warandpeace',
                                                      'some comment')
        # update relationship
        try:
            res = self.c.package_relationship_entity_put(
                'annakarenina', 'child_of', 'warandpeace', 'new comment')
            assert self.c.last_status == 200, self.c.last_status

            # read relationship
            res = self.c.package_relationship_register_get('annakarenina')
            assert self.c.last_status == 200, self.c.last_status
            rels = self.c.last_message
            assert len(rels) == 1, rels
            assert rels[0]['comment'] == 'new comment', rels[0]
        finally:
            self.delete_relationships()

    def test_14_package_relationship_delete(self):
        # create relationship
        res = self.c.package_relationship_entity_post('annakarenina',
                                                      'child_of',
                                                      'warandpeace',
                                                      'some comment')
        try:
            self.c.package_relationship_entity_delete('annakarenina',
                                                      'child_of',
                                                      'warandpeace')

            # read relationship gives 404
            assert_raises(CkanApiError,
                          self.c.package_relationship_register_get,
                          'annakarenina', 'child_of', 'warandpeace')
            assert self.c.last_status == 404, self.c.last_status

            # and register of relationships is blank
            res = self.c.package_relationship_register_get(
                'annakarenina', 'relationships', 'warandpeace')
            assert self.c.last_status == 200, self.c.last_status
            assert not res, res
        finally:
            self.delete_relationships()

    def test_15_package_edit_form_get(self):
        try:
            import ckanext.dgu
        except exceptions.ImportError, e:
            raise SkipTest(
                'Need dgu_form_api plugin (from ckanext-dgu) installed to test form api client.'
            )
        if 'dgu_form_api' not in config.get('ckan.plugins', ''):
            raise SkipTest(
                'Need dgu_form_api plugin (from ckanext-dgu) enabled to test form api client.'
            )

        res = self.c.package_edit_form_get('annakarenina')
        assert self.c.last_status == 200, self.c.last_status
        assert res, res
class TestCkanClient(CkanServerCase):

    @classmethod
    def setup_class(self):
        self.pid = self._start_ckan_server()
        self.test_base_location = 'http://127.0.0.1:5000/api'
        self._wait_for_url(url=self.test_base_location)
        self._recreate_ckan_server_testdata(config_path)
        # this is api key created for tester user by create-test-data in ckan
        test_api_key = 'tester'
        test_api_key2 = 'tester2'
        
        self.c = CkanClient(
            base_location=self.test_base_location,
            api_key=test_api_key,
            is_verbose=True,
        )
        self.c2 = CkanClient(
            base_location=self.test_base_location,
            api_key=test_api_key2,
            is_verbose=True,
        )

    @classmethod
    def teardown_class(self):
        self._stop_ckan_server(self.pid)

    def delete_relationships(self):
        res = self.c.package_relationship_register_get('annakarenina')
        if self.c.last_status == 200:
            if self.c.last_message:
                for rel_dict in self.c.last_message:
                    self.c.package_relationship_entity_delete( \
                        rel_dict['subject'],
                        rel_dict['type'],
                        rel_dict['object'])
        

    def test_01_get_locations(self):
        rest_base = self.test_base_location + '/rest'
        search_base = self.test_base_location + '/search'
        url = self.c.get_location('Base')
        assert url == self.test_base_location, url
        url = self.c.get_location('Package Register')
        assert url == rest_base + '/package'
        url = self.c.get_location('Package Entity', 'myname')
        assert url == rest_base + '/package/myname'
        url = self.c.get_location('Package Entity', 'myname',
                                  'relationships')
        assert url == rest_base + '/package/myname/relationships'
        url = self.c.get_location('Package Entity', 'myname',
                                  'relationships', 'name2')
        assert url == rest_base + '/package/myname/relationships/name2'
        url = self.c.get_location('Package Entity', 'myname',
                                  'child_of', 'name2')
        assert url == rest_base + '/package/myname/child_of/name2'
        url = self.c.get_location('Group Register')
        assert url == rest_base + '/group'
        url = self.c.get_location('Group Entity', 'myname')
        assert url == rest_base + '/group/myname'
        url = self.c.get_location('Tag Register')
        assert url == rest_base + '/tag'
        url = self.c.get_location('Tag Entity', 'myname')
        assert url == rest_base + '/tag/myname'
        url = self.c.get_location('Tag Entity', 'myname')
        assert url == rest_base + '/tag/myname'
        url = self.c.get_location('Package Search')
        assert url == search_base + '/package'

    def test_02_get_api_version(self):
        version = self.c.api_version_get()
        status = self.c.last_status
        assert status == 200
        body = self.c.last_body
        assert 'version' in body, body
        assert int(version) > 0, version

    def test_03_package_register_get(self):
        self.c.package_register_get()
        status = self.c.last_status
        assert status == 200
        body = self.c.last_body
        assert 'annakarenina' in body, body
        assert type(self.c.last_message) == list
        assert 'annakarenina' in self.c.last_message

    def test_04_package_entity_get(self):
        # Check registered entity is found.
        self.c.package_entity_get('annakarenina')
        status = self.c.last_status
        assert status == 200, status
        body = self.c.last_body
        assert 'annakarenina' in body
        assert self.c.last_message
        message = self.c.last_message
        assert type(message) == dict
        assert message['name'] == u'annakarenina'
        assert message['title'] == u'A Novel By Tolstoy'

    def test_05_package_entity_get_404(self):
        # Check unregistered entity is not found.
        assert_raises(CkanApiError,
                      self.c.package_entity_get,
                      'mycoffeecup')
        status = self.c.last_status
        assert status == 404, status

    @classmethod
    def _generate_pkg_name(self):
        pkg_name = 'ckanclienttest'
        import time
        timestr = str(time.time()).replace('.', '')
        pkg_name += timestr
        return pkg_name

    def test_06_package_register_post(self):
        pkg_name = self._generate_pkg_name()
        # Check package isn't registered.
        assert_raises(CkanApiError,
                      self.c.package_entity_get, pkg_name)
        status = self.c.last_status
        assert status == 404, status
        # Check registration of new package.
        package = {
            'name': pkg_name,
            'url': 'orig_url',
            'download_url': 'orig_download_url',
            'tags': ['russian', 'newtag'],
            'extras': {'genre':'thriller', 'format':'ebook'},
        }
        self.c.package_register_post(package)
        status = self.c.last_status
        assert status == 201, status

        # Check package is registered.
        self.c.package_entity_get(pkg_name)
        status = self.c.last_status
        assert status == 200, status
        message = self.c.last_message
        assert message
        assert 'name' in message, repr(message)
        name = message['name']
        assert name == pkg_name
        url = message['url']
        assert url == 'orig_url'
        download_url = message['download_url']
        assert download_url == 'orig_download_url'
        tags = message['tags']
        # order out is not guaranteed
        assert set(tags) == set(['newtag', 'russian']), tags
        extras = message['extras']
        assert extras == package['extras']
                    

    def test_07_package_entity_put(self):
        # Register new package.
        pkg_name_test_07 = self._generate_pkg_name()
        package = {
            'name': pkg_name_test_07,
            'url': 'orig_url',
            'download_url': 'orig_download_url',
            'tags': ['russian'],
        }
        self.c.package_register_post(package)
        status = self.c.last_status
        assert status == 201, status

        # Check update of existing package.
        mytag = 'mytag' + pkg_name_test_07
        package = {
            'name': pkg_name_test_07,
            'url': 'new_url',
            'download_url': 'new_download_url',
            'tags': ['russian', 'tolstoy', mytag],
            'extras': {'genre':'thriller', 'format':'ebook'},
        }
        self.c.package_entity_put(package)
        status = self.c.last_status
        assert status == 200

        # Check package is updated.
        self.c.package_entity_get(pkg_name_test_07)
        status = self.c.last_status
        assert status == 200, status
        message = self.c.last_message
        name = message['name']
        assert name == pkg_name_test_07
        url = message['url']
        assert url == 'new_url'
        download_url = message['download_url']
        assert download_url == 'new_download_url'
        tags = message['tags']
        # order out is not guaranteed
        assert set(tags) == set(['russian', 'tolstoy', mytag]), tags
        extras = message['extras']
        assert extras == package['extras']


    def test_08_package_entity_delete(self):
        # create a package to be deleted
        pkg_name = self._generate_pkg_name()
        self.c.package_register_post({'name': pkg_name})
        status = self.c.last_status
        assert status == 201, status        

        # check it is readable
        self.c.package_entity_get(pkg_name)
        assert self.c.last_status == 200, self.c.last_status

        # delete it
        self.c.package_entity_delete(pkg_name)

        # see it is not readable by another user
        assert_raises(CkanApiError,
                      self.c2.package_entity_get, pkg_name)
        assert self.c2.last_status == 403, self.c.last_status

        # see it is still readable by the author (therefore pkg admin)
        self.c.package_entity_get(pkg_name)
        assert self.c.last_status == 200, self.c.last_status

    def test_09_tag_register_get(self):
        self.c.tag_register_get()
        status = self.c.last_status
        assert status == 200
        body = self.c.last_body
        assert 'russian' in body
        assert type(self.c.last_message) == list
        assert 'russian' in self.c.last_message

    def test_10_pkg_search_basic(self):
        res = self.c.package_search('Novel')
        status = self.c.last_status
        assert status == 200, status
        assert_equal(list(res['results']), [u'annakarenina'])
        assert_equal(res['count'], 1)

    def test_10_pkg_search_paged(self):
        res = self.c.package_search('russian', search_options={'limit': 1})
        status = self.c.last_status
        assert status == 200, status
        all_results = list(res['results'])
        assert set(all_results) >= set([u'annakarenina', u'warandpeace']), all_results
        assert res['count'] >= 2, '%r %r' % (res, all_results)

    def test_10_pkg_search_options(self):
        res = self.c.package_search(None, search_options={'groups': 'roger'})
        status = self.c.last_status
        assert status == 200, status
        assert_equal(list(res['results']), [u'annakarenina'])
        assert_equal(res['count'], 1)

    def test_10_pkg_search_options_all_fields(self):
        res = self.c.package_search(None, search_options={'groups': 'roger',
                                                          'all_fields': True})
        status = self.c.last_status
        assert status == 200, status
        assert_equal(res['count'], 1)
        assert_equal(list(res['results'])[0]['name'], u'annakarenina')

    def test_11_package_relationship_post(self):
        res = self.c.package_relationship_register_get('annakarenina')
        assert self.c.last_status == 200, self.c.last_status
        assert not self.c.last_message, self.c.last_body

        # create relationship
        res = self.c.package_relationship_entity_post('annakarenina', 'child_of', 'warandpeace', 'some comment')
        try:
            assert self.c.last_status == 201, self.c.last_status
        finally:
            self.delete_relationships()
        
    def test_12_package_relationship_get(self):
        # create relationship
        res = self.c.package_relationship_entity_post('annakarenina', 'child_of', 'warandpeace', 'some comment')
        
        # read relationship
        try:
            res = self.c.package_relationship_register_get('annakarenina')
            assert self.c.last_status == 200, self.c.last_status
            rels = self.c.last_message
            assert len(rels) == 1, rels
            assert rels[0]['subject'] == 'annakarenina', rels[0]
            assert rels[0]['object'] == 'warandpeace', rels[0]
            assert rels[0]['type'] == 'child_of', rels[0]
            assert rels[0]['comment'] == 'some comment', rels[0]
        finally:
            self.delete_relationships()

    def test_13_package_relationship_put(self):
        # create relationship
        res = self.c.package_relationship_entity_post('annakarenina', 'child_of', 'warandpeace', 'some comment')
        # update relationship
        try:
            res = self.c.package_relationship_entity_put('annakarenina', 'child_of', 'warandpeace', 'new comment')
            assert self.c.last_status == 200, self.c.last_status

            # read relationship
            res = self.c.package_relationship_register_get('annakarenina')
            assert self.c.last_status == 200, self.c.last_status
            rels = self.c.last_message
            assert len(rels) == 1, rels
            assert rels[0]['comment'] == 'new comment', rels[0]
        finally:
            self.delete_relationships()

    def test_14_package_relationship_delete(self):
        # create relationship
        res = self.c.package_relationship_entity_post('annakarenina', 'child_of', 'warandpeace', 'some comment')
        try:
            self.c.package_relationship_entity_delete('annakarenina',
                                                      'child_of', 'warandpeace')

            # read relationship gives 404
            assert_raises(CkanApiError,
                          self.c.package_relationship_register_get,
                          'annakarenina', 'child_of', 'warandpeace')
            assert self.c.last_status == 404, self.c.last_status

            # and register of relationships is blank
            res = self.c.package_relationship_register_get('annakarenina', 'relationships', 'warandpeace')
            assert self.c.last_status == 200, self.c.last_status
            assert not res, res
        finally:
            self.delete_relationships()

    def test_15_package_edit_form_get(self):
        try:
            import ckanext.dgu
        except exceptions.ImportError, e:
            raise SkipTest('Need dgu_form_api plugin (from ckanext-dgu) installed to test form api client.')
        if 'dgu_form_api' not in config.get('ckan.plugins', ''):
            raise SkipTest('Need dgu_form_api plugin (from ckanext-dgu) enabled to test form api client.')
            
        res = self.c.package_edit_form_get('annakarenina')
        assert self.c.last_status == 200, self.c.last_status
        assert res, res
class TestCkanClient(CkanServerCase):
    @classmethod
    def setup_class(self):
        self.pid = self._start_ckan_server()
        self.test_base_location = "http://127.0.0.1:5000/api"
        self._wait_for_url(url=self.test_base_location)
        self._recreate_ckan_server_testdata(config_path)
        # this is api key created for tester user by create-test-data in ckan
        test_api_key = "tester"
        test_api_key2 = "tester2"

        self.c = CkanClient(base_location=self.test_base_location, api_key=test_api_key, is_verbose=True)
        self.c2 = CkanClient(base_location=self.test_base_location, api_key=test_api_key2, is_verbose=True)

    @classmethod
    def teardown_class(self):
        self._stop_ckan_server(self.pid)

    def delete_relationships(self):
        res = self.c.package_relationship_register_get("annakarenina")
        if self.c.last_status == 200:
            if self.c.last_message:
                for rel_dict in self.c.last_message:
                    self.c.package_relationship_entity_delete(rel_dict["subject"], rel_dict["type"], rel_dict["object"])

    def test_01_get_locations(self):
        rest_base = self.test_base_location + "/rest"
        search_base = self.test_base_location + "/search"
        url = self.c.get_location("Base")
        assert url == self.test_base_location, url
        url = self.c.get_location("Package Register")
        assert url == rest_base + "/package"
        url = self.c.get_location("Package Entity", "myname")
        assert url == rest_base + "/package/myname"
        url = self.c.get_location("Package Entity", "myname", "relationships")
        assert url == rest_base + "/package/myname/relationships"
        url = self.c.get_location("Package Entity", "myname", "relationships", "name2")
        assert url == rest_base + "/package/myname/relationships/name2"
        url = self.c.get_location("Package Entity", "myname", "child_of", "name2")
        assert url == rest_base + "/package/myname/child_of/name2"
        url = self.c.get_location("Group Register")
        assert url == rest_base + "/group"
        url = self.c.get_location("Group Entity", "myname")
        assert url == rest_base + "/group/myname"
        url = self.c.get_location("Tag Register")
        assert url == rest_base + "/tag"
        url = self.c.get_location("Tag Entity", "myname")
        assert url == rest_base + "/tag/myname"
        url = self.c.get_location("Tag Entity", "myname")
        assert url == rest_base + "/tag/myname"
        url = self.c.get_location("Package Search")
        assert url == search_base + "/package"

    def test_02_get_api_version(self):
        version = self.c.api_version_get()
        status = self.c.last_status
        assert status == 200
        body = self.c.last_body
        assert "version" in body, body
        assert int(version) > 0, version

    def test_03_package_register_get(self):
        self.c.package_register_get()
        status = self.c.last_status
        assert status == 200
        body = self.c.last_body
        assert "annakarenina" in body, body
        assert type(self.c.last_message) == list
        assert "annakarenina" in self.c.last_message

    def test_04_package_entity_get(self):
        # Check registered entity is found.
        self.c.package_entity_get("annakarenina")
        status = self.c.last_status
        assert status == 200, status
        body = self.c.last_body
        assert "annakarenina" in body
        assert self.c.last_message
        message = self.c.last_message
        assert type(message) == dict
        assert message["name"] == u"annakarenina"
        assert message["title"] == u"A Novel By Tolstoy"

    def test_05_package_entity_get_404(self):
        # Check unregistered entity is not found.
        assert_raises(CkanApiError, self.c.package_entity_get, "mycoffeecup")
        status = self.c.last_status
        assert status == 404, status

    @classmethod
    def _generate_pkg_name(self):
        pkg_name = "ckanclienttest"
        import time

        timestr = str(time.time()).replace(".", "")
        pkg_name += timestr
        return pkg_name

    def test_06_package_register_post(self):
        pkg_name = self._generate_pkg_name()
        # Check package isn't registered.
        assert_raises(CkanApiError, self.c.package_entity_get, pkg_name)
        status = self.c.last_status
        assert status == 404, status
        # Check registration of new package.
        package = {
            "name": pkg_name,
            "url": "orig_url",
            "download_url": "orig_download_url",
            "tags": ["russian", "newtag"],
            "extras": {"genre": "thriller", "format": "ebook"},
        }
        self.c.package_register_post(package)
        status = self.c.last_status
        assert status == 201, status

        # Check package is registered.
        self.c.package_entity_get(pkg_name)
        status = self.c.last_status
        assert status == 200, status
        message = self.c.last_message
        assert message
        assert "name" in message, repr(message)
        name = message["name"]
        assert name == pkg_name
        url = message["url"]
        assert url == "orig_url"
        download_url = message["download_url"]
        assert download_url == "orig_download_url"
        tags = message["tags"]
        # order out is not guaranteed
        assert set(tags) == set(["newtag", "russian"]), tags
        extras = message["extras"]
        assert extras == package["extras"]

    def test_07_package_entity_put(self):
        # Register new package.
        pkg_name_test_07 = self._generate_pkg_name()
        package = {
            "name": pkg_name_test_07,
            "url": "orig_url",
            "download_url": "orig_download_url",
            "tags": ["russian"],
        }
        self.c.package_register_post(package)
        status = self.c.last_status
        assert status == 201, status

        # Check update of existing package.
        mytag = "mytag" + pkg_name_test_07
        package = {
            "name": pkg_name_test_07,
            "url": "new_url",
            "download_url": "new_download_url",
            "tags": ["russian", "tolstoy", mytag],
            "extras": {"genre": "thriller", "format": "ebook"},
        }
        self.c.package_entity_put(package)
        status = self.c.last_status
        assert status == 200

        # Check package is updated.
        self.c.package_entity_get(pkg_name_test_07)
        status = self.c.last_status
        assert status == 200, status
        message = self.c.last_message
        name = message["name"]
        assert name == pkg_name_test_07
        url = message["url"]
        assert url == "new_url"
        download_url = message["download_url"]
        assert download_url == "new_download_url"
        tags = message["tags"]
        # order out is not guaranteed
        assert set(tags) == set(["russian", "tolstoy", mytag]), tags
        extras = message["extras"]
        assert extras == package["extras"]

    def test_08_package_entity_delete(self):
        # create a package to be deleted
        pkg_name = self._generate_pkg_name()
        self.c.package_register_post({"name": pkg_name})
        status = self.c.last_status
        assert status == 201, status

        # check it is readable
        self.c.package_entity_get(pkg_name)
        assert self.c.last_status == 200, self.c.last_status

        # delete it
        self.c.package_entity_delete(pkg_name)

        # see it is not readable by another user
        assert_raises(CkanApiError, self.c2.package_entity_get, pkg_name)
        assert self.c2.last_status == 403, self.c.last_status

        # see it is still readable by the author (therefore pkg admin)
        self.c.package_entity_get(pkg_name)
        assert self.c.last_status == 200, self.c.last_status

    def test_09_tag_register_get(self):
        self.c.tag_register_get()
        status = self.c.last_status
        assert status == 200
        body = self.c.last_body
        assert "russian" in body
        assert type(self.c.last_message) == list
        assert "russian" in self.c.last_message

    def test_10_pkg_search_basic(self):
        res = self.c.package_search("Novel")
        status = self.c.last_status
        assert status == 200, status
        assert_equal(list(res["results"]), [u"annakarenina"])
        assert_equal(res["count"], 1)

    def test_10_pkg_search_paged(self):
        res = self.c.package_search("russian", search_options={"limit": 1})
        status = self.c.last_status
        assert status == 200, status
        all_results = list(res["results"])
        assert set(all_results) >= set([u"annakarenina", u"warandpeace"]), all_results
        assert res["count"] >= 2, "%r %r" % (res, all_results)

    def test_10_pkg_search_options(self):
        res = self.c.package_search(None, search_options={"groups": "roger"})
        status = self.c.last_status
        assert status == 200, status
        assert_equal(list(res["results"]), [u"annakarenina"])
        assert_equal(res["count"], 1)

    def test_10_pkg_search_options_all_fields(self):
        res = self.c.package_search(None, search_options={"groups": "roger", "all_fields": True})
        status = self.c.last_status
        assert status == 200, status
        assert_equal(res["count"], 1)
        assert_equal(list(res["results"])[0]["name"], u"annakarenina")

    def test_11_package_relationship_post(self):
        res = self.c.package_relationship_register_get("annakarenina")
        assert self.c.last_status == 200, self.c.last_status
        assert not self.c.last_message, self.c.last_body

        # create relationship
        res = self.c.package_relationship_entity_post("annakarenina", "child_of", "warandpeace", "some comment")
        try:
            assert self.c.last_status == 201, self.c.last_status
        finally:
            self.delete_relationships()

    def test_12_package_relationship_get(self):
        # create relationship
        res = self.c.package_relationship_entity_post("annakarenina", "child_of", "warandpeace", "some comment")

        # read relationship
        try:
            res = self.c.package_relationship_register_get("annakarenina")
            assert self.c.last_status == 200, self.c.last_status
            rels = self.c.last_message
            assert len(rels) == 1, rels
            assert rels[0]["subject"] == "annakarenina", rels[0]
            assert rels[0]["object"] == "warandpeace", rels[0]
            assert rels[0]["type"] == "child_of", rels[0]
            assert rels[0]["comment"] == "some comment", rels[0]
        finally:
            self.delete_relationships()

    def test_13_package_relationship_put(self):
        # create relationship
        res = self.c.package_relationship_entity_post("annakarenina", "child_of", "warandpeace", "some comment")
        # update relationship
        try:
            res = self.c.package_relationship_entity_put("annakarenina", "child_of", "warandpeace", "new comment")
            assert self.c.last_status == 200, self.c.last_status

            # read relationship
            res = self.c.package_relationship_register_get("annakarenina")
            assert self.c.last_status == 200, self.c.last_status
            rels = self.c.last_message
            assert len(rels) == 1, rels
            assert rels[0]["comment"] == "new comment", rels[0]
        finally:
            self.delete_relationships()

    def test_14_package_relationship_delete(self):
        # create relationship
        res = self.c.package_relationship_entity_post("annakarenina", "child_of", "warandpeace", "some comment")
        try:
            self.c.package_relationship_entity_delete("annakarenina", "child_of", "warandpeace")

            # read relationship gives 404
            assert_raises(
                CkanApiError, self.c.package_relationship_register_get, "annakarenina", "child_of", "warandpeace"
            )
            assert self.c.last_status == 404, self.c.last_status

            # and register of relationships is blank
            res = self.c.package_relationship_register_get("annakarenina", "relationships", "warandpeace")
            assert self.c.last_status == 200, self.c.last_status
            assert not res, res
        finally:
            self.delete_relationships()

    def test_15_package_edit_form_get(self):
        try:
            import ckanext.dgu
        except exceptions.ImportError, e:
            raise SkipTest("Need dgu_form_api plugin (from ckanext-dgu) installed to test form api client.")
        if "dgu_form_api" not in config.get("ckan.plugins", ""):
            raise SkipTest("Need dgu_form_api plugin (from ckanext-dgu) enabled to test form api client.")

        res = self.c.package_edit_form_get("annakarenina")
        assert self.c.last_status == 200, self.c.last_status
        assert res, res