Создайте свой собственный список Todo CLI с Python, используя пакеты, такие как Click, Pyinquire и Chotter за считанные минуты!
Там тонна потрясающих пакетов, которые помогут вам построить красивые CLI, некоторые покрыты этой статьей Создание красивых интерфейсов командной строки с Python Отказ
Мы собираемся использовать некоторые из них, чтобы сделать хороший и интерактивный список ToDo CLI.
Мы собираемся использовать готовый API для отдыха, который помогает нам хранить и обновлять список Todo. API доступен на https://cottertodolist.herokuapp.com/ И вы можете найти исходный код и документацию на Github repo Отказ
Чтобы сделать CLI, мы будем использовать несколько пакетов:
- Функциональные возможности CLI и подсказки: Нажмите , а также Pyinquirer
- Аутентификация: Шплинт
Получить полный код для этого учебника в Github .
Давайте начнем с Super Simple CLI
В вашем каталоге проекта давайте начнем, сделав Виртуальский :
python -m venv venv/
Затем активируйте виртуальную среду с Источник
команда:
source venv/bin/activate
Теперь давайте установим Нажмите
сделать наши простые CLI:
pip install click
Затем сделайте файл для наших CLI – давайте назовем это cli.py
И мы сделаем простой приветствовать
команда.
# cli.py import click @click.group() def main(): """ Simple CLI that will greet you""" pass @main.command() @click.argument('name') def greet(name): """This will greet you back with your name""" click.echo("Hello, " + name) if __name__ == "__main__": main()
Вот как это выглядит, когда запустить:
❯ python cli.py greet Putri Hello, Putri
Теперь давайте построим наш список TodDo CLI.
Давайте проверим наши Документация API списка Todo Отказ Пример запроса, чтобы показать все списки выглядит так:
### Show all lists GET http://localhost:1234/list Authorization: Bearer
Как вы можете видеть, наш API требует Access_Token
Чтобы разрешить владельцам только для просмотра и обновления списка Todo.
Начните с регистрации/регистрации наших пользователей на API
Первое, что нам нужно сделать, это аутентифицировать наших пользователей и зарегистрировать его в API ToDo List. API выглядит так:
### Login or Register a user using Cotter's response ### From the Python SDK POST http://localhost:1234/login_register Content-Type: application/json { "oauth_token": { "access_token": "eyJhbGciOiJF...", "id_token": "eyJhbGciOiJFUzI...", "refresh_token": "40011:ra78TcwB...", "expires_in": 3600, "token_type": "Bearer", "auth_method": "OTP" } }
Для этого мы будем использовать SDK Python Cotter для генерации Oauth_tokens
Затем отправьте его в API списка Todo.
Вход в систему с Cotter
Сначала установите Cotter, используя:
pip install cotter
Тогда давайте обновим наш Cli.py
Чтобы добавить функцию входа:
# cli.py import click import os import cotter # 1️⃣ Add your Cotter API KEY ID here api_key = "" @click.group() def main(): """ A Todo List CLI """ pass @main.command() def login(): """Login to use the API""" # 2️⃣ Add a file called `cotter_login_success.html` # 3️⃣ Call Cotter's api to login port = 8080 # Select a port response = cotter.login_with_email_link(api_key, port) click.echo(response) if __name__ == "__main__": main()
Вам понадобится API_KEY_ID
от Cotter, который вы можете получить от Приборная панель Отказ
После инструкции SDK вам также понадобится HTML-файл под названием cotter_login_success.html
В вашем каталоге проекта. Скопировать cotter_login_success.html
Из примерной папки SDK в Github. Ваша папка Project должна теперь содержать 2 файла:
project-folder |- cli.py |- cotter_login_success.html
Теперь давайте запустим CLI и попробуйте войти в систему. Вы должны увидеть что-то вроде этого:
❯ python cli.py login Open this link to login at your browser: https://js.cotter.app/app?api_key=abcdefgh-c318-4fc1-81ad-5cc8b69051e8&redirect_url=http%3A%2F%2Flocalhost%3A8080&state=eabgzskfrs&code_challenge=zBa9xK4sI7zpqvDZL8iAX9ytSo0JZ0O4gWWuVIKTXU0&type=EMAIL&auth_method=MAGIC_LINK
Это также должно открыть ваш браузер, где вы можете ввести свою электронную почту и вход в систему.
Как только вы закончите вход, вы должны увидеть следующий ответ в вашем терминале:
{ "oauth_token": { "access_token": "eyJhbGciOiJFU...", "id_token": "eyJhbGciOiJF...", "refresh_token": "40291:czHCOxamERp1yA...Y", "expires_in": 3600, "token_type": "Bearer", "auth_method": "OTP" }, "identifier": {...}, "token": {...}, "user": {...} }
Это идеально подходит для наших /login_register
Конечная точка API, поэтому давайте отправим ответ от войдите в эту конечную точку в нашей функции входа в систему.
Зарегистрируйтесь или войдите пользователь на API ToDo List
Во-первых, нам нужно установить запросы на звонок HTTP-запросов:
pip install requests
Обновите наш Вход
Функция внутри Cli.py
к следующему:
# cli.py import requests @main.command() def login(): """Login to use the API""" # Add a file called `cotter_login_success.html` # Call Cotter's api to login port = 8080 # Select a port response = cotter.login_with_email_link(api_key, port) # 1️⃣ Add your Cotter API KEY ID here url = 'https://cottertodolist.herokuapp.com/login_register' headers = {'Content-Type': 'application/json'} data = response resp = requests.post(url, json=data, headers=headers) if resp.status_code != 200: resp.raise_for_status() click.echo(resp.json())
Теперь вы должны увидеть ответ {'user_id': '274825255751516680'}
Это означает, что мы успешно зарегистрированы или вошли в наш пользователь.
Хранение Oauth_tokens
Для последующего использования Мы не хотим просить пользователя войти каждый раз, когда нам нужно Access_Token
Отказ К счастью, COTTER уже предоставляет функцию легко хранить и получить (и автоматически обновлять) Access_Token
из файла.
Обновите свой Вход
Функция, хранение токена непосредственно перед эхом ответом:
# cli.py from cotter import tokenhandler token_file_name = "cotter_token.json" @main.command() def login(): ... tokenhandler.store_token_to_file(response["oauth_token"], token_file_name) click.echo(resp.json())
Создать список Todo
Наш Create Todo List API выглядит так:
### Create a new Todo list POST http://localhost:1234/list/create Authorization: BearerContent-Type: application/json { "name": "Web Repo" }
Давайте добавим функцию под названием Создать
В нашем Cli.py
ниже нашей функции входа
# cli.py @main.command() @click.option('--name', prompt='List name', help='Name for your new todo list') def create(name): """Create a todo list""" # Get access token access_token = tokenhandler.get_token_from_file(token_file_name, api_key)["access_token"] # Construct request url = "https://cottertodolist.herokuapp.com/list/create" headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + access_token} data = { "name": name } response = requests.post(url, json=data, headers=headers) if response.status_code != 200: response.raise_for_status() click.echo("List " + name + " created!")
Вышеуказанная функция берет аргумент под названием --имя
(Это попросит вас о названии списка), затем позвоните в API с нашим токеном доступа. Если вы запустите его, это будет выглядеть так:
❯ python cli.py create List name: Web Repo List Web Repo created!
Добавить задачу в список
Чтобы добавить задачу в список, API выглядит так:
### Create a Task within a list ### name = List name, task = Task name/description POST http://localhost:1234/todo/create Authorization: BearerContent-Type: application/json { "name": "Web Repo", "task": "Update favicon.ico" }
Поскольку пользователь может иметь более одного списка, мы хотим попросить их выбрать, какой список они хотят использовать. Мы можем использовать Pyinquirer Чтобы сделать хорошую подсказку с несколькими вариантами. Сначала установите Pyinquirer:
pip install PyInquirer
Затем добавьте функцию под названием Добавить
В нашем Cli.py
Отказ
# cli.py # Import PyInquirer prompt from PyInquirer import prompt @main.command() def add(): """Create a todo task for a list""" # Get access token from file access_token = tokenhandler.get_token_from_file(token_file_name, api_key)["access_token"] # Get all todo lists for the user url = "https://cottertodolist.herokuapp.com/list" headers = {'Authorization': 'Bearer ' + access_token} response = requests.get(url, headers=headers) lists = response.json() # Prompt to pick list options = map(lambda x: x["name"], lists) questions = [ { 'type': 'list', 'name': 'list_name', 'message': 'Add task to which list?', 'choices': options, }, { 'type': 'input', 'name': 'task_name', 'message': 'Task description', } ] answers = prompt(questions) if not answers: return # Call API to create task fot the selected list url = "https://cottertodolist.herokuapp.com/todo/create" headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + access_token} data = { "name": answers['list_name'], "task": answers['task_name'] } response = requests.post(url, json=data, headers=headers) if response.status_code != 200: response.raise_for_status() click.echo("Task " + answers['task_name'] + " is added in list " + answers['list_name'])
- Во-первых, нам нужно было вызвать API, чтобы переписать все списки Todo для пользователя.
- Первый вопрос имеет
Тип: список
который просит пользователя выбрать, какой список они хотят добавить новую задачу. - Второй вопрос имеет
Тип: ввод
который просит пользователя ввести описание новой задачи. - Используя ответы, мы называем наш API, чтобы добавить задачу в выбранный список.
Показать наши списки Todo
Теперь, когда мы создали список и добавили некоторые задачи, давайте посмотрим список! API, чтобы увидеть список выглядит так:
### Show all lists GET http://localhost:1234/list Authorization: Bearer
Давайте добавим функцию под названием Ls
Чтобы перечислить списки TODO для этого пользователя в cli.py
. Мы применим это правило:
Python Cli.py Ls
спросит вас, какой список вы хотите увидеть, то покажите этот список.Python Cli.py ls -a
Сразу будет отображать все ваши списки.
# cli.py @main.command() @click.option('-a', '--all', is_flag=True) # Make a boolean flag def ls(all): """Show lists""" # Get access token from file access_token = tokenhandler.get_token_from_file(token_file_name, api_key)["access_token"] # Get all lists url = "https://cottertodolist.herokuapp.com/list" headers = {'Authorization': 'Bearer ' + access_token} response = requests.get(url, headers=headers) if response.status_code != 200: response.raise_for_status() listsFormatted = response.json() if all == True: # Show all tasks in all lists for chosenList in listsFormatted: click.echo('\n' + chosenList['name']) for task in chosenList['tasks']: if task['done'] == True: click.echo("[✔] " + task['task']) else: click.echo("[ ] " + task['task']) else: # Show a prompt to choose a list questions = [ { 'type': 'list', 'name': 'list', 'message': 'Which list do you want to see?', 'choices': list(map(lambda lst: lst['name'], listsFormatted)) }, ] answers = prompt(questions) if not answers: return # Get the chosen list chosenList = list(filter(lambda lst: lst['name'] == answers['list'], listsFormatted)) if len(chosenList) <= 0: click.echo("Invalid choice of list") return chosenList = chosenList[0] # Show tasks in the chosen list click.echo(chosenList['name']) for task in chosenList['tasks']: if task['done'] == True: click.echo("[✔] " + task['task']) else: click.echo("[ ] " + task['task'])
- Во-первых, мы получаем все списки Todo для этого пользователя
- Если флаг
-
Указана, то мы переиграем в каждый список и распечатаваем имя списка и задачи вместе с галочкой - Если флаг
-
Не указано, то мы предлагаем пользователю выбрать список, затем мы повторяем задачи для этого выбранного списка и распечатайте задачи с помощью галочки.
Теперь попробуйте! Это должно выглядеть так:
❯ python cli.py ls -a Web Repo [ ] Update favicon.ico [ ] Add our logo to the footer [ ] Add a GIF that shows how our product works Morning Routine [ ] Drink coffee [ ] Grab yogurt [ ] Drink fish-oil
Очевидно, что ни одна из наших задач не выполняется, поскольку мы не сделали функцию, чтобы отметить задачу, как сделано. Давай сделать это следующим.
Проверьте и не проверьте задачу
Мы будем использовать мощный Pyinquire Контрольный список
Тип, чтобы позволить пользователю проверить и не проверить задачи. Наш API для обновления задачи выглядит так:
### Update task set done = true or false by id PUT http://localhost:1234/todo/update/done/274822869038400008 Authorization: BearerContent-Type: application/json { "done": true }
Давайте добавим функцию под названием переключать
нашему Cli.py
Отказ
# cli.py @main.command() def toggle(): """Update tasks in a list""" # Get access token from file access_token = tokenhandler.get_token_from_file(token_file_name, api_key)["access_token"] # Call API to list all tasks url = "https://cottertodolist.herokuapp.com/list" headers = {'Authorization': 'Bearer ' + access_token} response = requests.get(url, headers=headers) if response.status_code != 200: response.raise_for_status() listsFormatted = response.json() # Show a prompt to choose a list questions = [ { 'type': 'list', 'name': 'list', 'message': 'Which list do you want to update?', 'choices': list(map(lambda lst: lst['name'], listsFormatted)) }, ] answers = prompt(questions) if not answers: return # Get the chosen list chosenList = list(filter(lambda lst: lst['name'] == answers['list'], listsFormatted)) if len(chosenList) <= 0: click.echo("Invalid choice of list") return chosenList = chosenList[0] # Show an interactive checklist for the tasks questions = [ { 'type': 'checkbox', 'message': chosenList['name'], 'name': chosenList['name'], 'choices': list(map(lambda task: {'name': task['task'], 'checked': task["done"]}, chosenList['tasks'])), } ] answers = prompt(questions) if not answers: return # Call our Update API for each task in the list # set `done` as True or False based on answers for task in chosenList['tasks']: url = "https://cottertodolist.herokuapp.com/todo/update/done/" + task['id'] headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + access_token} data = { "done": task['task'] in answers[chosenList['name']] } response = requests.put(url, json=data, headers=headers) if response.status_code != 200: response.raise_for_status() click.echo(answers)
- Во-первых, мы называем API списка, чтобы получить все списки для пользователя и пригласить их выбрать список.
- Затем используя Pyinquirer с
Тип: CheckList
Мы можем показать им контрольный список для задач в списке и установить{'Checked': true}
для задач, которые уже сделаны. - Пользователь может использовать
Чтобы выбрать или отменить выбор задачи и нажмите Enter, чтобы обновить задачу.
Похоже, это выглядит:
Давайте посмотрим наш полный список Todo снова:
❯ python cli.py ls -a Web Repo [ ] Update favicon.ico [ ] Add our logo to the footer [ ] Add a GIF that shows how our product works Morning Routine [✔] Drink coffee [✔] Grab yogurt [ ] Drink fish-oil
Потрясающий! Наш ToDo-list CLI сделан!
Конечный результат должен выглядеть так:
Этот пост написан командой в Cotter – Мы строят легкие, быстрое и пароль для входа в систему для веб-сайтов, мобильных приложений, а теперь клиз тоже! Если вы строите веб-сайт, приложение или CLI, у нас есть все инструменты, необходимые для получения потока входа в систему в минутах.
Что дальше?
Это довольно хромает, если ваш пользователь должен всегда звонить Python Cli.py создать
, мы хотим изменить его в TODO CREATE
вместо. Следуйте за Эта статья чтобы узнать, как это сделать.
- Если вы хотите сделать свой собственный API для отдыха в колбе, проверить Исходный код списка TodDo API Что мы только что использовали, как защитить ваши маршруты API с помощью
Access_Token
Отказ Хотите сделать интерфейс для нашего списка Todo, чтобы он был доступен как от терминала, так и в Интернете? Проверьте наши учебные пособия на Реализация того же COTTER Войти в свой React Front End Отказ Это гарантирует, что ваши пользователи могут войти в систему и увидеть тот же список на протяжении всех платформ.
Вопросы и обратная связь.
Приходите и поговорите с основателями Chotter и других разработчиков, которые используют Cotter на Cotter’s Slack Channel Отказ
Готов к использованию Cotter?
Если вам понравилось этот учебник и хотите интегрировать Cotter на свой веб-сайт или приложение, вы можете Создать бесплатный аккаунт и Проверьте нашу документацию Отказ
Если вам нужна помощь, пинг нас на нашем Слабый канал или напишите нам на team@cotter.app Отказ
Оригинал: “https://dev.to/cotter/how-to-make-an-interactive-todo-list-cli-using-python-with-an-easy-login-mechanism-595h”