pip发布自定义package

939次阅读
没有评论

共计 24412 个字符,预计需要花费 62 分钟才能阅读完成。

pip发布自定义package

最近博主在折腾python调用nacos,这方面资料好少,还是java sdk多。。。一顿搜索过后发现了一个包:KcangNacos,看着还行倒腾了一会发现里面有些问题,就打算自己修复调整下并发布

cookiecutter

这是一个用来生成一个标准python package模板的工具,官网:https://cookiecutter-pypackage.readthedocs.io/en/latest/readme.html

安装

[root@jenkins-manager demo01]# pip install cookiecutter

使用模板生成一个package目录

[root@jenkins-manager demo01]# cookiecutter https://gitee.com/siq/cookiecutter-pypackage.git
/usr/local/lib/python3.6/site-packages/requests/__init__.py:104: RequestsDependencyWarning: urllib3 (1.26.12) or chardet (5.0.0)/charset_normalizer (2.0.12) doesn't match a supported version!
  RequestsDependencyWarning)
You've downloaded /root/.cookiecutters/cookiecutter-pypackage before. Is it okay to delete and re-download it? [yes]:
full_name [Audrey Roy Greenfeld]: KONE-XAD
email [audreyr@example.com]: 1793360097@qq.com
github_username [audreyr]: KONE-XAD
project_name [Python Boilerplate]: xadnacos
project_slug [xadnacos]: xadnacos
project_short_description [Python Boilerplate contains all the boilerplate you need to create a Python package.]: python sdk for nacos
pypi_username [KONE-XAD]: xadocker
version [0.1.0]: 0.1.0
use_pytest [n]: n
use_pypi_deployment_with_travis [y]: n
add_pyup_badge [n]: n
Select command_line_interface:
1 - Click
2 - Argparse
3 - No command-line interface
Choose from 1, 2, 3 [1]: 1
create_author_file [y]: y
Select open_source_license:
1 - MIT license
2 - BSD license
3 - ISC license
4 - Apache Software License 2.0
5 - GNU General Public License v3
6 - Not open source
Choose from 1, 2, 3, 4, 5, 6 [1]: 1

此时目录会生成一个package目录

[root@jenkins-manager demo01]# ll
total 0
drwxr-xr-x 6 root root 326 Feb  4 14:29 xadnacos
[root@jenkins-manager demo01]# ll xadnacos/
total 44
-rw-r--r-- 1 root root  151 Feb  4 14:29 AUTHORS.rst
-rw-r--r-- 1 root root 3536 Feb  4 14:29 CONTRIBUTING.rst
drwxr-xr-x 2 root root  191 Feb  4 14:29 docs
-rw-r--r-- 1 root root   89 Feb  4 14:29 HISTORY.rst
-rw-r--r-- 1 root root 1067 Feb  4 14:29 LICENSE
-rw-r--r-- 1 root root 2266 Feb  4 14:29 Makefile
-rw-r--r-- 1 root root  262 Feb  4 14:29 MANIFEST.in
-rw-r--r-- 1 root root  846 Feb  4 14:29 README.rst
-rw-r--r-- 1 root root  144 Feb  4 14:29 requirements_dev.txt
-rw-r--r-- 1 root root  392 Feb  4 14:29 setup.cfg
-rw-r--r-- 1 root root 1577 Feb  4 14:29 setup.py
drwxr-xr-x 2 root root   49 Feb  4 14:29 tests
-rw-r--r-- 1 root root  282 Feb  4 14:29 tox.ini
drwxr-xr-x 2 root root   58 Feb  4 14:29 xadnacos

编写package的功能

此时在xadnacos/xadnacos内编写你的功能

# 当前package目录结构
[root@jenkins-manager demo01]# tree
.
└── xadnacos
    ├── AUTHORS.rst
    ├── CONTRIBUTING.rst
    ├── docs
    │   ├── authors.rst
    │   ├── conf.py
    │   ├── contributing.rst
    │   ├── history.rst
    │   ├── index.rst
    │   ├── installation.rst
    │   ├── make.bat
    │   ├── Makefile
    │   ├── readme.rst
    │   └── usage.rst
    ├── HISTORY.rst
    ├── LICENSE
    ├── Makefile
    ├── MANIFEST.in
    ├── README.rst
    ├── requirements_dev.txt
    ├── setup.cfg
    ├── setup.py
    ├── tests
    │   ├── __init__.py
    │   └── test_xadnacos.py
    ├── tox.ini
    └── xadnacos
        ├── cli.py
        ├── __init__.py
        └── xadnacos.py

