간단한 로그인 메커니즘이 있는 Python을 사용하여 대화식 대기사항 목록 CLI를 만드는 방법

52693 단어 pythontutorialsecurity
Python으로 Click, PyInquirer, Cotter 등의 패키지를 사용하여 몇 분 안에 Todo List CLI를 구축할 수 있습니다!
멋진 CLI를 구축하는 데 도움을 줄 수 있는 좋은 패키지가 많습니다. 이 중 일부 패키지는 Building Beautiful Command Line Interfaces with Python을 소개합니다.
이 중 일부 도구를 사용하여 대화식 대기사항 목록 CLI를 만듭니다.

API


우리는 대기사항 목록을 저장하고 업데이트하는 데 도움을 주기 위해 기존의 RESTAPI를 사용할 것이다.API는 https://cottertodolist.herokuapp.com/에서 액세스할 수 있으며 Github Repo에서 소스 코드와 문서를 찾을 수 있습니다.

CLI


CLI를 만들기 위해 몇 가지 패키지를 사용합니다.
  • CLI 기능 및 팁: ClickPyInquirer
  • 인증: Cotter
  • Cotter's Github에서 이 강좌의 전체 코드를 가져오십시오.

    초간단 CLI부터 시작하겠습니다.


    프로젝트 디렉터리에서 virtualenv을 먼저 만듭니다.
    python -m venv venv/
    
    그런 다음 source 명령을 사용하여 가상 환경을 활성화합니다.
    source venv/bin/activate
    
    이제 click을 설치하여 간단한 cli:
    pip install click
    
    그런 다음 CLI에 대한 파일을 생성합니다. 이 파일을 cli.py이라고 명명하고 간단한 greet 명령을 생성합니다.
    # 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
    

    이제 업무 목록 CLI를 구축합니다.


    우리 Todo List API documentation을 검사합시다.모든 목록을 표시하는 예제 요청은 다음과 같습니다.
    ### Show all lists
    GET http://localhost:1234/list
    Authorization: Bearer <access_token>
    
    
    보시다시피 저희 API는 access_token이 필요합니다. 소유자만 대기사항 목록을 보고 업데이트할 수 있도록 합니다.

    사용자 등록 / 로그인 API부터


    우리가 해야 할 첫 번째 일은 사용자를 검증하고 Todo 목록 API에 등록하는 것이다.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"
        }
    }
    
    이를 위해, 우리는 Cotter의 Python SDK를 사용하여 oauth_tokens을 생성한 다음 이를 대기사항 목록 API로 보낼 것입니다.
    Cotter로 로그인
    먼저 다음 도구를 사용하여 오버헤드를 설치합니다.
    pip install cotter
    
    그런 다음 cli.py을 업데이트하여 로그인 함수를 추가합니다.
    # cli.py
    import click
    import os
    import cotter
    
    # 1️⃣ Add your Cotter API KEY ID here
    api_key = "<COTTER_API_KEY_ID>"
    
    @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()
    
    Cotter에서 제공하는 API_KEY_ID이 필요합니다. Dashboard에서 얻을 수 있습니다.
    SDK 설명에 따르면 프로젝트 디렉터리에는 cotter_login_success.html이라는 HTML 파일이 더 필요합니다.Github의 SDK 예제 폴더에서 cotter_login_success.html 을 복사합니다.프로젝트 폴더에 두 개의 파일이 포함되어야 합니다.
    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에 사용자 등록 또는 로그인


    우선 HTTP 요청을 호출하는 요청을 설치해야 합니다.
    pip install requests
    
    logincli.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을 쉽게 저장하고 얻을 수 있는 함수를 제공했다.
    응답하기 전에 영패를 저장하고 login 함수를 업데이트합니다.
    # 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()) 
    

    대기사항 목록 만들기


    당사의 작성 대기사항 목록 API는 다음과 같습니다.
    ### Create a new Todo list
    POST http://localhost:1234/list/create
    Authorization: Bearer <access_token>
    Content-Type: application/json
    
    {
        "name": "Web Repo"
    }
    
    로그인 함수 아래 createcli.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!")
    
    위의 함수는 --name이라는 매개 변수를 받아들여서 (목록의 이름을 물어볼 것입니다) 우리의 접근 영패를 사용하여 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: Bearer <access_token>
    Content-Type: application/json
    
    {
        "name": "Web Repo",   
        "task": "Update favicon.ico"
    }
    
    사용자가 여러 개의 목록을 가지고 있을 수 있기 때문에, 우리는 그들이 사용할 목록을 선택하기를 희망합니다.우리는 PyInquirer을 사용하여 여러 가지 옵션을 통해 좋은 힌트를 만들 수 있다.먼저 PyInquirer를 설치합니다.
    pip install PyInquirer
    
    그리고 addcli.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를 호출하여 사용자에게 모든 업무 목록을 열거해야 한다.
  • 의 첫 번째 문제는 type: list입니다. 사용자에게 새로운 작업을 추가할 목록을 선택하도록 요구합니다.
  • 두 번째 문제는 type: input입니다. 사용자에게 새로운 작업에 대한 설명을 입력하도록 요구합니다.
  • 은 선택한 목록에 작업을 추가하기 위해 API를 호출합니다.

  • 작업 목록 표시


    현재 우리는 목록을 만들고 작업을 추가했습니다. 목록을 봅시다!목록을 보는 API는 다음과 같습니다.
    ### Show all lists
    GET http://localhost:1234/list
    Authorization: Bearer <access_token>
    
    ls이라는 함수를 추가하여 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'])
    
    
  • 우선, 우리는 이 사용자의 모든 업무 목록을 얻었습니다.
  • 로고 -a을 지정하면 모든 목록, 인쇄 목록 이름과 작업, 체크 표시
  • 로고 -a이 지정되어 있지 않으면 사용자에게 목록을 선택하라고 알려주고 선택한 목록의 작업을 교체하고 체크 표시로 출력합니다.
  • 지금 해봐!그것은 마땅히 이렇게 해야 한다.
    ❯ 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
    
    분명히 우리의 임무는 완성되지 않았습니다. 왜냐하면 임무를 완성된 함수로 표시하는 함수를 만들지 않았기 때문입니다.우리 다음에 이렇게 합시다.

    작업 확인 및 취소


    PyInquirer의 강력한 checklist 유형을 사용하여 사용자가 검사 작업을 확인하고 취소할 수 있도록 합니다.작업을 업데이트하는 API는 다음과 같습니다.
    ### Update task set done = true or false by id
    PUT http://localhost:1234/todo/update/done/274822869038400008
    Authorization: Bearer <access_token>
    Content-Type: application/json
    
    {
        "done": true
    }
    
    togglecli.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를 호출하여 사용자에게 모든 목록을 가져오고 목록을 선택하라고 알립니다.
  • 그리고 type: checklist이 있는 PyInquirer를 사용하면 목록에 있는 작업의 검사표를 표시하고 완료된 작업에 {'checked': True}을 설정할 수 있습니다.
  • 사용자는 <space>을 사용하여 작업을 선택하거나 취소한 다음enter 키를 누르면 작업을 업데이트할 수 있습니다.
  • 보아하니 이렇다.

    전체 업무 목록을 다시 한 번 살펴보겠습니다.
    ❯ 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
    

    경탄했어우리의 대기사항 목록 CLI 완료!


    최종 결과는 다음과 같습니다.

    이 글은 팀이 Cotter에 쓴 것입니다. 저희는 사이트, 모바일 응용 프로그램, 그리고 현재의 CLIs를 위해 경량급, 신속, 비밀번호 없는 로그인 솔루션을 구축하고 있습니다!웹 사이트, 응용 프로그램 또는 CLI를 구축하는 경우 몇 분 안에 로그인 흐름을 설정하는 데 필요한 모든 도구를 제공합니다.

    다음은 뭐예요?


    만약 당신의 사용자가 항상 python cli.py create으로 전화를 하려고 한다면 큰일입니다. 우리는 todo create으로 바꾸고 싶습니다.this article에 따라 이 점을 어떻게 하는지 알아보세요.
  • 플라스크에서 REST API를 만들려면 the source code of the Todo List API을 보십시오. access_token을 사용하여 API 루트를 보호하는 방법을 알아보았습니다.
    터미널과 웹에서 접근할 수 있도록 업무 목록을 작성하고 싶으십니까?implementing the same Cotter Login to your React front end에서 우리의 강좌를 보십시오.이것은 사용자가 로그인하여 두 플랫폼에서 같은 목록을 볼 수 있도록 확보한다.
  • 질문과 피드백


    Cotter의 창시자와 Cotter's Slack Channel에서 Cotter를 사용하는 다른 개발자와 이야기해 봅시다.

    지출을 사용할 준비가 되었습니까?


    이 강좌를 좋아하고 Cotter를 웹 사이트나 응용 프로그램에 통합하려면 create a free accountcheck out our documentation을 사용할 수 있습니다.
    도움이 필요하시면 Slack channel으로 전화하거나 [email protected]으로 이메일을 보내주십시오.

    좋은 웹페이지 즐겨찾기