Как уже упоминалось, ваш токен командной строки при декодировании возвращает этот json
объект:
{'nested': '[{name=me,', 'id': '1}]'}
Быстрое погружение в пакет __main__.py
из jwt
дает этот небольшой фрагмент:
... snipped
def encode_payload(args):
# Try to encode
if args.key is None:
raise ValueError('Key is required when encoding. See --help for usage.')
# Build payload object to encode
payload = {}
for arg in args.payload:
k, v = arg.split('=', 1)
... some additional handling on v for time, int, float and True/False/None
... snipped
Как видите, ключ и значение полезной нагрузки определяются непосредственно на основе split('=', 1)
, поэтому все, что передано в первой командной строке =
после ключа, всегда будет определяться как одно значение (с некоторое преобразование потом).
Короче говоря, вложенные dict
s в CLI не поддерживаются .
Тем не менее, есть и хорошие новости: есть несколько способов обойти это:
Запустите импровизированный оператор непосредственно из CLI Python следующим образом:
> python -c "import jwt; print(jwt.encode({'nested':[{'name':'me', 'id':'1'}]}, 'secret').decode('utf-8'))"
# eyJ...Zq_k
Не совсем идеально, но дает вам то, что вам нужно.
Сохраните тот же сценарий в .py, способный принимать аргументы, и выполните его на CLI Python:
import sys, jwt
my_json = sys.argv[0]
token = jwt.encode(eval(my_json), 'secret')
print(token.decode('utf-8'))
# run in CLI
> python my_encode.py "{'nested':[{'name':'me', 'id':'1'}]}"
# eyJ...Zq_k
Обратите внимание, что использование eval()
здесь не идеально из-за проблем безопасности. Это просто мой ленивый способ реализации, потому что я не хочу писать парсер для аргументов. Если вам абсолютно необходимо использовать интерфейс командной строки для своей реализации, и он открыт, я настоятельно рекомендую вам вложить усилия в более тщательную очистку и анализ argv
.
Самый хитрый способ: вы можете попытаться изменить функцию Lib\site-packages\jwt\__main__.py
(на свой страх и риск) в соответствии с вашими потребностями, пока не будет добавлена официальная поддержка. Я хотел бы предостеречь, что вам должно быть довольно удобно писать свой собственный анализ, прежде чем подумать о том, чтобы возиться с основным кодом. Я сделал несколько попыток, прежде чем осознал ограничения, с которыми вы столкнетесь:
а. Основной метод encode()
не считает list
допустимым объектом JSON (но он должен). Так что сразу у вас должна быть dict
подобная строка для манипуляции.
б. Код всегда заставляет числа быть приведенными как int
или float
, если это возможно. Вам нужно как-то избежать этого или полностью изменить способ обработки чисел.
Моя попытка прошла примерно так:
def func(result, payload):
for arg in payload:
k, v = arg.split('=', 1)
if v.startswith('{') and v.endswith('}'):
result[k] = func({}, v[1:-1])
else:
... the rest of the existing code
Однако я быстро столкнулся с ограничением исходных аргументов, уже разделенных пробелами, и предположил, что это пара k
, v
, мне нужно дополнительно обработать другой разделитель, такой как ,
, а также возможность обрабатывать list
с, и это может стать более грязным. Это определенно выполнимо, и эффект незамедлительный, то есть CLI запускается прямо из этого __main__.py
, но это больше работы, чем я хотел бы вложить в данный момент, поэтому я оставляю это вашими умелыми руками.
Усилия по преодолению этих проблем для достижения того, что вам нужно, могут быть более чем необходимыми, зависит от ваших навыков и уровня комфорта. Так что выбирайте свою битву ... если CLI не является абсолютно необходимым, я бы предложил вместо этого использовать .py
методы.