Skip to content

Commit

Permalink
--annowork_user_id, --annowork_passwordを指定できるようにする (#176)
Browse files Browse the repository at this point in the history
* update pyproject

* `--annowork_usr_id`, `--annowork_password`を追加する

* format

* マスクする

* format

* python3.8でのエラーを修正
  • Loading branch information
yuji38kwmt authored Jan 30, 2024
1 parent a960b12 commit 580a6f6
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 35 deletions.
21 changes: 20 additions & 1 deletion annoworkcli/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from __future__ import annotations
import argparse
import copy
import logging
import sys
from typing import Optional, Sequence
Expand Down Expand Up @@ -43,6 +45,20 @@ def create_parser() -> argparse.ArgumentParser:
return parser


def mask_argv(argv: list[str]) -> list[str]:
"""
`argv`にセンシティブな情報が含まれている場合は、`***`に置き換える。
"""
tmp_argv = copy.deepcopy(argv)
for masked_option in ["--annowork_user_id", "--annowork_password", "--annofab_user_id", "--annofab_password"]:
try:
index = tmp_argv.index(masked_option)
tmp_argv[index + 1] = "***"
except ValueError:
continue
return tmp_argv


def main(arguments: Optional[Sequence[str]] = None):
"""
annoworkcli コマンドのメイン処理
Expand All @@ -60,7 +76,10 @@ def main(arguments: Optional[Sequence[str]] = None):
if hasattr(args, "subcommand_func"):
try:
set_default_logger(is_debug_mode=args.debug)
logger.info(f"{sys.argv=}")
argv = sys.argv
if arguments is not None:
argv = ["annoworkcli", *list(arguments)]
logger.info(f"args={mask_argv(argv)}")
args.subcommand_func(args)
except Exception as e:
logger.exception(e)
Expand Down
10 changes: 4 additions & 6 deletions annoworkcli/annofab/put_account_external_linkage_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,10 @@ def main(self, af_workspace_name: str, user_id_list: list[str]):

def main(args):
annowork_service = build_annoworkapi(args)
annofab_service = (
build_annofabapi_resource_and_login(
annofab_login_user_id=args.annofab_user_id,
annofab_login_password=args.annofab_password,
mfa_code=args.annofab_mfa_code,
)
annofab_service = build_annofabapi_resource_and_login(
annofab_login_user_id=args.annofab_user_id,
annofab_login_password=args.annofab_password,
mfa_code=args.annofab_mfa_code,
)
user_id_list = get_list_from_args(args.user_id)
assert user_id_list is not None
Expand Down
94 changes: 73 additions & 21 deletions annoworkcli/common/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@

import annoworkapi
from annoworkapi.api import DEFAULT_ENDPOINT_URL
from annoworkapi.exceptions import AnnoworkApiException
from annoworkapi.exceptions import CredentialsNotFoundError
from more_itertools import first_true

from annoworkcli.common.exeptions import CommandLineArgumentError
from annoworkcli.common.utils import get_file_scheme_path, read_lines_except_blank_line

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -53,7 +54,7 @@ def _get_help_string(self, action):
if action.default is not argparse.SUPPRESS:
defaulting_nargs = [argparse.OPTIONAL, argparse.ZERO_OR_MORE]
if action.option_strings or action.nargs in defaulting_nargs:
# 以下の条件だけ、annofabcli独自の設定
# 以下の条件だけ、annoworkcli独自の設定
if action.default is not None and not action.const:
help += " (default: %(default)s)"
return help
Expand Down Expand Up @@ -91,6 +92,18 @@ def create_parent_parser() -> argparse.ArgumentParser:
parent_parser = argparse.ArgumentParser(add_help=False, allow_abbrev=False)
group = parent_parser.add_argument_group(GLOBAL_OPTIONAL_ARGUMENTS_TITLE)
group.add_argument("--debug", action="store_true", help="HTTPリクエストの内容やレスポンスのステータスコードなど、デバッグ用のログが出力されます。")

group.add_argument(
"--annowork_user_id",
type=str,
help="Annoworkにログインする際のユーザーIDを指定します。",
)
group.add_argument(
"--annowork_password",
type=str,
help="Annoworkにログインする際のパスワードを指定します。",
)

group.add_argument(
"--endpoint_url",
type=str,
Expand Down Expand Up @@ -212,6 +225,41 @@ def prompt_yesnoall(msg: str) -> Tuple[bool, bool]:
return True, True


def _get_annowork_user_id_from_stdin() -> str:
"""標準入力からAnnoworkにログインする際のユーザーIDを取得します。"""
login_user_id = ""
while login_user_id == "":
login_user_id = input("Enter Annowork User ID: ")
return login_user_id


def _get_annowork_password_from_stdin() -> str:
"""標準入力からAnnoworkにログインする際のパスワードを取得します。"""
login_password = ""
while login_password == "":
login_password = getpass.getpass("Enter Annowork Password: ")
return login_password


def _get_endpoint_url_from_args_or_envvar(args: argparse.Namespace) -> str:
"""
コマンドライン引数`--endpoint_url`または環境変数`ANNOWORK_ENDPOINT_URL`から、AnnoworkのエンドポイントURLを取得します。
優先順位は次の通りです。
1. コマンドライン引数 `--endpoint_url`
2. 環境変数 `ANNOWORK_ENDPOINT_URL`
"""
endpoint_url = annoworkapi.api.DEFAULT_ENDPOINT_URL

if "ANNOWORK_ENDPOINT_URL" in os.environ:
endpoint_url = os.environ["ANNOWORK_ENDPOINT_URL"]

if args.endpoint_url is not None:
endpoint_url = args.endpoint_url

return endpoint_url


def build_annoworkapi(args: argparse.Namespace) -> annoworkapi.resource.Resource:
"""annoworkapiのインスタンスを生成します。
Expand All @@ -225,29 +273,33 @@ def build_annoworkapi(args: argparse.Namespace) -> annoworkapi.resource.Resource
Returns:
annoworkapi.resource.Resource: annoworkapiのインスタンス
"""
endpoint_url = annoworkapi.api.DEFAULT_ENDPOINT_URL

if "ANNOWORK_ENDPOINT_URL" in os.environ:
endpoint_url = os.environ["ANNOWORK_ENDPOINT_URL"]

if args.endpoint_url is not None:
endpoint_url = args.endpoint_url
endpoint_url = _get_endpoint_url_from_args_or_envvar(args)

# エンドポイントURLがデフォルトでない場合は、気付けるようにするためログに出力する
if endpoint_url != annoworkapi.api.DEFAULT_ENDPOINT_URL:
logger.info(f"endpoint_url='{endpoint_url}'")

if args.annowork_user_id is not None and args.annowork_password is not None:
return annoworkapi.build(
login_user_id=args.annowork_user_id, login_password=args.annowork_password, endpoint_url=endpoint_url
)

elif args.annowork_user_id is not None and args.annowork_password is None:
# コマンドライン引数でユーザーIDのみ指定された場合は、パスワードを標準入力から取得する
login_password = _get_annowork_password_from_stdin()
return annoworkapi.build(
login_user_id=args.annowork_user_id, login_password=login_password, endpoint_url=endpoint_url
)

elif args.annowork_user_id is None and args.annowork_password is not None:
# コマンドライン引数でパスワードのみ指定された場合は、エラーにする
raise CommandLineArgumentError("`--annowork_password`を指定する際は、`--annowork_user_id`も指定してください。")

# コマンドライン引数でユーザーID、パスワードが指定されていない場合
try:
return annoworkapi.build(endpoint_url=endpoint_url)
except AnnoworkApiException:
except CredentialsNotFoundError:
# 環境変数, netrcフィアルに認証情報が設定されていなかったので、標準入力から認証情報を入力させる。
login_user_id = ""
while login_user_id == "":
login_user_id = input("Enter Annowork User ID: ")

login_password = ""
while login_password == "":
login_password = getpass.getpass("Enter Annowork Password: ")

return annoworkapi.resource.Resource(
endpoint_url=endpoint_url, login_user_id=login_user_id, login_password=login_password
)
login_user_id = _get_annowork_user_id_from_stdin()
login_password = _get_annowork_password_from_stdin()
return annoworkapi.build(endpoint_url=endpoint_url, login_user_id=login_user_id, login_password=login_password)
4 changes: 4 additions & 0 deletions annoworkcli/common/exeptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ class AnnoworkCliException(Exception):
"""
annoworkcliに関するException
"""


class CommandLineArgumentError(AnnoworkCliException):
"""コマンドライン引数が正しくない場合のエラー"""
12 changes: 6 additions & 6 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ classifiers = [
[tool.poetry.dependencies]
python = "^3.8"
pyyaml = "*"
annoworkapi = ">=3.0.1"
annoworkapi = ">=3.1"
annofabapi = ">=0.72.0"
more-itertools = "*"
pandas = "*"
Expand Down

0 comments on commit 580a6f6

Please sign in to comment.