파이썬 패키지 만들기: 협업을 위한 코드 모듈화
소개
협업 프로젝트에서 우리가 만든 코드를 다른 팀에서 쉽게 사용할 수 있도록 패키지화하는 방법에 대해 알아보겠습니다. 이를 통해 pip install package_name
형태로 간편하게 설치하고 사용할 수 있는 패키지를 만들 수 있습니다.
# 사전 설치
pip install setuptools
패키지 구조 만들기
package_name/
├── package_name/
│ ├── __init__.py
│ └── function.py
├── README.md
├── requirements.txt
└── setup.py
패키지 구조 설명
위의 패키지 구조는 Python 패키지를 만들기 위한 기본적인 틀입니다. 각 파일과 디렉토리가 어떤 역할을 하는지 하나씩 살펴보겠습니다.
package_name/
: 최상위 디렉토리로, 패키지의 이름을 따서 만듭니다. 이 디렉토리 안에 실제 코드가 들어갑니다.package_name/__init__.py
: 이 파일은 패키지를 초기화하는 역할을 합니다. 이 파일이 있어야 Python이 이 디렉토리를 패키지로 인식합니다. (__version__ 을 통해 버전명을 명시해주는게 관례라고 합니다. 추후 버전 업데이트 이후에는 set.py와 version 명이 서로 같겠끔 같이 업데이트 해줍니다.)package_name/function.py
: 여기에 실제로 사용할 함수나 클래스를 정의합니다. 예를 들어, 간단한 함수 하나를 정의해보겠습니다.setup.py
: 이 파일은 패키지를 배포하고 설치하는 데 필요한 정보를 담고 있습니다.setup.py
파일의 예시는 다음과 같습니다.
from setuptools import setup, find_packages
setup(
name="package_name", # 패키지 이름
version="0.1.0", # 버전
description="A short description of your package", # 패키지 설명
author="Your Name", # 작성자
author_email="your.email@example.com", # 작성자 이메일
url="https://github.com/username/package_name", # 깃허브 저장소 URL
packages=find_packages(), # 패키지 찾기
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.6", # Python 버전 요구사항
install_requires=[ # 의존성 패키지 목록
"numpy>=1.19.0",
"pandas>=1.1.0",
],
)
이 setup.py
파일은 패키지의 메타데이터와 의존성을 정의합니다. 주요 항목들은 다음과 같습니다:
name
:pip
가 참조하는 패키지 이름version
: 패키지 버전author
,author_email
: 작성자 정보description
: 패키지에 대한 간단한 설명url
: 프로젝트 사이트 주소 (대부분 깃헙 주소를 사용한다.)download_url
: 소스 배포판의 다운로드 URL을 지정packages
: 패키지에 포함하거나 제외할 파일들을 선택하는 설정classifiers
: 패키지의 메타데이터를 분류하는 태그들로, Python 버전, 라이선스, 운영체제 등의 정보를 포함python_requires
: 패키지가 요구하는 최소 Python 버전을 지정package_data
: 기본적으로setup
은 파이썬 파일만 빌드에 포함시킨다. 파이썬 파일이 아닌 데이터 파일들(예: JSON, HTML, CSS 등)을 패키지에 포함시키기 위한 옵션이다.zip_safe
: 패키지가 ZIP 형식으로 설치되어도 안전한지를 나타내는 플래그, 일반적으로 package_data를 사용할 경우 False로 지정하고, 평소에도 False가 권장됩니다. (C 확장 모듈이 있는 경우, 런타임에 리소스 파일이 접근해야하는 경우, 패키지가 동적으로 파일을 찾아야하는 경우 False로 설정해야 합니다.)install_requires
: 패키지가 의존하는 다른 패키지들의 목록. pip install할 때, 여기에 나열된 라이브러리들을 같이 설치 합니다.
- package_data 사용 예)
더보기
setup(
...
package_data={
'my_package': [
'data/*.json', # my_package/data/ 안의 모든 JSON 파일
'templates/*.html', # my_package/templates/ 안의 모든 HTML 파일
'static/css/*.css', # my_package/static/css/ 안의 모든 CSS 파일
],
},
)
find_packages()
는 setuptools에서 제공하는 함수로, 프로젝트 디렉토리 내의 모든 Python 패키지를 자동으로 찾아주는 유틸리티입니다. 이 함수는 다음과 같은 특징을 가집니다:
__init__.py
파일이 있는 모든 디렉토리를 패키지로 인식합니다.- 재귀적으로 하위 디렉토리까지 검색하여 모든 패키지를 찾습니다.
- 특정 디렉토리나 패키지를 제외하고 싶을 때는
exclude
파라미터를 사용할 수 있습니다.
만약 find_packages()
를 사용하지 않는다면, 일일히 list로 넣어주어야 합니다.
- exclude 옵션을 사용했을 때의 예)
더보기
from setuptools import setup, find_packages
setup(
name='your-package',
version='1.0.0',
packages=find_packages(exclude=[
'tests', # 테스트 디렉토리 제외
'tests.*', # 테스트 패키지의 모든 하위 패키지 제외
'*.tests', # 모든 패키지의 tests 서브패키지 제외
'*.tests.*', # tests 서브패키지의 모든 하위 패키지 제외
'docs', # 문서 디렉토리 제외
]),
)
- setup.py의 ext_modules 파라미터를 사용하면 C나 C++로 작성된 확장 모듈을 패키지에 포함시킬 수 있습니다.
가이드 문서 참조: https://docs.python.org/ko/3.11/distutils/setupscript.html
패키지 설치하기
로컬 설치 ( w/ Git Clone)
# 패키지 디렉토리에서 pip install .
- 패키지를 site-packages 디렉토리에 복사하여 설치합니다.
# 패키지 디렉토리에서 pip install -e .
- 패키지가 site-packages 디렉토리에 현재 위치에 대한 심볼릭 링크를 생성합니다.
- 실제 코드는 원본 위치에 있게 됩니다.
- 실시간으로 패키지에 대한 수정이 반영되는 효과가 있습니다. -> 개발 중인 패키지를 테스트할 때, 유리합니다.
로컬 설치 ( w/o Git Clone)
- https를 통한 설치
- 별도의 인증 설정이 불필요한 설치 방법 입니다.
- github 계정에 대한 인증만 해주면 됩니다.
# 기본 설치
pip install git+https://github.com/username/repo.git
# 특정 브랜치 설치
pip install git+https://github.com/username/repo.git@develop
# 특정 태그 설치
pip install git+https://github.com/username/repo.git@v1.0.0
# 특정 커밋 설치
pip install git+https://github.com/username/repo.git@ad21f2c
- ssh를 통한 설치
- private 저장소 접근에 적합합니다.
- SSH 키 기반 인증 입니다. (feat. ssh-keygen)
# 기본 설치
pip install git+ssh://git@github.com/username/repo.git
# 특정 브랜치
pip install git+ssh://git@github.com/username/repo.git@branch_name
# 특정 태그
pip install git+ssh://git@github.com/username/repo.git@v1.0.0
# 특정 커밋
pip install git+ssh://git@github.com/username/repo.git@commit_hash
PyPI에 패키지 등록하기
참고한 페이지: https://teddylee777.github.io/python/pypi/
사전에 https://pypi.org/ 사이트에 들어가 패키지 명이 겹치지는 않는지 확인해주어야 한다고 합니다. (회원 가입도 해주어야 합니다.)
- wheel 파일(python 패키지의 배포 형식)을 만들어줍니다.
- sdist는 소스배포판을 생성하는 명령어 입니다. 설치 시 빌드 과정이 필요합니다.
- bdist_wheel은 wheel 배포판을 생성하는 명령어 입니다. 이미 빌드된 파일이기 때문에 컴파일이 불필요 합니다.
# 사전 준비
pip install wheel
# 소스 배포판(.tar.gz)과 wheel(.whl) 파일 생성
python setup.py sdist bdist_wheel
- PyPI에 업로드
- 업로드할 때, 아이디와 비밀번호를 물어봅니다.
# 사전 준비
pip install twine
# dist 안에 만들어진 배포판을 업로드 합니다.
python -m twine upload dist/*
Reference
- editable
https://draw-code-boy.tistory.com/m/602
- Pypi
https://teddylee777.github.io/python/pypi/
- 가이드문서
https://docs.python.org/ko/3.11/distutils/setupscript.html
- 그밖의 블로그
https://iambeginnerdeveloper.tistory.com/245
'AboutPython' 카테고리의 다른 글
GitHub Repo에 Poetry 적용 (1) | 2024.05.09 |
---|---|
어떤 상황에서 Array나 Numpy를 쓰는 것이 적절할까? (0) | 2024.04.22 |
[파이썬] Global Interpreter Lock (GIL)이란? (0) | 2024.04.13 |
[Python] Garbage Collection Tuning (1) | 2024.04.07 |
Python Type Hint : Union을 쓰는 이유 (1) | 2024.02.11 |