做个备忘,也希望可以帮到别人。
目录结构(初始化)
一般我们都会选择在项目的顶层包含较基础的文件,比如setup.py
,requirements
,README
等文件。
一般情况下,一个预发布的Python项目中应该包含以下几类文件:
- projects (项目的主体文件)
- setup.py
- requirements
- Readme (项目说明)
- docs (项目文档)
- test
其中,projects
文件夹要以项目命名,存放实际的Python Package.
这里放一个我的项目的目录作为例子。
➜ httpmultipart git:(master) tree -L 2
.
├── build
│ ├── bdist.linux-x86_64
│ └── lib.linux-x86_64-2.7
├── dist
│ ├── httpmultipart-0.1.0-py2.py3-none-any.whl
│ └── httpmultipart-0.1.0.tar.gz
├── docs
│ ├── _build
│ ├── conf.py
│ ├── index.rst
│ ├── Makefile
│ ├── userguide
│ └── userguide.rst
├── env
│ ├── bin
│ ├── include
│ ├── lib
│ └── local
├── httpmultipart
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── main.py
│ └── main.pyc
├── httpmultipart.egg-info
│ ├── dependency_links.txt
│ ├── not-zip-safe
│ ├── PKG-INFO
│ ├── SOURCES.txt
│ └── top_level.txt
├── LICENSE
├── MANIFEST.in
├── README.rst
├── setup.cfg
├── setup.py
└── test_httpmultipart.py
14 directories, 21 files
这个目录中包含了我的virtual enviroment
和打包构建时候生成的文件夹。
这些东西在下面会提到。
文档
文档的话,并没有严格要求必须使用什么样的工具进行构建,也没有很严格的格式要求。不过我推荐使用SPHINX
,它是用Python写的工具,使用了一种叫做reStructuredText
的语法编辑,可以对多个文本文件重编,可以输出成HTML或者PDF等格式。
这里稍微介绍下使用:
安装
$ pip install sphinx
初始化
$ cd docs $ sphinx-quickstart ...#(这里有一系列的提问,进行初始化)
编译
$ make html #(如果按照默认配置生成的Makefile的话,这样就可以编译出html了)
Sphinx的使用还有很多值得说的地方,推荐两个资料:
- 英文的Sphinx 的官方文档
- 中文的Python 开发实战
官方文档写的非常详细,那本书偏向于实战,是很不错的书。
还有很关键的一点是Sphinx有autodoc
和automodule
的扩展,
可以从代码中提取出文档,与代码直接进行关联。提供一个例子可以方便的在文档和源码中进行跳转。
Read the Docs 持续文档集成
说完写文档就不得不提到Read the Dosc
了,这是一个第三方的文档托管平台,使用Django
开发,它可以很轻松的和Github上的项目进行集成,在每次代码提交的时候会自动进行文档构建,我们可以看看生成文档的效果。现在有很多开源项目的文档都是托管在这里的,具体的配置可以参考官方文档。
TravisCI 持续集成
Travisci
可以与Github非常好的结合,可以手动导入repo
,并设置Webhooks & services
,在每次提交的时候都会测试运行来发现是否存在异常。在使用之前,我们需要先做一些初始化的操作:
创建
.travis.yml
文件我们需要告诉它一些基本的信息:
- 我们项目使用的语言
- 项目使用的语言版本
- 环境的依赖
- 是否需要
sudo
权限运行 - 使用什么命令来安装
- 使用什么命令运行测试
下面提供一个例子:
```YML language: python python: - 2.7 env: - DEPS=true - DEPS=false sudo: false install: - travis_retry python setup.py install - travis_retry pip install coveralls - coverage run test_httpmultipart.py - coverage report script: - python test_httpmultipart.py after_success: coveralls ```
PS: 在install
这一项配置中要注意,如果项目存在依赖,一定要进行安装,还有Travisci
提供了多项配置,包括出错重试等,具体配置可以参考官方文档,要特别注意travis_retry
等命令的使用,非常容易出现坑。
测试
Python有内置的unittest
测试库,支持断言;当然还有其他的一些测试框架,看个人喜好和项目需求。在项目中应该包含测试文件或者测试目录,测试文件一般以test_projects_name.py
命名。我选择使用coverage
作为测试覆盖率的检查,下面是一个运行示例:
➜ httpmultipart git:(master) coverage run test_httpmultipart.py
....
----------------------------------------------------------------------
Ran 4 tests in 36.125s
OK
➜ httpmultipart git:(master) coverage report
Name Stmts Miss Branch BrPart Cover
-------------------------------------------------------------
httpmultipart/__init__.py 10 0 0 0 100%
httpmultipart/main.py 37 0 4 0 100%
-------------------------------------------------------------
TOTAL 47 0 4 0 100%
Coveralls 测试覆盖率检查
Coveralls可以很友好的支持Github和Bitbucket仓库的导入,同时也可以很好的和Travisci
集成,在上面我们的.travis.yml
文件中,在最后一项after_success
中,我们就配置了对Coveralls
的支持。
发布包到PyPI
PyPI - the Python Package Index
是Python的包仓库,它允许我们将自己写的包上传上去,这样就可以使用pip
和easy_install
进行安装了。这里说一个很重要的事情:
请在发布自己项目之前做好测试,确认自己上传的是一个可用,无害的包
当你已经完成上面的步骤之后,那么你只需要以下几步就可以完成了。以我的项目为例子:
- 配置
setup.py
:
#!/usr/bin/env python
import os
import re
import sys
from codecs import open
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
if sys.argv[-1] == 'publish':
os.system('python setup.py sdist upload')
sys.exit()
packages = [
'httpmultipart',
]
requires = []
version = ''
with open('httpmultipart/__init__.py', 'r') as fd:
version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
fd.read(), re.MULTILINE).group(1)
if not version:
raise RuntimeError('Cannot find version information')
with open('README.rst', 'r', 'utf-8') as f:
readme = f.read()
setup(
name='httpmultipart',
version=version,
description='A httpmultipart post handler',
long_description=readme + '\n\n',
author='Jintao Zhang',
author_email='[email protected]',
url='https://github.com/tao12345666333/httpmultipart',
packages=packages,
package_data={'': ['LICENSE']},
package_dir={'httpmultipart': 'httpmultipart'},
include_package_data=True,
install_requires=requires,
license='MIT',
zip_safe=False,
platforms='any',
classifiers=(
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
'Natural Language :: English',
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Topic :: Software Development :: Libraries',
'Topic :: Software Development :: Libraries :: Python Modules',
),
)
当然大部分时候也不需要这么麻烦,简化的配置可以参考官方的文档。注意最下面那部分classifiers
是按照PyPI官方的列表填写的。还有,如果有些文件想要额外打包进去,那么需要在根目录添加MANIFEST.in
文件。
- 打包代码
$ python setup.py sdist # 生成pip支持的安装包
$ python setup.py bdist_wheel # 生成支持easy_install的安装包
发布到PyPI上
- 注册package
$ python setup.py register $ # 在这一步会有一些提示,按照提示选择,输入自己帐号密码相关的信息即可 $ # 在提示你要不要保存帐号信息的时候, $ # 你选择了‘y’, $ # 则会在你的用户目录下生成一个 .pypirc 的文件, $ # 其中明文保存着你的帐号和密码。
- 注册package
这里稍微再提一点,如果在提示是否保存账户信息的时候,选择了‘n’,想反悔了也没关系,我们可以手动创建一个~/.pypirc
文件。格式如下:
```
[distutils]
index-servers=pypi
[pypi]
repository = https://pypi.python.org/pypi
username = your username
password = your password
```
- 上传package
bash $ python setup.py sdist bdist_wheel upload
在上传完成提示200
响应的时候,你就上传成功了,去PyPI上看看有没有上传成功的包,并且试着用pip
进行安装吧!
这里我省略了一步,就是发布前的测试,你可以使用PyPI的测试服务器进行测试发布,发布到这里的包并不会对你正式发布有任何影响。
项目托管在Github上
开源到Github上后,就是继续维护和开发,这点就不多说了。
开发相关
建议使用virtualenv
之类的工具构建纯净的环境,重复的动作交给Make
之类的工具。
这篇算是一个小小的总结加备忘吧,经验尚缺,还望指正。