Как использовать 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, Это работало просто отлично.

Другие вопросы по тегам