Python flask multiprocess: 不能 "render" 发送网格电子邮件正文的 html 页面
Python flask multiprocess: cannot "render" a html page for the send grid email body
好的,我有一些重要的特定功能,即 运行 在后台作为多进程。又名第二个过程(以后可能更多)。
这样做的原因是它将重定向到一个 html 页面,说明请求已成功。
毕竟,在他的数据请求通过并转换数据之前,客户不会在加载页面上等待超过 7 分钟。是的,这是我的应用程序的基本功能。在您问为什么这需要这么长时间之前,这与 JSON 数据的结构有关。
简而言之,AKA 执行第一个请求以获取数据点列表,然后分别对每个数据点执行第二个请求,因为详细信息的请求 url 在该数据点内。
在此后台进程的最后一步,将通过发送网格发送邮件,并根据文件是否过大发送带有特殊“本地文件”的附件 link下载它。邮件的文本会根据情况有不同的内容,但你必须从中拿走的主要内容是文件是否作为附件,你将始终拥有本地文件“下载位置”。
import os
import base64
from datetime import datetime
from flask import Flask
import Classified.background_script.converter.GIPOD_Converter as data_conv
from flask import send_file, send_from_directory, safe_join, abort, render_template, jsonify
from Classified import app
from celery import Celery
import random
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import (
Mail, Attachment, FileContent, FileName,
FileType, Disposition, ContentId)
from sendgrid import SendGridAPIClient
import Classified.background_script.sendgrid as mail_delivery
send_grid_mail = 'Classified'
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
app = Flask(__name__)
def main(file_name: str,file_location:str, attachment_bool: bool, download_link:str, recipient_email: str):
file_path = file_location
if os.getenv('SENDGRID_API_KEY') == None:
print("No API KEY FOUND")
else:
print("API KEY FOUND")
html_string = generate_html_content(attachment_bool,download_link)
message = Mail(
from_email='Classified',
to_emails=recipient_email,
subject='Uw data is gereed.',
html_content= html_string)
if attachment_bool is True:
with open(file_path, 'rb') as f:
data = f.read()
f.close()
encoded_file = base64.b64encode(data).decode()
attachment = Attachment()
attachment.file_content = FileContent(encoded_file)
attachment.file_type = FileType('application/zip')
attachment.file_name = FileName('{}.zip'.format(file_name))
attachment.disposition = Disposition('attachment')
attachment.content_id = ContentId('Example Content ID')
message.attachment = attachment
try:
response = sg.send(message)
print(response.status_code)
print(response.body)
print(response.headers)
except Exception as e:
print("Failed scenario")
print("Scenerio checking")
# Generates the HTML variables for the email page.
def generate_html_content(attachment_bool: bool, download_link: str):
if attachment_bool is False:
Letter_1 = "Helaas was deze te groot om via mail door te sturen."
Letter_2 = "Klik hier om het bestand te downloaden."
if attachment_bool is True:
Letter_1 = "U vindt het bestand terug in de bijlage."
Letter_2 = "Is het bestand niet in de bijlage terug te vinden? Klik dan hier en download dan hier."
return render_template(
'email.html',
message_1 = Letter_1,
message_2 = Letter_2,
link = download_link,
title='YOU GOT MAIL'
)
if __name__ == "__main__":
main()
您可能会问我为什么使用 html 页面呈现功能?好吧,这是因为以下
本质上我是在渲染一个带有变量的静态模板
但是我遇到了一个特定的问题,当它不是多进程时我没有遇到。
Traceback (most recent call last):
File "D:\IDE\Anaconda3\envs\PYTHONGDAL\lib\multiprocessing\process.py", line 315, in _bootstrap
self.run()
File "D:\IDE\Anaconda3\envs\PYTHONGDAL\lib\multiprocessing\process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "D:\Programmeer portfolio\FLASK\Classfiied\Classfiied\views.py", line 178, in execute_order66
Order66.main(stringpart,url,sper_year,email)
File "D:\Programmeer portfolio\FLASK\Classfiied\Classfiied\background_script\backgroundtask.py", line 53, in main
mail_delivery.main(file_name,requested_data,attachment_bool,requested_data,email)
File "D:\Programmeer portfolio\FLASK\Classfiied\Classfiied\background_script\sendgrid\send_mail.py", line 30, in main
html_string = generate_html_content(attachment_bool,download_link)
File "D:\Programmeer portfolio\FLASK\Classfiied\Classfiied\background_script\sendgrid\send_mail.py", line 67, in generate_html_content
return render_template(
File "D:\IDE\Anaconda3\envs\Classfiied\lib\site-packages\flask\templating.py", line 146, in render_template
ctx.app.update_template_context(context)
AttributeError: 'NoneType' object has no attribute 'app'
我不明白为什么会出现此错误,是我需要做一些特别的事情,还是必须走另一条路,然后写完整的 HTML?
此处为 Twilio SendGrid 开发人员布道师。
跟踪结尾处的错误是:
File "D:\IDE\Anaconda3\envs\Classfiied\lib\site-packages\flask\templating.py", line 146, in render_template
ctx.app.update_template_context(context)
AttributeError: 'NoneType' object has no attribute 'app'
这告诉我 ctx
对象在这里是 NoneType
,它不应该是。我认为问题是你在 Flask 应用程序的上下文之外 运行ning 这段代码,它不是 运行ning Flask 路由以响应传入的 HTTP 请求,你只是调用它作为常规功能。当它不是多进程时,我猜这个 运行 在 Flask 路由的上下文中。
我查看了如何在 Flask 路由之外使用 render_template
并最终遇到了 these examples on Full Stack Python, particularly example 4, which used render_template
to render HTML that is then sent as an email. That example is from flask-base 并使用 with app.app_context()
到 运行 代码Flask 应用程序的上下文,但它不是路由的一部分。
我通常不是 Python 程序员,但也许像这样的东西适用于您的应用程序:
def generate_html_content(attachment_bool: bool, download_link: str):
if attachment_bool is False:
Letter_1 = "Helaas was deze te groot om via mail door te sturen."
Letter_2 = "Klik hier om het bestand te downloaden."
if attachment_bool is True:
Letter_1 = "U vindt het bestand terug in de bijlage."
Letter_2 = "Is het bestand niet in de bijlage terug te vinden? Klik dan hier en download dan hier."
with app.app_context():
return render_template(
'email.html',
message_1 = Letter_1,
message_2 = Letter_2,
link = download_link,
title='YOU GOT MAIL'
)
如果有帮助请告诉我。
好的,我有一些重要的特定功能,即 运行 在后台作为多进程。又名第二个过程(以后可能更多)。
这样做的原因是它将重定向到一个 html 页面,说明请求已成功。 毕竟,在他的数据请求通过并转换数据之前,客户不会在加载页面上等待超过 7 分钟。是的,这是我的应用程序的基本功能。在您问为什么这需要这么长时间之前,这与 JSON 数据的结构有关。
简而言之,AKA 执行第一个请求以获取数据点列表,然后分别对每个数据点执行第二个请求,因为详细信息的请求 url 在该数据点内。
在此后台进程的最后一步,将通过发送网格发送邮件,并根据文件是否过大发送带有特殊“本地文件”的附件 link下载它。邮件的文本会根据情况有不同的内容,但你必须从中拿走的主要内容是文件是否作为附件,你将始终拥有本地文件“下载位置”。
import os
import base64
from datetime import datetime
from flask import Flask
import Classified.background_script.converter.GIPOD_Converter as data_conv
from flask import send_file, send_from_directory, safe_join, abort, render_template, jsonify
from Classified import app
from celery import Celery
import random
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import (
Mail, Attachment, FileContent, FileName,
FileType, Disposition, ContentId)
from sendgrid import SendGridAPIClient
import Classified.background_script.sendgrid as mail_delivery
send_grid_mail = 'Classified'
sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
app = Flask(__name__)
def main(file_name: str,file_location:str, attachment_bool: bool, download_link:str, recipient_email: str):
file_path = file_location
if os.getenv('SENDGRID_API_KEY') == None:
print("No API KEY FOUND")
else:
print("API KEY FOUND")
html_string = generate_html_content(attachment_bool,download_link)
message = Mail(
from_email='Classified',
to_emails=recipient_email,
subject='Uw data is gereed.',
html_content= html_string)
if attachment_bool is True:
with open(file_path, 'rb') as f:
data = f.read()
f.close()
encoded_file = base64.b64encode(data).decode()
attachment = Attachment()
attachment.file_content = FileContent(encoded_file)
attachment.file_type = FileType('application/zip')
attachment.file_name = FileName('{}.zip'.format(file_name))
attachment.disposition = Disposition('attachment')
attachment.content_id = ContentId('Example Content ID')
message.attachment = attachment
try:
response = sg.send(message)
print(response.status_code)
print(response.body)
print(response.headers)
except Exception as e:
print("Failed scenario")
print("Scenerio checking")
# Generates the HTML variables for the email page.
def generate_html_content(attachment_bool: bool, download_link: str):
if attachment_bool is False:
Letter_1 = "Helaas was deze te groot om via mail door te sturen."
Letter_2 = "Klik hier om het bestand te downloaden."
if attachment_bool is True:
Letter_1 = "U vindt het bestand terug in de bijlage."
Letter_2 = "Is het bestand niet in de bijlage terug te vinden? Klik dan hier en download dan hier."
return render_template(
'email.html',
message_1 = Letter_1,
message_2 = Letter_2,
link = download_link,
title='YOU GOT MAIL'
)
if __name__ == "__main__":
main()
您可能会问我为什么使用 html 页面呈现功能?好吧,这是因为以下
本质上我是在渲染一个带有变量的静态模板
但是我遇到了一个特定的问题,当它不是多进程时我没有遇到。
Traceback (most recent call last):
File "D:\IDE\Anaconda3\envs\PYTHONGDAL\lib\multiprocessing\process.py", line 315, in _bootstrap
self.run()
File "D:\IDE\Anaconda3\envs\PYTHONGDAL\lib\multiprocessing\process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "D:\Programmeer portfolio\FLASK\Classfiied\Classfiied\views.py", line 178, in execute_order66
Order66.main(stringpart,url,sper_year,email)
File "D:\Programmeer portfolio\FLASK\Classfiied\Classfiied\background_script\backgroundtask.py", line 53, in main
mail_delivery.main(file_name,requested_data,attachment_bool,requested_data,email)
File "D:\Programmeer portfolio\FLASK\Classfiied\Classfiied\background_script\sendgrid\send_mail.py", line 30, in main
html_string = generate_html_content(attachment_bool,download_link)
File "D:\Programmeer portfolio\FLASK\Classfiied\Classfiied\background_script\sendgrid\send_mail.py", line 67, in generate_html_content
return render_template(
File "D:\IDE\Anaconda3\envs\Classfiied\lib\site-packages\flask\templating.py", line 146, in render_template
ctx.app.update_template_context(context)
AttributeError: 'NoneType' object has no attribute 'app'
我不明白为什么会出现此错误,是我需要做一些特别的事情,还是必须走另一条路,然后写完整的 HTML?
此处为 Twilio SendGrid 开发人员布道师。
跟踪结尾处的错误是:
File "D:\IDE\Anaconda3\envs\Classfiied\lib\site-packages\flask\templating.py", line 146, in render_template
ctx.app.update_template_context(context)
AttributeError: 'NoneType' object has no attribute 'app'
这告诉我 ctx
对象在这里是 NoneType
,它不应该是。我认为问题是你在 Flask 应用程序的上下文之外 运行ning 这段代码,它不是 运行ning Flask 路由以响应传入的 HTTP 请求,你只是调用它作为常规功能。当它不是多进程时,我猜这个 运行 在 Flask 路由的上下文中。
我查看了如何在 Flask 路由之外使用 render_template
并最终遇到了 these examples on Full Stack Python, particularly example 4, which used render_template
to render HTML that is then sent as an email. That example is from flask-base 并使用 with app.app_context()
到 运行 代码Flask 应用程序的上下文,但它不是路由的一部分。
我通常不是 Python 程序员,但也许像这样的东西适用于您的应用程序:
def generate_html_content(attachment_bool: bool, download_link: str):
if attachment_bool is False:
Letter_1 = "Helaas was deze te groot om via mail door te sturen."
Letter_2 = "Klik hier om het bestand te downloaden."
if attachment_bool is True:
Letter_1 = "U vindt het bestand terug in de bijlage."
Letter_2 = "Is het bestand niet in de bijlage terug te vinden? Klik dan hier en download dan hier."
with app.app_context():
return render_template(
'email.html',
message_1 = Letter_1,
message_2 = Letter_2,
link = download_link,
title='YOU GOT MAIL'
)
如果有帮助请告诉我。