Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Management command not found without unzipping .egg

Tags:

django

I have a django app that I've packaged according to the docs here: https://docs.djangoproject.com/en/1.5/intro/reusable-apps/

I installed the app into a virtual environment using setup.py.

./setup.py install

The app's web UI runs fine from the virtual environment. But I cannot access the custom management command with this vanilla install.

(django_grm)[grm@controller django_grm]$ python ./manage.py sync_to_graphite
Unknown command: 'sync_to_graphite'

Here's what the virtual environment looks like when the command will not execute:

(django_grm)[grm@controller django_grm]$ ll /home/grm/venv/django_grm/lib/python2.7/site-packages
total 1148
...
-rw-rw-r--  1 grm grm 243962 Jun 19 17:11 django_grm-0.0.4-py2.7.egg
...

However, once I unzip the .egg file, the management command works as expected.

(django_grm)[grm@controller django_grm]$ cd /home/grm/venv/django_grm/lib/python2.7/site-packages
(django_grm)[grm@controller site-packages]$ unzip django_grm-0.0.4-py2.7.egg 

(django_grm)[grm@controller site-packages]$ ll /home/grm/venv/django_grm/lib/python2.7/site-packages
total 1152
...
-rw-rw-r--  1 grm grm 243962 Jun 19 17:11 django_grm-0.0.4-py2.7.egg
drwxrwxr-x  6 grm grm   4096 Jun 19 17:16 dj_grm
...

(django_grm)[grm@controller site-packages]$ cd /home/grm/django_projects/django_grm/
(django_grm)[grm@controller django_grm]$ python ./manage.py sync_to_graphite

<success>

Is this normal behaviour? It feels wonky.

like image 925
Travis Bear Avatar asked Jun 20 '13 00:06

Travis Bear


2 Answers

I strongly suggest using pip instead of setup.py. It tends to do a much better job of installing packages as well as managing them.

Once you have your virtual environment in place, it would be:

$ . env/bin/activate
$ pip install [APP_NAME]

This installs a non-zipped version of the app in the virtual environment.

If the app is a zip from somewhere, you can still use pip

$ pip install http://[URL_TO_ZIP]
like image 169
tghw Avatar answered Nov 02 '22 14:11

tghw


Let's take a look at the part of the source that loads management commands:

def find_commands(management_dir):
    """
    Given a path to a management directory, returns a list of all the command
    names that are available.

    Returns an empty list if no commands are defined.
    """
    command_dir = os.path.join(management_dir, 'commands')
    try:
        return [f[:-3] for f in os.listdir(command_dir)
                if not f.startswith('_') and f.endswith('.py')]
    except OSError:
        return []

which is called by:

# Find and load the management module for each installed app.
for app_name in apps:
    try:
        path = find_management_module(app_name)
        _commands.update(dict([(name, app_name)
                               for name in find_commands(path)]))
    except ImportError:
        pass # No management module - ignore this app

So, yeah, Django doesn't support apps installed in a zipped file, at least here; it wants an explicit commands directory inside management_dir.


As @tghw notes, installing via pip will keep the package in a directory instead of zipping it. You can also (and probably should also) set zip_safe=False in your setup() command; this will stop setuptools/distribute/etc from trying to zip up your package no matter how you install it.

like image 21
Danica Avatar answered Nov 02 '22 15:11

Danica