How to set up and use a private PyPI repo ========================================= Accompanying blog post: [Splitting a Python codebase into dependencies for fun and profit](http://greenash.net.au/thoughts/2015/06/splitting-a-python-codebase-into-dependencies-for-fun-and-profit/) Based on: [Create a local PyPi repository using only mod_rewrite](https://major.io/2012/01/31/create-a-local-pypi-repository-using-only-mod_rewrite/) See also: [Local PyPI Options](http://bitofcheese.blogspot.com.au/2013/05/local-pypi-options.html) [Setting up a private, team-wide PyPI repository](http://blog.xelnor.net/private-pypi/) For a more advanced private PyPI, see: [devpi: PyPI server and packaging/testing/release tool](http://doc.devpi.net/) Create root directory for private PyPI -------------------------------------- ``` ssh dude@myserver.com ``` (On remote server) ``` mkdir /path/to/pypi.myserver.com mkdir /path/to/pypi.myserver.com/simple ``` Create self-signed SSL certificate ---------------------------------- ``` sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/apache2/ssl/pypi.myserver.com.key \ -out /etc/apache2/ssl/pypi.myserver.com.pem ``` Set up Apache vhost ------------------- ``` sudo htpasswd -c /etc/apache2/passwords_pypi pypi ``` ``` sudo vi /etc/apache2/sites-available/pypi.myserver.com ``` (Add these lines) ----- ``` ServerName pypi.myserver.com RewriteEngine On RewriteCond %{HTTPS} off RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} ServerName pypi.myserver.com DocumentRoot /data/www/pypi.myserver.com SSLEngine On SSLCertificateFile /etc/apache2/ssl/pypi.myserver.com.pem SSLCertificateKeyFile /etc/apache2/ssl/pypi.myserver.com.key AllowOverride None Options +Indexes IndexOptions SuppressColumnSorting IndexIgnore .. Order deny,allow Allow from all AuthType Basic AuthName "My Server" AuthBasicProvider file AuthUserFile /etc/apache2/passwords_pypi Require valid-user LogLevel warn ErrorLog /var/log/apache2/pypi-error.log CustomLog /var/log/apache2/pypi-access.log combined ``` ----- ``` cd /etc/apache2/sites-enabled sudo ln -s ../sites-available/pypi.myserver.com pypi.myserver.com sudo apache2ctl graceful ``` Create directory for new library in private PyPI ------------------------------------------------ ``` mkdir /path/to/pypi.myserver.com/simple/foobar-utils ``` ``` exit ``` Update library's code --------------------- (On local machine) ``` cd /path/to/foobar-utils ``` ``` vi foobar_utils.py ``` (Add these lines) ----- ```python __version__ = '0.1.0' foobar = 'Hey foo, I am a bar!' ``` ----- ``` vi setup.py ``` (Add these lines) ----- ```python import os import setuptools module_path = os.path.join(os.path.dirname(__file__), 'foobar_utils.py') version_line = [line for line in open(module_path) if line.startswith('__version__')][0] __version__ = version_line.split('__version__ = ')[-1][1:][:-2] setuptools.setup( name="foobar-utils", version=__version__, url="https://git.myserver.com/foobar-utils/", author="Mister foo", author_email="mister@foo.com", description="Utils for handling Foo and Bar.", long_description=open('README.rst').read(), py_modules=['foobar_utils'], zip_safe=False, platforms='any', install_requires=[], classifiers=[ 'Development Status :: 2 - Pre-Alpha', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', ], ) ``` ----- ``` vi README.rst ``` (Add these lines) ----- ``` foobar-utils ============ Utils for handling Foo and Bar. ``` ----- Upload new version of library code to private PyPI -------------------------------------------------- ``` python setup.py bdist_wheel --universal scp dist/foobar_utils-0.1.0-py2.py3-none-any.whl \ dude@myserver.com:/path/to/pypi.myserver.com/simple/foobar-utils/ ``` Configure pip to use private PyPI --------------------------------- ``` vi ~/.pip/pip.conf ``` (Add these lines) ``` [global] ; Extra index to private pypi dependencies extra-index-url = https://pypi:pyp1@pypi.myserver.com/simple/ trusted-host = pypi.myserver.com ``` Use private library in a project's requirements.txt --------------------------------------------------- ``` cd /path/to/projectfoo virtualenv . source bin/activate ``` ``` vi requirements.txt ``` (Add these lines) ----- ``` foobar-utils==0.1.0 ``` ----- ``` pip install -r requirements.txt ```