【问题标题】:Celery | Flask error: expected a bytes-like object, AsyncResult found芹菜 | Flask 错误:需要一个类似字节的对象,发现 AsyncResult
【发布时间】:2018-08-14 02:03:50
【问题描述】:

我目前正在开发一个烧瓶应用程序 (Python 3.6),并且想要集成 celery,因为我有多个长时间运行的后台任务。

编辑:Celery 4.1

集成没有问题,芹菜任务执行正确,但我无法访问正在运行的任务的当前状态。

芹菜,烧瓶设置:

def make_celery(app):
    celery = Celery(app.import_name,
                    backend=app.config["result_backend"],
                    broker=app.config["broker_url"])

    celery.conf.update(app.config)

    TaskBase = celery.Task

    class ContextTask(TaskBase):
        abstract = True

        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)

    celery.Task = ContextTask
    return celery


app = Flask(__name__)
app.config["broker_url"] = "redis://localhost:6379"
app.config["result_backend"] = "redis://localhost:6379"
app.config["DB"] = "../pyhodl.sqlite"

celery_app = make_celery(app)

芹菜任务:

@celery_app.task(bind=True, name="server.tasks.update_trading_pair")
def update_trading_pair(self, exchange, currency_a, currency_b):
    print(exchange, currency_a, currency_b)
    time.sleep(50)

调用任务并将值存储在字典中:

task_id = update_trading_pair.delay(exchange, currency_a, currency_b)
print("NEW TASK")
print(task_id)
id = exchange_mnemonic + "_" + currency_a + "_" + currency_b
TASK_STATES[id] = task_id

获取任务状态:

result = update_trading_pair.AsyncResult(TASK_STATES[market.__id__()])
print(result.state)
print(result) # works but only prints the task_id

这是引发错误。当我只打印结果对象时,它只打印task_id。如果我尝试检索当前状态,则会引发以下异常:

TypeError: sequence item 1: expected a bytes-like object, AsyncResult found

【问题讨论】:

  • print(result.status)怎么样
  • 引发同样的错误
  • 看看这个问题stackoverflow.com/questions/9034091/…希望对你有帮助
  • 我已经读过这个问题了。我的问题是我什至无法访问 AsyncResult 的属性,因为引发了错误。我什至不能调用 result.ready()、result.get() 或任何其他方法。尽管当我使用 type(result) 检查结果类型时,它说它是“celery.result.AsyncResult”。该错误表明发现了相同的 AsyncResult,因此该异常甚至没有意义。

标签: python flask celery typeerror celery-task


【解决方案1】:

解释:

当你调用你的任务时:

task_id = update_trading_pair.delay(exchange, currency_a, currency_b)

您的变量task_idAsyncResult 的一个实例,它不是字符串。

所以,您的变量 TASK_STATES[market.__id__()] 也是 AsyncResult 的一个实例,而它应该是一个字符串。

然后你试图用它实例化一个AsyncResult 对象

result = update_trading_pair.AsyncResult(TASK_STATES[market.__id__()])

所以你正在用另一个AsyncResult 对象实例化一个AsyncResult 对象,而它应该用一个字符串实例化。

也许您的困惑来自您的print(task_id),它向您显示了一个字符串,但是当您这样做时,会调用AsyncResult 对象的__str__ 方法,如果您在源代码中查看它here,

def __str__(self):
    """`str(self) -> self.id`."""
    return str(self.id)

它只是打印task_id 对象的id 属性。

解决方案:

您可以通过 TASK_STATES[id] = task_id.id 或通过

来修复它
result = update_trading_pair.AsyncResult(str(TASK_STATES[market.__id__()]))

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-04
相关资源
最近更新 更多