Soumik Bose commited on
Commit ·
cada408
1
Parent(s): bd41de4
ok
Browse files- .vscode/settings.json +3 -0
- controller.py +7 -0
- file_uploader.py +47 -0
.vscode/settings.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"python-envs.defaultEnvManager": "ms-python.python:system"
|
| 3 |
+
}
|
controller.py
CHANGED
|
@@ -49,6 +49,7 @@ from pydantic_mongo_executor_model import ExecutorPayload, ExecutorResponse
|
|
| 49 |
from report_service import FileBoxProps, ReportRequest, execute_report_generation
|
| 50 |
from supabase_service import upload_bytes_to_supabase, upload_file_to_supabase
|
| 51 |
from table_info_model import CsvFieldsRequest, CsvFieldsResponse
|
|
|
|
| 52 |
|
| 53 |
# --- Configuration & Setup ---
|
| 54 |
load_dotenv()
|
|
@@ -59,6 +60,8 @@ logging.basicConfig(
|
|
| 59 |
)
|
| 60 |
logger = logging.getLogger("API_Controller")
|
| 61 |
|
|
|
|
|
|
|
| 62 |
# ==============================================================================
|
| 63 |
# ASYNC CONNECTION POOL MANAGER (UPDATED WITH SSL FALLBACK)
|
| 64 |
# ==============================================================================
|
|
@@ -630,7 +633,11 @@ async def execute_chart_endpoint(payload: ChartExecutionPayload, token: str = De
|
|
| 630 |
image_bytes, error_msg, logs = await run_in_threadpool(execute_python_code, code=payload.code, csv_url=payload.csv_url)
|
| 631 |
if error_msg: return ChartExecutionResponse(status="error", error=error_msg, output_log=logs, request_id=request_id)
|
| 632 |
if payload.return_base64:
|
|
|
|
| 633 |
base64_str = base64.b64encode(image_bytes).decode('utf-8')
|
|
|
|
|
|
|
|
|
|
| 634 |
return ChartExecutionResponse(status="success", base64_image=base64_str, output_log=logs, request_id=request_id)
|
| 635 |
else:
|
| 636 |
unique_name = f"{uuid.uuid4()}.png"
|
|
|
|
| 49 |
from report_service import FileBoxProps, ReportRequest, execute_report_generation
|
| 50 |
from supabase_service import upload_bytes_to_supabase, upload_file_to_supabase
|
| 51 |
from table_info_model import CsvFieldsRequest, CsvFieldsResponse
|
| 52 |
+
from file_uploader import ExternalFileUploader
|
| 53 |
|
| 54 |
# --- Configuration & Setup ---
|
| 55 |
load_dotenv()
|
|
|
|
| 60 |
)
|
| 61 |
logger = logging.getLogger("API_Controller")
|
| 62 |
|
| 63 |
+
uploader = ExternalFileUploader()
|
| 64 |
+
|
| 65 |
# ==============================================================================
|
| 66 |
# ASYNC CONNECTION POOL MANAGER (UPDATED WITH SSL FALLBACK)
|
| 67 |
# ==============================================================================
|
|
|
|
| 633 |
image_bytes, error_msg, logs = await run_in_threadpool(execute_python_code, code=payload.code, csv_url=payload.csv_url)
|
| 634 |
if error_msg: return ChartExecutionResponse(status="error", error=error_msg, output_log=logs, request_id=request_id)
|
| 635 |
if payload.return_base64:
|
| 636 |
+
unique_name = f"{uuid.uuid4()}.png"
|
| 637 |
base64_str = base64.b64encode(image_bytes).decode('utf-8')
|
| 638 |
+
file_url = await run_in_threadpool(uploader.upload_file, file_bytes=image_bytes, file_name=unique_name)
|
| 639 |
+
if file_url:
|
| 640 |
+
return ChartExecutionResponse(status="success", image_url=file_url, output_log=logs, request_id=request_id)
|
| 641 |
return ChartExecutionResponse(status="success", base64_image=base64_str, output_log=logs, request_id=request_id)
|
| 642 |
else:
|
| 643 |
unique_name = f"{uuid.uuid4()}.png"
|
file_uploader.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import requests
|
| 3 |
+
from typing import Optional
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
class ExternalFileUploader:
|
| 7 |
+
def __init__(self):
|
| 8 |
+
self.base_url = os.getenv("FILE_UPLOAD_API_URL")
|
| 9 |
+
self.api_key = os.getenv("FILE_UPLOAD_API_KEY")
|
| 10 |
+
|
| 11 |
+
def upload_file(self, file_bytes: bytes, file_name: str) -> Optional[str]:
|
| 12 |
+
try:
|
| 13 |
+
files = {
|
| 14 |
+
"files": (file_name, file_bytes, "image/png")
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
headers = {
|
| 18 |
+
"X-API-Key": self.api_key
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
response = requests.post(
|
| 22 |
+
f"{self.base_url}/api/v1/files/bulk-upload",
|
| 23 |
+
headers=headers,
|
| 24 |
+
files=files,
|
| 25 |
+
timeout=30
|
| 26 |
+
)
|
| 27 |
+
|
| 28 |
+
if response.status_code != 200:
|
| 29 |
+
print("Upload failed:", response.text)
|
| 30 |
+
return None
|
| 31 |
+
|
| 32 |
+
data = response.json()
|
| 33 |
+
|
| 34 |
+
# Expecting array response
|
| 35 |
+
if not isinstance(data, list) or not data:
|
| 36 |
+
return None
|
| 37 |
+
|
| 38 |
+
first = data[0]
|
| 39 |
+
|
| 40 |
+
if not first.get("success"):
|
| 41 |
+
return None
|
| 42 |
+
|
| 43 |
+
return first["data"]["file_url"]
|
| 44 |
+
|
| 45 |
+
except Exception as e:
|
| 46 |
+
print("Uploader error:", str(e))
|
| 47 |
+
return None
|