lollms-webui/utilities/execution_engines/latex_execution_engine.py

137 lines
4.7 KiB
Python
Raw Normal View History

"""
project: lollms_webui
file: latex_execution_engine.py
author: ParisNeo
description:
This is a utility for executing latex code
"""
2024-12-19 12:48:57 +00:00
import json
import shutil
import subprocess
2024-12-19 12:48:57 +00:00
import time
from pathlib import Path
import tqdm
from ascii_colors import ASCIIColors, get_trace_exception, trace_exception
from fastapi import APIRouter, FastAPI, File, Request, UploadFile, routing
2024-02-28 00:06:59 +00:00
from lollms.client_session import Client
2024-12-19 12:48:57 +00:00
from lollms.databases.discussions_database import DiscussionsDB
from lollms.main_config import BaseConfig
from lollms.types import MSG_OPERATION_TYPE
2024-06-23 20:27:27 +00:00
from lollms.utilities import discussion_path_to_url
2024-12-19 12:48:57 +00:00
from pydantic import BaseModel
from starlette.responses import StreamingResponse
2024-02-28 00:06:59 +00:00
2024-12-19 12:48:57 +00:00
from lollms_webui import LOLLMSWebUI
lollmsElfServer: LOLLMSWebUI = LOLLMSWebUI.get_instance()
2024-12-19 12:48:57 +00:00
def execute_latex(code, client: Client, message_id):
2024-04-10 07:29:09 +00:00
# Start the timer.
start_time = time.time()
2024-04-10 07:29:09 +00:00
# Create a temporary file.
root_folder = client.discussion.discussion_folder
2024-12-19 12:48:57 +00:00
root_folder.mkdir(parents=True, exist_ok=True)
tmp_file = root_folder / f"latex_file_{message_id}.tex"
with open(tmp_file, "w", encoding="utf-8") as f:
2024-04-10 07:29:09 +00:00
f.write(code)
2024-04-10 07:29:09 +00:00
try:
# Determine the pdflatex command based on the provided or default path
if lollmsElfServer.config.pdf_latex_path:
pdflatex_command = lollmsElfServer.config.pdf_latex_path
else:
2024-12-19 12:48:57 +00:00
pdflatex_command = "pdflatex"
2024-04-10 07:29:09 +00:00
# Set the execution path to the folder containing the tmp_file
execution_path = tmp_file.parent
2024-04-10 07:29:09 +00:00
# Execute the Python code in a temporary file.
process = subprocess.Popen(
[pdflatex_command, "-interaction=nonstopmode", str(tmp_file)],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
2024-12-19 12:48:57 +00:00
cwd=execution_path,
2024-04-10 07:29:09 +00:00
)
2024-04-10 07:29:09 +00:00
# Get the output and error from the process.
output, error = process.communicate()
except Exception as ex:
# Stop the timer.
execution_time = time.time() - start_time
2024-04-10 07:29:09 +00:00
error_message = f"Error executing Python code: {ex}"
2024-12-19 12:48:57 +00:00
error_json = {
"output": "<div class='text-red-500'>"
+ ex
+ "\n"
+ get_trace_exception(ex)
+ "</div>",
"execution_time": execution_time,
}
2024-04-10 07:29:09 +00:00
return error_json
2024-04-10 07:29:09 +00:00
# Stop the timer.
execution_time = time.time() - start_time
# Check if the process was successful.
if process.returncode != 0:
# The child process threw an exception.
2024-12-19 12:48:57 +00:00
pdf_file = tmp_file.with_suffix(".pdf")
2024-04-10 07:40:15 +00:00
print(f"PDF file generated: {pdf_file}")
2024-04-10 07:29:09 +00:00
try:
2024-04-10 07:40:15 +00:00
error_message = f"Error executing Python code:\n{error.decode('utf-8', errors='ignore')}"
2024-04-10 07:29:09 +00:00
except:
error_message = f"Error executing Python code:\n{error}"
2024-04-10 07:40:15 +00:00
if pdf_file.exists():
# The child process was successful.
2024-12-19 12:48:57 +00:00
pdf_file = str(pdf_file).replace("\\", "/")
if (
not "http" in lollmsElfServer.config.host
and not "https" in lollmsElfServer.config.host
):
host = "http://" + lollmsElfServer.config.host
2024-04-10 07:40:15 +00:00
else:
host = lollmsElfServer.config.host
2024-06-23 20:27:27 +00:00
url = f"{host}:{lollmsElfServer.config.port}/{discussion_path_to_url(pdf_file)}"
2024-12-19 12:48:57 +00:00
error_json = {
"output": f"<div>Pdf file generated at: {pdf_file}\n<a href='{url}' target='_blank'>Click here to show</a></div><div>Output:{output.decode('utf-8', errors='ignore')}\n</div><div class='text-red-500'>"
+ error_message
+ "</div>",
"execution_time": execution_time,
}
2024-04-10 07:40:15 +00:00
2024-12-19 12:48:57 +00:00
else:
error_json = {
"output": f"<div>Output:{output.decode('utf-8', errors='ignore')}\n</div><div class='text-red-500'>"
+ error_message
+ "</div>",
"execution_time": execution_time,
}
2024-04-10 07:29:09 +00:00
return error_json
# The child process was successful.
2024-04-10 07:40:15 +00:00
# If the compilation is successful, you will get a PDF file
2024-12-19 12:48:57 +00:00
pdf_file = tmp_file.with_suffix(".pdf")
2024-04-10 07:40:15 +00:00
print(f"PDF file generated: {pdf_file}")
2024-04-10 07:29:09 +00:00
# The child process was successful.
2024-12-19 12:48:57 +00:00
pdf_file = str(pdf_file).replace("\\", "/")
if (
not "http" in lollmsElfServer.config.host
and not "https" in lollmsElfServer.config.host
):
host = "http://" + lollmsElfServer.config.host
2024-04-10 07:29:09 +00:00
else:
host = lollmsElfServer.config.host
2024-07-05 04:53:17 +00:00
url = f"{host}:{lollmsElfServer.config.port}{discussion_path_to_url(pdf_file)}"
2024-12-19 12:48:57 +00:00
output_json = {
"output": f"Pdf file generated at: {pdf_file}\n<a href='{url}' target='_blank'>Click here to show</a>",
"execution_time": execution_time,
}
2024-04-10 07:29:09 +00:00
return output_json