在我们安装 Python 库的时候,通常我们都是pip install XXX,感觉很酷,经常会想,这个XXX是怎么来的,我们可以自己生成吗?答案当然是可以的。下面我们就来看看如何生成并发布到pypi上使用。
1、创建一个这样的目录结构
- packaging_tutorial # 该目录名称随便取
- ├── LICENSE
- ├── README.md
- ├── example_pkg # 该目录名称随便取,该目录用于存放我们已经写好能正常使用的库/方法/项目
- │ └── __init__.py
- ├── setup.py
- └── tests
2、编辑example_pkg/__init__.py,写入以下内容
- name = "example_pkg"
3、编辑setup.py 文件,
- import os
- import setuptools
-
- # 如果readme文件中有中文,那么这里要指定encoding='utf-8',否则会出现编码错误
- with open(os.path.join(os.path.dirname(__file__), 'README.rst'), encoding='utf-8') as readme:
- README = readme.read()
-
- # 允许setup.py在任何路径下执行
- os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
-
- setuptools.setup(
- name="example-pkg-YOUR-USERNAME-HERE", # 库名,需要在pypi中唯一
- version="0.0.1", # 版本号
- author="Example Author", # 作者
- author_email="author@example.com", # 作者邮箱(方便使用者发现问题后联系我们)
- description="A small example package", # 简介
- long_description=long_description, # 详细描述(一般会写在README.md中)
- long_description_content_type="text/markdown", # README.md中描述的语法(一般为markdown)
- url="https://github.com/pypa/sampleproject", # 库/项目主页,一般我们把项目托管在GitHub,放该项目的GitHub地址即可
- packages=setuptools.find_packages(), #默认值即可,这个是方便以后我们给库拓展新功能的
- classifiers=[ # 指定该库依赖的Python版本、license、操作系统之类的
- "Programming Language :: Python :: 3",
- "License :: OSI Approved :: MIT License",
- "Operating System :: OS Independent",
- ],
- install_requires=[ # 该库需要的依赖库
- '你的库依赖的第三方库(也可以指定版本)',
- # exapmle
- 'pyautogui',
- 'Django >= 1.11, != 1.11.1, <= 2',
- ],
- python_requires='>=3.6',
- )
4、创建packaging_tutorial/README.md,向其写入自己对该库的简介、描述、配置等等,下面是一个实例
- # Example Package
-
- =====
- 登录和注册系统
- =====
- ## 这是一个用户登录和注册教学项目
- ## 这是一个可重用的登录和注册APP
- ## 该项目教程发布在www.cdsy.xyz
-
- ## 简单的使用步骤:
-
- 1. 创建虚拟环境
- 2. 使用pip安装第三方依赖
- 3. 添加相应的路由
- 4. 配置settings
- 5. 运行migrate命令,创建数据库和数据表
- 6. 链接你的index页面
- 7. 运行python manage.py runserver启动服务器
-
-
- ## 路由设置:
-
- from django.contrib import admin
- from django.urls import path, include
- from login import views
-
- urlpatterns = [
- path('admin/', admin.site.urls),
- path('index/', views.index),
- path('login/', views.login),
- path('register/', views.register),
- path('logout/', views.logout),
- path('confirm/', views.user_confirm),
- path('captcha/', include('captcha.urls'))
- ]
-
-
- ## settings配置:
-
- 1. 在INSTALLED_APPS中添加‘login’,'captcha'
- 2. 默认使用Sqlite数据库
- 3. LANGUAGE_CODE = 'zh-hans'
- 4. TIME_ZONE = 'Asia/Shanghai'
- 5. USE_TZ = False
-
- # 邮件服务设置
- 6. EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
- 7. EMAIL_HOST = 'smtp.sina.com'
- 8. EMAIL_PORT = 25
- 9. EMAIL_HOST_USER = 'xxxx@sina.com'
- 10. EMAIL_HOST_PASSWORD = 'xxxxx'
-
- # 注册有效期天数
- 11. CONFIRM_DAYS = 7
5、创建LICENSE版权申明文件。大多数Django相关的app都基于BSD版权。如果不是发布到正式场合,可以不写。对于每一个创建的库来说 LICENSE 是很重要的,这告诉大家我们的库能用在什么方面(商用?学习之类的)还有免责啊之类的;一般来说我们选择MIT
- MIT License
-
- Copyright (c) [year] [fullname]
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
MIT LICENSE 的大概意思是
- 软件可以随便用,随便改
- 可以免费,可以收费
- 软件的源文件里必须有这个许可证文档
- 我提供这个软件不是为了犯法,你要用它来犯法,那与我无关
- 你用这个软件犯事了,责任全在你自己,与其他贡献者无关
6、确保我们已安装最新setuptools和wheel和twine,下面是安装/更新命令
- python -m pip install --user --upgrade setuptools wheel twine
7、打包我们的库/项目
- python setup.py sdist bdist_wheel
此时在当前目录我们会看到以下输出:
- dist/
- example_pkg_your_username-0.0.1-py3-none-any.whl
- example_pkg_your_username-0.0.1.tar.gz
8、使用 twine 将打包好的库/项目上传到PYPI(需用到PYPI帐号密码,此时只是上传到PYPI测试服,还不能 pip install 这个库/项目)
- python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
我们会看到如下界面:
- Uploading distributions to https://test.pypi.org/legacy/
- Enter your username: [your username]
- Enter your password:
- Uploading example_pkg_your_username-0.0.1-py3-none-any.whl
- 100%|█████████████████████| 4.65k/4.65k [00:01<00:00, 2.88kB/s]
- Uploading example_pkg_your_username-0.0.1.tar.gz
- 100%|█████████████████████| 4.25k/4.25k [00:01<00:00, 3.05kB/s]
上传成功之后,我们可以去PYPI的测试服查看是否上传成功,能上传成功的话就说明肯定也能成功上传到PYPI正式服(附:PYPI测试服地址)
PYPI测试服的管理员会不定期删除上边的库,正式投入使用还是得上传到正式服。
若是想测试下上传到测试服的库能否使用,可以使用如下命令
- python -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-pkg-your-username
大致会出现以下:
- Collecting example-pkg-your-username
- Downloading https://test-files.pythonhosted.org/packages/.../example-pkg-your-username-0.0.1-py3-none-any.whl
- Installing collected packages: example-pkg-your-username
- Successfully installed example-pkg-your-username-0.0.1
9、将库上传到 PYPI正式服
- twine upload dist/*
参考1