return old versions

This commit is contained in:
maxim 2026-10-02 17:51:36 +03:00
parent 90ab2224dc
commit e454429467
2 changed files with 71 additions and 86 deletions

View File

@ -24,8 +24,8 @@ from src.core.clients import S3Storage, PollWorker
from src.core.async_cache import AsyncInMemoryCache from src.core.async_cache import AsyncInMemoryCache
# from src.core.logger import setup_logger # from src.core.logger import setup_logger
from nats.aio.client import Client as NATS from nats.aio.client import Client as NATS
import nkeys
import base64 import base64
import nkeys
from loguru import logger from loguru import logger
import os import os
@ -42,20 +42,6 @@ VERSION = "1.0.0"
UP_TIME = datetime.now(timezone.utc) UP_TIME = datetime.now(timezone.utc)
kp = nkeys.from_seed(settings.OPENBAO.NATS.NATS_SEED.encode('utf-8'))
def jwt_cb():
return settings.OPENBAO.NATS.NATS_JWT.encode('utf-8')
def sig_cb(nonce):
if (isinstance(nonce, str)):
nonce = nonce.encode('utf-8')
signed = kp.sign(nonce)
return base64.b64encode(signed)
async def sub_cb(msg): async def sub_cb(msg):
return None return None
@ -94,80 +80,75 @@ async def lifespan(app):
app.state.nats_subs = [] app.state.nats_subs = []
app.state.storage = None app.state.storage = None
app.state.nats = None app.state.nats = None
app.state.poller = None
app.state.pdf_poller = None
s3_client = None
smb_registered = False
try: try:
smbclient.register_session(settings.OPENBAO.SMB.SMB_HOST, settings.OPENBAO.SMB.SMB_LOGIN, settings.OPENBAO.SMB.SMB_PASSWORD) minio = settings.OPENBAO.MINIO
except: if minio is not None:
logger.exception("Ошибка при регистрации сессии SMB") s3_client = Minio(
s3_client = Minio(settings.OPENBAO.MINIO.MINIO_URL, access_key=settings.OPENBAO.MINIO.MINIO_ADMIN_LOGIN, secret_key=settings.OPENBAO.MINIO.MINIO_ADMIN_PASSWORD, cert_check=False) minio.MINIO_URL,
try: access_key=minio.MINIO_ADMIN_LOGIN,
bucket_exists = await s3_client.bucket_exists(settings.OPENBAO.MINIO.MINIO_BUCKET) secret_key=minio.MINIO_ADMIN_PASSWORD,
logger.info("Бакет проверен. bucket_exists={bucket_exists}", bucket_exists=bucket_exists) secure=minio.MINIO_SECURE,
except Exception as exc:
logger.exception(
"Не удалось проверить наличие бакетa. error_category=s3_error, error_type={error_type}, error={error}",
error_type=type(exc).__name__,
error=repr(exc),
)
return
storage = S3Storage(client=s3_client, bucket_name=settings.OPENBAO.MINIO.MINIO_BUCKET)
app.state.storage = storage
cache = AsyncInMemoryCache()
nc = NATS()
if not settings.DEBUG:
try:
await nc.connect(settings.OPENBAO.NATS.NATS_URL, user_jwt_cb=jwt_cb, signature_cb=sig_cb,
max_reconnect_attempts=2)
logger.info("Подключение к NATS произошло")
except Exception as exc:
logger.exception(
"Не удалось проверить наличие бакетa. error_category=nats_error, error_type={error_type}, error={error}",
error_type=type(exc).__name__,
error=repr(exc),
) )
return if not await s3_client.bucket_exists(minio.MINIO_BUCKET):
poller = PollWorker(nc, cache, storage) raise RuntimeError(f"Бакет MinIO {minio.MINIO_BUCKET!r} не создан")
await poller.start() app.state.storage = S3Storage(s3_client, minio.MINIO_BUCKET)
pdf_poller = PDFPollWorker(cache, storage) logger.info("MinIO подключён, бакет: {}", minio.MINIO_BUCKET)
await pdf_poller.start()
app.state.nats = nc smb = settings.OPENBAO.SMB
app.state.poller = poller if smb is not None:
app.state.pdf_poller = pdf_poller smbclient.register_session(smb.SMB_HOST, smb.SMB_LOGIN, smb.SMB_PASSWORD,
if not settings.DEBUG: port=smb.SMB_PORT)
handler_cb = build_file_handler(nc, storage) smb_registered = True
logger.info("SMB подключён")
nats_settings = settings.OPENBAO.NATS
if nats_settings is not None:
nc = NATS()
app.state.nats = nc
if not settings.DEBUG:
keypair = nkeys.from_seed(nats_settings.NATS_SEED.encode("utf-8"))
def user_jwt_cb():
return nats_settings.NATS_JWT.encode("utf-8")
def signature_cb(nonce):
return base64.b64encode(keypair.sign(nonce.encode("utf-8")))
await nc.connect(nats_settings.NATS_URL, user_jwt_cb=user_jwt_cb,
signature_cb=signature_cb, max_reconnect_attempts=2)
logger.info("NATS подключён")
missing = [name for name in ("MINIO", "NATS", "SMB")
if getattr(settings.OPENBAO, name) is None]
if missing:
logger.info("Распознавание файлов отключено: не настроены {}", ", ".join(missing))
else:
cache = AsyncInMemoryCache()
app.state.poller = PollWorker(nc, cache, app.state.storage)
await app.state.poller.start()
app.state.pdf_poller = PDFPollWorker(cache, app.state.storage)
await app.state.pdf_poller.start()
try:
# sub_xls = await nc.subscribe('files.tabular_parsed', cb=handler_cb)
# sub_img = await nc.subscribe('files.img_parsed', cb=handler_cb)
#
# app.state.nats_subs = [sub_xls, sub_img]
logger.info("Подписка на топики завершена")
except Exception as exc:
logger.warning(
"Не удалось подписаться на тему. error_category=nats_error, error_type={error_type}, error={error}",
error_type=type(exc).__name__,
error=repr(exc),
)
try:
logger.info("Приложение запущено") logger.info("Приложение запущено")
yield yield
except Exception as exc:
logger.exception("ОШИБКА ПРИ РАБОТЕ С СЕКРЕТАМИ error={error}", error=repr(exc))
finally: finally:
logger.info("Приложение закрывается") for worker in (app.state.poller, app.state.pdf_poller):
smbclient.reset_connection_cache() if worker is not None:
await worker.stop()
if not settings.DEBUG: if not settings.DEBUG:
for sub in app.state.nats_subs: for sub in app.state.nats_subs:
logger.info("Отписываемся от топика")
await sub.unsubscribe() await sub.unsubscribe()
if app.state.nats: if app.state.nats is not None:
await app.state.nats.close() await app.state.nats.close()
if app.state.poller: if s3_client is not None:
await app.state.poller.stop() await s3_client.close_session()
if app.state.storage: if smb_registered:
await app.state.storage.client.close_session() smbclient.reset_connection_cache()
if app.state.pdf_poller: logger.info("Приложение закрывается")
await app.state.pdf_poller.stop()
logger.info("CLOSING APP AT ALL")
app = FastAPI( app = FastAPI(
title="Fast API", title="Fast API",
@ -247,4 +228,4 @@ class SPAStaticFiles(StaticFiles):
app.mount("/", SPAStaticFiles(directory="web", html=True), name="web") app.mount("/", SPAStaticFiles(directory="web", html=True), name="web")
app.mount("/", StaticFiles(directory="web", html=True), name="web") app.mount("/", StaticFiles(directory="web", html=True), name="web")

View File

@ -1,4 +1,5 @@
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import Field
class DBSettings(BaseSettings): class DBSettings(BaseSettings):
@ -10,23 +11,25 @@ class MinioSettings(BaseSettings):
MINIO_ADMIN_LOGIN: str MINIO_ADMIN_LOGIN: str
MINIO_ADMIN_PASSWORD: str MINIO_ADMIN_PASSWORD: str
MINIO_BUCKET: str MINIO_BUCKET: str
MINIO_SECURE: bool = True
class NATSSettings(BaseSettings): class NATSSettings(BaseSettings):
NATS_URL: str NATS_URL: str
NATS_SEED: str NATS_JWT: str = Field(min_length=1)
NATS_JWT: str NATS_SEED: str = Field(min_length=1)
class SMBSettings(BaseSettings): class SMBSettings(BaseSettings):
SMB_HOST: str SMB_HOST: str
SMB_PORT: int = 445
SMB_PATH: str SMB_PATH: str
SMB_LOGIN: str SMB_LOGIN: str
SMB_PASSWORD: str SMB_PASSWORD: str
class OpenBAOSettings(BaseSettings): class OpenBAOSettings(BaseSettings):
DATABASE: DBSettings DATABASE: DBSettings
MINIO: MinioSettings MINIO: MinioSettings | None = None
NATS: NATSSettings NATS: NATSSettings | None = None
SMB: SMBSettings SMB: SMBSettings | None = None
class ServerSettings(BaseSettings): class ServerSettings(BaseSettings):
HOST: str = "0.0.0.0" HOST: str = "0.0.0.0"
@ -40,6 +43,7 @@ class Settings(BaseSettings):
VERSION: str = '1.0.0' VERSION: str = '1.0.0'
class Config: class Config:
case_sensitive = True
extra = "ignore" extra = "ignore"
env_file = ".env" env_file = ".env"
env_nested_delimiter = "__" env_nested_delimiter = "__"
@ -48,4 +52,4 @@ class Settings(BaseSettings):
def get_settings() -> Settings: def get_settings() -> Settings:
return Settings() return Settings()
settings = get_settings() settings = get_settings()