Как использовать argparse в реальном скрипте
Как работает argparse? Мне сказали "спрятать" пароль от соединения psycopg2, которое я создаю, чтобы иметь возможность запускать скрипт автоматически каждую неделю и иметь возможность делиться им между отделами. Это начало сценария psycopg2, где запрашивается пароль:
#Connect to database
conn_string = "host='my_aws_postgresql_database.rds.amazonaws.com' dbname='my_database_name' user='my_username' password='my_password'"
# print the connection string we will use to connect
print ("\"Connecting to database\n ->%s\"" % (conn_string))
Теперь, как бы я использовал argparse (и getpass), чтобы скрыть свой пароль? Я нашел этот сценарий на эту тему пару раз (я бы удалил оператор print после того, как заставил его работать):
import argparse
import getpass
class Password(argparse.Action):
def __call__(self, parser, namespace, values, option_string):
if values is None:
values = getpass.getpass()
setattr(namespace, self.dest, values)
parser = argparse.ArgumentParser('Test password parser')
parser.add_argument('-p', action=Password, nargs='?', dest='password',
help='Enter your password')
args = parser.parse_args()
print (args.password)
Я пытался добавить argparse
фрагмент над #Connect to database
код. И заменил password
часть на линии 2 с
conn_string =
"host='my_aws_postgresql_database.rds.amazonaws.com'
dbname='my_database_name'
user='my_username'
password='" + args + "'"
Затем я попытался запустить весь скрипт с помощью команды python3 my_script_file.py my_password -p
Меня просят ввести пароль, который я ввел, но при этом возникла следующая ошибка
usage: Test password parser [-h] [-p [PASSWORD]]
Test password parser: error: unrecognized arguments: my_password
Если я использую python3 my_script_file.py my_password
Я получаю ту же ошибку, но мне не нужно было вводить пароль (снова).
Я близок к решению? Это стандартный способ сделать это?
Проблема заключалась в том, что я использовал python3 my_script_file.py my_password -p
вместо правильного порядка python3 my_script_file.py -p my_password
см. принятый ответ ниже @hpaulj и комментарии к этому ответу.
2 ответа
Этот парсер дает пользователю 2 способа ввода пароля, в командной строке или с помощью отдельного getpass
незамедлительный:
import argparse
import getpass
class Password(argparse.Action):
def __call__(self, parser, namespace, values, option_string):
if values is None:
values = getpass.getpass()
setattr(namespace, self.dest, values)
parser = argparse.ArgumentParser('Test password parser')
parser.add_argument('-p', action=Password, nargs='?', dest='password',
help='Enter your password')
args = parser.parse_args()
print (args)
Образцы прогонов:
0911:~/mypy$ python3 stack44571340.py
Namespace(password=None)
0912:~/mypy$ python3 stack44571340.py -p test
Namespace(password='test')
0912:~/mypy$ python3 stack44571340.py -p
Password:
Namespace(password='testing')
0912:~/mypy$ python3 stack44571340.py test
usage: Test password parser [-h] [-p [PASSWORD]]
Test password parser: error: unrecognized arguments: test
Я тестировал без каких-либо аргументов (получил значение по умолчанию None
)`; с '-p test', который использует строку 'test'; просто "-p", который спрашивает; и без '-p', который выдает ошибку.
Я не знаю почему python3 my_script_file.py -p my_password
выдал ошибку; мое лучшее предположение, что в вашем определении парсера есть опечатка (что-то не так с nargs
?).
Не совсем понятно, как вы слили этот код парсера в более крупный скрипт. Если все сделано правильно, это не должно было изменить поведение анализатора.
Аргумент пароля будет использоваться как:
password='" + args.password + "'"
echo
Аргумент является позиционным, для которого требуется строка. В отличие от -p
с nargs='?'
, является необязательным помеченным аргументом, который учитывает трехсторонний ввод, который я иллюстрировал.
parser.add_argument("echo")
Спасибо @CarlShiles, твой ответ не сработал с этим длинным фрагментом argparse/getpass сверху, но это заставило меня понять, что я могу просто echo
пароль там. Итак, я сделал простой
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
а затем использовал ваше предложение, password='" + args.echo + "'"
, А затем запустил следующую команду python3 my_script_file.py my_password
, Это работало просто отлично.