feat: документация из Nextcloud, график у сотрудника, автоочистка фото, мониторинг, итог мастера, фильтр по местам; доп. сервисы в docker-compose
- docker-compose.yml: профили docs (Nextcloud), office (ONLYOFFICE Document Server), ai (Ollama + скачивание модели) - автонастройка: адреса Nextcloud, ONLYOFFICE, портала и модели подставляются из .env или по именам сервисов во внутренней сети Docker; значения из интерфейса важнее - локальная модель в своей сети (имя сервиса, частный IP) подключается без ключа API - .env.example, docs/DEPLOY.md (раздел 7а), README
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"""Автонастройка: значения из окружения и сервисов во внутренней сети Docker; сохранённое в интерфейсе важнее."""
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
os.environ.setdefault("DATABASE_URL", os.environ.get("TEST_DATABASE_URL") or "sqlite:///" + os.path.join(tempfile.mkdtemp(), "ac.db").replace("\\", "/"))
|
||||
os.environ.setdefault("SCHEDULER_INTERVAL", "3600")
|
||||
os.environ.setdefault("SECRET_KEY", "test-secret-key-for-pytest-0123456789abcdef")
|
||||
os.environ.setdefault("DATA_DIR", tempfile.mkdtemp())
|
||||
|
||||
from fastapi.testclient import TestClient # noqa: E402
|
||||
|
||||
from app import assistant, autoconf, settings_store as ss # noqa: E402
|
||||
from app.db import SessionLocal # noqa: E402
|
||||
from app.main import app # noqa: E402
|
||||
|
||||
V1 = "/api/v1"
|
||||
|
||||
|
||||
def test_autoconf_from_docker_network_and_env(monkeypatch):
|
||||
running = {"nextcloud", "onlyoffice", "ollama"}
|
||||
monkeypatch.setattr(autoconf, "resolves", lambda host: host in running)
|
||||
monkeypatch.setenv("NC_USER", "ncadmin")
|
||||
monkeypatch.setenv("NC_PASSWORD", "nc-secret-pass")
|
||||
monkeypatch.setenv("OLLAMA_MODEL", "qwen2.5:3b")
|
||||
monkeypatch.delenv("NC_URL", raising=False)
|
||||
with TestClient(app) as c:
|
||||
adm = {"Authorization": "Bearer " + c.post(f"{V1}/auth/login", json={"username": "admin", "password": "admin"}).json()["access_token"]}
|
||||
cfg = c.get(f"{V1}/docs/config", headers=adm).json()
|
||||
assert cfg["nc_url"] == "http://nextcloud" and cfg["nc_user"] == "ncadmin" and cfg["nc_password_set"]
|
||||
assert cfg["onlyoffice_url"] == "http://onlyoffice" and cfg["portal_internal_url"] == "http://app:8000"
|
||||
assert "nc-secret" not in str(cfg)
|
||||
assert c.get(f"{V1}/me", headers=adm).json()["docs"] is True
|
||||
a = c.get(f"{V1}/assistant/config", headers=adm).json()
|
||||
assert a["base_url"] == "http://ollama:11434/v1" and a["model"] == "qwen2.5:3b" and not a["enabled"]
|
||||
# локальная модель в сети Docker включается без ключа
|
||||
assert c.put(f"{V1}/assistant/config", headers=adm, json={"enabled": True}).status_code == 200
|
||||
with SessionLocal() as db:
|
||||
assert assistant.ready(db)
|
||||
c.put(f"{V1}/assistant/config", headers=adm, json={"enabled": False})
|
||||
# значение из интерфейса важнее автоматического
|
||||
c.put(f"{V1}/docs/config", headers=adm, json={"nc_url": "https://cloud.example.ru"})
|
||||
assert c.get(f"{V1}/docs/config", headers=adm).json()["nc_url"] == "https://cloud.example.ru"
|
||||
with SessionLocal() as db:
|
||||
ss.set_(db, "nc_url", "")
|
||||
db.commit()
|
||||
# сервисов нет — пусто, Nextcloud не подключён
|
||||
running.clear()
|
||||
monkeypatch.delenv("NC_USER")
|
||||
with SessionLocal() as db:
|
||||
assert ss.get(db, "nc_url") == "" and ss.get(db, "onlyoffice_url") == "" and ss.get(db, "portal_internal_url") == ""
|
||||
|
||||
|
||||
def test_is_local():
|
||||
assert autoconf.is_local("http://ollama:11434/v1") and autoconf.is_local("http://localhost:11434/v1")
|
||||
assert autoconf.is_local("http://192.168.1.50:11434/v1") and autoconf.is_local("http://10.0.0.5/v1")
|
||||
assert not autoconf.is_local("https://api.openai.com/v1") and not autoconf.is_local("http://8.8.8.8/v1") and not autoconf.is_local("")
|
||||
Reference in New Issue
Block a user