본문 바로가기

Programming/Python

[Python pip/PyPi] python package whl 파일 생성 및 PyPi 에 배포하기

sample github repository

https://github.com/Mishuni/Pip_Package_Practice.git

 

GitHub - Mishuni/Pip_Package_Practice: pip package deployment sample

pip package deployment sample. Contribute to Mishuni/Pip_Package_Practice development by creating an account on GitHub.

github.com

위  repository 구조를 참고하여 해당 포스팅을 진행하였습니다.

밑에 파일 구조가 정의된 폴더가 Pip_Package_Practice 입니다.

PIP package 생성 과정

원래의 파일 구조

(base) ➜  Pip_Package_Practice tree
.
├── test_package
│   ├── __init__.py
│   └── modules.py
├── README.md
└── setup.py

import 할 모듈 내용

# Pip_Package_Practice/test_package/modules.py
def add(a,b):
    print("Add function")
    return a+b

 

이제 앞으로, test_package 패키지 안에 modules.py 안에 있는 add 라는 function 을
pip install 을 통해 설치해서 별다른 경로 설정 없이 써보도록 하겠습니다.

setting

$ pip install wheel
$ pip install setuptools

setup.py

The setup.py file will contain information about your package, specifically the name of the package, its version, platform-dependencies and a whole lot more.

해당 setup.py 는 현재 패키지의 정보를 담고 있는 파일입니다. 여기서 패키지 이름이나 버전 등 패키지 관련 정보들을 세팅할 수 있습니다.

 

# Pip_Package_Practice/setup.py
from setuptools import setup, find_packages

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

setup(
    name='test', 
    version='0.1',
    description='test package',
    author='test1234',
    author_email='test1234@email.re.kr',
    long_description=long_description,
    python_requires='>=3.6',
    long_description_content_type="text/markdown",
    packages= find_packages(exclude = ['docs', 'tests*','__pycache__/']),
    )

make whl file

$ cd Pip_Package_Practice
$ python setup.py bdist_wheel

생성 후의 파일 구조

(base) ➜  Pip_Package_Practice tree
.
├── build
│   ├── bdist.linux-x86_64
│   └── lib
│       └── test_package
│           ├── __init__.py
│           └── modules.py
├── dist
│   └── test-0.1-py3-none-any.whl
├── pack
│   ├── __init__.py
│   └── modules.py
├── README.md
├── setup.py
└── test.egg-info
    ├── dependency_links.txt
    ├── PKG-INFO
    ├── SOURCES.txt
    └── top_level.txt

whl 파일 위치 : ./dist/test-0.1-py3-none-any.whl

whl 파일 이용 package install

# conda 가상환경 생성
$ conda create -n test python=3.6
# 가상환경 활성화
$ conda activate test
# whl 파일로 package 설치
$ pip install ./dist/test-0.1-py3-none-any.whl 
Processing ./dist/test-0.1-py3-none-any.whl
Installing collected packages: test
Successfully installed test-0.1

설치 잘 되었는지 확인

# 설치되었는지 확인
$ conda list | grep test
test    0.1    pypi_0    pypi
# import 확인
$ python
>>> from test_package import modules as mo
>>> mo.add(2,3)
Add function
5
>>> exit()

설치했던 package 삭제 및 가상환경 제거

# package 삭제
$ pip uninstall test -y
# 가상환경 비활성화
$ conda deactivate
# 앞서 만들었던 test 가상환경 삭제
$ conda remove --name test --all 

PIP PyPi 에 배포하기

PyPi 에 package 를 배포하기 위해서는 PyPi 회원가입을 해야합니다.

PyPi 사이트 를 접속하여 register로 가입하면 됩니다.

$ pip install twine

실제 PyPi repository 에 올리기 (package 이름 충돌나는 경우)

$ twine upload dist/*
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: 
Enter your password: 
Uploading test-0.1-py3-none-any.whl
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3.96k/3.96k [00:01<00:00, 3.08kB/s]
NOTE: Try --verbose to see response content.
HTTPError: 400 Bad Request from https://upload.pypi.org/legacy/
The name 'test' isn't allowed. See https://pypi.org/help/#project-name for more information.

 

PyPi 에 올라가는 package 는 이름이 중복될 수 없음으로 위 에러가 납니다.

그럴 때는 setup.py 에서 name 을 바꿔주고 다시 whl 파일을 생성해야 합니다.

본 설명에서는 package 이름에 직접 설정해준 username 을 추가하기로 했습니다.

 

# Pip_Package_Practice/setup.py
from setuptools import setup, find_packages

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

username = "username"

setup(
    name='test_%s'%username, 
    version='0.1',
    description='test package',
    author='test1234',
    author_email='test1234@email.re.kr',
    long_description=long_description,
    python_requires='>=3.6',
    long_description_content_type="text/markdown",
    packages= find_packages(exclude = ['docs', 'tests*','__pycache__/']),
    )

이름 바꾼 whl 파일 다시 생성

$ conda activate test
# package 삭제
$ pip uninstall test -y
$ python setup.py bdist_wheel
.
.
creating 'dist/test_username-0.1-py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it
.
.
removing build/bdist.linux-x86_64/wheel

실제 PyPi repository 에 올리기 (package 이름 충돌나지 않는 경우)

$ twine upload ./dist/test_username-0.1-py3-none-any.whl
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: 
Enter your password: 
Uploading test-0.1-py3-none-any.whl
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 3.96k/3.96k [00:01<00:00, 3.08kB/s]

View at:
https://pypi.org/project/test-username/0.1/

해당 배포 page 들어가서 확인 ( "https://pypi.org/project/패키지이름") 

아래는 예시 링크

https://pypi.org/project/test-username/

 

배포 잘 되었는지 확인

$ seminar conda list | grep test   
test-username    0.1     pypi_0    pypi
$ conda activate test
$ pip install test_username
$ python
>>> from test_package import modules as mo
>>> mo.add(2,3)
Add function
5
>>> exit()

 

여기서 주의할 점은
setup.py 에서 지정한 패키지 pip용 name 과
라이브러리에 파이썬에서 사용하는 패키지 이름이 다르다는 것이다.
이에 대해 헷갈리지 않도록 주의할 필요가 있다

 

이에 대한 예로
scikit-learn 을 들 수 있다.
scikit-learn 은 pip install scikit-learn 로 설치하지만
python 에서는 from sklearn 으로 import 를 시작하는 걸 볼 수 있다.

 

반응형