docs: README для Python MVP; robust seeding in run.py (only if DB empty)

This commit is contained in:
Elshat 2026-09-24 07:10:23 +00:00
parent 6c890fa20a
commit 3bd5a322d1
2 changed files with 51 additions and 2 deletions

View File

@ -1,2 +1,46 @@
# chto-ty-takoe-na-baze-kakih
# chto-ty-takoe-na-baze-kakih — AgroMarket Price Agent
MVP ИИ-агента, который ежедневно собирает открытые агро-цены (KZ/TJ/UZ/RU),
нормализует и категоризирует их, строит аналитику и отдаёт дашборд + дайджест.
## Стек
- Python 3.12, SQLite (переносимо на PostgreSQL), APScheduler, FastAPI + Plotly
- ИИ (LLM) — только **выписывает число из фрагмента источника**, сверка посимвольно
- Каждая цена — со ссылкой на источник и датой сбора
## Запуск
```bash
python3 -m pip install -r requirements.txt
export $(grep -v '^#' .env | xargs) # секреты в .env
python3 -m src.dashboard.run # дашборд на $PORT (дефолт 8000)
python3 -m src.scheduler --once # один прогон пайплайна + дайджест
python3 -m src.scheduler --daemon # демон (ежедневно 07:30)
python3 -m src.demo_data # синтетические данные (60 дней)
python3 -m pytest src/tests -q # тесты
```
## Структура
- `src/pipeline/` — fetch, extract, normalize, categorize, validate, llm_extract, raw, orchestrator
- `src/analytics/` — dynamics, spreads/arbitrage, seasonality, anomalies, alerts, forecast
- `src/dashboard/` — FastAPI: overview, products, product, countries, alerts, quality, sources
- `src/` — db.py (SQL), config.py, taxonomy.py, models.py, cache.py, scheduler.py, digest.py, demo_data.py
- `config/` — taxonomy.yaml, synonyms.yaml, sources.yaml
## Принципы (железо)
1. **Искренность**: LLM не выдумывает цены — только цитирует число из фрагмента,
затем строковая сверка. Не прошло — запись отбрасывается (не в карантин).
2. **Корректность**: «нет данных» ≠ «цена 0». Подозрительные значения — в карантин,
не в аналитику. Ниже порога (floor по категории) → quarantine.
3. **Легальность**: tier-3 / новые источники — `legal_status: pending_review`
(выключены по умолчанию). Никакого обходa captcha/роботов; честный User-Agent,
robots.txt, rate-limit, кеш.
4. **Идентичность**: повторный запуск не дублирует записи (ключ по
source+region+product+price_type+as_of+фрагмент+snapshot).
## Ограничения MVP
- КЗ-официальные источники (stat.gov.kz/uz/tj) недоступны из run-контейнера
(DNS) — только заглушки-адаптеры; нужен прогон из сети с доступом.
- Arbuz.kz / Sharyn — нет публичного API → `pending_review` + ручной CSV-дамп.
- Прогнозы — базовые (seasonal naive, SARIMA) с честным доверительным интервалом
и меткой «низкая уверенность».
- Модель арбитража (груз/тариф/комиссия) — предположения, помечены в UI как «assumptions».

View File

@ -14,9 +14,14 @@ def main() -> None:
format="%(asctime)s %(levelname)s %(name)s %(message)s")
port = int(os.environ.get("PORT", "8000"))
host = os.environ.get("DASHBOARD_HOST", "0.0.0.0")
# Make sure the DB exists and demo data is loaded (idempotent)
# Make sure the DB exists; seed demo data only if empty (idempotent)
from .. import db
from ..analytics.alerts import generate_alerts
rows = db.exec_sql("SELECT COUNT(*) AS t FROM prices")
if rows and rows[0]["t"] == 0 and os.environ.get("SEED_DEMO", "1") != "0":
logging.getLogger("dashboard").info("DB пуст — загружаю демо-данные")
from ..demo_data import generate
generate()
_ = db.source_health() # touch schema
generate_alerts()
uvicorn.run("src.dashboard.app:app", host=host, port=port,