æ建ç§æœ‰çš„ python 包å‘布ä¸å¿ƒ pypi
项目组现在使用Python越æ¥è¶Šå¤šï¼Œå¤§éƒ¨åˆ†è€é€»è¾‘都已ç»è¿ç§»åˆ°äº†Python上,相当数é‡çš„新逻辑都是Python写的。ç»è¿‡ä¹‹å‰çš„一段时间的分享,团队已ç»å¼€å§‹ä½¿ç”¨ virtualenv å’Œ setuptools æ¥è¿›è¡ŒPython代ç çš„å¼€å‘和打包和å‘布了。
但是现在的问题是,éšç€é¡¹ç›®è§„模的å˜å¤§ï¼Œä»¥åŠå‡ 个å项目的å¯åŠ¨ï¼Œä»£ç å¤ç”¨å¼€å§‹æˆä¸ºä¸€ä¸ªé—®é¢˜ã€‚有很多代ç 在多个库当ä¸è¢«ä½¿ç”¨ï¼Œåº”该被抽å–出æ¥æˆä¸ºå•ç‹¬çš„模å—。但是这些模å—和模å—çš„ä¾èµ–关系会比较å¤æ‚,比如一个应用å¯èƒ½éœ€è¦ä¾èµ–pypi上开æºçš„库,åŒæ—¶éœ€è¦ä¾èµ–一个内部的库,而内部的库åˆä¾èµ–å¼€æºçš„库。如何解决这ç§æƒ…况下的ä¾èµ–管ç†å’Œè‡ªåŠ¨åŒ…管ç†å‘¢ï¼Ÿ
实际上setuptools å’Œ easy_install å·²ç»æ供了完善的ä¾èµ–管ç†ï¼Œåœ¨setup.py当ä¸å†™ä¸Šæ‰€æœ‰ä¾èµ–的模å—åå·²ç»åœ¨å›¢é˜Ÿå†…å½¢æˆäº†å…±è¯†ï¼Œé‚£ä¹ˆå†…部模å—是å¦å¯ä»¥ç”¨åŒæ ·çš„æ–¹å¼è¿›è¡Œç®¡ç†å‘¢ï¼Ÿ
ç”案是肯定的。easy_install 本质是 pypi æœåŠ¡çš„客户端,它ä¾èµ–çš„webæœåŠ¡ç§°ä¸º pypi,或者å«Cheese Shop。是 http://pypi.python.org/simple/ 。这个页é¢ä¸‹é¢å°±æ˜¯ä¸€ç³»åˆ—çš„ index.html 文件,指å‘å„个版本的包文件。这个index.htmlæœ¬èº«æ²¡æœ‰ä¸¥æ ¼çš„æ ¼å¼è§„定,åªæ˜¯å…¶ä¸åº”该包å«<a>æ ‡ç¾ï¼ŒæŒ‡å‘æ¯ä¸ªç‰ˆæœ¬ã€‚easy_install 负责抽å–å‡ºè¿™äº›æ ‡ç¾ï¼Œå½¢æˆä¸€ä¸ªæ–‡ä»¶åˆ—表,比较版本,下载指定版本或者最近版本,并安装到系统上。
而且,easy_install支æŒä¸€ä¸ªå‘½ä»¤è¡Œå‚æ•° –index-url,或者çŸå‚æ•° -i ,å¯ä»¥æŒ‡å®šå…¼å®¹äºŽ pypi çš„ pypi 索引。这个索引åªè¦æ»¡è¶³pypi的规定就是å¯ä»¥çš„,自然,这个是å¯ä»¥è‡ªå·±æ建的。
但是easy_install有一个é™åˆ¶ï¼Œå°±æ˜¯åªèƒ½æŒ‡å®šä¸€ä¸ªindex URL。对于多个index的问题,PEP381明确说了,这是客户端的问题。easy_install选择ä¸è§£å†³è¿™ä¸ªé—®é¢˜ï¼Œä¹Ÿæ˜¯ä¸€ç§è§£å†³æ–¹æ¡ˆå§â€¦â€¦
但是easy_installä¸è§£å†³ï¼Œæˆ‘们就è¦æƒ³åŠžæ³•è‡ªå·±è§£å†³ã€‚去除这个é™åˆ¶æœ‰ä¸¤ä¸ªæ–¹æ³•ï¼Œä¸€ä¸ªæ˜¯è®©è‡ªå·±çš„ç§æœ‰pypi在å‘现ç§æœ‰åŒ…里é¢æ²¡æœ‰åŒ¹é…的包åå—的时候é‡å®šå‘到pypi.python.org/simple,å¦ä¸€ç§æ–¹æ³•å°±æ˜¯ä½¿ç”¨ easy_install çš„æ›¿ä»£å“ pip。在翻看了众多的部署脚本之åŽï¼Œæˆ‘们决定,还是使用å‰é¢ä¸€ä¸ªç–略。
除了常用的easy_installæ¥å®‰è£…包,pypi还需è¦ä¸€ä¸ªåŠŸèƒ½å°±æ˜¯æ”¯æŒ distutils 兼容的åè®®ä¸Šä¼ åŒ…åˆ°æœåŠ¡å™¨ã€‚对于使用disutils或者setuptools建立的setup.py文件,开å‘者å¯ä»¥ä½¿ç”¨ python setup.py register 将项目å注册到 pypi index,也å¯ä»¥é€šè¿‡ python setup.py bdist_egg upload ä¸Šä¼ æ‰“åŒ…å¥½çš„æ–‡ä»¶ã€‚è¿™ä¸ªå议很简å•ï¼Œå¾ˆå®¹æ˜“å³å¯å®žçŽ°ï¼Œåªæ˜¯å…¶ä¸éœ€è¦çš„用户管ç†æ–¹é¢ï¼Œç¨å¾®å¤æ‚和体力活一些。
也æ£æ˜¯å› 为简å•ï¼Œæ建ç§æœ‰çš„pypiæœåŠ¡å™¨çš„å¼€æºç¨‹åºæœ‰å¾ˆå¤šï¼ŒPEP 381当ä¸æœ‰ä¸¤ä¸ªæŽ¨è,分别是PloneSoftwareCenter å’Œ EggBasket。PloneSoftwareCenter是一个æ龙级别的东西,它是一个完整的CMS,pypiåªæ˜¯å…¶ä¸ä¸€ä¸ªå°å°çš„åŠŸèƒ½ã€‚ä¸ºäº†è¿™æ ·ä¸€ä¸ªç®€å•çš„功能需è¦å®‰è£…ä¸€å¤§å †Plone的东西,实在是难以接å—,而且它的文档简直是个æ¯å…·â€¦â€¦ï¼Œå”‰ã€‚
EggBasketç¨å¥½ï¼Œä½†æ˜¯ä¹Ÿè¦å®‰è£…ä¸€å †ä¸œè¥¿ï¼ŒåŒ…æ‹¬ä¸€åªå°æé¾™TurboGears。所幸TurboGearsåªæ˜¯ä¸€åªå°æ龙,而且EggBasket本身的文档比较清楚,一æ¥æ¥ç…§ç€åšå³å¯ã€‚由于一些安全方é¢çš„é™åˆ¶ï¼ŒEggBasketå•ç‹¬çš„æœåŠ¡å™¨ç«¯å£åœ¨æˆ‘们的æœåŠ¡å™¨ä¸Šæ˜¯ä¸èƒ½è®¿é—®åˆ°çš„ï¼Œå› æ¤æˆ‘们用apacheçš„mod_proxyåšäº†ä¸€ä¸ªåå‘代ç†ã€‚
很快,基于EggBasketå’Œapache mod_proxyåå‘代ç†çš„ç§æœ‰pypiå°±æ建起æ¥ï¼Œé—®é¢˜éšå³è€Œæ¥ï¼šEggBasketä¸æ”¯æŒæˆ‘们上é¢è¦æ±‚的自动é‡å®šå‘。所幸æºä»£ç 也ä¸å¤šï¼Œç®€å•ä¿®æ”¹äº†ä¸€ä¸‹ä¹‹åŽï¼Œåšäº†ä¸€ä¸ªpatch。需è¦çš„å¯ä»¥ä¸‹è½½ä¸‹æ¥è‡ªå·±apply。我已ç»è”系了EggBasket的作者,希望能够将这个patchåˆå¹¶è¿›å®˜æ–¹ä»£ç ,但是作者表示,他现在æ£åœ¨ä¼‘å‡ã€‚ã€update @2010-12-12 自从这个patchå‘é€è¿‡åŽ»å·²ç»æŽ¥è¿‘åŠå¹´äº†ï¼Œè¿˜æ²¡æœ‰å“应,好å§ï¼Œæˆ‘放弃了】
ç»è¿‡è¿™äº›patch,我们的pypiæœåŠ¡å™¨å°±æˆåŠŸæ建起æ¥äº†ã€‚项目组使用它的方å¼æ˜¯ï¼š
å¼€å‘机:
(dev) zhangc@dev-01:pypismpl$ python setup.py register -r http://pypi-server/pypi
We need to know who you are, so please choose either:
1. use your existing login,
2. register as a new user,
3. have the server generate a new password for you (and email it to you), or
4. quit
Your selection [default 1]: 1
Username: zhangc
Password: ********
Server response (200): OK
I can store your PyPI login so future submissions will be faster.
(the login will be stored in /home/zhangc/.pypirc)
Save your login (y/N)? y
è¿™æ¥æ“作执行一次å³å¯ï¼Œå¦‚果最åŽä¸€æ¥é€‰æ‹©äº†save login,则åŽé¢ä¸å†éœ€è¦æ¯æ¬¡éƒ½register。
在程åºæ–°ç‰ˆæœ¬ç¨³å®šäº†ä¹‹åŽï¼Œæ‰§è¡Œï¼š
(dev) zhangc@dev-01:pypismpl$ python setup.py bdist_egg upload -r http://pypi-server/pypi/upload
å³å¯æŠŠæ–°ç‰ˆæœ¬çš„程åºæ‰“包æˆeggå¹¶ä¸”ä¸Šä¼ åˆ°æœåŠ¡å™¨ã€‚
这时候如果通过æµè§ˆå™¨è®¿é—®pypiæœåŠ¡å™¨ï¼Œä¼šå‘现新版本的pypismpl程åºå·²ç»åœ¨é¡µé¢ä¸Šåˆ—出了。
然åŽåœ¨ç”Ÿäº§æœºä¸Šï¼š
(dev) zhangc@production-01:~$ sudo -u appuser -E /usr/app/env/bin/python -i http://pypi-server/pypi -U pypismpl
新版本的程åºå°±ä¼šè‡ªåŠ¨éƒ¨ç½²äº†ã€‚
æ–‡ç« å¾ˆä¸é”™ï¼Œå…³æ³¨ï¼
ä½ è¿˜çœŸæ˜¯å–œæ¬¢å¤§è›‡å•Š 🙂
我æ¥å¸®ä½ 纪念一下Blogé•¿è‰ä¸€å‘¨å¹´ã€‚
虽然是篇旧文了,但是æœç´¢çš„时候还是一直é å‰ã€‚
现在有了更好的解决方案了。pypiserver è½»é‡çº§ï¼Œä½¿ç”¨Bottleå¯ä»¥æ‰“包到åªæœ‰ä¸€ä¸ªæ–‡ä»¶ï¼Œåˆå¯ä»¥å¿«é€Ÿæ建到SAE上。
å‘到这里å…å¾—åŽæ¥äººé‡è¹ˆå¤è¾™ï¼Œ
é¡¹ç›®åœ°å€ https://github.com/wangeek/pypiserver4sae