第一步:写一个自己的Python包,setup.py
:
inst_data_dirs = ("sample_files", )
data_files = []
for inst_dir in inst_data_dirs:
dir_full_path = os.path.join(os.path.dirname(__file__), inst_dir)
for dirpath, dirnames, filenames in os.walk(dir_full_path):
list_files = [os.path.join(dirpath, f) for f in filenames]
data_files.append([dirpath, list_files])
install_proj_path = "/usr/local/share/mypackage"
for df in data_files:
df[0] = os.path.join(install_proj_path, df[0])
setuptools.setup(
name = "mypackage",
version = "1.0.0",
description = "<description>",
author = "<Author>",
author_email = "<Email>",
url = "<URL>",
data_files = data_files,
packages = ["mypackage"],
scripts = ["bin/mypackage-cmd"],
zip_safe = False
)
第二步:Install到本地做测试:python setup.py install
第三步:打包并上传到自己的pypi server:
sudo python setup.py sdist
- 上传到服务器
sftp myserver
, andput dist/mypackage.tar.gz
- 把这个tar.gz文件已到pypi的根目录下,例如:
/home/project/pypi
关于setup.py
Case 1: with PostInstall:
def rename_script():
if platform.system().lower() == "windows":
return
paths = os.environ["PATH"].split(":")
for path in paths:
src_path = os.path.join(path, "ospider.py")
if os.path.exists(src_path):
dest_path = os.path.join(path, "ospider")
os.rename(src_path, dest_path)
break
class PostDevelop(develop):
def run(self):
develop.run(self)
rename_script()
class PostInstall(install):
def run(self):
install.run(self)
rename_script()
setup(
...
cmdclass = {
"develop": PostDevelop,
"install": PostInstall
},
...
)
Case 2: include all data files inside one folder:
In file MANIFEST.in
: recursive-include package_folder *
and in setup.py
's setup()
function, add parameter include_package_data = True
问题
这里有个问题待解决,当用自己PostInstall时,放到pypi server上,然后用pip install去安装这个包,发现PostInstall的脚本根本没执行,在上面的例子里,也就是rename_script()
这个函数没有执行。Stackoverflow上有人问这个问题,但遗憾的是并没有一个好的解决方法,这个问题里他最后的解决方法是直接从repo里安装,不从pypi server上。所以我还挺奇怪"把包放pypi server上,然后pip不跑post install脚本"这种应该是很常见的问题,居然没有搜不到其他人问。