4 directories, 26 files

编写xadnacos.py内功能

参考KcangNacos调整修改:https://github.com/KcangYan/nacos-python-sdk.git

# 在原作者的nacos.py中服务注册漏了clusterName参数,导致所有服务都注册到默认集群中
[root@jenkins-manager demo01]# cat xadnacos/xadnacos/xadnacos.py
# -*- coding: utf-8 -*-
import requests,time
import hashlib
import urllib
import json

import logging

LOG_FORMAT = '%(asctime)s -%(name)s- %(threadName)s-%(thread)d - %(levelname)s - %(message)s'
DATE_FORMAT = "%m/%d/%Y %H:%M:%S %p"
#日志配置
logging.basicConfig(level=logging.INFO,format=LOG_FORMAT,datefmt=DATE_FORMAT)

import threading

class nacos:
    def __init__(self,ip="127.0.0.1",port=8848):
        self.ip = ip
        self.port = port
        self.__threadHealthyDict = {}
        self.__configDict = {}
        self.__registerDict = {}
        self.healthy = ""

    def __healthyCheckThreadRun(self):
        while True:
            time.sleep(5)
            self.healthy = int(time.time())
            #检查configThread
            try:
                for item in self.__configDict:
                    configMsg = item.split("\001")
                    dataId = configMsg[0]
                    group = configMsg[1]
                    tenant = configMsg[2]
                    x = int(time.time()) - self.__threadHealthyDict[dataId + group + tenant]
                    if (x > 50):
                        md5Content = configMsg[3]
                        myConfig = self.__configDict[item]
                        configThread = threading.Thread(target=self.__configListeningThreadRun,
                                                        args=(dataId, group, tenant, md5Content, myConfig))
                        self.__threadHealthyDict[dataId + group + tenant] = int(time.time())
                        configThread.start()
                        logging.info("配置信息监听线程重启成功: dataId=" + dataId + "; group=" + group + "; tenant=" + tenant)
            except:
                logging.exception("配置信息监听线程健康检查错误",exc_info=True)
            #检查registerThread
            try:
                x = int(time.time()) - self.__registerDict["healthy"]
                if (x > 15):
                    serviceIp = self.__registerDict["serviceIp"]
                    servicePort = self.__registerDict["servicePort"]
                    serviceName = self.__registerDict["serviceName"]
                    namespaceId = self.__registerDict["namespaceId"]
                    groupName = self.__registerDict["groupName"]
                    clusterName = self.__registerDict["clusterName"]
                    ephemeral = self.__registerDict["ephemeral"]
                    metadata = self.__registerDict["metadata"]
                    weight = self.__registerDict["weight"]
                    enabled = self.__registerDict["enabled"]
                    self.registerService(serviceIp,servicePort,serviceName,
                                         namespaceId,groupName,clusterName,
                                         ephemeral,metadata,weight,enabled)
            except:
                logging.exception("服务注册心跳进程健康检查失败",exc_info=True)

    def healthyCheck(self):
        t = threading.Thread(target=self.__healthyCheckThreadRun)
        t.start()
        logging.info("健康检查线程已启动")

    def __configListeningThreadRun(self,dataId,group,tenant,md5Content,myConfig):
        getConfigUrl = "http://" + self.ip + ":" + str(self.port) + "/nacos/v1/cs/configs"
        params = {
            "dataId": dataId,
            "group": group,
            "tenant": tenant
        }

        licenseConfigUrl = "http://" + self.ip + ":" + str(self.port) + "/nacos/v1/cs/configs/listener"
        header = {"Long-Pulling-Timeout": "30000"}
        while True:
            self.__threadHealthyDict[dataId + group + tenant] = int(time.time())
            if (tenant == "public"):
                files = {"Listening-Configs": (None, dataId + "\002" + group + "\002" + md5Content + "\001")}
            else:
                files = {"Listening-Configs": (None, dataId + "\002" + group + "\002" + md5Content + "\002" + tenant + "\001")}
            re = requests.post(licenseConfigUrl, files=files, headers=header)
            if (re.text != ""):
                try:
                    re = requests.get(getConfigUrl, params=params)
                    nacosJson = re.json()
                    md5 = hashlib.md5()
                    md5.update(re.content)
                    md5Content = md5.hexdigest()
                    for item in nacosJson:
                        myConfig[item] = nacosJson[item]
                    logging.info("配置信息更新成功: dataId=" + dataId + "; group=" + group + "; tenant=" + tenant)
                except:
                    logging.exception("配置信息更新失败:dataId=" + dataId + "; group=" + group + "; tenant=" + tenant,
                                      exc_info=True)
                    break

    def config(self,myConfig,dataId,group="DEFAULT_GROUP",tenant="public"):
        logging.info("正在获取配置: dataId="+dataId+"; group="+group+"; tenant="+tenant)
        getConfigUrl = "http://" + self.ip + ":" + str(self.port) + "/nacos/v1/cs/configs"
        params = {
            "dataId": dataId,
            "group": group,
            "tenant": tenant
        }
        try:
            re = requests.get(getConfigUrl, params=params)
            nacosJson = re.json()
            md5 = hashlib.md5()
            md5.update(re.content)
            md5Content = md5.hexdigest()

            self.__configDict[dataId+"\001"+group+"\001"+tenant+"\001"+md5Content] = myConfig

            for item in nacosJson:
                myConfig[item] = nacosJson[item]
            logging.info("配置获取成功:dataId="+dataId+"; group="+group+"; tenant="+tenant)
            configThread = threading.Thread(target=self.__configListeningThreadRun,args=(dataId,group,tenant,md5Content,myConfig))
            self.__threadHealthyDict[dataId+group+tenant] = int(time.time())
            configThread.start()
        except Exception:
            logging.exception("配置获取失败:dataId="+dataId+"; group="+group+"; tenant="+tenant, exc_info=True)

    def __registerBeatThreadRun(self,serviceIp,servicePort,serviceName,
                                groupName,namespaceId,metadata,weight,clusterName):

        beatUrl = "http://" + self.ip + ":" + str(self.port) + "/nacos/v1/ns/instance/beat?"
        beatJson = {
            "ip": serviceIp,
            "port": servicePort,
            "serviceName": serviceName,
            "metadata": metadata,
#            "scheduled": "true",
            "weight": weight
        }
        params_beat = {
            "serviceName": serviceName,
            "groupName": groupName,
            "clusterName": clusterName,
            "namespaceId": namespaceId,
            "beat": urllib.request.quote(json.dumps(beatJson))
        }
        for item in params_beat:
            beatUrl = beatUrl + item + "=" + params_beat[item] + "&"
        while True:
            self.__registerDict["healthy"] = int(time.time())
            try:
                time.sleep(5)
                re = requests.put(beatUrl[:-1])
                if(re.json()['code'] != 10200):
                    self.__registerDict["healthy"] = int(time.time())-10
                    logging.info(re.text)
                    break
            except json.JSONDecodeError:
                self.__registerDict["healthy"] = int(time.time()) - 10
                break
            except :
                logging.exception("服务心跳维持失败!",exc_info=True)
                break

    def registerService(self,serviceIp,servicePort,serviceName,namespaceId="public",
                        groupName="DEFAULT_GROUP",clusterName="DEFAULT",
                        ephemeral=True,metadata={},weight=1,enabled=True):
        self.__registerDict["serviceIp"] = serviceIp
        self.__registerDict["servicePort"] = servicePort
        self.__registerDict["serviceName"] = serviceName
        self.__registerDict["namespaceId"] = namespaceId
        self.__registerDict["groupName"] = groupName
        self.__registerDict["clusterName"] = clusterName
        self.__registerDict["ephemeral"] = ephemeral
        self.__registerDict["metadata"] = metadata
        self.__registerDict["weight"] = weight
        self.__registerDict["enabled"] = enabled

        self.__registerDict["healthy"] = int(time.time())


        registerUrl = "http://" + self.ip + ":" + str(self.port) + "/nacos/v1/ns/instance"
        params = {
            "ip": serviceIp,
            "port": servicePort,
            "serviceName": serviceName,
            "namespaceId": namespaceId,
            "groupName": groupName,
            "clusterName": clusterName,
            "ephemeral": ephemeral,
            "metadata": json.dumps(metadata),
            "weight": weight,
            "enabled": enabled
        }
        try:
            re = requests.post(registerUrl, params=params)
            if (re.text == "ok"):
                logging.info("服务注册成功。")
                beatThread = threading.Thread(target=self.__registerBeatThreadRun,
                                              args=(serviceIp,servicePort,serviceName,
                                              groupName,namespaceId,metadata,weight,clusterName))
                beatThread.start()
            else:
                logging.error("服务注册失败 "+re.text)
        except:
            logging.exception("服务注册失败",exc_info=True)

