File size: 2,380 Bytes
ad51766
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Runtime configuration loaded from environment variables.

Required:
    HY_API_KEY        API key for the upstream OpenAI-compatible endpoint.
    HY_BASE_URL       OpenAI-compatible base URL of the upstream endpoint.
    HY_MODEL          Model name passed to chat.completions.create.

Optional:
    HY_LOG_LEVEL      One of DEBUG / INFO / WARNING / ERROR (default: WARNING).
"""

from __future__ import annotations

import logging
import os

from openai import OpenAI


API_KEY = os.environ.get("HY_API_KEY", "").strip()
BASE_URL = os.environ.get("HY_BASE_URL", "").strip()
MODEL = os.environ.get("HY_MODEL", "").strip()
LOG_LEVEL = os.environ.get("HY_LOG_LEVEL", "WARNING").upper()


# Configure logging once at import time. Kept module-level (rather than
# behind ``if __name__ == "__main__"``) because every module in the
# project does ``logging.getLogger(__name__)`` and expects the format /
# level to already be set up. The handler is only installed if no other
# handler exists — embedders that have already configured logging are
# left untouched.
if not logging.getLogger().handlers:
    logging.basicConfig(
        level=getattr(logging, LOG_LEVEL, logging.WARNING),
        format="%(asctime)s %(levelname)s %(name)s: %(message)s",
    )
logger = logging.getLogger("Hy3")


# Surface missing required env vars loudly at import time. We don't
# raise — that would prevent the Gradio server from even starting up
# (and HuggingFace Spaces would just show a blank build-failed page),
# making it harder to debug. Instead: warn now, and the per-request
# code paths will still fail cleanly with the upstream API's own
# error message.
_missing = [
    name
    for name, val in (
        ("HY_API_KEY", API_KEY),
        ("HY_BASE_URL", BASE_URL),
        ("HY_MODEL", MODEL),
    )
    if not val
]
if _missing:
    logger.warning(
        "Required env var(s) not set: %s. "
        "The app will boot but every chat request will fail until they are "
        "configured (e.g. as HuggingFace Space secrets / variables).",
        ", ".join(_missing),
    )


# ``base_url=""`` would be passed through to httpx and produce undefined
# request URLs. ``None`` makes the OpenAI SDK fall back to its default
# (api.openai.com), which is at least a well-defined behaviour.
client = OpenAI(
    api_key=API_KEY or "missing-api-key",
    base_url=BASE_URL or None,
)