Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 패키지 만들고 PyPI에 배포하는 완벽 가이드

파이썬은 패키지를 만들고 외부에 게시하는 과정을 매우 간단하게 처리할 수 있도록 다양한 도구를 제공합니다. 이 글에서는 직접 만든 파이썬 모듈을 하나의 패키지로 묶고, PyPI(Python Package Index)에 업로드하여 전 세계 누구나 설치할 수 있게 만드는 전체 과정을 단계별로 살펴보겠습니다.

파이썬 패키지 관리 도구

파이썬의 패키지 관리는 여러 도구를 통해 이루어지며, 그중 핵심적인 두 가지는 다음과 같습니다.

  • pip — 파이썬 패키지 관리의 표준 도구입니다. 운영체제에 패키지를 수동으로 설치하거나 업데이트할 필요가 거의 없어 선호되는 선택지입니다. 패키지 목록과 해당 버전 정보를 체계적으로 관리하기 때문에, 별도의 독립된 환경에서 동일한 패키지 구성을 정확하게 재현할 수 있습니다.
  • PyPI(Python Package Index) — 사용자가 직접 올린 패키지들이 모여 있는 공개 저장소입니다. pip install 패키지명 명령어 한 줄로 이곳의 패키지를 손쉽게 설치할 수 있습니다.

1단계: 업로드할 패키지 준비하기

이미 배포할 준비가 된 패키지가 있다면 바로 다음 단계로 넘어가도 됩니다. 아직 없다면 아래 절차에 따라 아주 간단하게 파이썬 모듈과 패키지를 먼저 만들어 보세요.

모듈 만들기

먼저 자신의 코드를 담은 파이썬 파일을 생성합니다. 파일 이름을 myFirstPackage.py처럼 지정하세요. 이 파일 하나가 곧 '모듈'입니다. 데이터와 함수가 담긴 파일이므로 다른 곳에서 import하여 사용할 수 있습니다.

모듈을 패키지로 만들기

모듈을 패키지로 만드는 방법은 의외로 간단합니다. 디렉터리 안에 비어 있는 __init__.py 파일만 추가하면 됩니다.

echo >> __init__.py

또는 touch 명령어를 사용해도 됩니다.

touch __init__.py

디렉터리를 확인해 보면 다음과 같이 두 개의 파일이 들어 있는 것을 볼 수 있습니다.

$dir
Volume in drive C has no label.
Volume Serial Number is 8CD6-8D39

Directory of c:\Python\Python361\firstPackage

08-04-2019 05.44 PM <DIR> .
08-04-2019 05.44 PM <DIR> ..
08-04-2019 02.25 PM    47 myFirstPackage.py
08-04-2019 05.44 PM    13 __init__.py

firstPackage 디렉터리 안에 두 개의 파일이 존재하는 것을 확인할 수 있습니다. 즉, __init__.pymyFirstPackage.py 두 파일을 담고 있는 디렉터리 하나가 바로 '패키지'가 되는 것입니다.

2단계: 프로젝트 패키징 준비

본격적으로 패키징 작업을 하려면 샘플 프로젝트를 클론하여 자신의 모듈 이름으로 폴더를 지정합니다.

git clone https://github.com/pypa/sampleproject firstPackage

클론한 프로젝트에는 패키징에 중요한 역할을 하는 파일들이 포함되어 있습니다.

  • setup.py — 프로젝트 설정 정보를 지정하고 패키징 관련 명령을 실행할 수 있게 해주는 핵심 파일입니다. 예를 들어 python setup.py --help 명령어로 사용 가능한 옵션을 확인할 수 있습니다.
  • setup.cfg — setup.py 명령어들의 기본 옵션값을 담고 있는 INI 형식의 설정 파일입니다.
  • README.rst(또는 README.md) — reStructuredText나 마크다운 형식으로 프로젝트의 목적과 사용법을 설명하는 문서입니다.

이제 새로 만든 폴더 안에 자신의 모듈 파일을 복사하고, 기존의 "sample" 모듈은 삭제합니다. 최종적인 폴더 구조는 다음과 같습니다.

└───firstPackage
│ LICENSE.txt
│ MANIFEST.in
│ myFirstPackage.py
│ README.md
│ setup.cfg
│ setup.py
│ tox.ini
│ __init__.py

3단계: 패키지 이름, 버전, 설명 설정하기

setup.py 파일을 열어 자신의 파이썬 패키지에 대한 기본 정보를 입력합니다.

setup.py 예시

import setuptools

with open("README.md", "r") as fh:
long_description = fh.read()

setuptools.setup(
name="firstPackage",
version="0.0.1",
author="Rajesh Joshi",
author_email="callraj.joshi@gmail.com",
description="my First Package",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
)