def fallbackFun():
    return "request Error"
def timeOutFun():
    return "request time out"

class nacosBalanceClient:
    def __init__(self,ip="127.0.0.1",port=8848,serviceName="",
                      group="DEFAULT_GROUP",namespaceId="public",timeout=6,
                      fallbackFun=fallbackFun, timeOutFun=timeOutFun):
        self.ip = ip
        self.port = port
        self.serviceName = serviceName
        self.group = group
        self.namespaceId = namespaceId
        self.__LoadBalanceDict = {}
        self.timeout = timeout
        self.fallbackFun = fallbackFun
        self.timeOutFun  = timeOutFun

    def __doRequest(self,method,url,requestParamJson,*args,**kwargs) :
        if method == "GET" or method == "get":
            url = url + "/"
            for item in args:
                url = url + str(item) + "/"
            url = url[:-1]
            if kwargs.__len__() != 0:
                url = url + "?"
                for item in kwargs:
                    url = url + str(item) + "=" + str(kwargs[item]) + "&"
                url = url[:-1]
            return requests.get(url, timeout=self.timeout).text
        if method == "POST" or method == "post":
            if requestParamJson:
                header = {"Content-type": "application/json;charset=utf-8"}
                data = None
                for item in args:
                    data = item
                return requests.post(url,headers=header,data=json.dumps(data,ensure_ascii=False).encode("utf-8"), timeout=self.timeout).text
            else:
                files = {}
                for map in args:
                    for key in map:
                        files[key] = (None,map[key])
                return requests.post(url,files=files, timeout=self.timeout).text

    def __getAddress(self,serviceName,group,namespaceId):
        getProviderUrl = "http://" + self.ip + ":" + str(self.port) + "/nacos/v1/ns/instance/list"
        params = {
            "serviceName": serviceName,
            "groupName": group,
            "namespaceId": namespaceId
        }
        re = requests.get(getProviderUrl, params=params)
        try:
            msg = re.json()['hosts']
        except json.JSONDecodeError:
            msg = []
        hosts = []
        for item in msg:
            hosts.append({
                'ip': item['ip'],
                'port': item['port'],
                'healthy': item['healthy']
            })
        md5 = hashlib.md5()
        md5.update(json.dumps(hosts,ensure_ascii=False).encode("utf-8"))
        md5Content = md5.hexdigest()
        try:
            oldMd5 = self.__LoadBalanceDict[serviceName + group + namespaceId + "md5"]
        except KeyError:
            self.__LoadBalanceDict[serviceName + group + namespaceId + "md5"] = md5Content
            oldMd5 = ""
        if oldMd5 != md5Content:
            healthyHosts = []
            for host in msg:
                if host['healthy'] == True:
                    healthyHosts.append(host)
            self.__LoadBalanceDict[serviceName + group + namespaceId] = healthyHosts
            self.__LoadBalanceDict[serviceName + group + namespaceId + "index"] = 0

    def __loadBalanceClient(self,serviceName,group,namespaceId):
        try:
            x = int(time.time()) - self.__LoadBalanceDict[serviceName + group + namespaceId + "time"]
        except KeyError:
            x = 11
        if x > 10:
            self.__getAddress(serviceName,group,namespaceId)
            self.__LoadBalanceDict[serviceName + group + namespaceId + "time"] = int(time.time())

        index = self.__LoadBalanceDict[serviceName + group + namespaceId + "index"]
        l = len(self.__LoadBalanceDict[serviceName + group + namespaceId])
        if l == 0:
            logging.error("无可用服务 serviceName: "+serviceName+";group: "+group+";namespaceId: "+namespaceId)
            return ""
        if index >= l:
            self.__LoadBalanceDict[serviceName + group + namespaceId + "index"] = 1
            return self.__LoadBalanceDict[serviceName + group + namespaceId][0]['ip']+":"+str(self.__LoadBalanceDict[serviceName + group + namespaceId][0]['port'])
        else:
            self.__LoadBalanceDict[serviceName + group + namespaceId + "index"] = index + 1
            return  self.__LoadBalanceDict[serviceName + group + namespaceId][index]['ip'] + ":" + str(self.__LoadBalanceDict[serviceName + group + namespaceId][index]['port'])

    def customRequestClient(self,method,url,
                            requestParamJson=False,https=False):
        def requestPro(f):
            def mainPro(*args, **kwargs):
                address = self.__loadBalanceClient(self.serviceName, self.group, self.namespaceId)
                if address == "":
                    return
                else:
                    if https:
                        requestUrl = "https://" + address + url
                    else:
                        requestUrl = "http://" + address + url
                    try:
                        return self.__doRequest(method, requestUrl, requestParamJson, *args, **kwargs)
                    except requests.ConnectTimeout:
                        logging.exception("链接超时   ",exc_info=True)
                        return self.timeOutFun(self.serviceName,self.group,self.namespaceId,method,url)
                    except Exception as ex:
                        logging.exception("链接失败   ", exc_info=True)
                        return self.fallbackFun(self.serviceName,self.group,self.namespaceId,method,url,ex)
            mainPro.__name__ = f.__name__
            return mainPro
        return requestPro

