LoginSignup
4
6

More than 3 years have passed since last update.

FlaskでのCelery  非同期処理

Posted at

 

はじめに

Flaskで簡単なpythonアプリケーションを作成していました。そこで非同期処理を追加したいと思いました。
しかし、そこでいくつか詰まるポイントがあったため記事にしました。
1つ、先に言えることはpythonでの非同期処理はFlaskではないフレームワークの方が良いかもしれないということです。ググっていると他のフレームワークの方が情報が多く感じました。

実行内容

ユーザーがテキストボックスに2つの数字を打ち込み、ボタンを押す。
サーバー側は2つの数字を足し合わせる操作を非同期処理で行い、ユーザーへのレスポンスをすぐ返す。

実行環境

os: Windows10
redis Redis-x64-3.0.504.msi

python 3.5.6 (Anaconda)
Flask==1.1.1
celery==3.1.25
redis==2.10.6

実行手順

  • Anaconda Promptで「python sample.py」を実行する。
  • Anaconda Promptで 「celery -A sample.celery worker -l info」を実行する。
  • localhost:9000にアクセスし、テキストボックスに数字を打ち込み、計算実行を押す。
    view.png

  • 結果として、すぐにレスポンスが返る。celeryを実行したAnaconda Promptに計算結果が表示されていることを確認する。
    view2.png

つまづきポイント

  • celeryとredisのバージョンには相性があるのでまずは、これらを確認する。

  • redisがlocalhost:6397で動いているか確認する。

  • 非同期処理する関数がceleryのtaskに登録されているか確認する。
    (「celery -A sample.celery worker -l info」を実行したターミナル上で確認可能)

おわりに

簡単ですが、以下にsample.py, main.htmlを添付しました。この2ファイルで動きます。参考にしたサイトのURLも添付しておきました。

なにか質問、間違いがあればぜひコメントお願いします。

ソースコード

sample.py
# coding=utf-8
from flask import Flask, render_template, request

# Flaskアプリ準備
app = Flask("sample")

# this is a part of celery property to use in Flask
from celery import Celery
def make_celery(app):
    celery = Celery(
        app.import_name,
        backend=app.config['CELERY_RESULT_BACKEND'],
        broker=app.config['CELERY_BROKER_URL']
    )
    celery.conf.update(app.config)

    class ContextTask(celery.Task):
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return self.run(*args, **kwargs)

    celery.Task = ContextTask
    return celery

# update flask config to use celery
app.config.update(
    CELERY_BROKER_URL='redis://localhost:6379',
    CELERY_RESULT_BACKEND='redis://localhost:6379'
)
celery = make_celery(app)

@celery.task()
def add(a, b):
    print(a + b)
    return a + b

@app.route('/', methods=["GET", "POST"])
def sample():

    # POST時の処理
    if request.method == 'POST':
        return render_template(
            'main.html',  # 表示するHTMLファイル
            )

    # GET時の処理
    else:
        return render_template(
            'main.html',  # 表示するHTMLファイル
            )

@app.route('/celery', methods=["POST"])
def celery_test():

    if request.method == 'POST':
        a = int(request.form["num_one"])
        b = int(request.form["num_two"])
        result = add.delay(a,b)
        return render_template(
                'main.html',  # 表示するHTMLファイル           
                )

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=9000)
main.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8"/>
    <title>Sample</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  </head>

  <body>      
    <div class="container">
      <div class="jumbotron">
        <h1>
          <p align="center">
            <font size="10">Flask 非同期処理</font>
          </p>
        </h1>
      </div>

      <form class="" method="post" action="/celery" enctype="multipart/form-data">
        <div class="container" style="text-align: center;">
          <input type="number" name="num_one">  +  
          <input type="number" name="num_two">
        </div>

        <div class="button_wrapper" style="text-align: center;">
          <button type="submit" class="btn btn-lg btn-success" style="margin-top: 50px; ">計算実行</button>
        </div>

      </form>
    </div> 

  </body>
</html>

参考文献

Windows版Redisをインストールして触ってみる
http://kageura.hatenadiary.jp
Flask公式
https://flask.palletsprojects.com/en/1.0.x/patterns/celery/
python – Celery Workerを起動できない
https://codeday.me/jp/qa/20190525/900758.html
celery AttributeError: 'str' object has no attribute 'items' django Day14
http://www.programmersought.com/article/8120463251/

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6