This commit is contained in:
2026-01-27 20:29:27 +01:00
parent 4e0c5ead48
commit c6f2884759

163
app.py
View File

@@ -27,6 +27,18 @@ file_handler.setFormatter(logging.Formatter(
"%(asctime)s - %(levelname)s - %(name)s - %(message)s"
))
import pyodbc
def get_db_connection():
return pyodbc.connect(
"DRIVER={ODBC Driver 18 for SQL Server};"
"SERVER=VPS88.DATACENTER.CSTI;"
"DATABASE=Faircot-Test;"
"UID=SINGA_META;"
"PWD=Start.123;"
"TrustServerCertificate=yes;"
)
class AHKParser:
lab = "AHK"
@@ -484,48 +496,126 @@ predictor = ocr_predictor(pretrained=True)
logger.info("Models loaded successfully.")
# =============================
# 🧠 Smart OCR
# =============================
# @app.post("/ocr")
# async def ocr(file: UploadFile):
# logger.info(f"Received OCR request: {file.filename}")
# try:
# file_data = await file.read()
# ext = file.filename.lower()
@app.post("/weight-report")
def create_weight_report(payload: dict = Body(...)):
logger.info("Create weight report called")
# # --------- PDF with native text ---------
# if ext.endswith(".pdf"):
# logger.info("PDF detected → Extracting native text first")
# reader = PdfReader(io.BytesIO(file_data))
# direct_text = "".join(
# page.extract_text() or "" for page in reader.pages
# )
# -------- Validation minimale --------
required_fields = [
"chunk_key",
"gross_weight",
"net_weight",
"tare_total",
"bags",
"surveyor_code",
"place_key",
"report_date"
]
# if direct_text.strip():
# logger.info("Native PDF text found → No OCR needed")
# return {"ocr_text": direct_text}
missing = [f for f in required_fields if f not in payload]
if missing:
raise HTTPException(
status_code=400,
detail=f"Missing fields: {', '.join(missing)}"
)
# # -------- Fallback: scanned PDF OCR --------
# logger.info("No native text → PDF treated as scanned → OCR")
# from pdf2image import convert_from_bytes
# images = convert_from_bytes(file_data)
# text = ""
# for i, img in enumerate(images):
# logger.info(f"OCR page {i+1}/{len(images)}")
# text += pytesseract.image_to_string(img) + "\n"
try:
chunk_key = int(payload["chunk_key"])
gross_weight = float(payload["gross_weight"])
net_weight = float(payload["net_weight"])
tare_total = float(payload["tare_total"])
bags = int(payload["bags"])
surveyor_code = int(payload["surveyor_code"])
place_key = int(payload["place_key"])
report_date = int(payload["report_date"])
except Exception as e:
raise HTTPException(
status_code=400,
detail=f"Invalid payload types: {e}"
)
# return {"ocr_text": text}
try:
conn = get_db_connection()
cursor = conn.cursor()
# # --------- Image file OCR ---------
# logger.info("Image detected → Running OCR")
# img = Image.open(io.BytesIO(file_data))
# text = pytesseract.image_to_string(img)
# return {"ocr_text": text}
cursor.execute("""
EXEC dbo.sp_Singa_Automation_InsertWeightReport
@CHUNK_KEY = ?,
@BAGS_SOUND_AND_FULL = ?,
@BAGS_SOUND_AND_SLACK = 0,
@BAGS_DAMAGED_AND_FULL = 0,
@BAGS_DAMAGED_AND_SLACK = 0,
@BAGS_SHORT_LANDED = 0,
@GROSS_SOUND_AND_FULL = ?,
@GROSS_SOUND_AND_SLACK = 0,
@GROSS_DAMAGED_AND_FULL = 0,
@GROSS_DAMAGED_AND_SLACK = 0,
@GROSS_SAMPLES = 0,
@WEIGHING_DATE = ?,
@REPORT_DATE = ?,
@DATE_RECEIVED = ?,
@NET_WEIGHT = ?,
@TARE_TOTAL = ?,
@TARE_FOR_TEN_BAGS = 0,
@SURVEYOR_CODE = ?,
@PLACE_KEY = ?,
@SAMPLE_AFTER_WEIGHING = 'N',
@MODIFIED_BY = 'FAIRCOTBOT',
@MODIFY_DATE = ?,
@VERSION_NB = 1,
@FORWARDER_REF = 'API-TRYTON',
@INSURED_VALUE = '0',
@CREATED_BY = 1424,
@UPDATED_BY = 1424,
@BUY_INVOICE_AMOUNT = 0,
@BUY_CURR_KEY = 0,
@SEL_INVOICE_AMOUNT = 0,
@SEL_CURR_KEY = 0,
@CONSISTENCY = 'N',
@FINALIZED = 'N',
@MOISTURE_VALUE = NULL,
@REPORT_TYPE = 0,
@WET_WEIGHT = NULL,
@WSMD_LOCATION = 0
""",
chunk_key,
bags,
gross_weight,
report_date,
report_date,
report_date,
net_weight,
tare_total,
surveyor_code,
place_key,
report_date
)
# 🟢 On récupère le SELECT final de la SP
row = cursor.fetchone()
conn.commit()
if not row:
raise HTTPException(
status_code=500,
detail="Stored procedure returned no data"
)
return {
"success": True,
"weight_report_key": row.WEIGHT_REPORT_KEY
}
except Exception as e:
logger.exception("Weight report creation failed")
raise HTTPException(status_code=500, detail=str(e))
finally:
try:
conn.close()
except:
pass
# except Exception as e:
# logger.error(f"OCR failed: {e}", exc_info=True)
# raise HTTPException(status_code=500, detail=str(e))
@app.post("/ocr")
async def ocr(file: UploadFile):
"""
@@ -849,7 +939,6 @@ def call_extractor(text: str, lab: str = "AHK"):
return response.json()
@app.post("/parse")
async def parse_endpoint(text: str = Body(..., embed=True)):
lab = parse_report(text)