此时package的功能就完成了,接下来就准备调整包的一些基本信息

调整package基本信息

调整setup.py

[root@jenkins-manager xadnacos]# ll
total 44
-rw-r--r-- 1 root root  151 Feb  4 14:29 AUTHORS.rst
-rw-r--r-- 1 root root 3536 Feb  4 14:29 CONTRIBUTING.rst
drwxr-xr-x 2 root root  191 Feb  4 14:29 docs
-rw-r--r-- 1 root root   89 Feb  4 14:29 HISTORY.rst
-rw-r--r-- 1 root root 1067 Feb  4 14:29 LICENSE
-rw-r--r-- 1 root root 2266 Feb  4 14:29 Makefile
-rw-r--r-- 1 root root  262 Feb  4 14:29 MANIFEST.in
-rw-r--r-- 1 root root  846 Feb  4 14:29 README.rst
-rw-r--r-- 1 root root  144 Feb  4 14:29 requirements_dev.txt
-rw-r--r-- 1 root root  392 Feb  4 14:29 setup.cfg
-rw-r--r-- 1 root root 1642 Feb  4 14:55 setup.py
drwxr-xr-x 2 root root   49 Feb  4 14:29 tests
-rw-r--r-- 1 root root  282 Feb  4 14:29 tox.ini
drwxr-xr-x 2 root root   58 Feb  4 15:11 xadnacos
[root@jenkins-manager xadnacos]# cat setup.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""The setup script."""

