共计 24412 个字符,预计需要花费 62 分钟才能阅读完成。
最近博主在折腾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内编写你的功能
[ | ]|
. | |
└── 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> |
开始上传
[ | ]|
/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/
发布下一个版本
修改完功能后编辑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, | |
) |
重新生成包并上传
[ | ]|
[ | ]|
/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/ | |
正文完