Files
evo-sync/web/main.py
mguschin 1bf82adbfc Add sync engine and wire it into the web app
- Add sync_engine.py: background asyncio loop syncing Evotor products to VK market
- Wire sync_loop into lifespan alongside health_check_loop
- Add SYNC_INTERVAL_SECONDS and VK_DEFAULT_PHOTO_PATH settings to config
- Mount default product image in docker-compose
- Add synced_at column to CachedProduct model + migration
- Show synced_at status in catalog products template
- Fix VK groups API response parsing (handle list vs dict)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-10 17:05:37 +03:00

54 lines
1.6 KiB
Python

import asyncio
from contextlib import asynccontextmanager
from fastapi import FastAPI, Depends, Request
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from starlette.middleware.sessions import SessionMiddleware
from web.auth import get_current_user
from web.config import settings
from web.health_checker import health_check_loop
from web.sync_engine import sync_loop
from web.models import User
from web.routes import auth, profile, reset, evotor, vk, sync, catalog
from web.routes import connections
@asynccontextmanager
async def lifespan(app: FastAPI):
tasks = [
asyncio.create_task(health_check_loop(settings.HEALTH_CHECK_INTERVAL_SECONDS)),
asyncio.create_task(sync_loop(settings.SYNC_INTERVAL_SECONDS)),
]
yield
for t in tasks:
t.cancel()
for t in tasks:
try:
await t
except asyncio.CancelledError:
pass
app = FastAPI(title="ЭВОСИНК — Личный кабинет", lifespan=lifespan)
app.add_middleware(SessionMiddleware, secret_key=settings.SECRET_KEY)
app.mount("/static", StaticFiles(directory="web/static"), name="static")
app.include_router(auth.router)
app.include_router(profile.router)
app.include_router(reset.router)
app.include_router(evotor.router)
app.include_router(connections.router)
app.include_router(vk.router)
app.include_router(sync.router)
app.include_router(catalog.router)
@app.get("/")
def home(request: Request, user: User | None = Depends(get_current_user)):
if user:
return RedirectResponse("/profile", 302)
return RedirectResponse("/login", 302)