from setuptools import setup, find_packages

with open('README.rst', "r", encoding="utf-8") as readme_file:
    readme = readme_file.read()

with open('HISTORY.rst', "r", encoding="utf-8") as history_file:
    history = history_file.read()

requirements = ['Click>=7.0', 'requests>=2.20.0']

setup_requirements = [ ]

test_requirements = [ ]

setup(
    author="KONE-XAD",
    author_email='1793360097@qq.com',
    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
    classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Natural Language :: English',
        "Programming Language :: Python :: 2",
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
    ],
    description="python sdk for nacos",
    entry_points={
        'console_scripts': [
            'xadnacos=xadnacos.cli:main',
        ],
    },
    install_requires=requirements,
    license="MIT license",
    long_description=readme + '\n\n' + history,
    include_package_data=True,
    keywords='xadnacos',
    name='xadnacos',
    packages=find_packages(include=['xadnacos', 'xadnacos.*']),
    setup_requires=setup_requirements,
    test_suite='tests',
    tests_require=test_requirements,
    url='https://github.com/KONE-XAD/xadnacos',
    version='0.1.0',
    zip_safe=False,
)

编写README配置

安装打包依赖

[root@jenkins-manager xadnacos]# pip3 install --upgrade pip
[root@jenkins-manager xadnacos]# pip3 install twine setuptools setuptools-rust cffi wheel -i https://mirrors.aliyun.com/pypi/simple/

