教你把python poject发布到PyPI

2023-12-29 15:27:54 浏览数 (2)

一 前言

用过python的人应该对PyPi包管理仓库网站都不陌生,按照官方的定义是:

The Python Package Index (PyPI) is a repository of software for the Python programming language.

这是一个python语言的软件仓库,是一个官方的、由Python社区维护的Python软件包仓库。它是Python程序员共享和发布Python软件包的主要平台。在PyPI上,您可以找到几乎所有的Python包和库,这些包和库可以帮助您完成各种任务,如数据科学、机器学习、网络编程、Web开发等。

所以,看了上面的介绍,我们如何把自己的package发布到PyPI上呢?

二 实施

2.1 注册PyPI平台

首先去pypi网站去注册自己的账户,截至发稿,当前网站由于维护人员休假,垃圾恶意项目太多了,已经终止注册。等恢复之后可以参考其他网站进行注册。注册完成后,登陆并开启Two factor authentication,避免安全问题产生。登陆之后,需要先申请一个API token,作用域可以先设置为全局,方便后续将project package发布到PYPi上,因为上面开启了2FA,所以账户密码的方式已经不可以用来发布了。比如:

2.2 配置工程

按照我上一篇制作harness Python SDK 为例,首先需要在你的project 跟目录创建配置文件,比如我的当前的一级目录详情:

代码语言:bash复制
[root@VM harness_python_SDK]# tree -L 1  
.
|-- LICENSE
|-- README.md
|-- SECURITY.md
|-- build
|-- docs
|-- git_push.sh
|-- harness_python_sdk
|-- pyproject.toml
|-- requirements.txt
|-- setup.py
|-- test
|-- test-requirements.txt
`-- tox.ini

上面LICENSE,pyproject.toml是后加的配置文件,LICENSE文件即是你存放你的project版权内容描述的文件。参考MIT License:

代码语言:txt复制
Copyright (c) 2018 The Python Packaging Authority

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.

pyproject.toml是你发布到PyPI上的工程配置文件,内容包含工程的名称,版本,描述,作者,依赖,项目地址等。比如我这里写的:

代码语言:ini复制
[project]
name = "harness_python_sdk"
version = "1.0.0"
authors = [
  { name="xxx", email="xxx@sina.cn" },
]
description = "harness python sdk package"
readme = "README.md"
requires-python = ">=3.6"
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]

另外还有个比较重要的文件是setup.py,这个文件是用来配置生成你的安装包的信息,诸如版本号,描述,版本,依赖,long_description等信息。尤其是long_description,是按照一定规范来要求内容的,我这里是用了MD的格式:

代码语言:python代码运行次数:0复制
# coding: utf-8

from setuptools import setup, find_packages  # noqa: H301

NAME = "harness_python_sdk"
VERSION = "v1.0.0"
# To install the library, run the following
#
# python setup.py install
#
# prerequisite: setuptools
# http://pypi.python.org/pypi/setuptools

REQUIRES = ["urllib3 >= 1.15", "six >= 1.10", "certifi", "python-dateutil"]
with open("README.md", "r") as fh:
    long_description = fh.read()

setup(
    name=NAME,
    version=VERSION,
    description="Harness NextGen Software Delivery Platform API Reference",
    author_email="contact@harness.io",
    url="",
    keywords=["Swagger", "Harness NextGen Software Delivery Platform API Reference"],
    install_requires=REQUIRES,
    packages=find_packages(),
    include_package_data=True,
    long_description=long_description,
    long_description_content_type="text/markdown"
)

2.3 发布

发布时需要依赖wheel和twine工具,所以这里需要先安装。

代码语言:bash复制
pip install --upgrade pip -i https://pypi.org/simple --trusted-host pypi.org
python3 -m pip install --upgrade setuptools twine -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
python3 -m pip install --upgrade wheel -i http://pypi.douban.com/simple --trusted-host pypi.douban.com

安装完毕依赖,就可以执行打包和上传了:

代码语言:basic复制
python3 setup.py sdist bdist bdist_wheel

sdist是生成源码包,bdist_wheel是对应生成二进制包,执行上述指令完毕后会在当前目录生成一个dist文件夹,内容如下:

代码语言:bash复制
dist/
|-- harness_python_sdk-1.0.0-py3-none-any.whl
`-- harness_python_sdk-1.0.0.tar.gz

得到打的包之后就可以上传发布了:

- 首先配置~/.pypirc 文件,将之前的API token放到这个文件内:

代码语言:ini复制
[pypi]
  username = __token__
  password = pypi-xxxxxxxxxxxxxxxxxxx

- 然后在执行上传就不需要用户密码了:

代码语言:bash复制
twine upload dist/*

上传完毕后就可以在PyPI上看到自己的project:

2.4 验证

发布之后如何验证是否可用呢?那就很简单了,直接用pip安装就可以了,比如:

代码语言:bash复制
pip install harness-python-sdk #或 
pip install harness-python-sdk==1.0.0

写一个脚本验证下能否使用:

代码语言:python代码运行次数:0复制
from __future__ import print_function
import time
import harness_python_sdk
from harness_python_sdk.rest import ApiException
from pprint import pprint

# Configure API key authorization: x-api-key
configuration = harness_python_sdk.Configuration()
configuration.api_key['x-api-key'] = 'pat.xxx.xxx.xxx'
# Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
# configuration.api_key_prefix['x-api-key'] = 'Bearer'

# create an instance of the API class
api_instance = harness_python_sdk.PipelineApi(harness_python_sdk.ApiClient(configuration))
account_identifier = 'xxx' # str | Account Identifier for the Entity.
org_identifier = 'default' # str | Organization Identifier for the Entity.
project_identifier = 'mytest' # str | Project Identifier for the Entity.
body = harness_python_sdk.PipelineFilterProperties(filter_type="PipelineSetup") # PipelineFilterProperties | This is the body for the filter properties for listing pipelines. (optional)
page = 0 # int | Page Index of the results to fetch.Default Value: 0 (optional) (default to 0)
size = 25 # int | Results per page (optional) (default to 25)
get_default_from_other_repo = True # bool | if true, return all the default entities (optional)
get_distinct_from_branches = True # bool | Boolean flag to get distinct pipelines from all branches. (optional)

try:
    # List Pipelines
    api_response = api_instance.get_pipeline_list(account_identifier, org_identifier, project_identifier, body=body, page=page, size=size,get_default_from_other_repo=get_default_from_other_repo, get_distinct_from_branches=get_distinct_from_branches)
    pprint(api_response)
except ApiException as e:
    print("Exception when calling PipelineApi->get_pipeline_list: %sn" % e)

结果输出:

代码语言:json复制
{'correlation_id': '095719e805',
 'data': {'content': [{'connector_ref': None,
                       'created_at': 1663169879767,
                       'description': None,
                       'entity_validity_details': {'invalid_yaml': None,
                                                   'valid': True},
                       'execution_summary_info': {'deployments': [0,
                                                                  0,
                                                                  0,
                                                                  0,
                                                                  0,
                                                                  0,
                                                                  0],
                                                  'last_execution_id': '----',
                                                  'last_execution_status': 'Failed',
                                                  'last_execution_ts': 1667795067318,
                                                  'num_of_errors': [0,
                                                                    0,
                                                                    0,
                                                                    0,
                                                                    0,
                                                                    0,
                                                                    0]},
                       'filters': {u'ci': {u'repoNames': [u'ljw4010/gozbx-sender']},
                                   u'pms': {u'featureFlagStepCount': 0,
                                            u'stageTypes': [u'CI']}},
                       'git_details': None,
                       'identifier': 'Build_gozbx_sender_1663169879158',
                       'is_draft': False,
                       'last_updated_at': 1663169879767,
                       'modules': ['ci', 'pms'],
                       'name': 'Build gozbx-sender',
                       'num_of_stages': 1,
                       'stage_names': ['Build'],
                       'store_type': 'INLINE',
                       'tags': {},
                       'version': 268,
                       'yaml_version': '0'}],
          'empty': False,
          'first': True,
          'last': True,
          'number': 0,
          'number_of_elements': 1,
          'pageable': {'offset': 0,
                       'page_number': 0,
                       'page_size': 25,
                       'paged': True,
                       'sort': {'empty': False,
                                'sorted': True,
                                'unsorted': False},
                       'unpaged': False},
          'size': 25,
          'sort': {'empty': False, 'sorted': True, 'unsorted': False},
          'total_elements': 1,
          'total_pages': 1},
 'meta_data': None,
 'status': 'SUCCESS'}

所以基本是能符合预期了。

三 总结

本文基于先前生成的harness project的SDK,通过注册和配置项目,将其发布到PYPI仓库,方便其他用户调用和维护。若有不足之处,或者未尽事宜请评论区留言斧正。

0 人点赞