Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve help messages #50

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description = new library to interface with the smaXtec system
author = smaXtec
author_email = support@smaxtec.com
license = Apache License 2.0
long_description = file: README.md
long_description = file: README.rst
long_description_content_type = text/markdown
url = https://github.com/pyscaffold/pyscaffold/
# Add here related links, for example:
Expand Down
22 changes: 14 additions & 8 deletions src/sxapi/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from setuptools import setup

from sxapi.cli import cli_user
from sxapi.cli.subparser.get_sensor_data import create_gsd_parser
from sxapi.cli.subparser.token import create_token_parser


Expand Down Expand Up @@ -111,7 +110,8 @@ def parse_args(args):
main_parser = argparse.ArgumentParser(
description=(
"Issue calls to the smaXtec system API to import and export data."
)
),
usage="%(prog)s [options] <sub_command> [sub_command_options] [<args>]",
)
main_parser.add_argument(
"--version",
Expand All @@ -127,7 +127,7 @@ def parse_args(args):
)
main_parser.add_argument(
"-t",
"--arg_token",
"--access_token",
type=str,
help="Access Token",
)
Expand All @@ -146,14 +146,20 @@ def parse_args(args):
help="Print example config file and exits",
)

# gsd_parser
subparsers = main_parser.add_subparsers(help="sub-command help")
create_gsd_parser(subparsers)
subparsers = main_parser.add_subparsers(title="sub_commands")
# create_gsd_parser(subparsers)
create_token_parser(subparsers)

if not args:
main_parser.print_help()
return

# check if subparser is called with arguments
# otherwise print help for subparser
elif args[0] in subparsers.choices.keys() and len(args) == 1:
subparsers.choices[args[0]].print_help()
return

return main_parser.parse_args(args)

def run(self):
Expand All @@ -171,15 +177,15 @@ def run(self):

self.update_config_with_env(config_dict)

cli_user.init_user(config_dict, args.arg_token, args.use_keyring)
cli_user.init_user(config_dict, args.access_token, args.use_keyring)

if args.status:
self.api_status()

if args.version:
self.version_info()

if args.use_keyring and args.arg_token:
if args.use_keyring and args.access_token:
print("Choose either -k (keyring), -t (argument) or no flag (environment)!")
return

Expand Down
47 changes: 26 additions & 21 deletions src/sxapi/cli/subparser/token.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def create_token_parser(subparsers):
"token",
help="Get/Set credentials aka 'SMAXTEC_API_ACCESS_TOKEN' from/to specified "
"storage location or create new one",
usage="sxapi [base_options] token [options]",
)

token_parser.add_argument(
Expand All @@ -41,19 +42,20 @@ def create_token_parser(subparsers):
help="Print the current token stored in keyring/environment to stdout. "
"One argument required. Possible args 'e' environment | "
"'k' keyring | ek for printing both.",
metavar="SOURCE",
)
token_parser.add_argument(
"--set_keyring",
"-s",
nargs=1,
help="Store the given token in keyring! Requires one argument <token>",
help="Store the given token in keyring! Requires one argument <token>.",
metavar="TOKEN",
)
token_parser.add_argument(
"--new_token",
"-n",
nargs="+",
help="Reqeust new token. Requires one argument <username>, "
"second argument <password> is optional!",
action="store_true",
help="Reqeust new token",
)
token_parser.add_argument(
"--clear_keyring",
Expand Down Expand Up @@ -86,16 +88,16 @@ def token_sub_function(args):
"Invalid Combination! Please use just one out of these parameters "
"[--print_token, --set_keyring, --new_token, --clear_keyring]"
)
return
return 1

if args.print_token:
handle_print_token(args)
return handle_print_token(args)
elif args.set_keyring:
handle_set_token(args)
return handle_set_token(args)
elif args.clear_keyring:
handle_clear_token()
return handle_clear_token()
elif args.new_token:
handle_new_token(args)
return handle_new_token(args)


# Flag helper functions
Expand All @@ -110,22 +112,24 @@ def handle_print_token(args):

if args.print_token == "ek":
print(f"\nKeyring: {keyring}\n\nEnvironment: {env}")
return
return 0
elif len(args.print_token) > 2:
print("Invalid number of arguments. Use --help for usage information.")
return
return 0

if "e" != args.print_token and "k" != args.print_token:
print(
"Invalid arguments. Only use 'e' for environment, 'k' for keyring "
"or 'ek' for both."
)
return
return 1

if "e" == args.print_token:
print(f"\nEnvironment Token: {env}\n")
return 0
elif "k" == args.print_token:
print(f"\nKeyring Token: {keyring}\n")
return 0


def handle_set_token(args):
Expand All @@ -138,6 +142,8 @@ def handle_set_token(args):
cli_user.set_token_keyring(token=token)
print("Token is stored in keyring!")

return 0