开始打包

[root@jenkins-manager xadnacos]# python3 setup.py sdist bdist_wheel
running sdist
running egg_info
creating xadnacos.egg-info
writing xadnacos.egg-info/PKG-INFO
writing dependency_links to xadnacos.egg-info/dependency_links.txt
writing entry points to xadnacos.egg-info/entry_points.txt
writing requirements to xadnacos.egg-info/requires.txt
writing top-level names to xadnacos.egg-info/top_level.txt
writing manifest file 'xadnacos.egg-info/SOURCES.txt'
reading manifest file 'xadnacos.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '__pycache__' found under directory '*'
warning: no previously-included files matching '*.py[co]' found under directory '*'
warning: no files found matching '*.jpg' under directory 'docs'
warning: no files found matching '*.png' under directory 'docs'
warning: no files found matching '*.gif' under directory 'docs'
adding license file 'LICENSE'
adding license file 'AUTHORS.rst'
writing manifest file 'xadnacos.egg-info/SOURCES.txt'
running check
creating xadnacos-0.1.0
creating xadnacos-0.1.0/docs
creating xadnacos-0.1.0/tests
creating xadnacos-0.1.0/xadnacos
creating xadnacos-0.1.0/xadnacos.egg-info
copying files to xadnacos-0.1.0...
copying AUTHORS.rst -> xadnacos-0.1.0
copying CONTRIBUTING.rst -> xadnacos-0.1.0
copying HISTORY.rst -> xadnacos-0.1.0
copying LICENSE -> xadnacos-0.1.0
copying MANIFEST.in -> xadnacos-0.1.0
copying README.rst -> xadnacos-0.1.0
copying setup.cfg -> xadnacos-0.1.0
copying setup.py -> xadnacos-0.1.0
copying docs/Makefile -> xadnacos-0.1.0/docs
copying docs/authors.rst -> xadnacos-0.1.0/docs
copying docs/conf.py -> xadnacos-0.1.0/docs
copying docs/contributing.rst -> xadnacos-0.1.0/docs
copying docs/history.rst -> xadnacos-0.1.0/docs
copying docs/index.rst -> xadnacos-0.1.0/docs
copying docs/installation.rst -> xadnacos-0.1.0/docs
copying docs/make.bat -> xadnacos-0.1.0/docs
copying docs/readme.rst -> xadnacos-0.1.0/docs
copying docs/usage.rst -> xadnacos-0.1.0/docs
copying tests/__init__.py -> xadnacos-0.1.0/tests
copying tests/test_xadnacos.py -> xadnacos-0.1.0/tests
copying xadnacos/__init__.py -> xadnacos-0.1.0/xadnacos
copying xadnacos/cli.py -> xadnacos-0.1.0/xadnacos
copying xadnacos/xadnacos.py -> xadnacos-0.1.0/xadnacos
copying xadnacos.egg-info/PKG-INFO -> xadnacos-0.1.0/xadnacos.egg-info
copying xadnacos.egg-info/SOURCES.txt -> xadnacos-0.1.0/xadnacos.egg-info
copying xadnacos.egg-info/dependency_links.txt -> xadnacos-0.1.0/xadnacos.egg-info
copying xadnacos.egg-info/entry_points.txt -> xadnacos-0.1.0/xadnacos.egg-info
copying xadnacos.egg-info/not-zip-safe -> xadnacos-0.1.0/xadnacos.egg-info
copying xadnacos.egg-info/requires.txt -> xadnacos-0.1.0/xadnacos.egg-info
copying xadnacos.egg-info/top_level.txt -> xadnacos-0.1.0/xadnacos.egg-info
Writing xadnacos-0.1.0/setup.cfg
creating dist
Creating tar archive
removing 'xadnacos-0.1.0' (and everything under it)
running bdist_wheel
running build
running build_py
creating build
creating build/lib
creating build/lib/xadnacos
copying xadnacos/__init__.py -> build/lib/xadnacos
copying xadnacos/cli.py -> build/lib/xadnacos
copying xadnacos/xadnacos.py -> build/lib/xadnacos
/usr/local/lib/python3.6/site-packages/setuptools/command/install.py:37: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
  setuptools.SetuptoolsDeprecationWarning,
