如何在芹菜任务中从Django settings.py检索动态值?
我的Django依靠芹菜和芹菜来繁殖任务。我有3个systemd服务/单元:如何在芹菜任务中从Django settings.py检索动态值?,django,celery,systemd,Django,Celery,Systemd,我的Django依靠芹菜和芹菜来繁殖任务。我有3个systemd服务/单元: myapp.service(gunicorn守护进程) 芹菜-myapp.service(芹菜工人) celerybeat-myapp.service(celerybeat守护进程) 我在我的主“myapp.service”服务(systemd unit)中定义了一个环境变量MY_SECRET 我无法从settings.py或直接从任务(tasks.py)中的环境变量获取此值,但我可以直接使用settings.py或环
[Unit]
Description=My App
After=network.target
Wants=celery-myapp.service
Wants=celerybeat-myapp.service
[Service]
User=myapp
Group=nginx
Environment=MY_SECRET=1234
WorkingDirectory=/opt/myproject/
ExecStart=/opt/myproject/env/bin/gunicorn --workers 3 --log-level debug --bind unix://opt/myproject/myapp.sock myaproject.wsgi:application
[Install]
WantedBy=multi-user.target
我的Django项目“settings.py”中引用了环境变量以及我打算在应用程序中使用的其他设置:
设置.py
# Populated with environment variable defined by systemd unit
MY_SECRET = os.environ.get('MY_SECRET')
# Static value
MY_URL= 'http://127.0.0.1'
def my_view(request):
from django.conf import settings as project_settings
my_secret_env = os.environ.get('MY_SECRET')
my_secret_setting = project_settings.MY_SECRET
my_url_setting = project_settings.MY_URL
return render(request,'mypage.html',{
'my_secret_env': my_secret_env,
'my_secret_setting': my_secret_setting,
'my_url_setting': my_url_setting,
)
@shared_task
def task_mytask():
from django.conf import settings as project_settings
my_secret_env = os.environ.get('MY_SECRET')
my_secret_setting = project_settings.MY_SECRET
my_url_setting = project_settings.MY_URL
# No value displayed
print(my_secret_env)
# No value displayed
print(my_secret_setting)
# Value displayed properly
print(my_url_setting)
@periodic_task(run_every=timedelta(seconds=60))
def task_myperiodictask():
task_mytask.delay()
@shared_task()
def task_mytask(my_secret_env, my_secret_setting):
...
task_mytask.apply_async(args=[my_secret_env, my_secret_setting])
从我的视图中,我可以从settings.py和直接从environment获取定义为环境变量my_SECRET的值:
视图.py
# Populated with environment variable defined by systemd unit
MY_SECRET = os.environ.get('MY_SECRET')
# Static value
MY_URL= 'http://127.0.0.1'
def my_view(request):
from django.conf import settings as project_settings
my_secret_env = os.environ.get('MY_SECRET')
my_secret_setting = project_settings.MY_SECRET
my_url_setting = project_settings.MY_URL
return render(request,'mypage.html',{
'my_secret_env': my_secret_env,
'my_secret_setting': my_secret_setting,
'my_url_setting': my_url_setting,
)
@shared_task
def task_mytask():
from django.conf import settings as project_settings
my_secret_env = os.environ.get('MY_SECRET')
my_secret_setting = project_settings.MY_SECRET
my_url_setting = project_settings.MY_URL
# No value displayed
print(my_secret_env)
# No value displayed
print(my_secret_setting)
# Value displayed properly
print(my_url_setting)
@periodic_task(run_every=timedelta(seconds=60))
def task_myperiodictask():
task_mytask.delay()
@shared_task()
def task_mytask(my_secret_env, my_secret_setting):
...
task_mytask.apply_async(args=[my_secret_env, my_secret_setting])
mypage.html
{% block page_content %}
<!-- Value displayed properly -->
<p><strong>my_secret_env:</strong> {{ my_secret_env }}</p>
<!-- Value displayed properly -->
<p><strong>my_secret_setting:</strong> {{ my_secret_setting }}</p>
<!-- Value displayed properly -->
<p><strong>my_url_setting:</strong> {{ my_url_setting }}</p>
{% endblock %}
不确定你的目标是什么,但你永远不应该随意地传递你的秘密。但是,如果您愿意,您可能必须从调用任务的位置将它们作为参数传递。像这样: task.py
# Populated with environment variable defined by systemd unit
MY_SECRET = os.environ.get('MY_SECRET')
# Static value
MY_URL= 'http://127.0.0.1'
def my_view(request):
from django.conf import settings as project_settings
my_secret_env = os.environ.get('MY_SECRET')
my_secret_setting = project_settings.MY_SECRET
my_url_setting = project_settings.MY_URL
return render(request,'mypage.html',{
'my_secret_env': my_secret_env,
'my_secret_setting': my_secret_setting,
'my_url_setting': my_url_setting,
)
@shared_task
def task_mytask():
from django.conf import settings as project_settings
my_secret_env = os.environ.get('MY_SECRET')
my_secret_setting = project_settings.MY_SECRET
my_url_setting = project_settings.MY_URL
# No value displayed
print(my_secret_env)
# No value displayed
print(my_secret_setting)
# Value displayed properly
print(my_url_setting)
@periodic_task(run_every=timedelta(seconds=60))
def task_myperiodictask():
task_mytask.delay()
@shared_task()
def task_mytask(my_secret_env, my_secret_setting):
...
task_mytask.apply_async(args=[my_secret_env, my_secret_setting])
视图.py
# Populated with environment variable defined by systemd unit
MY_SECRET = os.environ.get('MY_SECRET')
# Static value
MY_URL= 'http://127.0.0.1'
def my_view(request):
from django.conf import settings as project_settings
my_secret_env = os.environ.get('MY_SECRET')
my_secret_setting = project_settings.MY_SECRET
my_url_setting = project_settings.MY_URL
return render(request,'mypage.html',{
'my_secret_env': my_secret_env,
'my_secret_setting': my_secret_setting,
'my_url_setting': my_url_setting,
)
@shared_task
def task_mytask():
from django.conf import settings as project_settings
my_secret_env = os.environ.get('MY_SECRET')
my_secret_setting = project_settings.MY_SECRET
my_url_setting = project_settings.MY_URL
# No value displayed
print(my_secret_env)
# No value displayed
print(my_secret_setting)
# Value displayed properly
print(my_url_setting)
@periodic_task(run_every=timedelta(seconds=60))
def task_myperiodictask():
task_mytask.delay()
@shared_task()
def task_mytask(my_secret_env, my_secret_setting):
...
task_mytask.apply_async(args=[my_secret_env, my_secret_setting])
另外,您可以尝试设置一个环境变量并尝试调用它
export MY_SETTING = 1234
我需要直接从环境变量中检索secret,或者使用settings.py作为中介(将配置值集中在一个位置)。我的共享任务不是从视图调用的,而是由基于数据库设置的定期任务触发的。哦,对了,我现在明白了。您是否尝试导出希望传递的环境变量?导出MY_SECRET=1234最后,我在celery.service和celerybeat.service中复制了Environment=MY_SECRET=1234,现在我可以在celery定期任务或celery共享任务中直接使用os.Environment.get('MY_SECRET')获取此环境变量的值,但这有点难看。