diff --git a/Algorithmia/client.py b/Algorithmia/client.py index 7247376..82078d0 100644 --- a/Algorithmia/client.py +++ b/Algorithmia/client.py @@ -24,18 +24,16 @@ class Client(object): requestSession = None bearerToken = None - - def __init__(self, apiKey = None, apiAddress = None, caCert = None, bearerToken=None): + def __init__(self, apiKey=None, apiAddress=None, caCert=None, bearerToken=None): # Override apiKey with environment variable config = None self.requestSession = requests.Session() if apiKey is None and 'ALGORITHMIA_API_KEY' in os.environ: apiKey = os.environ['ALGORITHMIA_API_KEY'] - if apiKey is None: - if bearerToken is None and 'ALGORITHMIA_BEARER_TOKEN' in os.environ: - bearerToken = os.environ['ALGORITHMIA_BEARER_TOKEN'] - self.bearerToken = bearerToken + elif bearerToken is None and 'ALGORITHMIA_BEARER_TOKEN' in os.environ: + bearerToken = os.environ['ALGORITHMIA_BEARER_TOKEN'] + self.bearerToken = bearerToken self.apiKey = apiKey if apiAddress is not None: self.apiAddress = apiAddress @@ -225,8 +223,8 @@ def postJsonHelper(self, url, input_object, parse_response_as_json=True, **query headers = {} if self.apiKey is not None: headers['Authorization'] = self.apiKey - else: - headers['Authorization'] = "Bearer "+ self.bearerToken + elif self.bearerToken is not None: + headers['Authorization'] = 'Bearer ' + self.bearerToken input_json = None if input_object is None: @@ -254,24 +252,24 @@ def getHelper(self, url, **query_parameters): headers = {} if self.apiKey is not None: headers['Authorization'] = self.apiKey - else: - headers['Authorization'] = 'Bearer '+ self.bearerToken + elif self.bearerToken is not None: + headers['Authorization'] = 'Bearer ' + self.bearerToken return self.requestSession.get(self.apiAddress + url, headers=headers, params=query_parameters) def getStreamHelper(self, url, **query_parameters): headers = {} if self.apiKey is not None: headers['Authorization'] = self.apiKey - else: - headers['Authorization'] = 'Bearer '+ self.bearerToken + elif self.bearerToken is not None: + headers['Authorization'] = 'Bearer ' + self.bearerToken return self.requestSession.get(self.apiAddress + url, headers=headers, params=query_parameters, stream=True) def patchHelper(self, url, params): headers = {'content-type': 'application/json'} if self.apiKey is not None: headers['Authorization'] = self.apiKey - else: - headers['Authorization'] = 'Bearer '+ self.bearerToken + elif self.bearerToken is not None: + headers['Authorization'] = 'Bearer ' + self.bearerToken return self.requestSession.patch(self.apiAddress + url, headers=headers, data=json.dumps(params)) # Used internally to get http head result @@ -279,8 +277,8 @@ def headHelper(self, url): headers = {} if self.apiKey is not None: headers['Authorization'] = self.apiKey - else: - headers['Authorization'] = 'Bearer '+ self.bearerToken + elif self.bearerToken is not None: + headers['Authorization'] = 'Bearer ' + self.bearerToken return self.requestSession.head(self.apiAddress + url, headers=headers) # Used internally to http put a file @@ -288,8 +286,8 @@ def putHelper(self, url, data): headers = {} if self.apiKey is not None: headers['Authorization'] = self.apiKey - else: - headers['Authorization'] = 'Bearer '+ self.bearerToken + elif self.bearerToken is not None: + headers['Authorization'] = 'Bearer ' + self.bearerToken if isJson(data): headers['Content-Type'] = 'application/json' @@ -303,8 +301,8 @@ def deleteHelper(self, url): headers = {} if self.apiKey is not None: headers['Authorization'] = self.apiKey - else: - headers['Authorization'] = 'Bearer '+ self.bearerToken + elif self.bearerToken is not None: + headers['Authorization'] = 'Bearer ' + self.bearerToken response = self.requestSession.delete(self.apiAddress + url, headers=headers) if response.reason == "No Content": return response @@ -364,11 +362,12 @@ def freeze(self, manifest_path, manifest_output_dir="."): required_files[i]['md5_checksum'] = md5_checksum lock_md5_checksum = md5_for_str(str(manifest_file)) manifest_file['lock_checksum'] = lock_md5_checksum - with open(manifest_output_dir+'/'+'model_manifest.json.freeze', 'w') as f: + with open(manifest_output_dir + '/' + 'model_manifest.json.freeze', 'w') as f: json.dump(manifest_file, f) else: print("Expected to find a model_manifest.json file, none was discovered in working directory") + def isJson(myjson): try: json_object = json.loads(myjson) diff --git a/Test/api/__init__.py b/Test/api/__init__.py index 9057bcf..ead17d3 100644 --- a/Test/api/__init__.py +++ b/Test/api/__init__.py @@ -23,6 +23,9 @@ def _start_webserver(): async def process_algo_req(request: Request, username, algoname, output: Optional[str] = None): metadata = {"request_id": "req-55c0480d-6af3-4a21-990a-5c51d29f5725", "duration": 0.000306774} content_type = request.headers['Content-Type'] + auth = request.headers.get('Authorization', None) + if auth is None: + return {"error": {"message": "authorization required"}} request = await request.body() if output and output == "void": return {"async": "abcd123", "request_id": "req-55c0480d-6af3-4a21-990a-5c51d29f5725"} diff --git a/Test/client_test.py b/Test/client_test.py index 0519266..3be87ad 100644 --- a/Test/client_test.py +++ b/Test/client_test.py @@ -9,11 +9,13 @@ import unittest import Algorithmia +from Algorithmia.errors import AlgorithmException from uuid import uuid4 if sys.version_info.major >= 3: unicode = str + class ClientDummyTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -71,7 +73,6 @@ def test_get_build_logs(self): self.assertTrue(u'error' not in result) - def test_edit_org(self): org_name = "a_myOrg84" @@ -138,7 +139,7 @@ def test_algorithm_programmatic_create_process(self): algorithm_name = "algo_e2d_test" payload = "John" expected_response = "hello John" - full_path = "a_Mrtest/" + algorithm_name + full_path = "a_Mrtest/" + algorithm_name details = { "summary": "Example Summary", "label": "QA", @@ -189,6 +190,23 @@ def test_algorithm_programmatic_create_process(self): response = created_algo.info(git_hash) self.assertEqual(response.version_info.semantic_version, "0.1.0", "information is incorrect") + + def test_no_auth_client(self): + + key = os.environ.get('ALGORITHMIA_API_KEY', "") + if key != "": + del os.environ['ALGORITHMIA_API_KEY'] + + client = Algorithmia.client(api_address="http://localhost:8080") + error = None + try: + client.algo("demo/hello").pipe("world") + except Exception as e: + error = e + finally: + os.environ['ALGORITHMIA_API_KEY'] = key + self.assertEqual(str(error), str(AlgorithmException(message="authorization required", stack_trace=None, error_type=None))) + else: class ClientTest(unittest.TestCase): seed(datetime.now().microsecond) @@ -201,7 +219,7 @@ class ClientTest(unittest.TestCase): def setUp(self): self.admin_api_key = unicode(os.environ.get('ALGORITHMIA_A_KEY')) self.regular_api_key = unicode(os.environ.get('ALGORITHMIA_API_KEY')) - + self.admin_username = self.admin_username + str(int(random() * 10000)) self.admin_org_name = self.admin_org_name + str(int(random() * 10000)) self.admin_client = Algorithmia.client(api_address="https://test.algorithmia.com", @@ -400,7 +418,5 @@ def test_algorithm_programmatic_create_process(self): def test_algo_freeze(self): self.regular_client.freeze("Test/resources/manifests/example_manifest.json", "Test/resources/manifests") - - if __name__ == '__main__': unittest.main()