Django + Gunicorn + Nginx + Python -> Link 从网络服务器下载文件
Django + Gunicorn + Nginx + Python -> Link to download file from webserver
在我的网页上,由 amazon-lightsail 在 nginx 和 gunicorn 后面托管的 Debian Web 服务器提供服务,用户可以发送请求以启动 Django 视图功能。此函数向后台进程添加一些工作,并每 5 秒检查一次后台进程是否创建了文件。如果文件存在,视图发送响应,用户可以下载文件。有时这个过程会花费很长时间,并且用户会收到 502 错误的网关消息。如果这个过程花费的时间太长,我喜欢向用户发送一封带有 link 的电子邮件,他可以在其中从 Web 服务器下载文件。我知道如何在该过程完成后发送电子邮件,但我不知道如何通过下载将文件提供给用户 link。
到此结束我的视图函数:
print('######### Serve Downloadable File #########')
while not os.path.exists(f'/srv/data/ship_notice/{user_token}'):
print('wait on file is servable')
time.sleep(5)
# Open the file for reading content
path = open(filepath, 'r')
# Set the mime type
mime_type, _ = mimetypes.guess_type(filepath)
# Set the return value of the HttpResponse
response = HttpResponse(path, content_type=mime_type)
# Set the HTTP header for sending to browser
response['Content-Disposition'] = f"attachment; filename={filename}"
# Return the response value
return response
处理完成后向用户发送邮件的另一个模型函数:
def send_mail_precipitation(filepath, user_token, email):
from django.core.mail import EmailMessage
import time
import os
while not os.path.exists(f'/srv/data/ship_notice/{user_token}'):
print('wait 30secs')
time.sleep(30)
msg = EmailMessage(
subject = 'EnviAi data',
body = 'The process is finished, you can download the file here.... ',
to = [email]
)
msg.send()
文件太大,无法使用 msg.attach_file(文件路径)
发送
我有什么选择可以向用户发送 link 来下载这些文件。我是否需要设置 ftp server/folder,或者我有哪些选项?当我希望 link 只有 72 小时有效时,我必须做什么样的工作?非常感谢!
更新
一种方法是将文件复制到 public 可用的静态文件夹。我应该出于任何原因避免这种方法吗?
不是一个直接的答案,而是一个可行的方法。
这样的 long-running 任务通常使用 Celery 等附加工具来实现。让 view/api 端点 运行 只要它需要并保持请求进程等待直到完成是一种不好的做法。好的做法是尽可能快地做出回应。
你的情况是:
- 创建一个 celery 任务来构建你的文件(创建任务很快)
- return 响应中的任务 ID
- 从具有给定任务 ID 的前端请求任务状态
- 任务完成后文件 URL 应该 returned
也可以添加 任务完成后将执行的代码(由 Celery 自动启动)。您可以调用 email_user_when_file_is_ready
函数来响应此事件。
要使文件可下载,您可以在 nginx 配置中添加一个位置,就像您对静态和媒体文件夹所做的那样。将您的文件放到位置映射的文件夹中,仅此而已。让用户 URL 访问您的文件。
在我的网页上,由 amazon-lightsail 在 nginx 和 gunicorn 后面托管的 Debian Web 服务器提供服务,用户可以发送请求以启动 Django 视图功能。此函数向后台进程添加一些工作,并每 5 秒检查一次后台进程是否创建了文件。如果文件存在,视图发送响应,用户可以下载文件。有时这个过程会花费很长时间,并且用户会收到 502 错误的网关消息。如果这个过程花费的时间太长,我喜欢向用户发送一封带有 link 的电子邮件,他可以在其中从 Web 服务器下载文件。我知道如何在该过程完成后发送电子邮件,但我不知道如何通过下载将文件提供给用户 link。
到此结束我的视图函数:
print('######### Serve Downloadable File #########')
while not os.path.exists(f'/srv/data/ship_notice/{user_token}'):
print('wait on file is servable')
time.sleep(5)
# Open the file for reading content
path = open(filepath, 'r')
# Set the mime type
mime_type, _ = mimetypes.guess_type(filepath)
# Set the return value of the HttpResponse
response = HttpResponse(path, content_type=mime_type)
# Set the HTTP header for sending to browser
response['Content-Disposition'] = f"attachment; filename={filename}"
# Return the response value
return response
处理完成后向用户发送邮件的另一个模型函数:
def send_mail_precipitation(filepath, user_token, email):
from django.core.mail import EmailMessage
import time
import os
while not os.path.exists(f'/srv/data/ship_notice/{user_token}'):
print('wait 30secs')
time.sleep(30)
msg = EmailMessage(
subject = 'EnviAi data',
body = 'The process is finished, you can download the file here.... ',
to = [email]
)
msg.send()
文件太大,无法使用 msg.attach_file(文件路径)
发送我有什么选择可以向用户发送 link 来下载这些文件。我是否需要设置 ftp server/folder,或者我有哪些选项?当我希望 link 只有 72 小时有效时,我必须做什么样的工作?非常感谢!
更新
一种方法是将文件复制到 public 可用的静态文件夹。我应该出于任何原因避免这种方法吗?
不是一个直接的答案,而是一个可行的方法。
这样的 long-running 任务通常使用 Celery 等附加工具来实现。让 view/api 端点 运行 只要它需要并保持请求进程等待直到完成是一种不好的做法。好的做法是尽可能快地做出回应。
你的情况是:
- 创建一个 celery 任务来构建你的文件(创建任务很快)
- return 响应中的任务 ID
- 从具有给定任务 ID 的前端请求任务状态
- 任务完成后文件 URL 应该 returned
也可以添加 email_user_when_file_is_ready
函数来响应此事件。
要使文件可下载,您可以在 nginx 配置中添加一个位置,就像您对静态和媒体文件夹所做的那样。将您的文件放到位置映射的文件夹中,仅此而已。让用户 URL 访问您的文件。