fix: site/ → src/ (stdlib conflict — site is built-in Python module)
Deploy contracts-flask / validate (push) Successful in 0s
Deploy contracts-flask / validate (push) Successful in 0s
This commit is contained in:
+2
-2
@@ -6,8 +6,8 @@ COPY requirements.txt .
|
|||||||
|
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
COPY site /app/site
|
COPY src /app/src
|
||||||
|
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
|
|
||||||
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--timeout", "300", "--workers", "1", "site.app:app"]
|
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--timeout", "300", "--workers", "1", "src.app:app"]
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
Больше никаких прокси на contracts.kube5s.ru — всё локально.
|
Больше никаких прокси на contracts.kube5s.ru — всё локально.
|
||||||
"""
|
"""
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from site.config import VERSION, MAX_CONTENT_LENGTH
|
from src.config import VERSION, MAX_CONTENT_LENGTH
|
||||||
from site.routes import register_routes
|
from src.routes import register_routes
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
@@ -30,10 +30,10 @@ def create_app():
|
|||||||
|
|
||||||
def _init_db():
|
def _init_db():
|
||||||
"""Создать БД + схему + seed prompts. SQLite — всё в одном файле /tmp."""
|
"""Создать БД + схему + seed prompts. SQLite — всё в одном файле /tmp."""
|
||||||
from site.db.connection import init_db
|
from src.db.connection import init_db
|
||||||
init_db()
|
init_db()
|
||||||
try:
|
try:
|
||||||
from site.db import prompts as db_prompts
|
from src.db import prompts as db_prompts
|
||||||
db_prompts.seed_defaults()
|
db_prompts.seed_defaults()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
@@ -95,77 +95,77 @@ class PgRepository:
|
|||||||
"""Реальный доступ к PostgreSQL через существующие db/*.py."""
|
"""Реальный доступ к PostgreSQL через существующие db/*.py."""
|
||||||
|
|
||||||
def insert_document(self, filename, mime_type, original_bytes, batch_id=None, zip_source=None):
|
def insert_document(self, filename, mime_type, original_bytes, batch_id=None, zip_source=None):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
return documents.insert(filename, mime_type, original_bytes,
|
return documents.insert(filename, mime_type, original_bytes,
|
||||||
batch_id=batch_id, zip_source=zip_source)
|
batch_id=batch_id, zip_source=zip_source)
|
||||||
|
|
||||||
def set_document_parsed(self, doc_id, elements):
|
def set_document_parsed(self, doc_id, elements):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
documents.set_parsed(doc_id, elements) # documents.set_parsed уже делает json.dumps
|
documents.set_parsed(doc_id, elements) # documents.set_parsed уже делает json.dumps
|
||||||
|
|
||||||
def set_document_error(self, doc_id, error):
|
def set_document_error(self, doc_id, error):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
documents.set_error(doc_id, error)
|
documents.set_error(doc_id, error)
|
||||||
|
|
||||||
def set_classification(self, doc_id, doc_type, own_number=None, parent_number=None,
|
def set_classification(self, doc_id, doc_type, own_number=None, parent_number=None,
|
||||||
doc_date=None, counterparty=None,
|
doc_date=None, counterparty=None,
|
||||||
classify_raw=None, classify_input=None):
|
classify_raw=None, classify_input=None):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
documents.set_classification(doc_id, doc_type, own_number, parent_number,
|
documents.set_classification(doc_id, doc_type, own_number, parent_number,
|
||||||
doc_date, counterparty,
|
doc_date, counterparty,
|
||||||
classify_raw=classify_raw, classify_input=classify_input)
|
classify_raw=classify_raw, classify_input=classify_input)
|
||||||
|
|
||||||
def set_classify_garbage(self, doc_id, reason=""):
|
def set_classify_garbage(self, doc_id, reason=""):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
documents.set_classify_garbage(doc_id, reason)
|
documents.set_classify_garbage(doc_id, reason)
|
||||||
|
|
||||||
def set_classify_failed(self, doc_id, error):
|
def set_classify_failed(self, doc_id, error):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
documents.set_classify_failed(doc_id, error)
|
documents.set_classify_failed(doc_id, error)
|
||||||
|
|
||||||
def list_pending(self, batch_id):
|
def list_pending(self, batch_id):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
return documents.list_pending(batch_id)
|
return documents.list_pending(batch_id)
|
||||||
|
|
||||||
def insert_contract(self, number, client=""):
|
def insert_contract(self, number, client=""):
|
||||||
from site.db import contracts
|
from src.db import contracts
|
||||||
c = contracts.insert(number, client)
|
c = contracts.insert(number, client)
|
||||||
return c["id"] if c else ""
|
return c["id"] if c else ""
|
||||||
|
|
||||||
def insert_supplement(self, contract_id, doc_id, supp_type):
|
def insert_supplement(self, contract_id, doc_id, supp_type):
|
||||||
from site.db import supplements
|
from src.db import supplements
|
||||||
supplements.insert(contract_id, doc_id, supp_type)
|
supplements.insert(contract_id, doc_id, supp_type)
|
||||||
|
|
||||||
def list_supplements(self, contract_id):
|
def list_supplements(self, contract_id):
|
||||||
from site.db import supplements
|
from src.db import supplements
|
||||||
return supplements.list_by_contract(contract_id)
|
return supplements.list_by_contract(contract_id)
|
||||||
|
|
||||||
def get_spec_current(self, contract_id):
|
def get_spec_current(self, contract_id):
|
||||||
from site.db import spec_current
|
from src.db import spec_current
|
||||||
return spec_current.list_by_contract(contract_id)
|
return spec_current.list_by_contract(contract_id)
|
||||||
|
|
||||||
def get_document(self, doc_id):
|
def get_document(self, doc_id):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
return documents.get(doc_id)
|
return documents.get(doc_id)
|
||||||
|
|
||||||
def list_by_batch(self, batch_id):
|
def list_by_batch(self, batch_id):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
return documents.list_by_batch(batch_id)
|
return documents.list_by_batch(batch_id)
|
||||||
|
|
||||||
def count_by_status(self, batch_id):
|
def count_by_status(self, batch_id):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
return documents.count_by_status(batch_id)
|
return documents.count_by_status(batch_id)
|
||||||
|
|
||||||
def reset_classify_status(self, batch_id):
|
def reset_classify_status(self, batch_id):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
documents.reset_classify_status(batch_id)
|
documents.reset_classify_status(batch_id)
|
||||||
|
|
||||||
def set_classify_processing(self, doc_id):
|
def set_classify_processing(self, doc_id):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
documents.set_classify_processing(doc_id)
|
documents.set_classify_processing(doc_id)
|
||||||
|
|
||||||
def delete_document(self, doc_id):
|
def delete_document(self, doc_id):
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
documents.delete(doc_id)
|
documents.delete(doc_id)
|
||||||
|
|
||||||
|
|
||||||
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
|
|
||||||
def register_routes(app):
|
def register_routes(app):
|
||||||
from site.routes.upload_bp import upload_bp
|
from src.routes.upload_bp import upload_bp
|
||||||
from site.routes.pipeline_bp import pipeline_bp
|
from src.routes.pipeline_bp import pipeline_bp
|
||||||
from site.routes.api_bp import api_bp
|
from src.routes.api_bp import api_bp
|
||||||
from site.routes.prompts_bp import prompts_bp
|
from src.routes.prompts_bp import prompts_bp
|
||||||
from site.routes.health_bp import health_bp
|
from src.routes.health_bp import health_bp
|
||||||
from site.routes.pages_bp import pages_bp
|
from src.routes.pages_bp import pages_bp
|
||||||
|
|
||||||
app.register_blueprint(upload_bp)
|
app.register_blueprint(upload_bp)
|
||||||
app.register_blueprint(pipeline_bp)
|
app.register_blueprint(pipeline_bp)
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
"""API blueprint — groups, documents, supplements, sync, cleanup, spec-current, chat."""
|
"""API blueprint — groups, documents, supplements, sync, cleanup, spec-current, chat."""
|
||||||
from flask import Blueprint, request, jsonify
|
from flask import Blueprint, request, jsonify
|
||||||
from site.db import documents, supplements, spec_current
|
from src.db import documents, supplements, spec_current
|
||||||
from site.db.connection import execute, query
|
from src.db.connection import execute, query
|
||||||
from site.services.grouping import group_documents, apply_groups
|
from src.services.grouping import group_documents, apply_groups
|
||||||
from site.config import LLM_URL, LLM_KEY, LLM_MODEL
|
from src.config import LLM_URL, LLM_KEY, LLM_MODEL
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
api_bp = Blueprint("api", __name__)
|
api_bp = Blueprint("api", __name__)
|
||||||
@@ -177,6 +177,6 @@ def chat():
|
|||||||
@api_bp.route("/api/cleanup", methods=["POST"])
|
@api_bp.route("/api/cleanup", methods=["POST"])
|
||||||
def api_cleanup():
|
def api_cleanup():
|
||||||
"""Полная очистка: os.remove(DB) + init новой. Данные гарантированно стёрты."""
|
"""Полная очистка: os.remove(DB) + init новой. Данные гарантированно стёрты."""
|
||||||
from site.db.connection import cleanup_db
|
from src.db.connection import cleanup_db
|
||||||
cleanup_db()
|
cleanup_db()
|
||||||
return jsonify(ok=True, message="all data cleaned")
|
return jsonify(ok=True, message="all data cleaned")
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Health probe — обязательно для Штурвала."""
|
"""Health probe — обязательно для Штурвала."""
|
||||||
from flask import Blueprint, jsonify
|
from flask import Blueprint, jsonify
|
||||||
from site.config import VERSION
|
from src.config import VERSION
|
||||||
|
|
||||||
health_bp = Blueprint("health", __name__)
|
health_bp = Blueprint("health", __name__)
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
"""Pipeline blueprint — SSE-сравнение + classify."""
|
"""Pipeline blueprint — SSE-сравнение + classify."""
|
||||||
import json, re, os, threading
|
import json, re, os, threading
|
||||||
from flask import Blueprint, request, jsonify, Response, stream_with_context
|
from flask import Blueprint, request, jsonify, Response, stream_with_context
|
||||||
from site.services.process import run_pipeline
|
from src.services.process import run_pipeline
|
||||||
from site.services.classify import classify_batch
|
from src.services.classify import classify_batch
|
||||||
from site.llm_prompt import build_prompt
|
from src.llm_prompt import build_prompt
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
|
|
||||||
pipeline_bp = Blueprint("pipeline", __name__)
|
pipeline_bp = Blueprint("pipeline", __name__)
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Prompts blueprint — CRUD + activate для версионирования промптов."""
|
"""Prompts blueprint — CRUD + activate для версионирования промптов."""
|
||||||
from flask import Blueprint, request, jsonify
|
from flask import Blueprint, request, jsonify
|
||||||
from site.db import prompts as db_prompts
|
from src.db import prompts as db_prompts
|
||||||
|
|
||||||
prompts_bp = Blueprint("prompts", __name__)
|
prompts_bp = Blueprint("prompts", __name__)
|
||||||
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
"""Upload blueprint — загрузка, конвертация, распаковка."""
|
"""Upload blueprint — загрузка, конвертация, распаковка."""
|
||||||
import io, os, base64, hashlib, zipfile, tempfile, subprocess
|
import io, os, base64, hashlib, zipfile, tempfile, subprocess
|
||||||
from flask import Blueprint, request, jsonify, send_file
|
from flask import Blueprint, request, jsonify, send_file
|
||||||
from site.services.parse import parse_file
|
from src.services.parse import parse_file
|
||||||
from site.db import documents
|
from src.db import documents
|
||||||
from site.config import MAX_CONTENT_LENGTH
|
from src.config import MAX_CONTENT_LENGTH
|
||||||
|
|
||||||
upload_bp = Blueprint("upload", __name__)
|
upload_bp = Blueprint("upload", __name__)
|
||||||
|
|
||||||
@@ -14,8 +14,8 @@ import json, re, os
|
|||||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
from site.db import documents as db_docs
|
from src.db import documents as db_docs
|
||||||
from site.llm_prompt import build_classify_prompt
|
from src.llm_prompt import build_classify_prompt
|
||||||
|
|
||||||
log = __import__("logging").getLogger(__name__)
|
log = __import__("logging").getLogger(__name__)
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ _classify_llm = None
|
|||||||
def _get_classify_client():
|
def _get_classify_client():
|
||||||
global _classify_llm
|
global _classify_llm
|
||||||
if _classify_llm is None:
|
if _classify_llm is None:
|
||||||
from site.services.llm_client import HttpxLLMClient
|
from src.services.llm_client import HttpxLLMClient
|
||||||
_classify_llm = HttpxLLMClient(url=LLM_URL, key=LLM_KEY, model=LLM_MODEL, max_tokens=1000, timeout=60)
|
_classify_llm = HttpxLLMClient(url=LLM_URL, key=LLM_KEY, model=LLM_MODEL, max_tokens=1000, timeout=60)
|
||||||
return _classify_llm
|
return _classify_llm
|
||||||
|
|
||||||
@@ -9,9 +9,9 @@ Grouping service — match classified documents into contract groups.
|
|||||||
- apply_groups(): создаёт contracts + supplements с авто-порядком по дате.
|
- apply_groups(): создаёт contracts + supplements с авто-порядком по дате.
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
from site.db import documents as db_docs
|
from src.db import documents as db_docs
|
||||||
from site.db import contracts as db_contracts
|
from src.db import contracts as db_contracts
|
||||||
from site.db import supplements as db_supplements
|
from src.db import supplements as db_supplements
|
||||||
|
|
||||||
|
|
||||||
def normalize_number(num):
|
def normalize_number(num):
|
||||||
@@ -12,7 +12,7 @@ _llm_client = None
|
|||||||
def _get_default_client():
|
def _get_default_client():
|
||||||
global _llm_client
|
global _llm_client
|
||||||
if _llm_client is None:
|
if _llm_client is None:
|
||||||
from site.services.llm_client import HttpxLLMClient
|
from src.services.llm_client import HttpxLLMClient
|
||||||
_llm_client = HttpxLLMClient(url=LLM_URL, key=LLM_KEY, model=LLM_MODEL)
|
_llm_client = HttpxLLMClient(url=LLM_URL, key=LLM_KEY, model=LLM_MODEL)
|
||||||
return _llm_client
|
return _llm_client
|
||||||
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
Адаптирован из deploy/compare/process.py: callback → generator.
|
Адаптирован из deploy/compare/process.py: callback → generator.
|
||||||
"""
|
"""
|
||||||
import json, time
|
import json, time
|
||||||
from site.db import supplements, spec_current, spec_events
|
from src.db import supplements, spec_current, spec_events
|
||||||
from site.services.metrics import check_arithmetic
|
from src.services.metrics import check_arithmetic
|
||||||
|
|
||||||
|
|
||||||
def run_pipeline(contract_id, order_ids, build_prompt_fn):
|
def run_pipeline(contract_id, order_ids, build_prompt_fn):
|
||||||
@@ -31,7 +31,7 @@ def run_pipeline(contract_id, order_ids, build_prompt_fn):
|
|||||||
yield {"type": "error", "message": "Нет распарсенных файлов"}
|
yield {"type": "error", "message": "Нет распарсенных файлов"}
|
||||||
return
|
return
|
||||||
|
|
||||||
from site.services.llm import call_llm
|
from src.services.llm import call_llm
|
||||||
|
|
||||||
for s in supps:
|
for s in supps:
|
||||||
sid = s["id"]
|
sid = s["id"]
|
||||||
|
Before Width: | Height: | Size: 246 B After Width: | Height: | Size: 246 B |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Reference in New Issue
Block a user