我的python包索引(独立服务器)
mypypi的Python项目详细描述
自述文件
这个包提供了一个基于zope 3的私有python包索引服务器。
mypypi服务器提供了设置私有或公共服务器所需的一切 皮皮镜。它还允许发布封闭源代码包。一起 可爱的.buildouthttp您可以设置一个安全的pypi镜像,您可以使用它 用于公共包和私有包的部署管理。专用软件包可以 基于组、角色和用户获得安全保护。mypypi服务器 支持同时混合私人和公共软件包的安全方式。
我们建议在apache proxy for ssl后面安装mypypi服务器 像任何其他ssl安全的zope应用程序一样卸载。但是如果你想用 非常简单的设置没有ssl,mypypi服务器应该作为 独立的应用服务器。
安装
安装过程非常简单,如install.txt文件所述。
用法
自1.1.0版以来,mypypi服务器的使用有一个更简单的概念 注册/上传包的索引或。在以前的版本中我们不得不使用 一些没有文档的apache重写了规则。让我们先概述一下 pypi服务器用于:
distutils–可以注册和上载新包
setuptools–可以注册和上载新软件包
轻松安装–从给定索引开始下载软件包
zc.buildout–下载从给定索引开始的包
mypypi–可以使用xml-rpc从另一个mypypi服务器镜像包
xmlrpclib–可以访问定义的api, http://wiki.python.org/moin/cheeseshopdev
urllib–可以获取或发布数据
一般来说,我们使用PYPI服务器执行3个不同的任务。
- 作为包下载的索引服务器(索引)
- 注册并上传新软件包(管理)
- 有关附加软件包信息的自省(自省)
mypypi服务器在根目录下提供以下页面和方法,例如 http://host:port
/–使用get和post请求的distutils和setuptools api方法
< DL>其他重要页面请访问:
< DL>/PYPI–列出50个最新包,包括批处理
< DL>身份验证
身份验证是在每个工具中隐式完成的。这意味着你不必 在任何URL中包括身份验证(例如用户名:密码主机:端口/页面)。 这意味着所有工具(如distutil、setuptools)都将使用 .pypirc 文件 用于身份验证。mypypi服务器使用xml-rpc客户端 .pypirc也一样。如果您想镜像,只需要mypypi的这个文件 普里夫ATE PYPI索引服务器需要身份验证。
https
distutils和setuptools不支持它们使用的任何方法。 我不知道有人如何使用ssl和非ssl实现api。但这 就是这样。只有在https端口上才能运行正常工作的mypypi服务器。 重要的方法注册,上传将使用一个https url,但是 列出分类器并验证选项不支持使用https。
释放
在mypypi服务器设置正常后,必须配置 如果你想得到真正的保护。我们使用增强的setup.py 我们包中的文件,它将阻止发布到pypi.python.org。这样 一个setup.py更改也将使发布过程更容易。有两个 下面描述的用于将发布过程绑定到给定存储库的选项。
setup.py(版本1)
由于我们可以在 .pypirc 文件中使用多个服务器设置数据,因此 使用此文件作为将发布过程绑定到给定存储库的基础。
注意,这允许通过服务器的名称将发布绑定到服务器,并且需要 每个可以发布这样一个包的开发人员都必须使用相同的 它的.pypirc文件中的服务器-存储库映射!
您的私人鸡蛋中更改的setup.py应该如下所示:
############################################################################### # # Copyright 2009 by Projekt01 GmbH , CH-6330 Cham # ############################################################################### """Setup for smart package $Id: setup.py 4820 2009-05-12 07:31:00Z adam.groszer $ """ #---[ START Server locking]-------------------------------------------------- LOCK_PYPI_SERVER = "http://pypi.your-domain.tld/eggs" import os import sys from setuptools import setup, find_packages def read(*rnames): return open(os.path.join(os.path.dirname(__file__), *rnames)).read() #---[ repository locking ]----------------------------------------------------- REPOSITORY = "myserver" def checkRepository(name): server = None # find repository in .pypirc file rc = os.path.join(os.path.expanduser('~'), '.pypirc') if os.path.exists(rc): config = ConfigParser() config.read(rc) if 'distutils' in config.sections(): # let's get the list of servers index_servers = config.get('distutils', 'index-servers') _servers = [s.strip() for s in index_servers.split('\n') if s.strip() != ''] for srv in _servers: if srv == name: repos = config.get(srv, 'repository') print "Found repository %s for %s in '%s'" % ( repos, name, rc) server = repos break if not server: print "No repository for %s found in '%s'" % (name, rc) sys.exit(1) COMMANDS_WATCHED = ('register', 'upload') changed = False for command in COMMANDS_WATCHED: if command in sys.argv: #found one command, check for -r or --repository commandpos = sys.argv.index(command) i = commandpos+1 repo = None while i<len(sys.argv) and sys.argv[i].startswith('-'): #check all following options (not commands) if (sys.argv[i] == '-r') or (sys.argv[i] == '--repository'): #next one is the repository itself try: repo = sys.argv[i+1] if repo.lower() != server.lower(): print "You tried to %s to %s, while this package "\ "is locked to %s" % (command, repo, server) sys.exit(1) else: #repo OK pass except IndexError: #end of args pass i=i+1 if repo is None: #no repo found for the command print "Adding repository %s to the command %s" % ( server, command ) sys.argv[commandpos+1:commandpos+1] = ['-r', server] changed = True if changed: print "Final command: %s" % (' '.join(sys.argv)) checkRepository(REPOSITORY) #---[ repository locking ]----------------------------------------------------- setup( name='smart', version = '1.0.0', url='http://pypi.your-domain.tld', license='commercial', description='Be smart', author='Adam Groszer, Roger Ineichen', author_email='dev@your-domain.tld', long_description='\n\n'.join([ open('README.txt').read(), open('CHANGES.txt').read(), ]), packages=find_packages('src'), package_dir = {'': 'src'}, namespace_packages=[], extras_require = dict( test = [ 'z3c.coverage', 'z3c.jsonrpc', 'z3c.testing', 'zope.testing', ], ), install_requires=[ 'setuptools', 'zope.interface', ], include_package_data = True, zip_safe = False, )
如您所见,我们将服务器锁定到行中给定的服务器名称:
REPOSITORY = "myserver"
给定服务器名称的真实存储库URL必须在 .pypirc文件位于主目录中,看起来像:
[distutils] index-servers = pypi localhost myrepos [pypi] repository: http://pypi.python.org/pypi username:your-username password:your-password [localhost] repository: http://localhost:8080 username:your-username password:your-password [myrepos] repository: http://localhost:8080 username:your-username password:your-password
对setup.py文件进行上述更改后,您可以发出:
python setup.py register sdist upload
或者只是:
python setup.py sdist upload
lock方法将确保存储库只在右边被释放 储存并防止鸡蛋意外地被公布给官方 pypi.python.org服务器随时可用。
setup.py(版本2)
以下概念使用指向pypi服务器的完整url。如果你不知道 由于遗留数据问题,希望确定完整的存储库url, 使用上述概念。在您的私人鸡蛋中更改的setup.py 应该是:
############################################################################### # # Copyright 2009 by Projekt01 GmbH , CH-6330 Cham # ############################################################################### """Setup for smart package $Id: setup.py 4820 2009-05-12 07:31:00Z adam.groszer $ """ #---[ START Server locking]-------------------------------------------------- LOCK_PYPI_SERVER = "http://pypi.your-domain.tld/eggs" import os import sys from setuptools import setup, find_packages def read(*rnames): return open(os.path.join(os.path.dirname(__file__), *rnames)).read() def check_server(server): if not server: return COMMANDS_WATCHED = ('register', 'upload') changed = False for command in COMMANDS_WATCHED: if command in sys.argv: #found one command, check for -r or --repository commandpos = sys.argv.index(command) i = commandpos+1 repo = None while i<len(sys.argv) and sys.argv[i].startswith('-'): #check all following options (not commands) if (sys.argv[i] == '-r') or (sys.argv[i] == '--repository'): #next one is the repository itself try: repo = sys.argv[i+1] if repo.lower() != server.lower(): print "You tried to %s to %s, while this package "\ "is locked to %s" % (command, repo, server) sys.exit(1) else: #repo OK pass except IndexError: #end of args pass i=i+1 if repo is None: #no repo found for the command print "Adding repository %s to the command %s" % ( server, command ) sys.argv[commandpos+1:commandpos+1] = ['-r', server] changed = True if changed: print "Final command: %s" % (' '.join(sys.argv)) check_server(LOCK_PYPI_SERVER) #---[ END Server locking]---------------------------------------------------- setup( name='smart', version = '1.0.0', url='http://pypi.your-domain.tld', license='commercial', description='Be smart', author='Adam Groszer, Roger Ineichen', author_email='dev@your-domain.tld', long_description='\n\n'.join([ open('README.txt').read(), open('CHANGES.txt').read(), ]), packages=find_packages('src'), package_dir = {'': 'src'}, namespace_packages=[], extras_require = dict( test = [ 'z3c.coverage', 'z3c.jsonrpc', 'z3c.testing', 'zope.testing', ], ), install_requires=[ 'setuptools', 'zope.interface', ], include_package_data = True, zip_safe = False, )
如您所见,我们将服务器锁定到行内的给定url:
LOCK_PYPI_SERVER = "http://pypi.your-domain.tld/eggs"
对setup.py文件进行上述更改后,您可以发出:
python setup.py register sdist upload
或者只是:
python setup.py sdist upload
lock方法将确保存储库只在右边被释放 储存并防止鸡蛋意外地被公布给官方 pypi.python.org服务器随时可用。
构建.cfg
由于我们使用了https连接,我们必须改进buildout.cfg文件 使用可爱的buildouthttp配方,启用ssl支持。见 可爱的。关于这个配方的更多信息。还要确保 你设置所需的信息,如可爱的食谱所述,如果你 第一次使用配方。
您的私有egg buildout.cfg应该如下所示:
############################################################################### # # Copyright 2009 by Projekt01 GmbH , CH-6330 Cham # ############################################################################### """Setup for smart package $Id: setup.py 4820 2009-05-12 07:31:00Z adam.groszer $ """ #---[ START Server locking]-------------------------------------------------- LOCK_PYPI_SERVER = "http://pypi.your-domain.tld/eggs" import os import sys from setuptools import setup, find_packages def read(*rnames): return open(os.path.join(os.path.dirname(__file__), *rnames)).read() #---[ repository locking ]----------------------------------------------------- REPOSITORY = "myserver" def checkRepository(name): server = None # find repository in .pypirc file rc = os.path.join(os.path.expanduser('~'), '.pypirc') if os.path.exists(rc): config = ConfigParser() config.read(rc) if 'distutils' in config.sections(): # let's get the list of servers index_servers = config.get('distutils', 'index-servers') _servers = [s.strip() for s in index_servers.split('\n') if s.strip() != ''] for srv in _servers: if srv == name: repos = config.get(srv, 'repository') print "Found repository %s for %s in '%s'" % ( repos, name, rc) server = repos break if not server: print "No repository for %s found in '%s'" % (name, rc) sys.exit(1) COMMANDS_WATCHED = ('register', 'upload') changed = False for command in COMMANDS_WATCHED: if command in sys.argv: #found one command, check for -r or --repository commandpos = sys.argv.index(command) i = commandpos+1 repo = None while i<len(sys.argv) and sys.argv[i].startswith('-'): #check all following options (not commands) if (sys.argv[i] == '-r') or (sys.argv[i] == '--repository'): #next one is the repository itself try: repo = sys.argv[i+1] if repo.lower() != server.lower(): print "You tried to %s to %s, while this package "\ "is locked to %s" % (command, repo, server) sys.exit(1) else: #repo OK pass except IndexError: #end of args pass i=i+1 if repo is None: #no repo found for the command print "Adding repository %s to the command %s" % ( server, command ) sys.argv[commandpos+1:commandpos+1] = ['-r', server] changed = True if changed: print "Final command: %s" % (' '.join(sys.argv)) checkRepository(REPOSITORY) #---[ repository locking ]----------------------------------------------------- setup( name='smart', version = '1.0.0', url='http://pypi.your-domain.tld', license='commercial', description='Be smart', author='Adam Groszer, Roger Ineichen', author_email='dev@your-domain.tld', long_description='\n\n'.join([ open('README.txt').read(), open('CHANGES.txt').read(), ]), packages=find_packages('src'), package_dir = {'': 'src'}, namespace_packages=[], extras_require = dict( test = [ 'z3c.coverage', 'z3c.jsonrpc', 'z3c.testing', 'zope.testing', ], ), install_requires=[ 'setuptools', 'zope.interface', ], include_package_data = True, zip_safe = False, )0
如您所见,mypypi服务器被用作索引。我们用私人电话 页面位于https://pypi.your-domain.tld/private" rel="nofollow">https://pypi.your-domain.tld/private,因为此页面强制 urllib处理程序使用基本身份验证领域身份验证。再次注意 需要使用.httpauth文件在 主文件夹。这样的.httpauth文件看起来像:
############################################################################### # # Copyright 2009 by Projekt01 GmbH , CH-6330 Cham # ############################################################################### """Setup for smart package $Id: setup.py 4820 2009-05-12 07:31:00Z adam.groszer $ """ #---[ START Server locking]-------------------------------------------------- LOCK_PYPI_SERVER = "http://pypi.your-domain.tld/eggs" import os import sys from setuptools import setup, find_packages def read(*rnames): return open(os.path.join(os.path.dirname(__file__), *rnames)).read() #---[ repository locking ]----------------------------------------------------- REPOSITORY = "myserver" def checkRepository(name): server = None # find repository in .pypirc file rc = os.path.join(os.path.expanduser('~'), '.pypirc') if os.path.exists(rc): config = ConfigParser() config.read(rc) if 'distutils' in config.sections(): # let's get the list of servers index_servers = config.get('distutils', 'index-servers') _servers = [s.strip() for s in index_servers.split('\n') if s.strip() != ''] for srv in _servers: if srv == name: repos = config.get(srv, 'repository') print "Found repository %s for %s in '%s'" % ( repos, name, rc) server = repos break if not server: print "No repository for %s found in '%s'" % (name, rc) sys.exit(1) COMMANDS_WATCHED = ('register', 'upload') changed = False for command in COMMANDS_WATCHED: if command in sys.argv: #found one command, check for -r or --repository commandpos = sys.argv.index(command) i = commandpos+1 repo = None while i<len(sys.argv) and sys.argv[i].startswith('-'): #check all following options (not commands) if (sys.argv[i] == '-r') or (sys.argv[i] == '--repository'): #next one is the repository itself try: repo = sys.argv[i+1] if repo.lower() != server.lower(): print "You tried to %s to %s, while this package "\ "is locked to %s" % (command, repo, server) sys.exit(1) else: #repo OK pass except IndexError: #end of args pass i=i+1 if repo is None: #no repo found for the command print "Adding repository %s to the command %s" % ( server, command ) sys.argv[commandpos+1:commandpos+1] = ['-r', server] changed = True if changed: print "Final command: %s" % (' '.join(sys.argv)) checkRepository(REPOSITORY) #---[ repository locking ]----------------------------------------------------- setup( name='smart', version = '1.0.0', url='http://pypi.your-domain.tld', license='commercial', description='Be smart', author='Adam Groszer, Roger Ineichen', author_email='dev@your-domain.tld', long_description='\n\n'.join([ open('README.txt').read(), open('CHANGES.txt').read(), ]), packages=find_packages('src'), package_dir = {'': 'src'}, namespace_packages=[], extras_require = dict( test = [ 'z3c.coverage', 'z3c.jsonrpc', 'z3c.testing', 'zope.testing', ], ), install_requires=[ 'setuptools', 'zope.interface', ], include_package_data = True, zip_safe = False, )1
注意,领域总是pypi。这是在服务器端定义的,可以 不会变的。当然,我们可以更改mypypi服务器中的域,但是 由于setuptools使用这个硬编码领域(eeek),buildout upload将 如果我们想把这个领域改变成别的什么,就不能再工作了。让我们知道 如果这会成为你真正的问题。
联系人
抱歉,这是最起码的文件。但我如果你有任何问题或 如果您想帮助改进文档,请随时与我们联系 <;dev at projekt01-ch>;