检查我的应用程序是否在开发/可编辑模式下运行

时间:2016-11-10 14:28:39

标签: python

我的Python应用程序可以通过常规方式安装,也可以使用pip以开发/可编辑模式安装,如下所示:

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

如何创建一个功能来内省我的virtualenv并检查我的应用程序是否在开发/可编辑模式下运行?

sys模块中是否有“标志”?

动机:在开发模式和生产中具有不同的配置。

编辑:我比较 virtualenv 目录。

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)

我测试 package_dir 是否是 virtualenv_dir 的子目录:如果它不是子目录,那么我处于开发模式。

EDIT2:

是否有更可靠的解决方案?

我想知道环境中是否没有数据/标志可以清楚地向我表明我的应用程序正在开发模式下运行。

如果另一个依赖项也在开发模式下会发生什么?

3 个答案:

答案 0 :(得分:4)

使用pip中的代码,我们可以确定:

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)

这种魔力来自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

dist中的pkg_resourcesdist_is_editable分布(正如我们上面获得的)。您当然可以直接使用FrozenRequirement函数,而不是通过# With `distribution` as above: from pip.utils import dist_is_editable print(dist_is_editable(distribution)) # True in my case ;)

UIView

答案 1 :(得分:1)

顶级解决方案需要针对更新版本的 pip 进行更新,其中 FrozenRequirement 类在 pip 的命名空间中不再可访问。

我在相关行中使用了此解决方法。

from pip._internal.operations.freeze import FrozenRequirement 
frozen_requirement = FrozenRequirement.from_dist(distribution)

答案 2 :(得分:0)

我不确定是否有可靠的方法来确定这一点。事实上,我建议您不要测试这样的路径,因为您可能会遇到各种操作系统或环境中的不同特殊情况。

我推荐了一些替代方案:

1)如果这是一个命令行实用程序,我建议允许加载可通过命令行标志配置的自定义配置文件:

from argparse import ArgumentParser
import sys
import json

parser = ArgumentParser(description='...')
parser.add_argument('-c', '--config', default='config.json')

def main(argv):
    args = parser.parse_args(argv)
    print('loading config file:', args.config)
    with open(args.config, 'r') as config:
        config = json.loads(config.read())
    print('loaded config', config) 
    # TODO do something with the config

if __name__ == '__main__':
    main(sys.argv[1:])

使用:python3 test1.py -c config-dev.json

运行

2)如果这不是CLI应用程序,您可以通过使用环境变量来实现类似的功能:

import os
import json

os.environ.get('CONFIG', 'config.json')

def main():
    config_file = os.environ.get('CONFIG', 'config.json')
    print('loading config file:', config_file)
    with open(config_file, 'r') as config:
        config = json.loads(config.read())
    print('loaded config', config) 
    # TODO do something with the config

if __name__ == '__main__':
    main()

使用:CONFIG=config-dev.json python3 test2.py或:

运行
export CONFIG=config-dev.json
python3 test2.py

您还可以创建一个shell脚本来帮助设置您的开发环境,让我们称之为customenv

source env/bin/activate
export CONFIG=config-dev.json

然后您可以使用此文件激活开发环境:

source customenv

3)如果您真的希望在开发环境的代码中有特殊情况,您也可以通过环境变量指定:

import os
is_dev_mode = 'MY_APP_DEV' in os.environ and os.environ['MY_APP_DEV'] == '1'
if is_dev_mode:
    print('dev mode!')

使用MY_APP_DEV=1 python3 test3.py或:

运行
export MY_APP_DEV=1
python3 -m test3.py

4)有关更多自定义:

import os
app_mode = os.environ.get('MY_APP_MODE', 'prod')
print(app_mode)