Files
contracts-app/site/upload.py
T

105 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
upload.py — Слой загрузки документов.
Blueprint /upload: принимает файлы, сохраняет в БД, запускает парсинг.
Поток:
POST /upload (multipart/form-data: file)
→ сохраняем original_bytes в documents (status='uploaded')
→ parser.parse() → elements
→ textify.to_text() → parsed_text
→ UPDATE documents SET parsed_text, status='parsed'
→ возвращаем document_id
Не зависит от LLM-слоёв. Только от parser.py, textify.py, db.py.
"""
from flask import Blueprint, request, jsonify
import db
import parser
import textify
import mimeutil
upload_bp = Blueprint("upload", __name__)
@upload_bp.route("/upload", methods=["POST"])
def upload():
"""
Загрузить файл договора/допника.
Ожидает multipart/form-data с полем 'file'.
Возвращает {document_id, filename, status}.
"""
# 1. Проверить что файл передан
if "file" not in request.files:
return jsonify({"error": "no file in request"}), 400
file = request.files["file"]
if not file.filename:
return jsonify({"error": "empty filename"}), 400
# 2. Определить MIME-тип (приоритет: расширение, а не content_type от браузера)
filename = file.filename
mime_type = mimeutil.guess_mime(filename) or file.content_type or "application/octet-stream"
file_bytes = file.read()
if not file_bytes:
return jsonify({"error": "empty file"}), 400
# 3. Сохранить исходный файл в БД
rowcount, err = db.execute(
"INSERT INTO documents (filename, mime_type, original_bytes, status) "
"VALUES (%s, %s, %s, 'uploaded')",
(filename, mime_type, file_bytes),
)
if err:
return jsonify({"error": f"db insert: {err}"}), 500
# 4. Получить ID созданного документа
doc, err = db.query_one(
"SELECT id FROM documents "
"WHERE filename = %s AND status = 'uploaded' "
"ORDER BY created_at DESC LIMIT 1",
(filename,),
)
if err or not doc:
return jsonify({"error": f"document not found after insert: {err}"}), 500
document_id = doc["id"]
# 5. Парсинг: bytes → elements → текст
parse_result = parser.parse(file_bytes, mime_type)
if parse_result.get("errors"):
# Парсинг частично не удался — сохраняем что смогли, помечаем ошибку
db.execute(
"UPDATE documents SET status = 'error', error_message = %s WHERE id = %s",
("; ".join(parse_result["errors"]), str(document_id)),
)
return jsonify({
"document_id": str(document_id),
"filename": filename,
"status": "error",
"errors": parse_result["errors"],
}), 422
# 6. JSON elements → линейный текст для LLM
elements = parse_result.get("elements", [])
parsed_text = textify.to_text(elements)
# 7. Обновить документ: текст + статус
db.execute(
"UPDATE documents SET parsed_text = %s, status = 'parsed' WHERE id = %s",
(parsed_text, str(document_id)),
)
return jsonify({
"document_id": str(document_id),
"filename": filename,
"status": "parsed",
"elements_count": len(elements),
})