from fastapi import FastAPI, UploadFile, File, Form from fastapi.responses import HTMLResponse import pandas as pd import io import re import os from google import genai from PIL import Image app = FastAPI() # 1. THE RAW HTML FRONTEND (Upgraded with JavaScript for dynamic loading) @app.get("/") def main_page(): return HTMLResponse(""" PLC Reader

🏭 PLC Data READER

Capture sinter plant log sheets to digitize tabular data.

Captured Image:

Captured your image
Analyzing your image... this takes a few seconds.
""") # 2. THE PYTHON BACKEND (Now only returns the formatted tables) @app.post("/extract") async def extract_data(api_key_input: str = Form(""), file: UploadFile = File(...)): try: api_key = os.environ.get("GEMINI_API_KEY") or api_key_input if not api_key: return HTMLResponse("
⚠️ Missing API Key. Please enter it above.
") image_bytes = await file.read() img = Image.open(io.BytesIO(image_bytes)) client = genai.Client(api_key=api_key) prompt = "Carefully extract all the data tables from this dashboard image. Format the output strictly as CSV. Enclose the CSV data inside ```csv ``` code blocks. Ensure column headers are included." response = client.models.generate_content( model="gemini-2.5-flash", contents=[prompt, img] ) csv_blocks = re.findall(r'```csv\n(.*?)\n```', response.text, re.DOTALL) if not csv_blocks: return HTMLResponse(f"
⚠️ No tables found. The model couldn't detect clear tables.

Raw Output:
{response.text}
") # Build the HTML snippet for the tables html_output = f"

✅ Extracted {len(csv_blocks)} Table(s)

" for i, csv_data in enumerate(csv_blocks): df = pd.read_csv(io.StringIO(csv_data)) html_output += f"

Table {i+1}

" html_output += f"
{df.to_html(index=False, border=0)}
" return HTMLResponse(html_output) except Exception as e: return HTMLResponse(f"
❌ Error Processing Image:
{str(e)}
")