Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if my application runs in development/editable mode

Tags:

python

My Python application can be install the normal way, or in development/editable mode with pip, like this:

virtualenv my_app
source my_app/bin/activate
pip install -e my_app

How can I make a function to introspect my virtualenv and check if my application runs in development/editable mode?

Is there any "flag" in sys module for that?

Motivation: have different configuration in development mode, and in production.

EDIT: I compare the virtualenv and the package directories.

import os
import sys

import pkg_resources

main_pkg = 'my_app'
package_dir = pkg_resources.resource_filename(main_pkg, '__init__.py')
virtualenv_dir = os.path.dirname(os.path.dirname(sys.executable))
common_path = os.path.commonprefix([package_dir, virtualenv_dir])
is_dev_mode = not common_path.startswith(virtualenv_dir)

I test if the package_dir is a subdirectory of the virtualenv_dir: if it is not a subdirectory, then I am on development mode.

EDIT2:

Is there a more reliable solution?

I want to know if there isn’t a data/a flag in the environment that would clearly indicate to me that my application is running in development mode.

What will happen if another dependency is in development mode too?

like image 475
Laurent LAPORTE Avatar asked Nov 10 '16 14:11

Laurent LAPORTE


2 Answers

Using code from pip we can determine this:

import pip
import pkg_resources

# I've done `pip install -e .` for a git repo I'm working in inside
# a virtualenv
distributions = {v.key: v for v in pkg_resources.working_set}
# >>> distribution
# pre-commit 0.9.3 (/home/asottile/workspace/pre-commit)
distribution = distributions['pre-commit']

# Below is approximately how `pip freeze` works, see the end of
# the answer for a simpler approach, still using pip

# Turn into a pip FrozenRequirement (I'm using pip 9.0.1, it may
# be different for your version)
# I've passed an empty list for the second argument (dependency_links)
# I don't think it's necessary?
frozen_requirement = pip.FrozenRequirement.from_dist(distribution, [])

# Query whether the requirement is installed editably:
print(frozen_requirement.editable)

The magic of this comes from a little function inside pip (pip.utils):

def dist_is_editable(dist):
    """Is distribution an editable install?"""
    for path_item in sys.path:
        egg_link = os.path.join(path_item, dist.project_name + '.egg-link')
        if os.path.isfile(egg_link):
            return True
    return False

The dist in this is a pkg_resources distribution (as we acquired above). You of course can use the dist_is_editable function directly instead of going through FrozenRequirement:

# With `distribution` as above:
from pip.utils import dist_is_editable
print(dist_is_editable(distribution))  # True in my case ;)
like image 171
Anthony Sottile Avatar answered Oct 17 '22 09:10

Anthony Sottile


The top solution needs updating for a more recent version of pip, where the FrozenRequirement class is no longer accessible in pip's namespace.

I used this workaround in the relevant lines.

from pip._internal.operations.freeze import FrozenRequirement 
frozen_requirement = FrozenRequirement.from_dist(distribution)
like image 27
jenclark Avatar answered Oct 17 '22 07:10

jenclark