각 항목의 의미는 다음과 같습니다. name은 PyPI에서 검색될 패키지 이름이고, version은 배포 버전입니다. description은 짧은 요약, long_description에는 README 내용이 들어가며 PyPI 페이지 상세 설명으로 표시됩니다. classifiers는 지원 언어 버전, 라이선스 종류, 호환 운영체제 등을 분류해 주는 메타데이터입니다.

라이선스 파일(LICENSE.txt)

라이선스 파일은 MIT 라이선스 기준으로 다음과 같이 작성할 수 있습니다.

MIT License

Copyright (c) [2019] [firstPackage]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md 작성

README는 패키지 소개와 사용 방법을 간결히 담으면 됩니다.

## firstPackage
This is a sample package to learn the steps of creating and publishing package.

4단계: 실제 빌드(패키징) 진행하기

먼저 작업 환경에 setuptools와 wheel 패키지를 설치하거나 최신 버전으로 업데이트합니다.

>pip install wheel twine setuptools --upgrade

소스 배포판(sdist) 생성

첫 번째로 소스 배포판(source distribution)을 만듭니다. 이 형태의 배포판은 pip으로 설치할 때 빌드 과정이 한 번 더 필요합니다.

>python setup.py sdist

휠(wheel) 배포판 생성

다음으로 '휠(wheel)'이라 불리는 빌드된 패키지를 생성합니다. 휠은 소스 배포판보다 설치 속도가 훨씬 빠르기 때문에 함께 배포하는 것이 좋습니다.

>python setup.py bdist_wheel

빌드가 성공적으로 끝나면 firstPackage 폴더 안의 dist 디렉터리에서 setup.py와 나란히 압축된 패키지 파일들을 확인할 수 있습니다.

5단계: 로컬 환경에서 패키지 테스트하기

배포 전에 패키지가 제대로 설치되는지 확인하는 것이 좋습니다. 임의의 다른 위치에 새 가상 환경(virtual environment)을 만들고 활성화합니다.

c:\Users\rajesh>virtualenv myPackage
Using base prefix 'c:\\python\\python361'
New python executable in c:\Users\rajesh\myPackage\Scripts\python.exe
Installing setuptools, pip, wheel...done.

c:\Users\rajesh\myPackage>.\Scripts\activate

(myPackage) c:\Users\rajesh\myPackage>

그런 다음 앞서 만든 압축 파일(tar.gz)을 새 환경에 설치합니다.

>pip install firstPackage-0.0.1.tar.gz

설치가 정상적으로 완료되었는지 확인하려면 pip list 명령어로 현재 환경에 설치된 전체 패키지 목록을 출력해 봅니다.

>pip list
Package      Version
------------ -------
firstPackage  0.0.1
pip           19.0.3
setuptools    41.0.0
wheel         0.33.1

목록에 firstPackage 0.0.1이 보이면 패키지가 정상적으로 설치된 것입니다.

6단계: PyPI에 패키지 게시하기

이제 패키지를 PyPI에 업로드하여 공개할 차례입니다. 먼저 setup.py 파일이 있는 경로로 이동한 뒤, twine 패키지를 설치하거나 최신 버전으로 업데이트합니다. twine은 PyPI에 안전하게 패키지를 업로드해 주는 공식 도구입니다.

>pip install --upgrade twine

마지막으로 twine 명령어를 사용해 dist 디렉터리 안의 배포 파일 전체를 PyPI에 업로드합니다.

>twine upload dist/*
Enter your username: callraj.joshi
Enter your password:
Uploading distributions to https://upload.pypi.org/legacy/
Uploading firstPackage-0.0.1-py2.py3-none-any.whl
…

PyPI 계정의 사용자 이름과 비밀번호를 입력하면 업로드가 자동으로 시작됩니다. 참고로 요즘은 비밀번호 대신 API 토큰을 사용하는 것이 권장되므로, twine 업로드 시 username에 __token__, password에 API 토큰 값을 입력하는 방식도 활용해 보세요.

업로드가 완료되면 https://pypi.org/project/firstPackage/ 같은 주소에서 자신의 패키지 페이지를 확인할 수 있고, 이후 누구나 pip install firstPackage 명령어로 설치할 수 있게 됩니다.

마무리

지금까지 파이썬 모듈 만들기부터 __init__.py 추가, setup.py 작성, sdist와 wheel 빌드, 가상 환경 테스트, 그리고 twine을 통한 PyPI 배포까지 전 과정을 살펴보았습니다. 처음에는 단계가 많아 보이지만 한 번 익혀두면 이후에는 몇 개의 명령어만으로 반복해서 배포할 수 있습니다. 자신만의 유용한 코드를 패키지로 만들어 오픈소스 생태계에 기여해 보세요.