Python 3 current_についてappがサブスレッドに渡される
2440 ワード
Flaskを勉強していたとき、「Flask Web開発」という本には、スレッドを使った非同期送信メールの例がありました
メールを送信すると、エラーが常に発生します.RuntimeError:Working outside of application context.後で資料を探して、current_を渡すことを知っています.appの問題
current_アプリはFlaskでエージェントで、Flaskのソースコードを見ると、外部に包まれていることがわかります.
このLocalProxyは展開しませんが、このLocalProxyの役割は、スレッド/コヒーレンスに基づいて現在のコヒーレンス/スレッドに対応するオブジェクトを返すことです.つまり、スレッドAがLocalProxyにAスレッドBを詰め込み、LocalProxyにBを詰め込むことです.どこにいても、スレッドAは永遠にAを取り、スレッドBは永遠にBを取ります.
これはFlaskでrequest、current_をコードで直接使用できることです.appのような変数の下位原因.だから、ここに新しいスレッドが開いているので、実際のオブジェクトを伝えないと、スレッドの中でcurrent_を使用します.appはflaskコンテキストがないため、オブジェクトを取得できません.
リアルオブジェクトを取得するFlaskには、次の方法があります.get_current_object()公式ドキュメントは、次のように解釈されます.
Return the current object. This is useful if you want the real object behind the proxy at a time for performance reasons or because you want to pass the object into a different context.
send_の変更Email関数のコードは次のとおりです.
これで非同期でメールを送信できました
from . import mail,create_app
def send_async_email(app,msg):
with app.app_context():
mail.send(msg)
def send_email(to,subject,template,**kwargs):
msg = Message(current_app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,
sender=current_app.config['FLASKY_MAIL_SENDER'], recipients=[to])
msg.body = render_template(template + '.txt', **kwargs)
msg.html = render_template(template + '.txt', **kwargs)
#with current_app.app_context():
# mail.send(msg)
thr = Thread(target=send_async_email, args=(current_app, msg))
thr.start()
return thr
メールを送信すると、エラーが常に発生します.RuntimeError:Working outside of application context.後で資料を探して、current_を渡すことを知っています.appの問題
current_アプリはFlaskでエージェントで、Flaskのソースコードを見ると、外部に包まれていることがわかります.
def _find_app():
top = _app_ctx_stack.top
if top is None:
raise RuntimeError(_app_ctx_err_msg)
return top.app
...
current_app = LocalProxy(_find_app)
このLocalProxyは展開しませんが、このLocalProxyの役割は、スレッド/コヒーレンスに基づいて現在のコヒーレンス/スレッドに対応するオブジェクトを返すことです.つまり、スレッドAがLocalProxyにAスレッドBを詰め込み、LocalProxyにBを詰め込むことです.どこにいても、スレッドAは永遠にAを取り、スレッドBは永遠にBを取ります.
これはFlaskでrequest、current_をコードで直接使用できることです.appのような変数の下位原因.だから、ここに新しいスレッドが開いているので、実際のオブジェクトを伝えないと、スレッドの中でcurrent_を使用します.appはflaskコンテキストがないため、オブジェクトを取得できません.
リアルオブジェクトを取得するFlaskには、次の方法があります.get_current_object()公式ドキュメントは、次のように解釈されます.
Return the current object. This is useful if you want the real object behind the proxy at a time for performance reasons or because you want to pass the object into a different context.
send_の変更Email関数のコードは次のとおりです.
def send_email(to,subject,template,**kwargs):
msg = Message(current_app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject,
sender=current_app.config['FLASKY_MAIL_SENDER'], recipients=[to])
msg.body = render_template(template + '.txt', **kwargs)
msg.html = render_template(template + '.txt', **kwargs)
#with current_app.app_context():
# mail.send(msg)
#current_app ,
# _get_current_object
app = current_app._get_current_object()
thr = Thread(target=send_async_email, args=(app, msg))
thr.start()
return thr
これで非同期でメールを送信できました