File size: 1,466 Bytes
fda8fb3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from __future__ import annotations

from dataclasses import dataclass

from fastapi import HTTPException, Request
from huggingface_hub import parse_huggingface_oauth

from app.core.config import Settings


@dataclass(frozen=True, slots=True)
class UserContext:
    id: str
    username: str
    display_name: str | None
    avatar_url: str | None
    authenticated: bool


def get_optional_user(request: Request) -> UserContext | None:
    if "session" not in request.scope:
        return None
    try:
        oauth_info = parse_huggingface_oauth(request)
    except AssertionError:
        return None
    if oauth_info is None:
        return None

    user_info = oauth_info.user_info
    username = user_info.preferred_username or user_info.sub or "hf-user"
    display_name = user_info.name or username
    return UserContext(
        id=user_info.sub or username,
        username=username,
        display_name=display_name,
        avatar_url=user_info.picture,
        authenticated=True,
    )


def require_user(request: Request, settings: Settings) -> UserContext:
    user = get_optional_user(request)
    if user is not None:
        return user
    if settings.require_auth:
        raise HTTPException(status_code=401, detail="Sign in with Hugging Face to use this service.")
    return UserContext(
        id="anonymous",
        username="anonymous",
        display_name="Anonymous",
        avatar_url=None,
        authenticated=False,
    )