Python Flask: работник RQ вызывает ошибку ключа из-за переменной среды

#python #python-2.7 #flask #python-rq

#python #python-2.7 #flask #python-rq

Вопрос:

Я пытаюсь настроить очередь redis и работника для обработки очереди с помощью моего приложения flask. Я реализую это для обработки задачи, которая отправляет электронные письма. Я немного смущен, потому что кажется, что трассировка стека говорит, что моя переменная среды ‘APP_SETTINGS’ не установлена, когда она фактически установлена.

Перед запуском приложения, redis или worker я устанавливаю APP_SETTINGS:

 export APP_SETTINGS="project.config.DevelopmentConfig"
 

Однако, когда элемент добавляется в очередь, вот трассировка стека:

 17:00:00 *** Listening on default...
17:00:59 default: project.email.sendMailInBG(<flask_mail.Message object at 0x7fc930e1c3d0>) (aacf9546-5558-4db8-9232-5f36c25d521b)
17:01:00 KeyError: 'APP_SETTINGS'
Traceback (most recent call last):
  File "/home/tony/pyp-launch/venv/local/lib/python2.7/site-packages/rq/worker.py", line 588, in perform_job
    rv = job.perform()
  File "/home/tony/pyp-launch/venv/local/lib/python2.7/site-packages/rq/job.py", line 498, in perform
    self._result = self.func(*self.args, **self.kwargs)
  File "/home/tony/pyp-launch/venv/local/lib/python2.7/site-packages/rq/job.py", line 206, in func
    return import_attribute(self.func_name)
  File "/home/tony/pyp-launch/venv/local/lib/python2.7/site-packages/rq/utils.py", line 150, in import_attribute
    module = importlib.import_module(module_name)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/tony/pyp-launch/project/__init__.py", line 24, in <module>
    app.config.from_object(os.environ['APP_SETTINGS'])
  File "/home/tony/pyp-launch/venv/lib/python2.7/UserDict.py", line 40, in __getitem__
    raise KeyError(key)
KeyError: 'APP_SETTINGS'
Traceback (most recent call last):
  File "/home/tony/pyp-launch/venv/local/lib/python2.7/site-packages/rq/worker.py", line 588, in perform_job
    rv = job.perform()
  File "/home/tony/pyp-launch/venv/local/lib/python2.7/site-packages/rq/job.py", line 498, in perform
    self._result = self.func(*self.args, **self.kwargs)
  File "/home/tony/pyp-launch/venv/local/lib/python2.7/site-packages/rq/job.py", line 206, in func
    return import_attribute(self.func_name)
  File "/home/tony/pyp-launch/venv/local/lib/python2.7/site-packages/rq/utils.py", line 150, in import_attribute
    module = importlib.import_module(module_name)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/home/tony/pyp-launch/project/__init__.py", line 24, in <module>
    app.config.from_object(os.environ['APP_SETTINGS'])
  File "/home/tony/pyp-launch/venv/lib/python2.7/UserDict.py", line 40, in __getitem__
    raise KeyError(key)
KeyError: 'APP_SETTINGS'
17:01:00 Moving job to u'failed' queue
17:01:00 
17:01:00 *** Listening on default...
 

email.py

 from flask.ext.mail import Message

from project import app, mail
from redis import Redis
from rq import use_connection, Queue

q = Queue(connection=Redis())


def send_email(to, subject, template, emailable):

    if emailable==True:   
        msg = Message(
            subject,
            recipients=[to],
            html=template,
            sender=app.config['MAIL_DEFAULT_SENDER']
        )
        q.enqueue(sendMailInBG, msg)

    else:
        print("no email sent, emailable set to: "   str(emailable))

def sendMailInBG(msgContent):

    with app.test_request_context():
        mail.send(msgContent)
 

worker.py

 import os

import redis
from rq import Worker, Queue, Connection

listen = ['default']

redis_url = os.getenv('REDISTOGO_URL', 'redis://localhost:6379')

conn = redis.from_url(redis_url)

if __name__ == '__main__':
    with Connection(conn):
        worker = Worker(list(map(Queue, listen)))
        worker.work()
 

Я был бы очень признателен за еще один взгляд на это. Я ни за что на свете не могу понять, что здесь происходит.

Комментарии:

1. какой результат echo $APP_SETTINGS ?

2. В терминале, который я определил: (venv) tony@tony-VirtualBox:~/pyp-запустите $ echo $ APP_SETTINGS project.config. DevelopmentConfig. В другом терминале он равен Null, не уверен, почему. Нужно ли это определять в каждом терминале?

Ответ №1:

Благодаря подсказке @danidee я обнаружил, что переменные среды должны быть определены в каждом терминале. Следовательно, APP_SETTINGS был определен для фактического приложения, но не для рабочего.

Решение состояло в том, чтобы установить APP_SETTINGS в рабочем терминале.