installing to build/bdist.linux-x86_64/wheel
running install
running install_lib
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/wheel
creating build/bdist.linux-x86_64/wheel/xadnacos
copying build/lib/xadnacos/__init__.py -> build/bdist.linux-x86_64/wheel/xadnacos
copying build/lib/xadnacos/cli.py -> build/bdist.linux-x86_64/wheel/xadnacos
copying build/lib/xadnacos/xadnacos.py -> build/bdist.linux-x86_64/wheel/xadnacos
running install_egg_info
Copying xadnacos.egg-info to build/bdist.linux-x86_64/wheel/xadnacos-0.1.0-py3.6.egg-info
running install_scripts
adding license file "LICENSE" (matched pattern "LICEN[CS]E*")
adding license file "AUTHORS.rst" (matched pattern "AUTHORS*")
creating build/bdist.linux-x86_64/wheel/xadnacos-0.1.0.dist-info/WHEEL
creating 'dist/xadnacos-0.1.0-py2.py3-none-any.whl' and adding 'build/bdist.linux-x86_64/wheel' to it
adding 'xadnacos/__init__.py'
adding 'xadnacos/cli.py'
adding 'xadnacos/xadnacos.py'
adding 'xadnacos-0.1.0.dist-info/AUTHORS.rst'
adding 'xadnacos-0.1.0.dist-info/LICENSE'
adding 'xadnacos-0.1.0.dist-info/METADATA'
adding 'xadnacos-0.1.0.dist-info/WHEEL'
adding 'xadnacos-0.1.0.dist-info/entry_points.txt'
adding 'xadnacos-0.1.0.dist-info/top_level.txt'
adding 'xadnacos-0.1.0.dist-info/RECORD'
removing build/bdist.linux-x86_64/wheel

# 执行完后,将在新创建的dist目录中创建两个文件,一个源归档文件和一个wheel文件
[root@jenkins-manager xadnacos]# ll
total 44
-rw-r--r-- 1 root root  151 Feb  4 14:29 AUTHORS.rst
drwxr-xr-x 4 root root   43 Feb  4 15:17 build
-rw-r--r-- 1 root root 3536 Feb  4 14:29 CONTRIBUTING.rst
drwxr-xr-x 2 root root   78 Feb  4 15:17 dist
drwxr-xr-x 2 root root  191 Feb  4 14:29 docs
-rw-r--r-- 1 root root   89 Feb  4 14:29 HISTORY.rst
-rw-r--r-- 1 root root 1067 Feb  4 14:29 LICENSE
-rw-r--r-- 1 root root 2266 Feb  4 14:29 Makefile
-rw-r--r-- 1 root root  262 Feb  4 14:29 MANIFEST.in
-rw-r--r-- 1 root root  846 Feb  4 14:29 README.rst
-rw-r--r-- 1 root root  144 Feb  4 14:29 requirements_dev.txt
-rw-r--r-- 1 root root  392 Feb  4 14:29 setup.cfg
-rw-r--r-- 1 root root 1642 Feb  4 15:16 setup.py
drwxr-xr-x 2 root root   49 Feb  4 14:29 tests
-rw-r--r-- 1 root root  282 Feb  4 14:29 tox.ini
drwxr-xr-x 2 root root   58 Feb  4 15:11 xadnacos
drwxr-xr-x 2 root root  154 Feb  4 15:17 xadnacos.egg-info
[root@jenkins-manager xadnacos]# ll dist/
total 20
-rw-r--r-- 1 root root  7139 Feb  4 15:17 xadnacos-0.1.0-py2.py3-none-any.whl
-rw-r--r-- 1 root root 11691 Feb  4 15:17 xadnacos-0.1.0.tar.gz

发布package到pypi仓库

配置pypi仓库即账号密码

[root@jenkins-manager xadnacos]# cat ~/.pypirc
[distutils]
index-servers=pypi

