asnannp commited on
Commit
f9aae2c
·
1 Parent(s): f415181

deploy: sync backend to Space root (learn-lesson HF cache fix)

Browse files
app/core/http_status.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Starlette status aliases that work on both old and new releases.
2
+
3
+ Starlette renamed 413/422 constants. CI's newer package has the new names and
4
+ deprecates the old ones; older local installs only have the old names.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from starlette import status as starlette_status
10
+
11
+ HTTP_413_CONTENT_TOO_LARGE = getattr(
12
+ starlette_status,
13
+ "HTTP_413_CONTENT_TOO_LARGE",
14
+ starlette_status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
15
+ )
16
+ HTTP_422_UNPROCESSABLE_CONTENT = getattr(
17
+ starlette_status,
18
+ "HTTP_422_UNPROCESSABLE_CONTENT",
19
+ starlette_status.HTTP_422_UNPROCESSABLE_ENTITY,
20
+ )
app/routes/auth.py CHANGED
@@ -633,6 +633,18 @@ def session(current_user: User = Depends(require_user)) -> User:
633
  return current_user
634
 
635
 
 
 
 
 
 
 
 
 
 
 
 
 
636
  @router.get("/google/start", name="google_start")
637
  def google_start(
638
  request: Request,
 
633
  return current_user
634
 
635
 
636
+ @router.post("/logout", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
637
+ def logout(response: Response) -> None:
638
+ """Clear the backend-scoped media session cookie for this browser."""
639
+ production = _is_production_environment()
640
+ response.delete_cookie(
641
+ MEDIA_AUTH_COOKIE,
642
+ path="/generated",
643
+ secure=production,
644
+ samesite="none" if production else "lax",
645
+ )
646
+
647
+
648
  @router.get("/google/start", name="google_start")
649
  def google_start(
650
  request: Request,
app/routes/chat_history.py CHANGED
@@ -11,6 +11,7 @@ from sqlalchemy.orm import Session
11
 
12
  from app.core.auth import require_user
13
  from app.core.database import get_db
 
14
  from app.models.chat_session import ChatMessageRecord, ChatSession
15
  from app.models.document import Document
16
  from app.models.user import User
@@ -121,7 +122,7 @@ def create_session(
121
  context_source_id = body.context_data.source_id if body.context_data else None
122
  if body.source_id and context_source_id and body.source_id != context_source_id:
123
  raise HTTPException(
124
- status_code=status.HTTP_422_UNPROCESSABLE_CONTENT,
125
  detail="The chat source and academic context source must match.",
126
  )
127
  source_id = body.source_id or context_source_id
 
11
 
12
  from app.core.auth import require_user
13
  from app.core.database import get_db
14
+ from app.core.http_status import HTTP_422_UNPROCESSABLE_CONTENT
15
  from app.models.chat_session import ChatMessageRecord, ChatSession
16
  from app.models.document import Document
17
  from app.models.user import User
 
122
  context_source_id = body.context_data.source_id if body.context_data else None
123
  if body.source_id and context_source_id and body.source_id != context_source_id:
124
  raise HTTPException(
125
+ status_code=HTTP_422_UNPROCESSABLE_CONTENT,
126
  detail="The chat source and academic context source must match.",
127
  )
128
  source_id = body.source_id or context_source_id
app/services/file_storage.py CHANGED
@@ -5,6 +5,7 @@ import shutil
5
 
6
  from fastapi import HTTPException, UploadFile, status
7
 
 
8
  from app.utils.ids import prefixed_id
9
 
10
 
@@ -78,7 +79,7 @@ def save_upload_file(upload_file: UploadFile, upload_dir: Path) -> StoredFile:
78
  if too_large:
79
  destination.unlink(missing_ok=True)
80
  raise HTTPException(
81
- status_code=status.HTTP_413_CONTENT_TOO_LARGE,
82
  detail=(
83
  f"File exceeds the 20 MB limit "
84
  f"({total_bytes / (1024 * 1024):.1f} MB uploaded so far). "
 
5
 
6
  from fastapi import HTTPException, UploadFile, status
7
 
8
+ from app.core.http_status import HTTP_413_CONTENT_TOO_LARGE
9
  from app.utils.ids import prefixed_id
10
 
11
 
 
79
  if too_large:
80
  destination.unlink(missing_ok=True)
81
  raise HTTPException(
82
+ status_code=HTTP_413_CONTENT_TOO_LARGE,
83
  detail=(
84
  f"File exceeds the 20 MB limit "
85
  f"({total_bytes / (1024 * 1024):.1f} MB uploaded so far). "
tests/test_http_status.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from app.core.http_status import HTTP_413_CONTENT_TOO_LARGE, HTTP_422_UNPROCESSABLE_CONTENT
2
+
3
+
4
+ def test_http_status_aliases_are_valid_codes() -> None:
5
+ assert HTTP_413_CONTENT_TOO_LARGE == 413
6
+ assert HTTP_422_UNPROCESSABLE_CONTENT == 422
tests/test_textbook_video_ingestion.py CHANGED
@@ -1,13 +1,20 @@
 
 
1
  from pathlib import Path
2
 
3
- from scripts.ingest_sslc_physics_textbooks import (
4
- ChapterCandidate,
5
- classify_block,
6
- detect_chapters,
7
- find_chapter_pdf_page,
8
- parse_contents_chapters,
9
- stable_hash,
10
- )
 
 
 
 
 
11
 
12
 
13
  def test_contents_parser_preserves_book_page_numbers() -> None:
 
1
+ import importlib.util
2
+ import sys
3
  from pathlib import Path
4
 
5
+ _SCRIPT = Path(__file__).resolve().parents[1] / "scripts" / "ingest_sslc_physics_textbooks.py"
6
+ _SPEC = importlib.util.spec_from_file_location("ingest_sslc_physics_textbooks", _SCRIPT)
7
+ assert _SPEC and _SPEC.loader
8
+ _INGEST = importlib.util.module_from_spec(_SPEC)
9
+ sys.modules[_SPEC.name] = _INGEST
10
+ _SPEC.loader.exec_module(_INGEST)
11
+
12
+ ChapterCandidate = _INGEST.ChapterCandidate
13
+ classify_block = _INGEST.classify_block
14
+ detect_chapters = _INGEST.detect_chapters
15
+ find_chapter_pdf_page = _INGEST.find_chapter_pdf_page
16
+ parse_contents_chapters = _INGEST.parse_contents_chapters
17
+ stable_hash = _INGEST.stable_hash
18
 
19
 
20
  def test_contents_parser_preserves_book_page_numbers() -> None: