python项目打包上传PyPI

PyPI

PyPI(Python Package Index)是Python编程语言中最大的第三方软件包仓库,它是Python生态系统的核心组成部分。PyPI提供了一个集中存储和分发Python软件包的平台,为开发者和用户提供了便利的方式来查找、安装和分享各种Python软件包。

在PyPI上,开发者可以发布自己的Python软件包,而其他开发者和用户则可以轻松地通过pip等工具安装这些软件包。PyPI中的软件包涵盖了各种领域,包括Web开发、数据科学、机器学习、人工智能等。无论是初学者还是有经验的开发者,都能从PyPI中找到适合自己需求的软件包。

使用PyPI非常简单,只需在命令行中运行pip install package-name命令,就能安装你需要的软件包。同时,PyPI支持版本控制,使得开发者可以灵活地选择软件包的特定版本进行安装。这为项目开发和维护提供了方便。

作为一个开放的平台,PyPI鼓励开发者共享他们的项目和代码,并与其他开发者合作。通过PyPI,开发者可以轻松获取其他人的优秀代码,并在自己的项目中重用。这种共享和合作精神促进了Python社区的繁荣和创新。

PyPI在Python生态系统中扮演着关键的角色,它提供了一个开放、共享和可访问的平台,使得Python开发者能够更加高效地开发项目、分享代码、并与全球开发者社区共同成长。无论是新手还是专业开发者,都应该充分利用PyPI的优势,探索更多有趣和有用的Python软件包,为自己的项目增添活力与创新。

示例项目

首先,更新pip工具,然后创建一个项目目录:

pip install --upgrade pip
mkdir packaging_example && cd packaging_example

接着创建如下目录结构:

packaging_example/
├── LICENSE
├── pyproject.toml
├── README.md
├── src/
│   └── example_package_YOUR_USERNAME_HERE/
│       ├── __init__.py
│       └── example.py
└── tests/

YOUR_USERNAME_HERE要取一个独特点的名字,以避免跟其他人上传的包冲突,我这里起的名字是peter777😀

包含Python文件的目录应与项目名称匹配。这样可以简化配置,并对安装该包的用户更加明显。

__init__.py文件是必需的,以便将该目录作为一个包进行导入,并且应该是空的。

example.py是包中一个模块的示例,其中可以包含你的包的逻辑(函数、类、常量等)。打开该文件并输入以下内容:

def add_one(number):return number + 1

so easy! 如果你对Python的模块和导入包不熟悉,请花几分钟阅读Python的包和模块文档。

pyproject.toml

pyproject.toml文件告诉"frontend"构建工具(如pip和build工具)要使用什么"backend"工具来为你的项目创建分发包。你可以从多个后端工具中选择。本文使用setuptools,但与Hatchling、Flit、PDM等支持metadata项目表的其他工具的工作方式相同。

注意:

某些构建后端是更大工具的一部分,它们提供命令行界面和额外功能,如项目初始化和版本管理,以及构建、上传和安装软件包。本文使用单一目的的独立工具。

打开pyproject.toml并输入:

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

requires 是一个包含构建你的软件包所需依赖的列表。你不需要手动安装这些依赖,构建工具(如pip)会在构建过程中自动在一个临时的、隔离的虚拟环境中安装它们。

build-backend 是构建工具在执行构建过程时所使用的 Python 对象的名称。它指定了用于构建你的项目的后端工具。不同的构建工具可能使用不同的后端工具来执行构建操作。在 pyproject.toml 文件中,你可以指定你想要使用的后端工具名称。例如,如果你想使用 setuptools 来构建你的项目,可以将 build-backend 设置为 "setuptools.build_meta"。这样一来,构建工具就会使用 setuptools 来执行项目的构建过程。

接下来在pyproject.toml中继续填写项目元数据:

[project]
name = "example_package_YOUR_USERNAME_HERE"
version = "0.0.1"
authors = [{ name="Example Author", email="author@example.com" },
]
description = "A small example package"
readme = "README.md"
requires-python = ">=3.7"
classifiers = ["Programming Language :: Python :: 3","License :: OSI Approved :: MIT License","Operating System :: OS Independent",
][project.urls]
"Homepage" = "https://github.com/pypa/sampleproject"
"Bug Tracker" = "https://github.com/pypa/sampleproject/issues"

YOUR_USERNAME_HERE 替换为你的用户名,确保你拥有一个独特的软件包名称,避免与其他遵循本教程的人上传的软件包冲突。

  • name 是你的软件包的分发名称。它可以是任何名称,只要包含字母、数字、下划线、连字符和点号。同时,它在 PyPI 上不能与已有的软件包名称重复。请确保在本教程中使用你的用户名作为名称,以确保你不会尝试上传与现有包同名的软件包。

  • version 是软件包的版本号。可以参考版本说明规范了解更多关于版本号的细节。某些构建后端可能允许通过其他方式指定版本号,例如从文件或git标签中获取。

  • authors 用于标识软件包的作者。你需要为每个作者指定姓名和电子邮件。也可以以相同格式列出维护者(maintainers)。

  • description 是对软件包的简短、一句话概述。

  • readme 是一个指向包含软件包详细描述的文件的路径。这将在 PyPI 上的软件包详情页面上显示。在本例中,描述从 README.md 文件中加载(这是一种常见的模式)。还有一种更高级的表格形式,详细描述在项目元数据规范中。

  • requires-python 指定你的项目支持的Python版本。安装工具如pip会回溯查找旧版本的软件包,直到找到一个与匹配的Python版本相符的版本。

  • classifiers 给索引和pip一些关于你的软件包的额外元数据。在本例中,软件包仅与Python 3兼容,采用MIT许可证,且不依赖于特定操作系统。你应该至少包含你的软件包适用的Python版本、软件包所使用的许可证以及支持的操作系统信息。有关分类器的完整列表,请参阅 https://pypi.org/classifiers/。

  • urls 允许你列出任意数量的额外链接,以在PyPI上展示。通常这可以用来提供源代码、文档、问题跟踪器等链接。

可以参阅项目元数据规范(Project Metadata Specification)了解更多字段细节和定义内容。

接下来就可以开始打包了,打包前需要先安装build包,然后打包:

❯ python -m pip install --upgrade build
❯ python -m build
* Creating virtualenv isolated environment...
* Installing packages in isolated environment... (setuptools>=61.0)
* Getting build dependencies for sdist...
running egg_info
creating src\example_package_peter777.egg-info
writing src\example_package_peter777.egg-info\PKG-INFO
writing dependency_links to src\example_package_peter777.egg-info\dependency_links.txt
writing top-level names to src\example_package_peter777.egg-info\top_level.txt
writing manifest file 'src\example_package_peter777.egg-info\SOURCES.txt'
reading manifest file 'src\example_package_peter777.egg-info\SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'src\example_package_peter777.egg-info\SOURCES.txt'
* Building sdist...
running sdist
running egg_info
writing src\example_package_peter777.egg-info\PKG-INFO
writing dependency_links to src\example_package_peter777.egg-info\dependency_links.txt
writing top-level names to src\example_package_peter777.egg-info\top_level.txt
reading manifest file 'src\example_package_peter777.egg-info\SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'src\example_package_peter777.egg-info\SOURCES.txt'
running check
creating example_package_peter777-0.0.1
creating example_package_peter777-0.0.1\src
creating example_package_peter777-0.0.1\src\example_package_peter777
creating example_package_peter777-0.0.1\src\example_package_peter777.egg-info
copying files to example_package_peter777-0.0.1...
copying LICENSE -> example_package_peter777-0.0.1
copying README.md -> example_package_peter777-0.0.1
copying pyproject.toml -> example_package_peter777-0.0.1
copying src\example_package_peter777\__init__.py -> example_package_peter777-0.0.1\src\example_package_peter777
copying src\example_package_peter777\example.py -> example_package_peter777-0.0.1\src\example_package_peter777
copying src\example_package_peter777.egg-info\PKG-INFO -> example_package_peter777-0.0.1\src\example_package_peter777.egg-info
copying src\example_package_peter777.egg-info\SOURCES.txt -> example_package_peter777-0.0.1\src\example_package_peter777.egg-info
copying src\example_package_peter777.egg-info\dependency_links.txt -> example_package_peter777-0.0.1\src\example_package_peter777.egg-info
copying src\example_package_peter777.egg-info\top_level.txt -> example_package_peter777-0.0.1\src\example_package_peter777.egg-info
Writing example_package_peter777-0.0.1\setup.cfg
Creating tar archive
removing 'example_package_peter777-0.0.1' (and everything under it)
* Building wheel from sdist
* Creating virtualenv isolated environment...
* Installing packages in isolated environment... (setuptools>=61.0)
* Getting build dependencies for wheel...
running egg_info
writing src\example_package_peter777.egg-info\PKG-INFO
writing dependency_links to src\example_package_peter777.egg-info\dependency_links.txt
writing top-level names to src\example_package_peter777.egg-info\top_level.txt
reading manifest file 'src\example_package_peter777.egg-info\SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'src\example_package_peter777.egg-info\SOURCES.txt'
* Installing packages in isolated environment... (wheel)
* Building wheel...
running bdist_wheel
running build
running build_py
creating build
creating build\lib
creating build\lib\example_package_peter777
copying src\example_package_peter777\example.py -> build\lib\example_package_peter777
copying src\example_package_peter777\__init__.py -> build\lib\example_package_peter777
running egg_info
writing src\example_package_peter777.egg-info\PKG-INFO
writing dependency_links to src\example_package_peter777.egg-info\dependency_links.txt
writing top-level names to src\example_package_peter777.egg-info\top_level.txt
reading manifest file 'src\example_package_peter777.egg-info\SOURCES.txt'
adding license file 'LICENSE'
writing manifest file 'src\example_package_peter777.egg-info\SOURCES.txt'
installing to build\bdist.win-amd64\wheel
running install
running install_lib
creating build\bdist.win-amd64
creating build\bdist.win-amd64\wheel
creating build\bdist.win-amd64\wheel\example_package_peter777
copying build\lib\example_package_peter777\example.py -> build\bdist.win-amd64\wheel\.\example_package_peter777
copying build\lib\example_package_peter777\__init__.py -> build\bdist.win-amd64\wheel\.\example_package_peter777
running install_egg_info
Copying src\example_package_peter777.egg-info to build\bdist.win-amd64\wheel\.\example_package_peter777-0.0.1-py3.8.egg-info
running install_scripts
creating build\bdist.win-amd64\wheel\example_package_peter777-0.0.1.dist-info\WHEEL
creating 'C:\Users\yp.wang\OneDrive - hi2me\working\packaging_example\dist\.tmp-yy65h9xp\example_package_peter777-0.0.1-py3-none-any.whl' and adding 'build\bdist.win-amd64\wheel' to it
adding 'example_package_peter777/__init__.py'
adding 'example_package_peter777/example.py'
adding 'example_package_peter777-0.0.1.dist-info/LICENSE'
adding 'example_package_peter777-0.0.1.dist-info/METADATA'
adding 'example_package_peter777-0.0.1.dist-info/WHEEL'
adding 'example_package_peter777-0.0.1.dist-info/top_level.txt'
adding 'example_package_peter777-0.0.1.dist-info/RECORD'
removing build\bdist.win-amd64\wheel
Successfully built example_package_peter777-0.0.1.tar.gz and example_package_peter777-0.0.1-py3-none-any.whl

看到最后一行就说明打包成功了。是时候将软件包上传到Python Package Index了!

首先,需要在TestPyPI上注册一个帐户。TestPyPI是包索引的一个单独实例,旨在用于测试和实验。对于像本文这样的实验,我们不希望上传到真正的索引,因此TestPyPI非常适合。要注册一个帐户,请访问 https://test.pypi.org/account/register/ 并按照页面上的步骤完成注册。在上传任何软件包之前,还需要验证电子邮件地址。更多细节请参阅《使用TestPyPI》。

为了安全地上传你的项目,你需要一个PyPI API令牌。在 https://test.pypi.org/manage/account/#api-tokens 上创建一个令牌,将"Scope"设置为"Entire account"。在复制和保存令牌之前,不要关闭该页面,因为你之后将无法再看到这个令牌。

现在,我已经注册好了,可以使用Twine工具上传分发包。需要安装Twine:

python -m pip install --upgrade twine

安装完成后,就可以使用Twine上传软件包到TestPyPI。上传的命令如下:

❯ python -m twine upload --repository testpypi dist/*
Uploading distributions to https://test.pypi.org/legacy/
Enter your username: __token__
Enter your password:
Uploading example_package_peter777-0.0.1-py3-none-any.whl
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.6/17.6 kB • 00:00 • ?
Uploading example_package_peter777-0.0.1.tar.gz
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.2/17.2 kB • 00:00 • ?View at:
https://test.pypi.org/project/example-package-peter777/0.0.1/

上传过程会收到一个用户名和密码的提示。对于用户名,请使用__token__。对于密码,请使用令牌值,包括前缀pypi-。密码粘贴时不会有任何字符提示,确定正确继续执行就可以。

这样就上传成功了,接下来用pip安装验证下:

❯ pip install -i https://test.pypi.org/simple/ example-package-peter777==0.0.1
Defaulting to user installation because normal site-packages is not writeable
Looking in indexes: https://test.pypi.org/simple/
Collecting example-package-peter777==0.0.1Obtaining dependency information for example-package-peter777==0.0.1 from https://test-files.pythonhosted.org/packages/fe/2e/f7b20dd99cbf107e44382654fd410cb5edce9162412e23710bce1399bcf7/example_package_peter777-0.0.1-py3-none-any.whl.metadataDownloading https://test-files.pythonhosted.org/packages/fe/2e/f7b20dd99cbf107e44382654fd410cb5edce9162412e23710bce1399bcf7/example_package_peter777-0.0.1-py3-none-any.whl.metadata (573 bytes)
Downloading https://test-files.pythonhosted.org/packages/fe/2e/f7b20dd99cbf107e44382654fd410cb5edce9162412e23710bce1399bcf7/example_package_peter777-0.0.1-py3-none-any.whl (14 kB)
Installing collected packages: example-package-peter777
Successfully installed example-package-peter777-0.0.1~ via 🐍 v3.8.10 took 4s
❯ python
Python 3.8.10 (tags/v3.8.10:3d8993a, May  3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from example-package-peter777 import exampleFile "<stdin>", line 1from example-package-peter777 import example^
SyntaxError: invalid syntax
>>> from example_package_peter777 import example
>>> example.add_one(5)
6

注意,虽然上传到pypi的路径是example-package-peter777pip安装时也是pip install -i https://test.pypi.org/simple/ example-package-peter777==0.0.1,但是在导入包时应使用example_package_peter777

公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/75294.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL触发器详解保证入土

文章目录 简介一、MySQL触发器基础触发器分类基础常用关键字1. 定义触发器2. 创建和删除触发器3. 执行时机和条件 二、MySQL触发器的使用场景1. 数据完整性约束插入触发器更新触发器删除触发器 2. 数据变更日志的记录与追踪3. 触发器与存储过程的对比与选择 三、触发器的性能和…

C++学习笔记(重载、类)

C 1、函数重载2、类2.1、类的方法和属性2.2、类的方法的定义2.3、构造器和析构器2.4、基类与子类2.5、类的public、protected、private继承2.6、类的方法的重载2.7、子类方法的覆盖2.8、继承中的构造函数和析构函数 1、函数重载 函数重载大概可以理解为&#xff0c;定义两个名…

【2023年数学建模国赛】C题解题思路

第一问 要求分析分析蔬菜各品类及单品销售量的分布规律及相互关系。该问题可以拆分成三个角度进行剖析。 1&#xff09;各种类蔬菜的销售量分布、蔬菜种类与销售量之间的关系&#xff1b;2&#xff09;各种类蔬菜的销售量的月份分布、各种类蔬菜销售量与月份之间的相关关系&a…

Curator实现Zookeeper分布式锁

Curator实现Zookeeper分布式锁 1、介绍 Curator是netflix公司开源的一套zookeeper客户端&#xff0c;目前是Apache的顶级项目。与Zookeeper提供的原生客户端相比&#xff0c;Curator的抽象层次更高&#xff0c;简化了Zookeeper客户端的开发量。Curator解决了很多zookeeper客户…

C语言实现三字棋

实现以下&#xff1a; 1游戏不退出&#xff0c;继续玩下一把&#xff08;循环&#xff09; 2应用多文件的形式完成 test.c. --测试游戏 game.c -游戏函数的实现 game.h -游戏函数的声明 (2)游戏再走的过程中要进行数据的存储&#xff0c;可以使用3*3的二维数组 char bor…

idea VCS配置多个远程仓库

Idea VCS配置多个远程仓库 首先要有两个或多个不同远程仓库地址 idea 添加数据源 查看推送记录 添加数据源 ok之后填写账号密码 推送本地项目 选择不同远程地址 push 查看不同远程地址的 不同分支的 推送记录 不期而遇的温柔&#xff1a; 应用开源架构进行项目开发&#xff0…

Java版企业电子招标采购系统源码—企业战略布局下的采购寻源

功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外部供…

Qt串口基本设置与协议收发

前言 1.一直都想要做一个Qt上位机&#xff0c;趁着这个周末有时间&#xff0c;动手写一下 2.comboBox没有点击的信号&#xff0c;所以做了一个触发的功能 3.Qt的数据类型很奇怪&#xff0c;转来转去的我也搞得很迷糊 4.给自己挖个坑&#xff0c;下一期做一个查看波形的上位…

Android 9.0 网络之netd详解

一、DHCP流程 分析netd之前先了解一下网络自动获取IP流程&#xff0c;借鉴下图流程查看代码&#xff1a; &#xff08;1&#xff09;WIFI扫描到可用网络后进行连接&#xff0c;代码路径&#xff1a;\frameworks\opt\net\wifi\service\java\com\android\server\wifi\WifiStateMa…

OJ练习第167题——单词接龙

单词接龙 力扣链接&#xff1a;127. 单词接龙 题目描述 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> … -> sk&#xff1a; 每一对相邻的单词只差一个字母。 对于 1 < i < k 时&…

Vue2+Vue3笔记(尚硅谷张天禹老师)day03

声明:只是记录&#xff0c;初心是为了让页面更好看,会有错误,我并不是一个会记录的人&#xff0c;所以有点杂乱无章的感觉&#xff0c;我先花点时间把视频迅速过掉&#xff0c;再来整理这些杂乱无章的内容 计划是一天更新一点 待做的东西 完成博客记录把完成后的博客记录拆成单…

计算机网络的故事——简单的HTTP协议

简单的HTTP协议 文章目录 简单的HTTP协议一、简单的HTTP协议 一、简单的HTTP协议 HTTP是不保存状态的协议&#xff0c;为了实现保存状态功能于是引入了Cookie技术。 method: get:获取资源 post:传输实体主体 put:传输文件 head:获取报文首部&#xff0c;用于确认URI的有效性以…

把文件上传到Gitee的详细步骤

目录 第一步&#xff1a;创建一个空仓库 第二步&#xff1a;找到你想上传的文件所在的地址&#xff0c;打开命令窗口&#xff0c;git init 第三步&#xff1a;git add 想上传的文件 &#xff0c;git commit -m "给这次提交取个名字" 第四步&#xff1a;和咱们在第…

从0开始的ios自动化测试

最近由于工作内容调整&#xff0c;需要开始弄ios自动化了。网上信息有点杂乱&#xff0c;这边我就按我的实际情况&#xff0c;顺便记录下来&#xff0c;看是否能帮到有需要的人。 环境准备 安装tidevice pip3 install -U “tidevice[openssl]”它的作用是&#xff0c;帮你绕…

C++ 多态语法点

前置知识点 成员变量和成员函数分开存储&#xff0c;只有非静态成员变量才属于类的对象上。 静态成员变量和静态成员函数没有在类上存储。 非静态成员函数也不属于类的对象上 class Animal {public:virtual void speak(){cout<<"动物在说话"<<endl;}}v…

注解-宋红康

目录 一、注解&#xff08;Annotation&#xff09;概述二、常见的注解实例三、如何自定义注解四、JDK中的四个元注解五、Java8注解的新特性1、可重复注解2、类型注解 一、注解&#xff08;Annotation&#xff09;概述 二、常见的注解实例 三、如何自定义注解 自定义注解必须配…

Filter过滤器及HttpServletRequest和HttpServletResponse

拦截器&#xff08;Interceptor&#xff09;和过滤器&#xff08;Filter&#xff09;的执行顺序 tomcat->Filter->Interceptor->Controller 过滤器&#xff08;Filter&#xff09;概述&#xff1f; Filter过滤器是JavaWeb的三大组件之一&#xff0c;三大组件分别为&…

虚拟化和容器

文章目录 1 介绍1.1 简介1.2 虚拟化工作原理1.3 两大核心组件&#xff1a;QEMU、KVMQEMUKVM 1.4 发展历史1.5 虚拟化类型1.6 云计算与虚拟化1.7 HypervisorHypervisor分为两大类 1.8 虚拟化 VS 容器 2 虚拟化应用dockerdocker 与虚拟机的区别 K8Swine 参考 1 介绍 1.1 简介 虚…

springBoot对接Apache POI 实现excel下载和上传

搭建springboot项目 此处可以参考 搭建最简单的SpringBoot项目_Steven-Russell的博客-CSDN博客 配置Apache POI 依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.2</version> </…

轻量高效、灵活可扩展!了解下Alibaba QLExpress规则引擎的魅力

文章首发地址 QLExpress是一个基于Java语言的轻量级、高性能的规则引擎。它提供了一种简洁、灵活的方式来编写和执行规则&#xff0c;可以用于实现复杂的业务逻辑和决策过程。以下是QLExpress的一些特性和功能&#xff1a; 简洁易用&#xff1a; QLExpress采用类似于SQL的语法…