[pypi]
repository = https://upload.pypi.org/legacy/
username = <username>
password = <password>

开始上传

[root@jenkins-manager xadnacos]# twine upload dist/xadnacos-0.1.0*
/usr/local/lib/python3.6/site-packages/requests/__init__.py:104: RequestsDependencyWarning: urllib3 (1.26.12) or chardet (5.0.0)/charset_normalizer (2.0.12) doesn't match a supported version!
  RequestsDependencyWarning)
Uploading distributions to https://upload.pypi.org/legacy/
Uploading xadnacos-0.1.0-py2.py3-none-any.whl
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.1k/12.1k [00:03<00:00, 3.79kB/s]
Uploading xadnacos-0.1.0.tar.gz
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 16.3k/16.3k [00:02<00:00, 7.85kB/s]

View at:
https://pypi.org/project/xadnacos/0.1.0/

此时打开提示的连接:https://pypi.org/project/xadnacos/0.1.0/

pip发布自定义package

发布下一个版本

修改完功能后编辑setup.py文件,将里面的version跟换即可,此处修改REAME.txt做示范

[root@jenkins-manager xadnacos]# cat README.rst
========
xadnacos
========


.. image:: https://img.shields.io/pypi/v/xadnacos.svg
        :target: https://pypi.python.org/pypi/xadnacos

.. image:: https://img.shields.io/travis/KONE-XAD/xadnacos.svg
        :target: https://travis-ci.org/KONE-XAD/xadnacos

.. image:: https://readthedocs.org/projects/xadnacos/badge/?version=latest
        :target: https://xadnacos.readthedocs.io/en/latest/?badge=latest
        :alt: Documentation Status




python sdk for nacos


* Free software: MIT license
* Documentation: https://xadnacos.readthedocs.io.


Features
--------

* TODO

Credits
-------

This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.

.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage

修改setup.py中的版本

[root@jenkins-manager xadnacos]# cat setup.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""The setup script."""

from setuptools import setup, find_packages

with open('README.rst', 'r', encoding='utf-8') as readme_file:
    readme = readme_file.read()

with open('HISTORY.rst', 'r', encoding='utf-8') as history_file:
    history = history_file.read()

requirements = ['Click>=7.0', 'requests>=2.20.0']

setup_requirements = [ ]

test_requirements = [ ]

setup(
    author="KONE-XAD",
    author_email='1793360097@qq.com',
    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
    classifiers=[
        'Development Status :: 2 - Pre-Alpha',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: MIT License',
        'Natural Language :: English',
        "Programming Language :: Python :: 2",
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
    ],
    description="python sdk for nacos",
    entry_points={
        'console_scripts': [
            'xadnacos=xadnacos.cli:main',
        ],
    },
    install_requires=requirements,
    license="MIT license",
    long_description=readme + '\n\n' + history,
    include_package_data=True,
    keywords='xadnacos',
    name='xadnacos',
    packages=find_packages(include=['xadnacos', 'xadnacos.*']),
    setup_requires=setup_requirements,
    test_suite='tests',
    tests_require=test_requirements,
    url='https://github.com/KONE-XAD/xadnacos',
    version='0.1.3',
    zip_safe=False,
)

重新生成包并上传

[root@jenkins-manager xadnacos]# python3 setup.py sdist bdist_wheel
[root@jenkins-manager xadnacos]# twine upload dist/xadnacos-0.1.3*
/usr/local/lib/python3.6/site-packages/requests/__init__.py:104: RequestsDependencyWarning: urllib3 (1.26.12) or chardet (5.0.0)/charset_normalizer (2.0.12) doesn't match a supported version!
  RequestsDependencyWarning)
Uploading distributions to https://upload.pypi.org/legacy/
Uploading xadnacos-0.1.3-py2.py3-none-any.whl
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 13.6k/13.6k [00:03<00:00, 4.49kB/s]
Uploading xadnacos-0.1.3.tar.gz
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 17.7k/17.7k [00:02<00:00, 8.08kB/s]

View at:
https://pypi.org/project/xadnacos/0.1.3/
pip发布自定义package

正文完
 
xadocker
版权声明:本站原创文章,由 xadocker 2023-02-04发表,共计24412字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)