MarisUK commited on
Commit
f7763a2
·
verified ·
1 Parent(s): 9731a54

GitHub Actions deploy 6c3a8a0e7d279ff033ddcb436e68cb29e1155820

Browse files
core-python/tests/test_huggingface_human_training_space.py CHANGED
@@ -3,7 +3,9 @@
3
  from __future__ import annotations
4
 
5
  import importlib
 
6
  import sys
 
7
  from pathlib import Path
8
 
9
  from fastapi.testclient import TestClient
@@ -87,6 +89,40 @@ def test_register_and_login_flow(monkeypatch, tmp_path: Path) -> None:
87
  assert login_body["platform"]["examples"]
88
 
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  def test_login_rejects_invalid_password(monkeypatch, tmp_path: Path) -> None:
91
  client = TestClient(human_training_space_app.app)
92
  monkeypatch.setattr(
 
3
  from __future__ import annotations
4
 
5
  import importlib
6
+ import json
7
  import sys
8
+ import tempfile
9
  from pathlib import Path
10
 
11
  from fastapi.testclient import TestClient
 
89
  assert login_body["platform"]["examples"]
90
 
91
 
92
+ def test_register_with_storage_fallback(monkeypatch) -> None:
93
+ client = TestClient(human_training_space_app.app)
94
+ original_users_file = human_training_space_app.USERS_FILE
95
+ fallback_root = Path(tempfile.gettempdir()) / human_training_space_app.USER_STORE_FALLBACK_DIRNAME
96
+ fallback_file = fallback_root / original_users_file.name
97
+ if fallback_file.exists():
98
+ fallback_file.unlink()
99
+ original_path_mkdir = Path.mkdir
100
+
101
+ def fail_default_data_mkdir(self: Path, *args, **kwargs) -> None:
102
+ if self == original_users_file.parent:
103
+ raise PermissionError("read-only")
104
+ return original_path_mkdir(self, *args, **kwargs)
105
+
106
+ monkeypatch.setattr(human_training_space_app, "USERS_FILE", original_users_file)
107
+ monkeypatch.setattr(Path, "mkdir", fail_default_data_mkdir)
108
+ human_training_space_app.SESSION_STORE.clear()
109
+
110
+ response = client.post(
111
+ "/api/auth/register",
112
+ json={
113
+ "full_name": "Māris Ozols",
114
+ "email": "maris-fallback@example.com",
115
+ "password": "drosha-parole-123",
116
+ "role": "owner",
117
+ },
118
+ )
119
+
120
+ assert response.status_code == 200
121
+ assert fallback_file.exists()
122
+ payload = json.loads(fallback_file.read_text(encoding="utf-8"))
123
+ assert payload["maris-fallback@example.com"]["role"] == "owner"
124
+
125
+
126
  def test_login_rejects_invalid_password(monkeypatch, tmp_path: Path) -> None:
127
  client = TestClient(human_training_space_app.app)
128
  monkeypatch.setattr(
huggingface_human_training_space/app.py CHANGED
@@ -9,6 +9,7 @@ import os
9
  import secrets
10
  import subprocess
11
  import sys
 
12
  from datetime import UTC, datetime
13
  from pathlib import Path
14
  from threading import Lock
@@ -162,9 +163,10 @@ PLATFORM_SECTIONS = {
162
  ],
163
  }
164
 
165
- LOGO_URL = "https://github.com/MarisUK/maris.ai.human.training/M-Core.png"
166
  PERSISTENT_DIR = Path(get_env_any_or_default("MARIS_PERSISTENT_DIR", "HF_PERSISTENT_DIR", default="/data"))
167
  USERS_FILE = PERSISTENT_DIR / "human-training-users.json"
 
168
  TRAIN_SCRIPT = str(REPO_ROOT / "huggingface" / "train-hf.sh")
169
  LOG_DIR = Path(
170
  get_env_any_or_default(
@@ -255,24 +257,41 @@ def _timestamp() -> str:
255
  return datetime.now(UTC).replace(microsecond=0).isoformat()
256
 
257
 
258
- def _ensure_user_store() -> None:
259
- USERS_FILE.parent.mkdir(parents=True, exist_ok=True)
260
- if not USERS_FILE.exists():
261
- USERS_FILE.write_text("{}\n", encoding="utf-8")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
 
263
 
264
  def _load_users() -> dict[str, dict[str, str]]:
265
- _ensure_user_store()
266
  try:
267
- payload = json.loads(USERS_FILE.read_text(encoding="utf-8"))
268
  except json.JSONDecodeError as exc:
269
  raise HTTPException(status_code=500, detail="Lietotāju glabātuve nav nolasāma.") from exc
270
  return payload if isinstance(payload, dict) else {}
271
 
272
 
273
  def _save_users(users: dict[str, dict[str, str]]) -> None:
274
- _ensure_user_store()
275
- USERS_FILE.write_text(json.dumps(users, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
276
 
277
 
278
  def _hash_password(password: str, salt_hex: str | None = None) -> tuple[str, str]:
 
9
  import secrets
10
  import subprocess
11
  import sys
12
+ import tempfile
13
  from datetime import UTC, datetime
14
  from pathlib import Path
15
  from threading import Lock
 
163
  ],
164
  }
165
 
166
+ LOGO_URL = "https://github.com/user-attachments/assets/347ded6a-40dc-4991-9cc7-4207cffdf452"
167
  PERSISTENT_DIR = Path(get_env_any_or_default("MARIS_PERSISTENT_DIR", "HF_PERSISTENT_DIR", default="/data"))
168
  USERS_FILE = PERSISTENT_DIR / "human-training-users.json"
169
+ USER_STORE_FALLBACK_DIRNAME = "maris-human-training-space"
170
  TRAIN_SCRIPT = str(REPO_ROOT / "huggingface" / "train-hf.sh")
171
  LOG_DIR = Path(
172
  get_env_any_or_default(
 
257
  return datetime.now(UTC).replace(microsecond=0).isoformat()
258
 
259
 
260
+ def _resolve_user_store_path() -> Path:
261
+ try:
262
+ USERS_FILE.parent.mkdir(parents=True, exist_ok=True)
263
+ except PermissionError:
264
+ fallback_root = Path(tempfile.gettempdir()) / USER_STORE_FALLBACK_DIRNAME
265
+ try:
266
+ fallback_root.mkdir(parents=True, exist_ok=True)
267
+ except PermissionError as exc:
268
+ raise HTTPException(
269
+ status_code=500,
270
+ detail="Lietotāju glabātuve nav pieejama ne primārajā, ne rezerves vietā.",
271
+ ) from exc
272
+ return fallback_root / USERS_FILE.name
273
+ return USERS_FILE
274
+
275
+
276
+ def _ensure_user_store() -> Path:
277
+ users_file = _resolve_user_store_path()
278
+ if not users_file.exists():
279
+ users_file.write_text("{}\n", encoding="utf-8")
280
+ return users_file
281
 
282
 
283
  def _load_users() -> dict[str, dict[str, str]]:
284
+ users_file = _ensure_user_store()
285
  try:
286
+ payload = json.loads(users_file.read_text(encoding="utf-8"))
287
  except json.JSONDecodeError as exc:
288
  raise HTTPException(status_code=500, detail="Lietotāju glabātuve nav nolasāma.") from exc
289
  return payload if isinstance(payload, dict) else {}
290
 
291
 
292
  def _save_users(users: dict[str, dict[str, str]]) -> None:
293
+ users_file = _ensure_user_store()
294
+ users_file.write_text(json.dumps(users, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
295
 
296
 
297
  def _hash_password(password: str, salt_hex: str | None = None) -> tuple[str, str]: