Zenithwang commited on
Commit
d3eab6a
·
verified ·
1 Parent(s): abaf7bb

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -25
app.py CHANGED
@@ -3,7 +3,7 @@ import os
3
  import base64
4
  import gradio as gr
5
  from PIL import Image
6
- from openai import OpenAI
7
 
8
  # ------- 配置区 -------
9
  # 推荐在 HF Space 的 Settings - Variables and secrets 里设置:
@@ -11,46 +11,67 @@ from openai import OpenAI
11
  # 如果前台定义变量 (比如 STEPFUN_KEY),下面会依然被读取。
12
  STEPFUN_ENDPOINT = "https://api.stepfun.com/v1"
13
  MODEL_NAME = "step-3"
14
-
15
  # --------------------
16
 
17
  def _get_api_key() -> str:
18
- """获取 API KEY,如果没有设置则抛出异常"""
19
- # 优先用 OPENAI_API_KEY(OpenAI SDK 的默认约定),否则回退 STEPFUN_KEY
 
 
 
20
  return os.getenv("OPENAI_API_KEY") or os.getenv("STEPFUN_KEY")
21
 
22
-
23
  def _pil_to_data_url(img: Image.Image, fmt: str = "PNG") -> str:
24
- """将 PIL 图片转换成 base64 Data URL"""
 
 
 
 
25
  buf = io.BytesIO()
26
  img.save(buf, format=fmt)
27
  b64 = base64.b64encode(buf.getvalue()).decode("utf-8")
28
  mime = "image/png" if fmt.upper() == "PNG" else "image/jpeg"
29
  return f"data:{mime};base64,{b64}"
30
 
31
-
32
- def _make_client() -> OpenAI:
 
 
 
 
 
33
  key = _get_api_key()
34
  if not key:
35
  raise RuntimeError(
36
  "API Key 未设置\n请到 Space 的 Settings - Variables and secrets 添加:\n"
37
  "Name=OPENAI_API_KEY, Value=你的 StepFun API Key(或用 STEPFUN_KEY 也可)。"
38
  )
39
- # 创建客户端时指定 StepFun 的 base_url
40
- return OpenAI(api_key=key, base_url=STEPFUN_ENDPOINT)
41
-
42
-
43
- client = _make_client()
44
-
 
 
 
 
 
 
 
 
45
 
46
  def chat_with_step3(image: Image.Image, question: str) -> str:
47
- """调用 StepFun 的 step-3 模型进行推理"""
 
 
 
 
 
48
  if image is None:
49
  return "请先上传图片。"
50
  if not question:
51
  question = "请描述这张图片。"
52
-
53
- # 将 PIL 图片转成 Data URL,传到 StepFun
54
  data_url = _pil_to_data_url(image, fmt="PNG")
55
  messages = [
56
  {
@@ -62,17 +83,10 @@ def chat_with_step3(image: Image.Image, question: str) -> str:
62
  },
63
  ]
64
  try:
65
- # 调用 StepFun 的 OpenAI 兼容接口,不设置 max_tokens
66
- resp = client.chat.completions.create(
67
- model=MODEL_NAME,
68
- messages=messages,
69
- )
70
- return resp.choices[0].message.content
71
  except Exception as e:
72
- # 返回异常信息,方便调试
73
  return f"调用失败: {e!r}"
74
 
75
-
76
  # 构建 Gradio 界面
77
  iface = gr.Interface(
78
  fn=chat_with_step3,
 
3
  import base64
4
  import gradio as gr
5
  from PIL import Image
6
+ import httpx # Use httpx for direct API calls instead of openai SDK
7
 
8
  # ------- 配置区 -------
9
  # 推荐在 HF Space 的 Settings - Variables and secrets 里设置:
 
11
  # 如果前台定义变量 (比如 STEPFUN_KEY),下面会依然被读取。
12
  STEPFUN_ENDPOINT = "https://api.stepfun.com/v1"
13
  MODEL_NAME = "step-3"
 
14
  # --------------------
15
 
16
  def _get_api_key() -> str:
17
+ """
18
+ 获取 API KEY,如果没有设置则返回 None。
19
+ 首先尝试读取环境变量 OPENAI_API_KEY(OpenAI SDK 的默认约定),
20
+ 如果不存在再尝试读取 STEPFUN_KEY。
21
+ """
22
  return os.getenv("OPENAI_API_KEY") or os.getenv("STEPFUN_KEY")
23
 
 
24
  def _pil_to_data_url(img: Image.Image, fmt: str = "PNG") -> str:
25
+ """
26
+ 将 PIL 图片转换成 base64 Data URL。
27
+ 接收一个 PIL.Image 对象和输出格式(默认为 PNG),
28
+ 返回可用于 StepFun OpenAI 兼容接口的 data:image/...;base64,... 字符串。
29
+ """
30
  buf = io.BytesIO()
31
  img.save(buf, format=fmt)
32
  b64 = base64.b64encode(buf.getvalue()).decode("utf-8")
33
  mime = "image/png" if fmt.upper() == "PNG" else "image/jpeg"
34
  return f"data:{mime};base64,{b64}"
35
 
36
+ def _post_chat(messages: list, temperature: float = 0.7) -> str:
37
+ """
38
+ 调用 StepFun 的 chat/completions 接口并返回模型回复。
39
+ 使用 httpx 库向 StepFun 的 OpenAI 兼容接口发送请求,
40
+ 避免使用 openai SDK 导致的 "No API found" 错误。
41
+ messages 参数应符合 OpenAI 接口规范。
42
+ """
43
  key = _get_api_key()
44
  if not key:
45
  raise RuntimeError(
46
  "API Key 未设置\n请到 Space 的 Settings - Variables and secrets 添加:\n"
47
  "Name=OPENAI_API_KEY, Value=你的 StepFun API Key(或用 STEPFUN_KEY 也可)。"
48
  )
49
+ url = f"{STEPFUN_ENDPOINT}/chat/completions"
50
+ headers = {
51
+ "Authorization": f"Bearer {key}",
52
+ "Content-Type": "application/json",
53
+ }
54
+ payload = {
55
+ "model": MODEL_NAME,
56
+ "messages": messages,
57
+ "temperature": temperature,
58
+ }
59
+ resp = httpx.post(url, headers=headers, json=payload, timeout=60)
60
+ resp.raise_for_status()
61
+ data = resp.json()
62
+ return data["choices"][0]["message"]["content"]
63
 
64
  def chat_with_step3(image: Image.Image, question: str) -> str:
65
+ """
66
+ 调用 StepFun 的 step-3 模型进行推理。
67
+ 首先检查上传的图像和问题文本是否有效,将图像编码为 data URL,
68
+ 构造符合 OpenAI 接口规范的 messages 数组,然后通过 `_post_chat` 发送请求。
69
+ 如遇异常则返回错误信息。
70
+ """
71
  if image is None:
72
  return "请先上传图片。"
73
  if not question:
74
  question = "请描述这张图片。"
 
 
75
  data_url = _pil_to_data_url(image, fmt="PNG")
76
  messages = [
77
  {
 
83
  },
84
  ]
85
  try:
86
+ return _post_chat(messages)
 
 
 
 
 
87
  except Exception as e:
 
88
  return f"调用失败: {e!r}"
89
 
 
90
  # 构建 Gradio 界面
91
  iface = gr.Interface(
92
  fn=chat_with_step3,