Я попробовал использовать NSSM, чтобы настроить его как службу, и пока все казалось, работало, служба не могла открыть файлы DOCX, что бы я ни пытался.
Я также экспериментировал с pywin32, но запросы полностью завершались неудачей после запуска службы.
Я не думаю, что это разрешение проблема. Я добавил ведение журнала в свой код и убедился, что файлы DOCX получены правильно, имеют правильные разрешения и имеют правильный формат.
Есть ли у кого-нибудь идеи, как решить эту проблему?
Вот мой код:
Код: Выделить всё
import win32com.client
import pythoncom
import inspect, os
from flask import Flask, request, send_file
import tempfile
import logging
import time
# Set up logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
app = Flask(__name__)
# WordHandler class to handle opening and closing Word application
class WordHandler:
def __init__(self):
self.word = None
logger.debug("WordHandler initialized")
# Enter and exit methods allow to initialize and close the Word application correctly
def __enter__(self):
logger.debug("Starting Word application...")
start_time = time.time()
pythoncom.CoInitialize()
self.word = win32com.client.DispatchEx("Word.Application")
logger.debug(f"Word application started in {time.time() - start_time:.2f} seconds")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
logger.debug("Closing Word application...")
if self.word:
self.word.Quit()
pythoncom.CoUninitialize()
logger.debug("Word application closed")
# Process document method handles both TOC update and PDF conversion in a single Word session
def process_document(self, docx_file):
"""Handles both TOC update and PDF conversion in a single Word session"""
logger.debug(f"Opening document: {docx_file}")
start_time = time.time()
doc = self.word.Documents.Open(docx_file)
logger.debug(f"Document opened in {time.time() - start_time:.2f} seconds")
# Update TOC
logger.debug("Updating Table of Contents...")
toc_start = time.time()
doc.TablesOfContents(1).Update()
logger.debug(f"TOC updated in {time.time() - toc_start:.2f} seconds")
doc.Save()
# Convert to PDF
pdf_file = docx_file.replace('.docx', '.pdf')
logger.debug(f"Converting to PDF: {pdf_file}")
pdf_start = time.time()
doc.SaveAs(pdf_file, FileFormat=17)
logger.debug(f"PDF conversion completed in {time.time() - pdf_start:.2f} seconds")
doc.Close()
logger.debug("Document closed")
return pdf_file
@app.route('/status', methods=['GET'])
def status():
return {'status': 'API is running', 'version': '1.0'}, 200
@app.route('/convert', methods=['POST'])
def convert():
logger.debug("Received conversion request")
if 'file' not in request.files:
logger.warning("No file provided in request")
return 'No file provided', 400
file = request.files['file']
if not file.filename.endswith('.docx'):
logger.warning(f"Invalid file format: {file.filename}")
return 'Invalid file format. Please upload a .docx file', 400
# Use of variables to store temporary files and paths
word_handler = None
temp_dir = None
temp_docx = None
pdf_path = None
try:
# Create temporary file with write permissions
logger.debug("Creating temporary directory...")
temp_dir = tempfile.mkdtemp()
temp_docx = os.path.join(temp_dir, 'input.docx')
logger.debug(f"Saving uploaded file to {temp_docx}")
file.save(temp_docx)
# Process document
logger.debug("Starting document processing...")
process_start = time.time()
word_handler = WordHandler()
word_handler.__enter__()
pdf_path = word_handler.process_document(temp_docx)
logger.debug(f"Document processing completed in {time.time() - process_start:.2f} seconds")
# Send the PDF file
response = send_file(
pdf_path,
mimetype='application/pdf',
as_attachment=True,
download_name='converted.pdf'
)
# Clean up after sending response
@response.call_on_close
def cleanup():
logger.debug("Starting cleanup...")
try:
if word_handler:
word_handler.__exit__(None, None, None)
if temp_docx and os.path.exists(temp_docx):
os.unlink(temp_docx)
if temp_dir and os.path.exists(temp_dir):
os.rmdir(temp_dir)
if pdf_path and os.path.exists(pdf_path):
os.unlink(pdf_path)
logger.debug("Cleanup completed")
except Exception as e:
logger.error(f"Error during cleanup: {str(e)}")
return response
except Exception as e:
# Clean up in case of error
if word_handler:
word_handler.__exit__(None, None, None)
try:
if temp_docx and os.path.exists(temp_docx):
os.unlink(temp_docx)
if temp_dir and os.path.exists(temp_dir):
os.rmdir(temp_dir)
if pdf_path and os.path.exists(pdf_path):
os.unlink(pdf_path)
except:
pass
return str(e), 500
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5000, debug=True)
Подробнее здесь: https://stackoverflow.com/questions/793 ... ocx-to-pdf
Мобильная версия