этап 2: переиспользуемый модуль upload (sink) вместо рукописного транспорта

- копирую модуль upload/ из drhider (слои 1-2)
- blueprint: параметр sink (drhider-сессия по умолчанию, сверка — DB+парсинг)
- upload_bp: contracts_upload_sink = _store_and_parse
- routes: регистрирую create_upload_refs_blueprint(cfg, sink=...)
- app.py: корень репо в sys.path (для import upload)
- History: план переиспользования + ревью Соннета
This commit is contained in:
“Naeel”
2026-08-26 08:07:43 +03:00
parent 55bd7a027d
commit db58a433fb
46 changed files with 1986 additions and 27 deletions
+4
View File
@@ -4,6 +4,10 @@
import sys, os
# site/ в sys.path — импортируем модули напрямую, без префиксов
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
# корень репо — для переиспользуемого модуля upload/ (как в drhider)
_REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if _REPO_ROOT not in sys.path:
sys.path.insert(0, _REPO_ROOT)
from flask import Flask
from config import VERSION, MAX_CONTENT_LENGTH
+12 -1
View File
@@ -2,12 +2,14 @@
def register_routes(app):
from routes.upload_bp import upload_bp
import config
from routes.upload_bp import upload_bp, contracts_upload_sink
from routes.pipeline_bp import pipeline_bp
from routes.api_bp import api_bp
from routes.prompts_bp import prompts_bp
from routes.health_bp import health_bp
from routes.pages_bp import pages_bp
from upload.backend.upload_refs import create_upload_refs_blueprint
app.register_blueprint(upload_bp)
app.register_blueprint(pipeline_bp)
@@ -15,3 +17,12 @@ def register_routes(app):
app.register_blueprint(prompts_bp)
app.register_blueprint(health_bp)
app.register_blueprint(pages_bp)
# Переиспользуемый слой закачки через ВМ (модуль upload, паттерн drhider)
app.register_blueprint(create_upload_refs_blueprint({
"apiPrefix": "/api",
"vmUploadPrefix": config.VM_UPLOAD_PREFIX,
"maxFileBytes": config.VM_UPLOAD_MAX_BYTES,
"pullRetries": config.PULL_RETRIES,
"pullRetryDelay": config.PULL_RETRY_DELAY,
}, sink=contracts_upload_sink))
+5 -26
View File
@@ -179,34 +179,13 @@ def upload():
return jsonify(ok=True, doc_id=result["doc_id"], contract_id=result["contract_id"], parsed=result["parsed"])
@upload_bp.route("/api/upload_refs", methods=["POST"])
def upload_refs():
"""Загрузка через ВМ-буфер (паттерн drhider): бэк тянет файлы с ВМ.
def contracts_upload_sink(name, content, batch_id=None, contract_id=None, zip_source=None):
"""Sink для переиспользуемого модуля upload: вставить файл в documents + авто-парсинг.
Тело (маленькое, <64КБ): {batch_id, contract_id, zip_source, files:[{name,size,url}]}.
Для каждой ссылки: SSRF-проверка → лимит → pull с ретраями → store+parse → DELETE с ВМ.
Вызывается модулем create_upload_refs_blueprint(cfg, sink=...) на каждый
вытянутый с ВМ файл. Возвращает dict с ключами ok/doc_id/contract_id/parsed.
"""
data = request.get_json(silent=True) or {}
files = data.get("files") or []
batch_id = data.get("batch_id")
contract_id = data.get("contract_id")
zip_source = data.get("zip_source")
if not files:
return jsonify(ok=False, error="no files"), 400
results = []
for ref in files:
ref_name = _safe_name(str(ref.get("name", "") or ""))
try:
name, content = _pull_from_ref(ref)
except Exception as e:
results.append({"name": ref_name, "ok": False, "error": str(e)})
continue
stored = _store_and_parse(name, content, batch_id, contract_id, zip_source)
results.append({"name": name, **stored})
return jsonify(ok=True, results=results)
return _store_and_parse(name, content, batch_id, contract_id, zip_source)
@upload_bp.route("/convert-doc", methods=["POST"])