Skip to content


Restricting uploads to public PyPI

Many companies use an internal PyPI server for storing their proprietary python packages. This makes managing python libraries and application dependencies so much easier. But unfortunately this also makes it easy for people to accidentally upload their private code to the public PyPI unintentionally.

Lucky for us, there’s a cool extension to setuptools called restricted_pkg! Unlucky for us, it leaves something to be desired in terms of user experience. Let’s say we have an example library called xl which uses restricted_pkg to prevent accidental uploads. Building on the usage given in restricted_pkg‘s docs, our setup.py will go like this:

from setuptools import find_packages
from restricted_pkg import setup
 
setup(name='xl',
      version='0.1.0',
      packages=['xl'],
      private_repository="https://pypi.example.com",
      install_requires=[
        "distribute",
        "restricted_pkg",
      ],
)

So far so good. But when we try to pip install that in a clean virtualenv, its going to fail.

$ pip install -e xl/
Obtaining file:///Users/codyaray/xl
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "", line 20, in 
      File "/Users/codyaray/xl/setup.py", line 2, in 
        from restricted_pkg import setup
    ImportError: No module named restricted_pkg
 
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /Users/codyaray/xl

That makes us sad. Why must restricted_pkg make our users do more work? No!

The workaround I’ve developed is to check whether restricted_pkg is already installed and auto-install it if its missing. Since this is a standard python import, we can’t really rely on setuptools magic. The simplest most concise way I’ve found so far is to wrap the import in a try/catch and programmatically invoke pip (in a hacky abusive way).

try:
      from restricted_pkg import setup
except ImportError:
      import pip
      pip.main(['install', 'restricted_pkg'])
      from restricted_pkg import setup
 
setup(name='xl',
      version='0.1.0',
      packages=['xl'],
      private_repository='https://pypi.example.com')

Its a minimum of boilerplate, very comprehensible, and gets the job done.

Posted in Tutorials.


0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.



Some HTML is OK

or, reply to this post via trackback.

 



Log in here!