From 196881ea25dc160fb18c97d11fdea3817f50aa0b Mon Sep 17 00:00:00 2001 From: mutantsan Date: Tue, 29 Apr 2025 10:16:34 +0300 Subject: [PATCH 1/3] remove unused imports and variables --- ckanapi/cli/action.py | 6 ++--- ckanapi/cli/delete.py | 8 +----- ckanapi/cli/dump.py | 6 ++--- ckanapi/cli/search.py | 2 +- ckanapi/remoteckan.py | 6 ++--- ckanapi/tests/mock/mock_ckan.py | 2 -- ckanapi/tests/test_cli_dump.py | 42 ++++++++++++++++++++----------- ckanapi/tests/test_datapackage.py | 2 +- ckanapi/tests/test_remote.py | 5 +--- setup.py | 2 -- 10 files changed, 38 insertions(+), 43 deletions(-) diff --git a/ckanapi/cli/action.py b/ckanapi/cli/action.py index ceb5eaa..fd9c87b 100644 --- a/ckanapi/cli/action.py +++ b/ckanapi/cli/action.py @@ -33,9 +33,9 @@ def action(ckan, arguments, stdin=None): for kv in arguments['KEY=STRING']: if hasattr(kv, 'decode'): kv = kv.decode('utf-8') - skey, p, svalue = kv.partition('=') - jkey, p, jvalue = kv.partition(':') - fkey, p, fvalue = kv.partition('@') + skey, _, svalue = kv.partition('=') + jkey, _, jvalue = kv.partition(':') + fkey, _, fvalue = kv.partition('@') if len(jkey) > len(skey) < len(fkey): action_args[skey] = svalue elif len(skey) > len(jkey) < len(fkey): diff --git a/ckanapi/cli/delete.py b/ckanapi/cli/delete.py index f98f7f6..8e9bb28 100644 --- a/ckanapi/cli/delete.py +++ b/ckanapi/cli/delete.py @@ -7,14 +7,8 @@ import json from datetime import datetime from itertools import chain -import re -try: - from urllib.parse import urlparse -except ImportError: - from urlparse import urlparse -from ckanapi.errors import (NotFound, NotAuthorized, ValidationError, - SearchIndexError) +from ckanapi.errors import NotFound, NotAuthorized from ckanapi.cli import workers from ckanapi.cli.utils import completion_stats, compact_json, quiet_int_pipe diff --git a/ckanapi/cli/dump.py b/ckanapi/cli/dump.py index b2d2d2b..24a883a 100644 --- a/ckanapi/cli/dump.py +++ b/ckanapi/cli/dump.py @@ -8,8 +8,7 @@ from datetime import datetime import os -from ckanapi.errors import (CKANAPIError, NotFound, NotAuthorized, ValidationError, - SearchIndexError) +from ckanapi.errors import CKANAPIError, NotFound, NotAuthorized from ckanapi.cli import workers from ckanapi.cli.utils import completion_stats, compact_json, \ quiet_int_pipe @@ -167,7 +166,7 @@ def reply(error, record=None): for line in iter(stdin.readline, b''): try: name = json.loads(line.decode('utf-8')) - except UnicodeDecodeError as e: + except UnicodeDecodeError: reply('UnicodeDecodeError') continue @@ -238,4 +237,3 @@ def populate_res_views(ckan, res): if not views: return # return if the resource views list is empty res['resource_views'] = views - diff --git a/ckanapi/cli/search.py b/ckanapi/cli/search.py index a6c2549..b7b9855 100644 --- a/ckanapi/cli/search.py +++ b/ckanapi/cli/search.py @@ -7,7 +7,7 @@ import json from os.path import expanduser -from ckanapi.cli.utils import compact_json, pretty_json +from ckanapi.cli.utils import compact_json from ckanapi.errors import CLIError diff --git a/ckanapi/remoteckan.py b/ckanapi/remoteckan.py index 7db7eda..37d432c 100644 --- a/ckanapi/remoteckan.py +++ b/ckanapi/remoteckan.py @@ -1,10 +1,10 @@ try: - from urllib2 import Request, urlopen, HTTPError from urlparse import urlparse except ImportError: - from urllib.request import Request, urlopen, HTTPError from urllib.parse import urlparse +import requests + from ckanapi.errors import CKANAPIError from ckanapi.common import (ActionShortcut, prepare_action, reverse_apicontroller_action) @@ -21,8 +21,6 @@ # add your site above instead of changing this PARALLEL_LIMIT = os.getenv('CKANAPI_PARALLEL_LIMIT', default = 3) -import requests - class RemoteCKAN(object): """ diff --git a/ckanapi/tests/mock/mock_ckan.py b/ckanapi/tests/mock/mock_ckan.py index 2f717b3..4e8ae3f 100644 --- a/ckanapi/tests/mock/mock_ckan.py +++ b/ckanapi/tests/mock/mock_ckan.py @@ -1,7 +1,6 @@ import json import cgi import csv -from wsgiref.util import setup_testing_defaults from wsgiref.simple_server import make_server try: from cStringIO import StringIO @@ -73,4 +72,3 @@ def mock_ckan(environ, start_response): httpd = make_server('localhost', 8901, mock_ckan) httpd.serve_forever() - diff --git a/ckanapi/tests/test_cli_dump.py b/ckanapi/tests/test_cli_dump.py index c3ab6a4..7db2db7 100644 --- a/ckanapi/tests/test_cli_dump.py +++ b/ckanapi/tests/test_cli_dump.py @@ -71,11 +71,17 @@ def setUp(self): self.stderr = BytesIO() def test_worker_one(self): - rval = dump_things_worker(self.ckan, 'datasets', - {'--datastore-fields': False, - '--resource-views': False, - '--insecure': False}, - stdin=BytesIO(b'"34"\n'), stdout=self.stdout) + dump_things_worker( + self.ckan, + "datasets", + { + "--datastore-fields": False, + "--resource-views": False, + "--insecure": False, + }, + stdin=BytesIO(b'"34"\n'), + stdout=self.stdout, + ) response = self.stdout.getvalue() self.assertEqual(response[-1:], b'\n') timstamp, error, data = json.loads(response.decode('UTF-8')) @@ -83,19 +89,25 @@ def test_worker_one(self): self.assertEqual(data["title"], "Thirty-four") def test_worker_two(self): - rval = dump_things_worker(self.ckan, 'datasets', - {'--datastore-fields': False, - '--resource-views': False, - '--insecure': False}, - stdin=BytesIO(b'"12"\n"34"\n'), stdout=self.stdout) + dump_things_worker( + self.ckan, + "datasets", + { + "--datastore-fields": False, + "--resource-views": False, + "--insecure": False, + }, + stdin=BytesIO(b'"12"\n"34"\n'), + stdout=self.stdout, + ) response = self.stdout.getvalue() self.assertEqual(response.count(b'\n'), 2, response) self.assertEqual(response[-1:], b'\n') r1, r2 = response.split(b'\n', 1) - timstamp, error, data = json.loads(r1.decode('UTF-8')) + _, error, data = json.loads(r1.decode('UTF-8')) self.assertEqual(error, None) self.assertEqual(data["title"], "Twelve") - timstamp, error, data = json.loads(r2.decode('UTF-8')) + _, error, data = json.loads(r2.decode('UTF-8')) self.assertEqual(error, None) self.assertEqual(data["title"], "Thirty-four") @@ -105,7 +117,7 @@ def test_worker_error(self): stdin=BytesIO(b'"99"\n'), stdout=self.stdout) response = self.stdout.getvalue() self.assertEqual(response[-1:], b'\n') - timstamp, error, data = json.loads(response.decode('UTF-8')) + _, error, data = json.loads(response.decode('UTF-8')) self.assertEqual(error, "NotFound") self.assertEqual(data, None) @@ -115,7 +127,7 @@ def test_worker_group(self): stdin=BytesIO(b'"ab"\n'), stdout=self.stdout) response = self.stdout.getvalue() self.assertEqual(response[-1:], b'\n') - timstamp, error, data = json.loads(response.decode('UTF-8')) + _, error, data = json.loads(response.decode('UTF-8')) self.assertEqual(error, None) self.assertEqual(data, {"title":"ABBA"}) @@ -125,7 +137,7 @@ def test_worker_organization(self): stdin=BytesIO(b'"cd"\n'), stdout=self.stdout) response = self.stdout.getvalue() self.assertEqual(response[-1:], b'\n') - timstamp, error, data = json.loads(response.decode('UTF-8')) + _, error, data = json.loads(response.decode('UTF-8')) self.assertEqual(error, None) self.assertEqual(data, {"title":"Super Trouper"}) diff --git a/ckanapi/tests/test_datapackage.py b/ckanapi/tests/test_datapackage.py index 28ac98e..86265d5 100644 --- a/ckanapi/tests/test_datapackage.py +++ b/ckanapi/tests/test_datapackage.py @@ -182,7 +182,7 @@ def test_simple(self): u'name': u'Image', u'url': u'http://example.com/image.png', } - filename = 'image_saved.png' + os.makedirs('/test/data') stderr = BytesIO() # TODO mock the HTTP request to example.com diff --git a/ckanapi/tests/test_remote.py b/ckanapi/tests/test_remote.py index 76186b9..27ec6e2 100644 --- a/ckanapi/tests/test_remote.py +++ b/ckanapi/tests/test_remote.py @@ -2,8 +2,6 @@ import time import os import atexit -import socket -import requests from ckanapi import RemoteCKAN, NotFound try: @@ -49,7 +47,7 @@ def kill_child(): r = urlopen(TEST_CKAN + '/api/action/site_read') if r.getcode() == 200: break - except URLError as e: + except URLError: pass time.sleep(0.1) @@ -121,4 +119,3 @@ def test_resource_upload_content_type(self): def tearDownClass(cls): cls._mock_ckan.kill() cls._mock_ckan.wait() - diff --git a/setup.py b/setup.py index 856e689..1ae5b80 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,6 @@ #!/usr/bin/env python from setuptools import setup -import sys install_requires=[ @@ -52,4 +51,3 @@ api=ckanapi.cli.ckan_click:api """ ) - From 62ed3dc148a03b1c5e5ef75a9cf326015fb3daf7 Mon Sep 17 00:00:00 2001 From: mutantsan Date: Tue, 29 Apr 2025 11:57:56 +0300 Subject: [PATCH 2/3] add api header name option for cli and remote client --- ckanapi/cli/dump.py | 9 ++++++- ckanapi/cli/main.py | 19 ++++++++------ ckanapi/common.py | 8 +++--- ckanapi/const.py | 1 + ckanapi/datapackage.py | 14 ++++++----- ckanapi/remoteckan.py | 41 +++++++++++++++++++++++++------ ckanapi/testappckan.py | 15 +++++++---- ckanapi/tests/test_cli_dump.py | 10 +++++--- ckanapi/tests/test_datapackage.py | 17 +++++++------ 9 files changed, 91 insertions(+), 43 deletions(-) create mode 100644 ckanapi/const.py diff --git a/ckanapi/cli/dump.py b/ckanapi/cli/dump.py index 24a883a..56fb34d 100644 --- a/ckanapi/cli/dump.py +++ b/ckanapi/cli/dump.py @@ -14,6 +14,7 @@ quiet_int_pipe from ckanapi.datapackage import create_datapackage, \ populate_datastore_res_fields +from ckanapi.const import API_KEY_HEADER_NAME def dump_things(ckan, thing, arguments, @@ -106,7 +107,13 @@ def dump_things(ckan, thing, arguments, datapackages_path = arguments['--datapackages'] apikey = arguments['--apikey'] if datapackages_path: - create_datapackage(record, datapackages_path, stderr, apikey) + create_datapackage( + record, + datapackages_path, + stderr, + apikey, + ckan.apikey_header_name or API_KEY_HEADER_NAME, + ) # keep the output in the same order as names while expecting_number in results: diff --git a/ckanapi/cli/main.py b/ckanapi/cli/main.py index 04ce7f5..5c1394e 100644 --- a/ckanapi/cli/main.py +++ b/ckanapi/cli/main.py @@ -4,34 +4,34 @@ ckanapi action ACTION_NAME [(KEY=STRING | KEY:JSON | KEY@FILE ) ... | -i | -I JSON_INPUT] [-j | -J] [-P PROFILE ] - [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-g] [--insecure]] + [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-A APIKEY_HEADER_NAME] [-g] [--insecure]] ckanapi batch [-I JSONL_INPUT] [-s START] [-m MAX] [--local-files] [-p PROCESSES] [-l LOG_FILE] [-qwz] - [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [--insecure]] + [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-A APIKEY_HEADER_NAME] [-g] [--insecure]] ckanapi delete (datasets | groups | organizations | users | related) (ID_OR_NAME ... | [-I JSONL_INPUT] [-s START] [-m MAX]) [-p PROCESSES] [-l LOG_FILE] [-qwz] - [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [--insecure]] + [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-A APIKEY_HEADER_NAME] [-g] [--insecure]] ckanapi dump (datasets | groups | organizations | users | related) (ID_OR_NAME ... | --all) ([-O JSONL_OUTPUT] | [-D DIRECTORY]) [-p PROCESSES] [-dqwzRU] - [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-g] [--insecure]] + [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-A APIKEY_HEADER_NAME] [-g] [--insecure]] ckanapi load datasets [--upload-resources] [-I JSONL_INPUT] [-s START] [-m MAX] [-p PROCESSES] [-l LOG_FILE] [-n | -o] [-qwz] - [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [--insecure]] + [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-A APIKEY_HEADER_NAME] [-g] [--insecure]] ckanapi load (groups | organizations) [--upload-logo] [-I JSONL_INPUT] [-s START] [-m MAX] [-p PROCESSES] [-l LOG_FILE] [-n | -o] [-qwzU] - [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [--insecure]] + [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-A APIKEY_HEADER_NAME] [-g] [--insecure]] ckanapi load (users | related) [-I JSONL_INPUT] [-s START] [-m MAX] [-p PROCESSES] [-l LOG_FILE] [-n | -o] [-qwz] - [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [--insecure]] + [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-A APIKEY_HEADER_NAME] [-g] [--insecure]] ckanapi search datasets [(KEY=STRING | KEY:JSON ) ... | -i | -I JSON_INPUT] [-O JSONL_OUTPUT] [-z] - [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-g] [--insecure]] + [[-c CONFIG] [-u USER] | -r SITE_URL [-a APIKEY] [-A APIKEY_HEADER_NAME] [-g] [--insecure]] ckanapi (-h | --help) ckanapi --version @@ -39,6 +39,8 @@ -h --help show this screen --version show version -a --apikey=APIKEY API key to use for remote actions + -A --apikey-header-name=APIKEY_HEADER_NAME + API key header name to use for remote actions --all all the things -c --config=CONFIG CKAN configuration file for local actions, defaults to $CKAN_INI or development.ini @@ -129,6 +131,7 @@ def main(running_with_paster=False): if arguments['--remote']: ckan = RemoteCKAN(arguments['--remote'], apikey=arguments['--apikey'], + apikey_header_name=arguments['--apikey-header-name'], user_agent="ckanapi-cli/{version} (+{url})".format( version=__version__, url='https://github.com/open-data/ckanapi'), diff --git a/ckanapi/common.py b/ckanapi/common.py index 87d2bd7..49c5921 100644 --- a/ckanapi/common.py +++ b/ckanapi/common.py @@ -62,7 +62,7 @@ def is_file_like(v): isinstance(v, tuple) and len(v) >= 2 and hasattr(v[1], 'read')) -def prepare_action(action, data_dict=None, apikey=None, files=None, +def prepare_action(action, data_dict=None, apikey=None, apikey_header_name=None, files=None, base_url='api/action/'): """ Return action_url, data_json, http_headers @@ -84,10 +84,8 @@ def prepare_action(action, data_dict=None, apikey=None, files=None, else: data_dict = json.dumps(data_dict).encode('ascii') headers['Content-Type'] = 'application/json' - if apikey: - apikey = str(apikey) - headers['X-CKAN-API-Key'] = apikey - headers['Authorization'] = apikey + if apikey and apikey_header_name: + headers[apikey_header_name] = apikey url = base_url + action return url, data_dict, headers diff --git a/ckanapi/const.py b/ckanapi/const.py new file mode 100644 index 0000000..56ec10b --- /dev/null +++ b/ckanapi/const.py @@ -0,0 +1 @@ +API_KEY_HEADER_NAME = "Authorization" diff --git a/ckanapi/datapackage.py b/ckanapi/datapackage.py index 22f1de1..d071113 100644 --- a/ckanapi/datapackage.py +++ b/ckanapi/datapackage.py @@ -16,13 +16,12 @@ } -def create_resource(resource, filename, datapackage_dir, stderr, apikey): +def create_resource(resource, filename, datapackage_dir, stderr, apikey, apikey_header_name): '''Downloads the resource['url'] to disk. ''' path = os.path.join('data', filename) headers = {} - headers['X-CKAN-API-Key'] = apikey - headers['Authorization'] = apikey + headers[apikey_header_name] = apikey try: r = requests.get(resource['url'], headers=headers, stream=True) @@ -34,6 +33,8 @@ def create_resource(resource, filename, datapackage_dir, stderr, apikey): except requests.ConnectionError: stderr.write('URL {url} refused connection. The resource will not be downloaded\n'.format(url=resource['url'])) except requests.exceptions.RequestException as e: + print(e.args) + stderr.write(str(e.args[0]) if len(e.args) > 0 else '') stderr.write('\n') except Exception as e: @@ -41,7 +42,7 @@ def create_resource(resource, filename, datapackage_dir, stderr, apikey): return resource -def create_datapackage(record, base_path, stderr, apikey): +def create_datapackage(record, base_path, stderr, apikey, apikey_header_name): # TODO: how are we going to handle which resources to # leave alone? They're very inconsistent in some instances # And I can't imagine anyone wants to download a copy @@ -67,8 +68,9 @@ def create_datapackage(record, base_path, stderr, apikey): filename = resource_filename(dres) # download the resource - cres = \ - create_resource(resource, filename, datapackage_dir, stderr, apikey) + cres = create_resource( + resource, filename, datapackage_dir, stderr, apikey, apikey_header_name + ) dres['path'] = 'data/' + filename populate_schema_from_datastore(cres, dres) diff --git a/ckanapi/remoteckan.py b/ckanapi/remoteckan.py index 37d432c..6f0e3d7 100644 --- a/ckanapi/remoteckan.py +++ b/ckanapi/remoteckan.py @@ -3,13 +3,16 @@ except ImportError: from urllib.parse import urlparse +import os + import requests from ckanapi.errors import CKANAPIError from ckanapi.common import (ActionShortcut, prepare_action, reverse_apicontroller_action) from ckanapi.version import __version__ -import os +from ckanapi.const import API_KEY_HEADER_NAME + # add your sites to remove parallel limits on ckanapi cli MY_SITES = ['localhost', '127.0.0.1', '[::1]'] @@ -28,8 +31,8 @@ class RemoteCKAN(object): :param address: the web address of the CKAN instance, e.g. 'http://demo.ckan.org', stored as self.address - :param apikey: the API key to pass as an 'X-CKAN-API-Key' header - when actions are called, stored as self.apikey + :param apikey: the API key to pass as an authorization header + :param apikey_header_name: the header name to use for the API key :param user_agent: the User-agent to report when making requests :param get_only: only use GET requests (default: False) :param session: session to use (default: None) @@ -37,9 +40,18 @@ class RemoteCKAN(object): base_url = 'api/action/' - def __init__(self, address, apikey=None, user_agent=None, get_only=False, session=None): + def __init__( + self, + address, + apikey=None, + apikey_header_name=API_KEY_HEADER_NAME, + user_agent=None, + get_only=False, + session=None, + ): self.address = address self.apikey = apikey + self.apikey_header_name = apikey_header_name self.get_only = get_only self.session = session if not user_agent: @@ -58,8 +70,16 @@ def __init__(self, address, apikey=None, user_agent=None, get_only=False, sessio # add your sites to MY_SITES above instead of removing this self.parallel_limit = PARALLEL_LIMIT - def call_action(self, action, data_dict=None, context=None, apikey=None, - files=None, requests_kwargs=None): + def call_action( + self, + action, + data_dict=None, + context=None, + apikey=None, + apikey_header_name=None, + files=None, + requests_kwargs=None, + ): """ :param action: the action name, e.g. 'package_create' :param data_dict: the dict to pass to the action as JSON, @@ -81,8 +101,13 @@ def call_action(self, action, data_dict=None, context=None, apikey=None, raise CKANAPIError("RemoteCKAN: files may not be sent when " "get_only is True") url, data, headers = prepare_action( - action, data_dict, apikey or self.apikey, files, - base_url=self.base_url) + action, + data_dict, + apikey or self.apikey, + apikey_header_name or self.apikey_header_name, + files, + base_url=self.base_url, + ) headers['User-Agent'] = self.user_agent url = self.address.rstrip('/') + '/' + url requests_kwargs = requests_kwargs or {} diff --git a/ckanapi/testappckan.py b/ckanapi/testappckan.py index 84c4fd5..2d8dc8f 100644 --- a/ckanapi/testappckan.py +++ b/ckanapi/testappckan.py @@ -3,6 +3,8 @@ from ckanapi.errors import CKANAPIError from ckanapi.common import (ActionShortcut, prepare_action, reverse_apicontroller_action) +from ckanapi.const import API_KEY_HEADER_NAME + class TestAppCKAN(object): """ @@ -10,12 +12,13 @@ class TestAppCKAN(object): :param test_app: the paste.fixture.TestApp instance, stored as self.test_app - :param apikey: the API key to pass as an 'X-CKAN-API-Key' header - when actions are called, stored as self.apikey + :param apikey: the API key to pass as an authorization header + :param apikey_header_name: the header name to use for the API key """ - def __init__(self, test_app, apikey=None): + def __init__(self, test_app, apikey=None, apikey_header_name=API_KEY_HEADER_NAME): self.test_app = test_app self.apikey = apikey + self.apikey_header_name = apikey_header_name self.action = ActionShortcut(self) def call_action(self, action, data_dict=None, context=None, apikey=None, @@ -35,8 +38,10 @@ def call_action(self, action, data_dict=None, context=None, apikey=None, if context: raise CKANAPIError("TestAppCKAN.call_action does not support " "use of context parameter, use apikey instead") - url, data, headers = prepare_action(action, data_dict, - apikey or self.apikey, files) + + url, data, headers = prepare_action( + action, data_dict, apikey or self.apikey, self.apikey_header_name, files + ) kwargs = {} if files: diff --git a/ckanapi/tests/test_cli_dump.py b/ckanapi/tests/test_cli_dump.py index 7db2db7..0e660a3 100644 --- a/ckanapi/tests/test_cli_dump.py +++ b/ckanapi/tests/test_cli_dump.py @@ -1,18 +1,22 @@ -from ckanapi.cli.dump import dump_things, dump_things_worker -from ckanapi.errors import NotFound import json import tempfile import shutil from os.path import exists +from io import BytesIO try: import unittest2 as unittest except ImportError: import unittest -from io import BytesIO + +from ckanapi.cli.dump import dump_things, dump_things_worker +from ckanapi.errors import NotFound +from ckanapi.const import API_KEY_HEADER_NAME class MockCKAN(object): + apikey_header_name = API_KEY_HEADER_NAME + def call_action(self, name, data_dict, requests_kwargs=None): try: return { diff --git a/ckanapi/tests/test_datapackage.py b/ckanapi/tests/test_datapackage.py index 86265d5..a266a84 100644 --- a/ckanapi/tests/test_datapackage.py +++ b/ckanapi/tests/test_datapackage.py @@ -1,15 +1,17 @@ -from ckanapi.datapackage import ( - dataset_to_datapackage, create_resource, create_datapackage, - resource_filename, populate_schema_from_datastore) - try: import unittest2 as unittest except ImportError: import unittest -from io import BytesIO + import os +from io import BytesIO + from pyfakefs import fake_filesystem_unittest +from ckanapi.datapackage import ( + dataset_to_datapackage, create_resource, create_datapackage, + resource_filename, populate_schema_from_datastore) +from ckanapi.const import API_KEY_HEADER_NAME class TestDatasetToDataPackage(unittest.TestCase): def test_simple_dataset(self): @@ -190,7 +192,7 @@ def test_simple(self): returned_resource = create_resource( resource, filename='image_saved.png', datapackage_dir='/test', stderr=stderr, - apikey='') + apikey='', apikey_header_name=API_KEY_HEADER_NAME) stderr.seek(0) assert not stderr.read() @@ -230,7 +232,8 @@ def test_simple(self): datapackage_dir, datapackage, json_path = \ create_datapackage(record=dataset, base_path='/test/', - stderr=stderr, apikey='') + stderr=stderr, apikey='', + apikey_header_name=API_KEY_HEADER_NAME) stderr.seek(0) assert not stderr.read() From 12eec3980e3ae36e713ff119af16206ced212163 Mon Sep 17 00:00:00 2001 From: mutantsan Date: Tue, 29 Apr 2025 12:18:38 +0300 Subject: [PATCH 3/3] pin the version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1ae5b80..c31bdfa 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ setup( name='ckanapi', - version='4.8', + version='4.9', description= 'A command line interface and Python module for ' 'accessing the CKAN Action API',