I want to ensure that os.environ
and sys.path
are identical for all ways we start the Python interpreter:
我要确保操作系统。环境和系统。路径与我们启动Python解释器的所有方式是相同的:
- web requests via Django, and Apache mod_wsgi
- 通过Django和Apache mod_wsgi进行web请求
- Cron jobs
- Cron作业
- Interactive logins via ssh
- 交互式登录通过ssh
- Celery jobs
- 芹菜的工作
- Jobs started via systemd
- 通过systemd工作开始
Is there a common way to solve this?
有共同的解决方法吗?
If yes, great: How does it look like?
如果是,很好:它看起来怎么样?
If no, sad: Everybody solves this on his own. ... What is a good way to solve this?
如果没有,悲伤:每个人都自己解决这个问题。解决这个问题的好办法是什么?
Operating System: Linux (with systemd support)
操作系统:Linux(支持系统d)
Update
更新
More explicit:
更明确的表示:
- I want
sys.path
to be the same in web requests, cron jobs, python started from shell, ... - 我想要系统。在web请求、cron作业、python从shell中启动的路径是相同的……
- I want
os.environ
to be the same in web requests, cron jobs, python started from shell, ... - 我想操作系统。环境在web请求、cron作业、python从shell开始,…
Update2
更新2
For systemd we use EnvironmentFile
对于systemd,我们使用环境文件
Update3
Update3
We use virtualenv
我们使用virtualenv
4 个解决方案
#1
6
You can use envdir python port (here is the original) for managing the environment variables.
您可以使用envdir python端口(这里是原始端口)来管理环境变量。
If you are only concerned about Django, I suggest using envdir from your settings.py
programmatically
如果您只关心Django,我建议在您的设置中使用envdir。py程序
You can update the environment programmatically (e.g.: in the wsgi file, django's manage.py
, settings.py
, etc.)
您可以通过编程方式更新环境(例如:在wsgi文件中,django的管理)。py,设置。py,等等)。
import envdir
import os
# print os.environ['FOO'] # would raise a KeyError
path = '../envdir/prod'
if not os.path.isdir(path):
raise ValueError('%s is not a dir' % path)
envdir.Env(path)
print os.environ['FOO']
or you can run the your process through envdir
on the command line, e.g.: envdir envs/prod/ python manage.py runserver
或者可以在命令行上通过envdir运行进程,例如:envdir envs/prod/ python管理。py runserver
I suggest creating aliases for python, pip, etc. (as you don't want to overwrite the system's own python), e.g.: alias python-mycorp="envdir /abs/path/to/envs/prod/ python"
(or if you prefer, write a full shell script instead of an alias).
我建议为python、pip等创建别名(因为您不想覆盖系统本身的python),例如:alias python-mycorp=“envdir /abs/path/to/envs/prod/ python”(或者如果您愿意,可以编写一个完整的shell脚本而不是别名)。
#2
2
This mapping is captured the first time the os module is imported, typically during Python startup as part of processing site.py. Changes to the environment made after this time are not reflected in os.environ, except for changes made by modifying os.environ directly.
这个映射是在第一次导入os模块时捕获的,通常是在作为处理site.py的一部分的Python启动期间。在此之后对环境所做的更改没有反映在os中。环境,除了修改os所做的更改。直接环境。
They all have to use the same interpreter. If they launch by the same user, they probably are.
他们都必须使用相同的翻译。如果它们由相同的用户启动,那么它们很可能是相同的。
#3
2
As you can see in the documentation of sys.path, it is initialized with the environment variable PYTHONPATH
and then with an installation dependent default (site). So, they are intended to be different.
正如你在sys的文档中看到的。路径,使用环境变量PYTHONPATH初始化,然后使用依赖于安装的默认值(site)。所以,它们是不同的。
But, you can use the -S
option during the interpreter invocation: python -S script.py
in order to skip some site specific configuration hook. Nevertheless, you will still have the standard library stuff in your sys.path
.
但是,您可以在解释器调用期间使用-S选项:python -S脚本。py为了跳过某些站点特定的配置钩子。不过,您仍然可以在sys.path中使用标准库。
If you really really want os.path['PYTHONPATH'] == sys.path
, you should do it explicitly, as the documentation says:
如果你真的想要操作系统。路[' PYTHONPATH ']= =系统。路径,你应该明确地做,因为文档说明:
A program is free to modify this list for its own purposes
程序可以*地为自己的目的修改这个列表
The standard places to put those kind of specific manipulations are:
这些具体操作的标准位置是:
- A
sitecustomize
module, typically created by a system administrator in the site-packages directory, which can do arbitrary configurations. - sitecustomize模块,通常由站点包目录中的系统管理员创建,可以执行任意配置。
- A
usercustomize
module, which intention is the same assitecustomize
but only executed ifENABLE_USER_SITE
is true. - usercustomize模块,其意图与sitecustomize相同,但只有在ENABLE_USER_SITE为真时才执行。
- Customization to the
sys.path
directly from the script. I.e:sys.path = os.env['PYTHONPATH']
. - 定制系统。直接从脚本的路径。我。艾凡:sys。路径= os.env(“PYTHONPATH环境”)。
#4
-2
I'm going to assume you meant os.environ['PYTHONPATH'] == sys.path , because otherwise I can't understand the question. Anyway, the solution would be to use virtualenvs.
我猜你指的是操作系统。环境(“PYTHONPATH环境”)= =系统。路径,否则我无法理解这个问题。无论如何,解决方案是使用virtualenv。
- Setup a virtualenv
- 设置一个virtualenv
- Edit the /bin/activate and add entry PYTHONPATH=your-sys-path.
- 编辑/bin/activate并添加条目PYTHONPATH=your-sys-path。
- Make sure your mod_wsgi, celery, cron jobs and shell login(bash_login?) all activate the virtualenv when they are started and use the virtualenv/bin/python for execution.
- 确保您的mod_wsgi、芹菜、cron作业和shell login(bash_login?)在启动时都激活了virtualenv,并使用virtualenv/bin/python执行。
Done.
完成了。
#1
6
You can use envdir python port (here is the original) for managing the environment variables.
您可以使用envdir python端口(这里是原始端口)来管理环境变量。
If you are only concerned about Django, I suggest using envdir from your settings.py
programmatically
如果您只关心Django,我建议在您的设置中使用envdir。py程序
You can update the environment programmatically (e.g.: in the wsgi file, django's manage.py
, settings.py
, etc.)
您可以通过编程方式更新环境(例如:在wsgi文件中,django的管理)。py,设置。py,等等)。
import envdir
import os
# print os.environ['FOO'] # would raise a KeyError
path = '../envdir/prod'
if not os.path.isdir(path):
raise ValueError('%s is not a dir' % path)
envdir.Env(path)
print os.environ['FOO']
or you can run the your process through envdir
on the command line, e.g.: envdir envs/prod/ python manage.py runserver
或者可以在命令行上通过envdir运行进程,例如:envdir envs/prod/ python管理。py runserver
I suggest creating aliases for python, pip, etc. (as you don't want to overwrite the system's own python), e.g.: alias python-mycorp="envdir /abs/path/to/envs/prod/ python"
(or if you prefer, write a full shell script instead of an alias).
我建议为python、pip等创建别名(因为您不想覆盖系统本身的python),例如:alias python-mycorp=“envdir /abs/path/to/envs/prod/ python”(或者如果您愿意,可以编写一个完整的shell脚本而不是别名)。
#2
2
This mapping is captured the first time the os module is imported, typically during Python startup as part of processing site.py. Changes to the environment made after this time are not reflected in os.environ, except for changes made by modifying os.environ directly.
这个映射是在第一次导入os模块时捕获的,通常是在作为处理site.py的一部分的Python启动期间。在此之后对环境所做的更改没有反映在os中。环境,除了修改os所做的更改。直接环境。
They all have to use the same interpreter. If they launch by the same user, they probably are.
他们都必须使用相同的翻译。如果它们由相同的用户启动,那么它们很可能是相同的。
#3
2
As you can see in the documentation of sys.path, it is initialized with the environment variable PYTHONPATH
and then with an installation dependent default (site). So, they are intended to be different.
正如你在sys的文档中看到的。路径,使用环境变量PYTHONPATH初始化,然后使用依赖于安装的默认值(site)。所以,它们是不同的。
But, you can use the -S
option during the interpreter invocation: python -S script.py
in order to skip some site specific configuration hook. Nevertheless, you will still have the standard library stuff in your sys.path
.
但是,您可以在解释器调用期间使用-S选项:python -S脚本。py为了跳过某些站点特定的配置钩子。不过,您仍然可以在sys.path中使用标准库。
If you really really want os.path['PYTHONPATH'] == sys.path
, you should do it explicitly, as the documentation says:
如果你真的想要操作系统。路[' PYTHONPATH ']= =系统。路径,你应该明确地做,因为文档说明:
A program is free to modify this list for its own purposes
程序可以*地为自己的目的修改这个列表
The standard places to put those kind of specific manipulations are:
这些具体操作的标准位置是:
- A
sitecustomize
module, typically created by a system administrator in the site-packages directory, which can do arbitrary configurations. - sitecustomize模块,通常由站点包目录中的系统管理员创建,可以执行任意配置。
- A
usercustomize
module, which intention is the same assitecustomize
but only executed ifENABLE_USER_SITE
is true. - usercustomize模块,其意图与sitecustomize相同,但只有在ENABLE_USER_SITE为真时才执行。
- Customization to the
sys.path
directly from the script. I.e:sys.path = os.env['PYTHONPATH']
. - 定制系统。直接从脚本的路径。我。艾凡:sys。路径= os.env(“PYTHONPATH环境”)。
#4
-2
I'm going to assume you meant os.environ['PYTHONPATH'] == sys.path , because otherwise I can't understand the question. Anyway, the solution would be to use virtualenvs.
我猜你指的是操作系统。环境(“PYTHONPATH环境”)= =系统。路径,否则我无法理解这个问题。无论如何,解决方案是使用virtualenv。
- Setup a virtualenv
- 设置一个virtualenv
- Edit the /bin/activate and add entry PYTHONPATH=your-sys-path.
- 编辑/bin/activate并添加条目PYTHONPATH=your-sys-path。
- Make sure your mod_wsgi, celery, cron jobs and shell login(bash_login?) all activate the virtualenv when they are started and use the virtualenv/bin/python for execution.
- 确保您的mod_wsgi、芹菜、cron作业和shell login(bash_login?)在启动时都激活了virtualenv,并使用virtualenv/bin/python执行。
Done.
完成了。