<파이썬> 파이썬 패키지 만들어보기

|
이번 글에서는 파이썬 패키지를 만드는 방법을 배워보려고 한다. 아랑고DB 관련 글을 작성하면서 맵퍼를 패키지화 할 필요가 있는데, 겸사겸사 글도 함께 작성하게 되었다. 정신없는 2021 연말, 연초를 거쳐 아랑고DB 맵퍼를 함께 만들다보니 오랜만에 작성하는 글이 되었다. 😂

들어가기에 앞서

이 글은 미디엄에 있는 잘 쓰여진 글PyPI 튜토리얼을 나도 실제로 따라하면서 한글로 정리하는 형태로 진행될 예정이다.

또한 모듈을 만들 정도면 기본적인 파이썬 지식이나 쉘 커맨드를 알고 있다고 가정하고 세부적인 설명은 생략한다.

본문에서는 이러한 내용도 모두 짚고 넘어가니, 여기서 설명이 부족하다면 꼭 살펴보자.

1. 모듈? 패키지?

파이썬에서 프로그램이 길어지게 되면 스크립트를 여러 파일로 분할하게 된다. 이때, .py 형태로 파일을 나누게 되고, 이들을 각각 모듈 modules 이라고 부른다.

모듈에서 선언된 모든 함수와 선언들은 다른 모듈에서 임포트 될 수 있다.

패키지는 파이썬의 모듈을 구조화하는 형태를 의미하고, 모듈들의 집합을 나타낸다.

우리는 여러 모듈로 구성된 패키지를 만들 예정이다!

심심하면 여기를 더 읽어보자.

2. 패키지 만들어보기

나는 Ubuntu Shell을 통해 해당 작업을 진행할 예정이다. 아마 일부 커맨드를 제외하고는 파이썬 명령어를 쓸 일이 더 많을 것 같으니 OS가 달라도 괜찮지 않을까..?

1) 디렉토리 구조 세팅해주기

PyPI의 튜토리얼을 보면 디렉토리 경로를 설정해주는 것부터가 시작이다. 여기서 사용자가 내 패키지를 어떤 이름으로 임포트 할 지 미리 생각해두면 좋다.

왜냐하면 실제로 패키지를 인스톨하는 pip install 패키지이름 명령어와 import 패키지이름의 명령어에서 쓰이는 이름은 다를 수 있기 때문이다.

만약 내가 A라는 패키지 이름을 원했지만, 이미 PyPI 패키지에 유사한 이름이 있는 경우 이 이름을 사용하지 못한다!

그럼에도 임포트는 A라는 이름으로 하길 원하면 패키지의 디렉토리 이름을 그렇게 설정해주면 된다.

아래는 내가 설정한 디렉토리 구조의 예시이다. 나는 아랑고DB를 쉽게 맵핑해주는 파이썬 패키지를 만들고 있다. 이름은 python-arango-mapper이며, 임포트는 pam으로 하고싶다.

python_arango_mapper/
├──LICENSE
├──README.md
├──setup.py
├──src/
│   └── pam/
│       ├──__init.py
│       ├──그리고 패키지에서 사용하는 다른 파일들

위에서 보면 패키지 루트 디렉토리에는 패키지와 관련된 메타 정보를 갖는 파일들이 포함된다.

  • LICENSE는 내 패키지의 이용 권리에 관한 disclaimer이며, 여기에서 나에게 맞는 타입을 골라서, 복사해서 텍스트 그대로 붙여넣으면 된다.
  • README.md는 깃 저장소를 최초 만들 때 생성되는 파일과 동일하다. 패키지에 대한 설명을 넣어주면 된다.
  • 그다음 가장 중요한 파일이 setup.py인데, 내 파이썬 패키지에 대한 모든 설정 정보들을 포함한다.

2) setup.py 세팅

내가 만든 setup.py는 아래와 같이 구성되어 있다.

from setuptools import find_packages, setup
import setuptools

install_requires = [
    'bleach==4.1.0',
    'certifi==2021.10.8',
    'cffi==1.15.0',
    'charset-normalizer==2.0.9',
    'colorama==0.4.4',
    'cryptography==36.0.1',
    'dataclasses==0.8',
    'docutils==0.18.1',
    'idna==3.3',
    'importlib-metadata==4.8.3',
    'jeepney==0.7.1',
    'keyring==23.4.0',
    'packaging==21.3',
    'pkg_resources==0.0.0',
    'pkginfo==1.8.2',
    'pycparser==2.21',
    'Pygments==2.10.0',
    'PyJWT==2.3.0',
    'pyparsing==3.0.6',
    'python-arango==7.3.0',
    'readme-renderer==32.0',
    'requests==2.26.0',
    'requests-toolbelt==0.9.1',
    'rfc3986==1.5.0',
    'SecretStorage==3.3.1',
    'setuptools-scm==6.3.2',
    'six==1.16.0',
    'tomli==1.2.3',
    'tqdm==4.62.3',
    'twine==3.7.1',
    'typing_extensions==4.0.1',
    'urllib3==1.26.7',
    'webencodings==0.5.1',
    'zipp==3.6.0'
]

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

