Миграция 134_planning_projects.sql + planning_harvest.py: ингест утверждённых ППТ/ПМТ ЕКБ из геопортал-WFS (один BBOX-запрос на слой, geom уже 4326 → SetSRID без Transform) → planning_projects (project_type/source_key UNIQUE, doc_status/год). SAVEPOINT per-row, beat monthly (1-е 06:00). Зависит от TLS-фикса #1103. Документ-центричная таблица отдельно от ird_overlays. 3 теста. ТЭП/PDF — follow-up. Refs #1085. Co-authored-by: lekss361 <lekss361@gendsgn.local> Co-committed-by: lekss361 <lekss361@gendsgn.local>
79 lines
3 KiB
Python
79 lines
3 KiB
Python
"""Celery app — single source of truth для Celery configuration.
|
|
|
|
Beat schedule build → app/workers/beat_schedule.py.
|
|
Worker lifecycle hooks (process_init, worker_ready) → app/workers/lifecycle.py.
|
|
"""
|
|
|
|
import logging
|
|
import os
|
|
|
|
import sentry_sdk
|
|
from celery import Celery
|
|
from sentry_sdk.integrations.celery import CeleryIntegration
|
|
from sentry_sdk.integrations.httpx import HttpxIntegration
|
|
from sentry_sdk.integrations.logging import LoggingIntegration
|
|
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
|
|
|
from app.core.config import settings
|
|
from app.observability.sentry_scrub import scrub_sensitive_query
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# SDK инициализируется в обоих процессах (FastAPI-сервер и Celery-воркер),
|
|
# чтобы события из тасков попадали в GlitchTip. SDK безопасен для двойного
|
|
# вызова — повторный sentry_sdk.init() в одном процессе заменяет клиента.
|
|
if settings.glitchtip_dsn:
|
|
sentry_sdk.init(
|
|
dsn=settings.glitchtip_dsn,
|
|
environment=settings.environment,
|
|
release=os.getenv("GIT_SHA") or os.getenv("SENTRY_RELEASE") or "unknown",
|
|
traces_sample_rate=settings.glitchtip_traces_sample_rate,
|
|
profiles_sample_rate=0.0,
|
|
send_default_pii=False,
|
|
before_send_transaction=scrub_sensitive_query,
|
|
integrations=[
|
|
CeleryIntegration(monitor_beat_tasks=True),
|
|
SqlalchemyIntegration(),
|
|
HttpxIntegration(),
|
|
LoggingIntegration(level=logging.INFO, event_level=logging.ERROR),
|
|
],
|
|
)
|
|
logger.info(
|
|
"GlitchTip SDK initialised in Celery worker (env=%s)",
|
|
settings.environment,
|
|
)
|
|
|
|
celery_app = Celery(
|
|
"gendesign",
|
|
broker=settings.redis_url,
|
|
backend=settings.redis_url,
|
|
include=[
|
|
"app.workers.tasks.scrape_kn",
|
|
"app.workers.tasks.scrape_kn_catalog_objects",
|
|
"app.workers.tasks.refresh_analytics",
|
|
"app.workers.tasks.scrape_objective",
|
|
"app.workers.tasks.objective_etl",
|
|
"app.workers.tasks.nspd_geo",
|
|
"app.workers.tasks.nspd_sync",
|
|
"app.workers.tasks.poi_sync",
|
|
"app.workers.tasks.noise_sync",
|
|
"app.workers.tasks.pzz_sync",
|
|
"app.workers.tasks.scrape_cadastre",
|
|
"app.workers.tasks.ekburg_permits_sync",
|
|
"app.workers.tasks.cbr_macro_sync",
|
|
"app.workers.tasks.supply_layers_refresh",
|
|
"app.workers.tasks.forecast",
|
|
"app.workers.tasks.ird_harvest",
|
|
"app.workers.tasks.opportunity_harvest",
|
|
"app.workers.tasks.planning_harvest",
|
|
],
|
|
)
|
|
celery_app.conf.timezone = "Europe/Moscow"
|
|
|
|
# Apply beat schedule (DB → fallback → hardcoded entries)
|
|
from app.workers.beat_schedule import build_beat_schedule # noqa: E402
|
|
|
|
celery_app.conf.beat_schedule = build_beat_schedule()
|
|
|
|
# Register lifecycle hooks (import for side-effect — signal decorator registration)
|
|
from app.workers import lifecycle # noqa: E402, F401
|