Add dockerized Magnit API service

This commit is contained in:
q 2026-03-09 11:26:53 +03:00
parent d77941a9a7
commit ad4dc0b341
7 changed files with 25 additions and 3 deletions

View file

@ -1,5 +1,6 @@
# Secrets and local runtime state # Secrets and local runtime state
magnit_session.json magnit_session.json
data/
.env .env
.env.* .env.*
*.log *.log

2
.gitignore vendored
View file

@ -1,5 +1,7 @@
# Secrets and local runtime state # Secrets and local runtime state
magnit_session.json magnit_session.json
data/*
!data/.gitkeep
.env .env
.env.* .env.*

View file

@ -13,4 +13,4 @@ COPY README.md /app/README.md
EXPOSE 8080 EXPOSE 8080
CMD ["python3", "magnit_api.py", "--session-file", "/app/magnit_session.json", "serve", "--host", "0.0.0.0", "--port", "8080"] CMD ["python3", "magnit_api.py", "--session-file", "/data/magnit_session.json", "serve", "--host", "0.0.0.0", "--port", "8080"]

View file

@ -25,6 +25,7 @@ docker compose up -d --build
``` ```
По умолчанию сервис публикуется только в loopback на `127.0.0.1:18080`. По умолчанию сервис публикуется только в loopback на `127.0.0.1:18080`.
Docker хранит session-файл в `./data/magnit_session.json`, а не в корне проекта.
Проверка: Проверка:
@ -140,3 +141,5 @@ curl -X POST "http://127.0.0.1:18080/session/bootstrap" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d @payload.json -d @payload.json
``` ```
При Docker session сохранится в `./data/magnit_session.json`.

1
data/.gitkeep Normal file
View file

@ -0,0 +1 @@

View file

@ -8,7 +8,7 @@ services:
ports: ports:
- "127.0.0.1:${MAGNIT_API_PORT:-18080}:8080" - "127.0.0.1:${MAGNIT_API_PORT:-18080}:8080"
volumes: volumes:
- ./magnit_session.json:/app/magnit_session.json:rw - ./data:/data
healthcheck: healthcheck:
test: test:
[ [

View file

@ -54,15 +54,30 @@ class SessionConfig:
f"Файл сессии не найден: {path}. " f"Файл сессии не найден: {path}. "
"Создайте его через POST /session/bootstrap или команду bootstrap." "Создайте его через POST /session/bootstrap или команду bootstrap."
) )
if path.is_dir():
raise MagnitError(
f"Ожидался JSON-файл сессии, но путь является директорией: {path}. "
"Проверьте docker volume mount."
)
return cls(**json.loads(path.read_text(encoding="utf-8"))) return cls(**json.loads(path.read_text(encoding="utf-8")))
@classmethod @classmethod
def load_or_default(cls, path: Path) -> "SessionConfig": def load_or_default(cls, path: Path) -> "SessionConfig":
if not path.exists(): if not path.exists():
return cls() return cls()
if path.is_dir():
raise MagnitError(
f"Ожидался JSON-файл сессии, но путь является директорией: {path}. "
"Проверьте docker volume mount."
)
return cls.load(path) return cls.load(path)
def save(self, path: Path) -> None: def save(self, path: Path) -> None:
if path.exists() and path.is_dir():
raise MagnitError(
f"Невозможно сохранить сессию: путь является директорией, а не файлом: {path}."
)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text( path.write_text(
json.dumps(asdict(self), ensure_ascii=False, indent=2) + "\n", json.dumps(asdict(self), ensure_ascii=False, indent=2) + "\n",
encoding="utf-8", encoding="utf-8",
@ -193,7 +208,7 @@ class MagnitClient:
def __init__(self, session_path: Path = SESSION_FILE, timeout_seconds: int = DEFAULT_TIMEOUT_SECONDS): def __init__(self, session_path: Path = SESSION_FILE, timeout_seconds: int = DEFAULT_TIMEOUT_SECONDS):
self.session_path = session_path self.session_path = session_path
self.timeout_seconds = timeout_seconds self.timeout_seconds = timeout_seconds
self.session_config = SessionConfig.load(session_path) self.session_config = SessionConfig.load_or_default(session_path)
self.http = requests.Session() self.http = requests.Session()
self._sync_cookies() self._sync_cookies()