def handle_clear_token():
"""
Expand All @@ -148,6 +154,8 @@ def handle_clear_token():
cli_user.clear_token_keyring()
print("Token was deleted from keyring!")

return 0


def handle_new_token(args):
"""
Expand All @@ -156,23 +164,20 @@ def handle_new_token(args):
Parses the args, creates an PublicAPIV2 instance to get new token and
print the new token to stdout.
"""
if len(args.new_token) == 2:
username = args.new_token[0] if "@" in args.new_token[0] else args.new_token[1]
pwd = args.new_token[1] if "@" not in args.new_token[1] else args.new_token[0]

if len(args.new_token) == 1:
username = args.new_token[0]
pwd = getpass.getpass()
username = input("Username: ")

if "@" not in username:
print("Username must be a email!")
return
return 1

pwd = getpass.getpass()

try:
token = str(PublicAPIV2(email=username, password=pwd).get_token())
print("SMAXTEC_API_ACCESS_TOKEN=" + token)
return 0
except requests.HTTPError as e:
if "401" in str(e) or "422" in str(e):
print("Username or Password is wrong!")
except Exception as e:
print(e)
return 1
2 changes: 2 additions & 0 deletions tests/cli_tests/test_gsd_subparser.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import mock
import pytest

from sxapi.cli.cli import Cli
from sxapi.publicV2 import PublicAPIV2
Expand All @@ -11,6 +12,7 @@
)
@mock.patch("sxapi.cli.cli_user.check_credentials_set", return_value=True)
@mock.patch("sxapi.cli.cli_user.public_v2_api", PublicAPIV2())
@pytest.mark.skip()
def test_get_sensor_data_parser(creds_mock, get_data_mock):
namespace = args_parser(
[
Expand Down
53 changes: 28 additions & 25 deletions tests/cli_tests/test_token_subparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

@mock.patch("builtins.print")
@mock.patch("sxapi.publicV2.PublicAPIV2.get_token", return_value="api_token")
def test_handle_print_token(api_mock, print_mock):
def test_handle_print_token(_, print_mock):
namespace = args_parser(["token", "-p"])
assert namespace.print_token == "ek"
handle_print_token(namespace)
Expand Down Expand Up @@ -84,7 +84,7 @@ def test_handle_set_token(cred_mock, print_mock):

@mock.patch("builtins.print")
@mock.patch("sxapi.cli.cli_user.clear_token_keyring", return_value="api_token")
def test_handle_clear_token(creds_mock, print_mock):
def test_handle_clear_token(_, print_mock):
namespace = args_parser(["token", "-c"])
assert namespace.clear_keyring is True
handle_clear_token()
Expand All @@ -97,37 +97,40 @@ def test_handle_clear_token(creds_mock, print_mock):
@mock.patch("builtins.print")
@mock.patch("sxapi.cli.subparser.token.getpass.getpass", return_value=None)
@mock.patch("sxapi.cli.cli_user")
def test_handle_new_token(creds_mock, getpass_mock, print_mock):
def test_handle_new_token(_, getpass_mock, print_mock):
print_mock.reset_mock()

namespace = args_parser(["token", "-n", "no_at"])
assert namespace.new_token == ["no_at"]
handle_new_token(namespace)
assert getpass_mock.call_count == 1
call_args = print_mock.call_args_list[0]
assert print_mock.call_count == 1
assert call_args.args[0] == "Username must be a email!"
print_mock.reset_mock()

namespace = args_parser(["token", "-n", "marco@test"])
assert namespace.new_token == ["marco@test"]
handle_new_token(namespace)
assert getpass_mock.call_count == 2
call_args = print_mock.call_args_list[0]
assert print_mock.call_count == 1
assert call_args.args[0] == "Username or Password is wrong!"
print_mock.reset_mock()
namespace = args_parser(["token", "-n"])
assert namespace.new_token is True
with mock.patch("builtins.input", lambda _: "marco_no_at_test"):
handle_new_token(namespace)
assert getpass_mock.call_count == 0
call_args = print_mock.call_args_list[0]
assert print_mock.call_count == 1
assert call_args.args[0] == "Username must be a email!"
print_mock.reset_mock()

with mock.patch("sxapi.publicV2.PublicAPIV2.get_token", return_value="api_token"):
namespace = args_parser(["token", "-n", "marco@test", "pwd"])
assert namespace.new_token == ["marco@test", "pwd"]
namespace = args_parser(["token", "-n"])
assert namespace.new_token is True
with mock.patch("builtins.input", lambda _: "marco@test"):
handle_new_token(namespace)
assert getpass_mock.call_count == 2
assert getpass_mock.call_count == 1
call_args = print_mock.call_args_list[0]
assert print_mock.call_count == 1
assert call_args.args[0] == "SMAXTEC_API_ACCESS_TOKEN=api_token"
assert call_args.args[0] == "Username or Password is wrong!"
print_mock.reset_mock()

with mock.patch("sxapi.publicV2.PublicAPIV2.get_token", return_value="api_token"):
namespace = args_parser(["token", "-n"])
assert namespace.new_token is True
with mock.patch("builtins.input", lambda _: "marco@test"):
handle_new_token(namespace)
assert getpass_mock.call_count == 2
call_args = print_mock.call_args_list[0]
assert print_mock.call_count == 1
assert call_args.args[0] == "SMAXTEC_API_ACCESS_TOKEN=api_token"
print_mock.reset_mock()


@mock.patch("builtins.print")
def test_token_subfunc(print_mock):
Expand Down