PYPIを登録し、独自のパッケージを作成


📌 緒論


新しい機能を作成しながらsetupします.pyを使用して初めてPyPIに登録します.PyPIにパッケージとsetupを登録する方法.pyの使い方を復習して、新しい機能を作ってみましょう.

📍Hey突然命令語


ユーザーが$ hey insutance [options]で始まるコマンドを簡単に入力すると、情報を簡単に教えてくれるプロジェクトが行われます.

📌 かいはつ


📍github repoの作成


これらの機能をコアに向上させるために、新しいRepo、「hey-instance」を作成しました.
自分でREAMを書きたくないmd, .gitignoreも追加されました.
TMI)この時,新しい認識が得られた.github repoの名前を自分のIDにすると、次のように秘密を見つける文が出てきます!独自のプロファイルを作成できるようです.

📍ファイル構造

  • ファイル構造(__init__.pyを入れる理由を知りたい場合は、関連記事を参照)
  • hey-insutance
    	├── README.md
    	├── insutance
    	│   ├── __init__.py
    	│   ├── answer.py
    	│   ├── command.py
    	│   ├── main.py
    	└── setup.py

    📍argparse検索コマンドの使用


    [注]argparse document
    # hey-insutance/insutnace/command.py
    import argparse
    
    class CommandParser:
      def __init__(self) -> None:
        self.parser = argparse.ArgumentParser(prog="hey")
        self.subparser = self.parser.add_subparsers(
            dest="my_name",
            help="write my name"
        )
    
      def get_args(self) -> argparse.Namespace:
        insutance_parser = self.subparser.add_parser(
            "insutance",
            help="what do you want to know about me?"
        )
        options_group = insutance_parser.add_mutually_exclusive_group(required=True)
        options_group.add_argument("--name", action="store_true", help=f"이름이 뭔가요?")
        options_group.add_argument("--age", action="store_true", help=f"몇 살이에요?")
    
        return self.parser.parse_args()
    [subsparserを作成した理由]$ hey insutance [options]命令でinsutance部分を固定したいのでサブparserが生成される.もちろん,subsparserはなく,パラメータとしてargs.my_name == "insutance"を生成できるが,対応する分岐文を記述したくないためsubsparserを生成する.
    [option group作成理由]insutance_parserオプションを組み合わせます.required=Trueの値をスケーリングすると、次のオプション値のうち少なくとも1つが必要になります.なければ、エラーが発生します.また、重複する値があるとエラーが発生します.
    [オプションが正しく適用されていることを確認する方法]
    $ python insutance/command.py insutance --help

    📍質問に答える機械人間を作成する

    $ hey insutnace --nameというように質問すると、答えを出す必要があります.答えをprint文に簡単に出力するクラスがあり、以下のAnswerBotクラスを生成したほうがいいと思います.
    # hey-insutance/insutance/answer.py
    import time
    
    class AnswerBot:
      def print_answer_slowly(self, answer) -> None:
        for answer in answer.split("\n"):
          print(answer.strip())
          if answer.strip() != "":
            time.sleep(1)
    
      def print_my_name(self) -> None:
        answer = """
          제 이름은 insutance 에요:)
          그 외에도 다른 닉네임으로도 활동하고 있어요!
          '최낙타', 'camellionchild'
    
          저의 본명은 알려드리지 않을거에요!
        """
        self.print_answer_slowly(answer)
    
      def print_my_old(self) -> None:
        answer = """
          제 나이가 궁금하시군요!
          몇 살처럼 보이나요 ?!
    
          제 나이는 ..!
          두구두구두구두구두구두구두구두구두구두구두구....
    
          비밀~!
          생일만 알려드릴게요!
          저의 생일은 11월 11일 빼빼로데이 입니다!      
        """
        self.print_answer_slowly(answer)

    📍 本文を書く


    すべてのタスクを実行するために、本文にコードが記述されています.
    なぜmain文で実行するのですか?setup.pyを作成するときに便利だと思いますが、main()関数を見るだけでどのような機能を実現するか簡単に理解できます.
    # hey-insutance/insutance/main.py
    from insutance.answer import AnswerBot
    from insutance.command import CommandParser
    
    def main():
      args = CommandParser().get_args()
      answerbot = AnswerBot()
    
      if args.name:
        answerbot.print_my_name()
      elif args.age:
        answerbot.print_my_old()

    📍 setup.pyの作成


    本規格で提供されるsetuptoolsを用いて以下に記述する.(Null値の部分は削除できます.)
    # hey-insutance/setup.py
    from setuptools import setup, find_packages
    
    setup(
        name="insutance",   # pypi 에 등록할 라이브러리 이름
        version="0.0.1",    # pypi 에 등록할 version (수정할 때마다 version up을 해줘야 함)
        description="Hey insutance! Who are you?",
        author="insutance",
        author_email="[email protected]",
        url="https://github.com/insutance/hey-insutance",
        python_requires=">= 3.8",
        packages=find_packages(),
        install_requires=[],
        zip_safe=False,
        # 중요한 부분
        entry_points={
            "console_scripts": [
                "hey = insutance.main:main"
            ]
        },
        package_data={},
        include_package_data=True
    )
    ここで重要な部分はentry_points部分です.$ hey insutance [options]のように$ heyで始まるはずです.上記の「オプションがうまく適用されるようにする方法」の項では、Pythonコマンドを使用して実行する方法を変更できます.
    entry_points={
        "console_scripts": [
            # hey라는 명령어를 입력하면 insutance/main 에 있는 main() 함수를 실행시켜줘! 
            "hey = insutance.main:main"
        ]
    }
    # before
    $ python insutance/command.py insutance --help
    
    # after, entry_points 설정 후
    $ hey insutance --help
    [試験方法]
    setup.pyファイルの作成が完了し、$ heyコマンドを使用してテストする場合は、以下のコマンドを入力してpipインストールする必要があります.
    $ python setup.py install
    このコマンドを実行すると、builddistinsutance.egg-infoのフォルダが生成されます.また、$ pip listを運転するとsetupします.pyがnameセクションで作成した値は、versionセクションで作成した値として出力されることがわかります.

    コマンドを入力すると、以下のように自分で設定したオプションが表示されます.

    📌 登録


    📍会員収入


    アカウントのパスワードがなければ、https://pypi.org/account/register/のサイトに会員登録することができます.

    📍パッケージ名の重複を確認


    https://pypi.org/は、このサイトで重複するパッケージ名があるかどうかを確認します.(パッケージ名はsetup.pyでnameの値です.)
    Tip)検索時には出ないかもしれません.ない方法を確認してURLで確認すればいいです.https://pypi.org/project/{package_name}/が検索されなければ、本当にありません.

    📍 必要なパッケージのインストールと構築


    既に会員に加入しており、パッケージ名も重複していない場合は、今からpypiに登録しましょう.
    まず、pypi登録に必要なパッケージをインストールします.
  • setup.pyファイルで使用されるsetuptools
  • バージョンのwheel
  • 導入時に使用されるtwine
  • # setuptools는 기본으로 내장되어 있음. 없다면 설치
    $ pip install setuptools
    $ pip install wheel
    $ pip install twine
    前に作成したsetup.pyからパッケージの構築を始めましょう.
    # setup.py 파일이 있는 경로에서 아래 명령어 실행.
    $ python setup.py bdist_wheel

    📍登録


    上のコマンドを入力して、次のフォルダが作成されていることを確認します.
  • build
  • {packagename}.egg-info
  • dist
  • 作成された場合は、distフォルダ内のファイル名をコピーします.(拡張子を含め、.whlが生成される場合があります.)ファイル名をコピーしたら、次のコマンドを実行します.
    $ twine upload dist/{확장자를 포함한 파일 이름}
    
    # example
    $ twine upload dist/insutance-0.0.1-py3-none-any.whl
    コマンドを入力すると、自分のusernameとpasswordを入力するよう求められます.pypiの会員が入力したusernameとpasswordを入力すればいいです.
    [Pypi登録完了画面]

    📍パッケージの確認


    上記の部分が完了したら、pypiで検索すると、自分が作成したパッケージが登録されているのが見えます.(時間がかかるかもしれません)