feat: expose recommendation streaming api
This commit is contained in:
parent
e8d20158e3
commit
41aa93c3c7
7 changed files with 473 additions and 12 deletions
|
|
@ -1,5 +1,6 @@
|
|||
"""HTTP routes for Spotify login and session management."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import cast
|
||||
|
||||
import httpx2
|
||||
|
|
@ -7,7 +8,7 @@ from fastapi import APIRouter, Request
|
|||
from fastapi.responses import JSONResponse, RedirectResponse, Response
|
||||
|
||||
from app.adapters.spotify.login import begin_login, complete_login
|
||||
from app.adapters.spotify.session import PendingLogins, SessionStore
|
||||
from app.adapters.spotify.session import PendingLogins, SessionStore, SpotifySession
|
||||
from app.config import Settings
|
||||
|
||||
SESSION_COOKIE_NAME = "discovery_session"
|
||||
|
|
@ -15,6 +16,14 @@ SESSION_COOKIE_NAME = "discovery_session"
|
|||
router = APIRouter()
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ResolvedSession:
|
||||
"""A session and stable cache key selected for one request."""
|
||||
|
||||
session_id: str
|
||||
session: SpotifySession
|
||||
|
||||
|
||||
@router.get("/api/auth/login")
|
||||
def login(request: Request) -> RedirectResponse:
|
||||
"""Start Spotify Authorization Code with PKCE login."""
|
||||
|
|
@ -65,12 +74,10 @@ async def callback(
|
|||
@router.get("/api/auth/me")
|
||||
def current_session(request: Request) -> JSONResponse:
|
||||
"""Return the display name for a valid application session."""
|
||||
session_id = request.cookies.get(SESSION_COOKIE_NAME)
|
||||
session_store = cast(SessionStore, request.app.state.session_store)
|
||||
session = session_store.get(session_id) if session_id is not None else None
|
||||
if session is None:
|
||||
resolved = resolve_session(request)
|
||||
if resolved is None:
|
||||
return JSONResponse({"detail": "Not authenticated"}, status_code=401)
|
||||
return JSONResponse({"display_name": session.display_name})
|
||||
return JSONResponse({"display_name": resolved.session.display_name})
|
||||
|
||||
|
||||
@router.post("/api/auth/logout", status_code=204)
|
||||
|
|
@ -95,3 +102,19 @@ def logout(request: Request) -> Response:
|
|||
|
||||
def _login_error_redirect() -> RedirectResponse:
|
||||
return RedirectResponse("/?login=error", status_code=307)
|
||||
|
||||
|
||||
def resolve_session(request: Request) -> ResolvedSession | None:
|
||||
"""Resolve the cookie session or the installed live seed session."""
|
||||
session_store = cast(SessionStore, request.app.state.session_store)
|
||||
cookie_session_id = request.cookies.get(SESSION_COOKIE_NAME)
|
||||
if cookie_session_id is not None:
|
||||
cookie_session = session_store.get(cookie_session_id)
|
||||
if cookie_session is not None:
|
||||
return ResolvedSession(cookie_session_id, cookie_session)
|
||||
|
||||
seed_session_id = cast(str | None, getattr(request.app.state, "seed_session_id", None))
|
||||
seed_session = session_store.get(seed_session_id) if seed_session_id is not None else None
|
||||
if seed_session is None or seed_session_id is None:
|
||||
return None
|
||||
return ResolvedSession(seed_session_id, seed_session)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue