File size: 2,899 Bytes
9bb793c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11f019c
9bb793c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"""
Factory pour créer un genai.Client selon le type de provider (R06, R11).

Standalone — ne modifie pas les fichiers providers de la Session A.
La clé API n'est jamais dans le code : lue exclusivement depuis les variables
d'environnement (R06).
"""
# 1. stdlib
import json
import logging
import os

# 2. third-party
from google import genai
from google.oauth2 import service_account

# 3. local
from app.schemas.model_config import ProviderType

logger = logging.getLogger(__name__)

_VERTEX_SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]
_DEFAULT_VERTEX_LOCATION = "us-central1"


def build_client(provider_type: ProviderType) -> genai.Client:
    """Crée un genai.Client configuré pour le provider indiqué.

    Lit les variables d'environnement nécessaires selon le provider :
    - GOOGLE_AI_STUDIO  → GOOGLE_AI_STUDIO_API_KEY
    - VERTEX_SA         → VERTEX_SERVICE_ACCOUNT_JSON

    Args:
        provider_type: type de provider (GOOGLE_AI_STUDIO,
                       VERTEX_SERVICE_ACCOUNT).

    Returns:
        Instance genai.Client prête à l'emploi.

    Raises:
        RuntimeError: si la variable d'environnement requise est absente.
        ValueError: si le JSON du compte de service est invalide ou incomplet.
    """
    if provider_type == ProviderType.GOOGLE_AI_STUDIO:
        api_key = os.environ.get("GOOGLE_AI_STUDIO_API_KEY")
        if not api_key:
            raise RuntimeError(
                "Variable d'environnement manquante : GOOGLE_AI_STUDIO_API_KEY"
            )
        logger.debug("Client Google AI Studio créé")
        return genai.Client(api_key=api_key)

    if provider_type == ProviderType.VERTEX_SERVICE_ACCOUNT:
        sa_json_str = os.environ.get("VERTEX_SERVICE_ACCOUNT_JSON")
        if not sa_json_str:
            raise RuntimeError(
                "Variable d'environnement manquante : VERTEX_SERVICE_ACCOUNT_JSON"
            )
        try:
            sa_info = json.loads(sa_json_str)
        except json.JSONDecodeError as exc:
            raise ValueError(
                f"VERTEX_SERVICE_ACCOUNT_JSON : JSON invalide — {exc}"
            ) from exc

        project_id: str | None = sa_info.get("project_id")
        if not project_id:
            raise ValueError(
                "VERTEX_SERVICE_ACCOUNT_JSON : champ 'project_id' manquant dans le JSON"
            )

        credentials = service_account.Credentials.from_service_account_info(
            sa_info,
            scopes=_VERTEX_SCOPES,
        )
        logger.debug(
            "Client Vertex AI (compte de service) créé",
            extra={"project": project_id},
        )
        return genai.Client(
            vertexai=True,
            project=project_id,
            location=_DEFAULT_VERTEX_LOCATION,
            credentials=credentials,
        )

    raise ValueError(f"Type de provider inconnu : {provider_type}")