January 23, 2022
최근 python 패키지를 pypi 에 배포해본 경험을 공유하려고 합니다.
약간의 튜토리얼식으로 작성했으니 따라해보시는걸 추천해드립니다!
제가 배포한 패키지는 rcs-pydantic 입니다.
간단한 구조이니 튜토리얼을 따라하기 귀찮으시면 fork
받으셔서 이것저것 살펴보시면 되겠습니다.
패키지 배포를 좀 더 간편하게 하기 위해서 poetry
를 설치해야 합니다
python -m pip install poetry
다음 명령어를 통해서 프로젝트를 생성합니다. 프로젝트 이름은 임의로 poetry-demo 라고 정했습니다.
poetry new poetry-demo
다음과 같은 폴더구조가 생성됩니다.
poetry-demo
├── pyproject.toml
├── README.rst
├── poetry_demo
│ └── __init__.py
└── tests
├── __init__.py
└── test_poetry_demo.py
함께 생성된 pyproject.toml 에는 이전글 에서 설명했던 것처럼 시스템 요구사항이 포함되어 있습니다.
pep518
이 등장하기 전 생성되었던 패키지들은 대부분 setup.py
, setup.cfg
에 정의되어있습니다.
이제 poetry 에서는 2021년 3월 1일에 최종적으로 승인된 메타데이터에 관한 제안 pep621과 pep631 에 대한 논의가 이루어지고 있습니다.
아직 논의가 마무리 되지 않은 현재 시점에서 pep621
을 공식적으로 지원하는 파이썬 패키지 관리 툴은 pdm 과 flit 이 있습니다.
우리는 poetry
를 사용할 것이지만 flit
에 대해서도 살펴 보는 것을 권장합니다.
poetry
가 pep621
를 공식적으로 지원하는지는 여기 로드맵에서 확인할 수 있습니다.
배포하기 위해서는 pypi.org 에 회원가입을 먼저 해야합니다.
회원가입후 이메일 인증까지 받으면! 이제 배포 준비가 완료되었습니다.
다음 명령어로 배포를 시작해보겠습니다.
poetry publish --build
아까 가입한 pypi 의 이름과 비밀번호를 입력하고 나면 다음과 같이 실제 pypi.org 패키지 서버에 배포된 것을 확인할 수 있을 것 입니다.
동일한 이름의 패키지 배포가 불가능하니 각자 프로젝트의 이름과 버전을 다르게 설정해주세요 🙃
poetry-demo 이름으로 올라온 패키지가 만개 이상…😱
내가 올린 패키지를 import 해서 사용해보기 위해서 간단한 코드를 작성해보겠습니다.
패키지 이름이 poetry-demo 라는 가정하에, main.py 를 생성하면 다음과 같은 구조가 됩니다.
poetry-demo
├── pyproject.toml
├── README.rst
├── poetry_demo
│ ├── __init__.py
│ └── main.py # 방금 생성한 파일└── tests
├── __init__.py
└── test_poetry_demo.py
main.py 에 간단한 코드를 작성해보겠습니다.
def sum_a_and_b(a: int, b: int) -> int:
return a + b
지금과 같이 배포하면 다른 프로젝트에서 내 코드를 다음과 같이 사용할 수 있게 됩니다.
from poetry_demo import main
main.sum_a_and_b(1,2)
그런데 지금껏 다른 프로젝트에서는 main 없이 from poetry_demo import sum_a_and_b
이런식으로 사용하셨을겁니다.
이렇게 만들도록 하기 위해서 __init__.py
에 다음과 같이 작성합니다.
# flake8: noqa
from .main import *
__all__ = [
"sum_a_and_b",
]
__version__ = "0.1.0"
이제 다음과 같이 사용할 수 있게 되었습니다.
from poetry_demo import sum_a_and_b
sum_a_and_b(1,2)
이제 파이썬 패키지를 손수 배포해봤으니 github action 을 통해서 자동으로 릴리즈 해보도록 하겠습니다.
다음과 같이 publish.yml 파일을 생성합니다.
poetry-demo
├── .github
│ └── workflows
│ └── publish.yml # 방금 생성한 파일
├── pyproject.toml
├── README.rst
├── poetry_demo
│ ├── __init__.py
│ └── main.py
└── tests
├── __init__.py
└── test_poetry_demo.py
publish.yml 파일을 다음과 같이 작성합니다.
name: Publish
on:
release:
types:
- created
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.7'
- uses: actions/cache@v2
id: cache
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish
- name: Install poetry
if: steps.cache.outputs.cache-hit != 'true'
run: pip install poetry
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: poetry install
- name: Publish
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
run: poetry publish --build
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
pypi 에 토큰으로 배포하기 위해서 토큰 발행이 필요합니다.
https://pypi.org/manage/account/ 에 방문해서 Add API token
버튼을 눌러서 토큰을 발행하면 다음과 같이 토큰이 생성됩니다.
이제 github repository settings > Secrets > New repository secret
에 들어가서 발급받은 키를 PYPI_TOKEN
값에 작성해줍니다.
이제 준비가 모두 끝났습니다
본인의 레파지토리 주소 github.com/username/repo-name 에 들어가서 새로운 릴리즈를 생성할 수 있습니다.
아래처럼 Create a new release 를 누릅니다.
다음과 같이 프로젝트에서 사용한 태그를 입력하고 엔터를 누르면 새로운 태그가 생성됩니다.
릴리즈 타이틀을 입력하고 publish release 를 하면 새로운 액션이 생성되며 동작하게 됩니다.
동작이 완료되면 https://pypi.org 에서 본인이 생성한 패키지를 찾을수 있고 pip install
을 통해서 다운로드 할 수 있습니다.
지금까지는 남이 올려놓은 오픈소스만 사용하다가 처음으로 내가 만든 오픈소스를 배포해보았습니다.
생각보다 간단했고, 내가 자주 사용하던 오픈소스들도 생각보다 어렵게 구현되지 않은 경우가 대부분이었습니다.
오픈소스에 기여한다는것이 멀고 어렵게 느껴졌었지만 이렇게 한발 더 다가가게 되었습니다.
여러분도 자신만의 패키지를 배포해서 오픈소스에 한발 더 다가가 보는건 어떨까요?