setup(
    name='python-arango-mapper',
    package_dir={"": "src"},
    packages=setuptools.find_packages(where="src"),
    python_requires=">=3.6",
    install_requires=install_requires,
    version='0.1.5',
    description='fast and easy-to-use python-arango mapper library',
    long_description=long_description,
    long_description_content_type="text/markdown",
    author='lee ui dam',
    author_email='ud803da@gmail.com',
    url='https://github.com/ud803/python-arango-mapper',
    license='GNU General Public License v3.0'
)
install_requires에 들어갈 패키지는 수동으로 하나하나 작성할 필요가 없다. 내가 테스트했던 환경에서 pip freeze 명령어를 쓰면 설치된 목록이 쭉 나온다. 불필요한 패키지는 없애고 복사해서 사용하자.
  • 패키지를 구동하기 위해 필요한 최소한의 패키지 목록을 install_requires에 문자열의 리스트로 기록해준다
  • name은 PyPI에 등록할 패키지의 정식 이름이다. 중복되거나 부적절한 경우 등록시 에러가 난다.
  • package_dirpackages는 패키지에 포함할 소스의 위치에 관한 설정이며, 나는 위처럼 해주었다.
  • version은 내가 설정하는 내 패키지의 버전을 의미한다. 나도 아직 버저닝에 익숙하지는 않지만, **동일한 버전인 경우 중복 & 수정 업로드가 불가능하다!! **
  • long_description은 PyPI 에 올라갈 내 패키지 설명 페이지에 들어갈 내용이다. long을 쓰지 않으면 README.md가 아닌 짧은 설명만 올라가길래 이렇게 설정했다

3) 배포 버전 만들기

이제 준비가 다 끝났으니, 실제 파이썬 명령어를 통해 배포 버전을 만들고, 배포해보자.

python3 명령어 뒤에 붙는 -m 옵션은 옵션 뒤에 따라오는 파이썬 패키지를 실행한다는 의미이다. 즉, 아래 명령어는 python3에서 pip 패키지를 쓸건데, 패키지의 명령어가 install이고, 그 install의 옵션이 --upgrade pip이에요 라는 뜻이다.
# pip 업그레이드
python3 -m pip install --upgrade pip

# build 패키지 업그레이드
python3 -m pip install --upgrade build

# setup.py가 있는 디렉토리에서 실행, 패키지를 빌드한다
python3 -m build

이렇게하면 python_arango_mapper/dist/ 폴더에 두 개의 파일이 생긴다. 이제 업로드해보자.

업로드 전에 테스트 PyPI실제 PyPI서 계정만 먼저 만들어주자!

PyPI는 테스트 사이트에 먼저 업로드하는 것을 권장한다.

4) 테스트 업로드하기

# twine 패키지 업그레이드
python3 -m pip install --upgrade twine

python3 -m twine upload --repository testpypi dist/*

테스트 PyPI에 성공적으로 업로드가 되었으면, 계정으로 로그인해서 내 프로젝트가 잘 들어간 것을 확인하면 된다.

5) 실제 업로드하기

테스트까지 끝났으면, 이제 정말로 세상에 내 패키지를 배포해보자.

다 동일하고, 업로드 대상 저장소만 바꿔주면 된다. 그런데 PyPI가 이미 디폴트 저장소이기 때문에 옵션만 지워준다.

# 실제 PyPI에 첫 패키지 배포!!
python3 -m twine upload dist/*

짝짝짝!! 축하한다. 드디어 내 첫 패키지가 세상에 발을 디뎠다.

3. 패키지 테스트해보기

이제 내가 만든 패키지가 잘 동작하는지 바로 확인해보자.

pip install python-arango-mapper를 통해 설치를 하고, 내가 테스트했던 코드들을 실험해보면 된다!

4. 마치며

실제 패키지를 배포할 때는 깃을 통해 버전을 관리하고, 테스트 코드를 작성하는 등의 과정을 거친다.

나는 귀찮아서.. 테스트 코드는 작성하지 않았지만 깃허브에 올려두고 코드 관리를 하고 있다.

혹시 글이 도움이 되셨다면 python-arango-mapper 깃허브에 가서 스타를 꾸욱 눌러주시면 정말 감사하겠다!! 😗