I am creating a function in my app that uses an API call to push dynamic HTML to convert it to a PDF. The API returns a download URL.
What I want to do, ideally without download back to my server and serving locally, is to have the file immediately start downloading. I was able to do this with send_file()
with local files, but not with files stored elsewhere.
My code is:
@app.route('/generatereport', methods=['GET'])
@login_required
def generateReport():
precords = people.find({"parentrecord": current_user.user_json['_id']}).sort('nextContact', pymongo.ASCENDING)
todayDate = date.today()
result = pdfgeneratorv2(info=precords, date=todayDate, user=current_user.user_json)
return send_file(result, as_attachment=True)
and my pdfgeneratorv2 function is:
from jinja2 import Environment, select_autoescape, FileSystemLoader
from api2pdf import Api2Pdf
from dotenv import load_dotenv
import os
load_dotenv(dotenv_path='creds.env')
a2p_client = Api2Pdf(os.environ.get('Api2PdfKey'))
def pdfgeneratorv2(info, date, user):
env = Environment(
loader=FileSystemLoader('templates'),
autoescape=select_autoescape(['html', 'xml'])
)
template = env.get_template('ReportTemplate.html')
html = template.render(records=info, todayDate=date, user=user)
api_response = a2p_client.Chrome.html_to_pdf(html, file_name='Networking Report.pdf')
print(api_response.result)
return api_response.result['FileUrl']
help would be greatly appreciated!
The error I get is:
Traceback (most recent call last):
File "C:\Users\David PC\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 2525, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\David PC\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 1822, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\David PC\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\David PC\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "C:\Users\David PC\AppData\Local\Programs\Python\Python310\lib\site-packages\flask_login\utils.py", line 290, in decorated_view
return current_app.ensure_sync(func)(*args, **kwargs)
File "C:\Users\David PC\Desktop\VS Code Python\Flask Site\app.py", line 576, in generateReport
return send_file(result, as_attachment=True)
File "C:\Users\David PC\AppData\Local\Programs\Python\Python310\lib\site-packages\flask\helpers.py", line 537, in send_file
return werkzeug.utils.send_file( # type: ignore[return-value]
File "C:\Users\David PC\AppData\Local\Programs\Python\Python310\lib\site-packages\werkzeug\utils.py", line 440, in send_file
stat = os.stat(path)
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: 'C:\\Users\\David PC\\Desktop\\VS Code Python\\Flask Site\\https://URLREMOVED'
CodePudding user response:
Thank you to @OneCricketeer for pointing me in the right direction.
I ended up solving this using BytesIO.
My pdfgeneratorv2
function remained identical. My generateReport
route was changed to:
@app.route('/generatereport', methods=['GET'])
@login_required
@limiter.limit("1/minute") # Maximum of 1 request per minute
def generateReport():
precords = people.find({"parentrecord": current_user.user_json['_id']}).sort('nextContact', pymongo.ASCENDING)
todayDate = date.today()
result = pdfgeneratorv2(info=precords, date=todayDate, user=current_user.user_json)
resp = requests.get(result)
return send_file(BytesIO(resp.content), mimetype="application/pdf", download_name="Networking Report.pdf", as_attachment=True)
This also allows me to not have to delete the file afterwards.