27.01.26
This commit is contained in:
163
app.py
163
app.py
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user