diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/gridscale_api_client_python.iml b/.idea/gridscale_api_client_python.iml new file mode 100644 index 0000000..14273e4 --- /dev/null +++ b/.idea/gridscale_api_client_python.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..bc85450 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,20 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..5706053 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..52045b0 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dev-requirements.txt b/dev-requirements.txt index d8b1b8f..2a221be 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -7,3 +7,4 @@ rope black pytest pytest-mock +pyyaml diff --git a/examples/__init__.py b/examples/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/examples/config.yaml b/examples/config.yaml new file mode 100644 index 0000000..9f7be7d --- /dev/null +++ b/examples/config.yaml @@ -0,0 +1,9 @@ +projects: +- name: default + userId: user123 + token: pass123 + url: https://api.gridscale.io +- name: something-else + userId: user456 + token: pass456 + url: https://api.gridscale.io \ No newline at end of file diff --git a/examples/configloader.py b/examples/configloader.py new file mode 100644 index 0000000..4f01d3f --- /dev/null +++ b/examples/configloader.py @@ -0,0 +1,62 @@ +import shutil +import sys +import os.path +import pathlib +import yaml + + +def default_config_path(): + """ + + this checks the operation system of the user. + this is used to determine the standard save location for the global gridscale config file. + + """ + #check if os is linux + if(sys.platform in ("linux", "linux2")): + path = "~/.config/gridscale" + path = os.path.expanduser(path) + if not os.path.exists(path): + os.makedirs(path) + #check if os is windows + elif(sys.platform in ("win32", "cygwin", "msys")): + path = "%APPDATA%\gridscale" + path = os.path.expanduser(path) + if not os.path.exists(path): + os.makedirs(path) + #check if os is mac os + elif(sys.platform in ("darwin", "os2", "os2emx")): + path = "~/Library/Application Support/gridscale" + path = os.path.expanduser(path) + if not os.path.exists(path): + os.makedirs(path) + else: + raise RuntimeError("Operating system not supported") + + return path + + +def create_config(path): + """ + this will copy the currently used config file in the standard folder + """ + syspath = default_config_path() + "/config.yaml" + shutil.copyfile(path, syspath) + + +def load_config(path): + """ + First checking "path" to match minimum length and other requirements. + + Then it opens the specified config file and returns all keys which include token and UserId. + """ + # opens specified file to retrieve config tokens + if isinstance(path, (pathlib.Path, str)): + assert path + with open(f"{path}", 'r') as stream: + data = yaml.safe_load(stream) + # return list of dictionaries for all projects + for value in data.values(): + return (value) + else: + raise AssertionError diff --git a/examples/examples.py b/examples/examples.py index e29f7c8..2dc1f03 100644 --- a/examples/examples.py +++ b/examples/examples.py @@ -2,7 +2,9 @@ from pprint import pprint from uuid import uuid4 +import os from index_by.key import index_by_key +from configloader import load_config from gs_api_client import SyncGridscaleApiClient, GridscaleApiClient, models from gs_api_client import Configuration @@ -16,11 +18,12 @@ # api_config.debug = True api_config.host = 'https://api.gridscale.io' - #TODO: Insert your API token and User ID - api_config.api_key['X-Auth-Token'] = "AUTH_TOKEN" - api_config.api_key['X-Auth-UserId'] = "USER_UUID" - # api_config.debug = True - + #TODO: Change filename + configfile = load_config("config.yaml") + api_config.api_key['X-Auth-Token'] = configfile[0].get("token") + api_config.api_key['X-Auth-UserId'] = configfile[0].get("userId") + api_config.debug = True + print('-' * 80) client = SyncGridscaleApiClient(configuration=api_config, http_info=False) diff --git a/tests/example-config.yaml b/tests/example-config.yaml new file mode 100644 index 0000000..adff316 --- /dev/null +++ b/tests/example-config.yaml @@ -0,0 +1,10 @@ +projects: + - name: default + userId: user123 + token: pass123 + url: https://api.gridscale.io + + - name: something-else + userId: user456 + token: pass456 + url: https://api.gridscale.io diff --git a/tests/test_config.py b/tests/test_config.py index d5ceaab..d267bee 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,4 +1,13 @@ +import os.path +import shutil + +import pytest + from gs_api_client import Configuration +from examples.configloader import load_config + + +CURRENT_DIR = os.path.dirname(os.path.realpath(__file__)) def test_debug_is_disabled_by_default(): @@ -9,3 +18,59 @@ def test_debug_is_disabled_by_default(): def test_tls_certs_are_verified_by_default(): config = Configuration() assert config.verify_ssl + + +def test_load_config_from_yaml(): + """Make sure we can load a config from a given YAML file.""" + + example_config = os.path.join(CURRENT_DIR, "example-config.yaml") + res = load_config(example_config) + assert isinstance(res, list) + assert len(res) == 2 + assert isinstance(res[0], dict) + assert res[0]["name"] == "default" + assert res[1]["name"] == "something-else" + + +def test_load_config_works_without_fileext(tmp_path): + """Ensure load_config does not interpret file path or file name.""" + + example_config = os.path.join(CURRENT_DIR, "example-config.yaml") + dest = tmp_path / "a" + shutil.copyfile(example_config, dest) + res = load_config(dest) + assert isinstance(res, list) + assert len(res) == 2 + + +def test_load_config_handles_non_existing_file(): + """ "Ensure load_config raises FileNotFoundError.""" + + with pytest.raises(FileNotFoundError): + load_config("fufu.yaml") + + +def test_load_config_checks_for_bogus_input(): + """ "Ensure load_config checks it's input.""" + + with pytest.raises(AssertionError): + load_config(42) + + with pytest.raises(AssertionError): + load_config("") + + +def test_load_config_propagates_parsing_errors(): + """ "Ensure load_config raises any error during parsing.""" + + import yaml + + not_a_yaml_file = os.path.join(CURRENT_DIR, "test_config.py") + with pytest.raises(yaml.YAMLError): + load_config(not_a_yaml_file) + + +def test_load_config_has_doc_string(): + """ "Make sure load_config is documented.""" + + assert load_config.__doc__