zoukankan      html  css  js  c++  java
  • 打包上传python代码到pypi,通过pip安装使用

    上传自己的模块到pypi,可以用pip安装,方便自己和其他人使用

    打包结构如下图所示

    ├── project_name  # 工程文件夹,所有代码文件存放目录
    │   ├── a.py
    │   ├── b.py
    │   ├── __init__.py  # 这个文件不能少
    │   ├── dir
    │   │   ├── d.py
    │   │   ├── e.py
    │   │   ├── f.zip
    │   │   └── __init__.py
    │   ├── README.md
    │   └── requirements.txt
    └── setup.py  # 用于打包配置的代码,与project_name文件夹同级目录
    

    注意事项

    1. 项目内部采用工程名(模块名,包名)开头的方式导入模块,比如: from project_name.xxx import abc,不然外部安装成功后,使用也会报错
    2. 项目根目录下需要有 __init__.py 文件,且如果需要将指定目录打包,对应目录下也需要有此文件
    3. 尽量不要用相对路径方式导入,尽量使用 项目名.模块名 方式导入
    4. 如果要加载配置文件,代码里面使用绝对路径方式:使用 项目名__file__ 取路径 或者 项目名.__path__[0]来得到绝对路径
    5. 非py文件需要在 setup.py 的 data_files 参数里面配置,不然打包时所需的 配置文件、模型文件不会被打包

    生成安装文件

    先到pypi官网 https://pypi.org/搜索一下项目是否重名

    setup.py

    from setuptools import find_packages, setup
    
    name = 'img_classifier'
    requires_list = open(f'{name}/requirements.txt', 'r', encoding='utf8').readlines()
    requires_list = [i.strip() for i in requires_list]
    
    setup(
        name=name,  # 包名同工程名,这样导入包的时候更有对应性
        version='1.0.0',
        author="Jayson",
        author_email='jaysonteng@163.com',
        description="encapsulate logger",
        python_requires="==3.7.*",
        packages=find_packages(),
        package_data={"": ["*"]},  # 数据文件全部打包
        include_package_data=True,  # 自动包含受版本控制(svn/git)的数据文件
        zip_safe=False,
        # data_files=['img_classifier/config/conf.yaml',
        #             'img_classifier/models/flag.pt',
        #             'img_classifier/people_model/face.lib',
        #             'img_classifier/porn_model/porn_classifier_model.onnx'
        #             ]
        
        # 设置依赖包
        install_requires=requires_list
    )
    
    –name 包名称
    –version (-V) 包版本
    –author 程序的作者
    –author_email 程序的作者的邮箱地址
    –maintainer 维护者
    –maintainer_email 维护者的邮箱地址
    –url 程序的官网地址
    –license 程序的授权信息
    –description 程序的简单描述
    –long_description 程序的详细描述
    –platforms 程序适用的软件平台列表
    –classifiers 程序的所属分类列表
    –keywords 程序的关键字列表
    –packages 需要处理的包目录(包含__init__.py的文件夹)
    –py_modules 需要打包的python文件列表
    –download_url 程序的下载地址
    –cmdclass
    –data_files 打包时需要打包的数据文件,如图片,配置文件等
    –scripts 安装时需要执行的脚步列表
    –package_dir 告诉setuptools哪些目录下的文件被映射到哪个源码包。一个例子:package_dir = {’’: ‘lib’},表示“root package”中的模块都在lib 目录中。
    –requires 定义依赖哪些模块
    –provides定义可以为哪些模块提供依赖
    –find_packages() 对于简单工程来说,手动增加packages参数很容易,刚刚我们用到了这个函数,它默认在和setup.py同一目录下搜索各个含有 init.py的包。
    其实我们可以将包统一放在一个src目录中,另外,这个包内可能还有aaa.txt文件和data数据文件夹。另外,也可以排除一些特定的包
    find_packages(exclude=[".tests", ".tests.", "tests.", “tests”])
    –install_requires = [“requests”] 需要安装的依赖包
    –entry_points 动态发现服务和插件,下面详细讲
    

    MANIFEST.in 文件

    由于 data_files 参数即将被弃用,所以后续需要使用此方法
    include_package_data = True  # setup中这个参数必须声明
    
    MANIFEST.in文件与setup.py文件在同一层目录
    
    # 然后在 MANIFEST.in 中代码格式如下,进行文件的操作
    include *.txt  # 包含文件
    recursive-include examples *.txt *.py  # 递归查找这三个类型文件,多个文件用空格隔开
    prune examples/sample?/build  # 排除此文件
    

    打包安装

    python setup.py build   # build可以省略
    
    python setup.py sdist   ## dist目录下生成了最终的压缩包(默认格式tar.gz),可以指定压缩包类型通过指定参数  --formats=zip,gztar...  参考链接:https://docs.python.org/3.7/distutils/sourcedist.html
    
    cd dist
    
    解压:tar -zxvf **.tar.gz   # 也可以不解压,通过easy_install 来直接安装,ps:通过easy_install安装的卸载相对麻烦些
    
    python setup.py build   # build可以省略
    
    python setup.py install # 安装模块
    
    python setup.py develop # 调试模式,不会真正安装,生成一个软链接,这边更新以后,导入的包会随之更新,方便调试
    

    这种方式安装较麻烦,并且包含的文件有重复的情况,在package/包/根目录下面有重复的data_files的文件

    安装后,包名下划线会被转换为短横线,在pip list中可以看到

    使用下面命令生成 egg 包:

    python setup.py bdist_egg
    

    或者生成 whl 包:

    python setup.py bdist_wheel  # 在dist目录下生成 *.whl文件
    python3 setup.py sdist bdist_wheel  # 可以wheel和源文件同时生成
    pip install *whl
    

    其他格式打包

    python setup.py bdist_wininst  # 生成windows .exe 可执行文件
    python setup.py bdist_rpm  # 实现linux rpm 包的构建
    

    上传

    典型的 .pypirc 文件

    可以配置到$HOME/.pypirc文件中,就不用多次输入了。window: C:Users用户名.pypirc

    上传方式1,不推荐,用户密码容易被劫持

    [distutils]
    index-servers = pypi
    
    [pypi]
    repository = https://upload.pypi.org/legacy/
    username:xxx
    password:xxx
    
    [pypitest]
    repository: https://test.pypi.org/legacy/  # 测试平台
    username: your_username
    password: your_password
    
    # 然后使用这条命令进行信息注册,完成后,你可以在 PyPi 上看到项目信息。
    python setup.py register
    
    # 注册完了后,你还要上传源码包,别人才使用下载安装
    python setup.py upload  # 默认上传到正式平台
    python setup.py upload -r pypi  # 正式平台
    python setup.py upload -r pypitest  # 测试平台
    python setup.py sdist upload -r pypi # 一步创建发布
    

    上传方式2,推荐

    或者也可以使用 twine 工具注册上传

    pypi官网:https://pypi.org/

    去官网注册个账号

    使用 twine 上传自己的 python 包到 pypi

    # 安装twine
    pip install twine
    
    # 打包检查
    python setup.py check
    
    # 打包
    python3 setup.py sdist build
    
    # 上传
    twine upload dist/*
    
    # .pypirc文件只需要下面内容
    [pypi]
    username:xxx
    password:xxx
    
    # 下载安装
    pip install name  # name是setup里面name对应的名字
    

    twine 提示输入 pypi 账号和密码,上传成功否就能在自己的pypi账号中看到了。

    但是并不是马上就能使用 pip 安装了。需要等待一段时间。

    如果要更新原版,除了pip uninstall外,还需要删除原来缓存的文件,不然不会下载新的。

    如果更新了版本号,就不存在这种情况

    windows路径:C:Users(自己的用户名)AppDataRoamingPythonPython35site-packages

    linux路径:~/.cache/pip

    报错

    ## 1
    ValueError: pypitest not found in .pypirc
    解决方法: 将其放到根目录
    
    ## 2
    configparser.NoSectionError: No section: 'pypi pypitest'
    解决方法: 需要配置
    [distutils] 
    index-servers = 
        pypi
        pypitest
    注意需要用上面的格式,换行
    
    ## 3
    Server response (410): Project pre-registration is no longer required or supported, upload your files instead.
    解决方法:别使用python setup.py register、upload方法,使用twine方法上传
    
    

    参考链接:https://www.cnblogs.com/leffss/p/12029963.html

  • 相关阅读:
    编译器合成的拷贝构造函数
    WIN phone 8.1 SDK 坑遇到 Hyper-V
    JDBC编程步骤
    关闭safari浏览器button默认样式
    Codeforces Round #273 (Div. 2)
    android Activity之间数据传递 Parcelable和Serializable接口的使用
    如何删除JAVA集合中的元素
    Android自定义长按事件
    关于android多点触控
    Android Touch系统简介(二):实例详解onInterceptTouchEvent与onTouchEvent的调用过程
  • 原文地址:https://www.cnblogs.com/jaysonteng/p/15221886.html
Copyright © 2011-2022 走看看