lydgs commited on
Commit
a8a963a
·
verified ·
1 Parent(s): 205280e

Update Dockerfile

Browse files
Files changed (1) hide show
  1. Dockerfile +12 -98
Dockerfile CHANGED
@@ -2,60 +2,32 @@ FROM python:3.11-slim
2
 
3
  WORKDIR /app
4
 
5
- # 安装必要库
6
  RUN pip install fastapi uvicorn google-genai
7
 
8
- # 生成 main.py,包含动态模型列表 + Chat + Embeddings
9
  RUN cat > main.py << 'PYEOF'
10
  from fastapi import FastAPI, Request
11
- from fastapi.responses import JSONResponse, StreamingResponse
12
  from google import genai
13
- import os, uvicorn, json, time
14
 
15
  app = FastAPI()
16
  GOOGLE_API_KEY = os.environ["GOOGLE_API_KEY"]
17
  client = genai.Client(api_key=GOOGLE_API_KEY)
18
 
19
- # ---------- 模型名称映射(短名 -> 完整 resources 名)----------
20
- MODEL_MAP = {
21
- # 聊天模型
22
- "gemini-2.5-flash": "models/gemini-2.5-flash",
23
- "gemini-2.5-pro": "models/gemini-2.5-pro",
24
- "gemini-1.5-flash": "models/gemini-1.5-flash",
25
- "gemini-1.5-pro": "models/gemini-1.5-pro",
26
- # 嵌入模型
27
- "gemini-embedding-001": "models/gemini-embedding-001",
28
- "gemini-embedding-2-preview": "models/gemini-embedding-2-preview",
29
- }
30
-
31
  # 静态模型列表:作为 API 调用失败时的后备方案
32
  STATIC_MODELS = [
33
- {"id": "gemini-2.5-flash", "object": "model", "owned_by": "gemini"},
34
- {"id": "gemini-2.5-pro", "object": "model", "owned_by": "gemini"},
35
- {"id": "gemini-1.5-flash", "object": "model", "owned_by": "gemini"},
36
- {"id": "gemini-1.5-pro", "object": "model", "owned_by": "gemini"},
37
  {"id": "gemini-embedding-001", "object": "model", "owned_by": "gemini"},
38
  {"id": "gemini-embedding-2-preview", "object": "model", "owned_by": "gemini"},
39
  ]
40
 
41
- # ---------- 辅助函数 ----------
42
- def get_full_model_name(short_name: str) -> str:
43
- """将短模型名转换为完整的 resources 路径,若未找到则自动添加 models/ 前缀"""
44
- return MODEL_MAP.get(short_name, f"models/{short_name}")
45
-
46
- def convert_openai_messages(messages: list) -> list:
47
- """将 OpenAI 格式的 messages 转换为 Gemini 要求的 contents 格式"""
48
- contents = []
49
- for msg in messages:
50
- role = msg.get("role", "user")
51
- text = msg.get("content", "")
52
- # Gemini 使用 "user" 和 "model" 角色,将 "assistant" 映射为 "model"
53
- if role == "assistant":
54
- role = "model"
55
- elif role not in ("user", "model"):
56
- role = "user" # 其他角色一律视为 user
57
- contents.append({"role": role, "parts": [{"text": text}]})
58
- return contents
59
 
60
  def fetch_embedding_models():
61
  """动态获取支持 embedContent 的 Gemini Embedding 模型列表"""
@@ -76,77 +48,19 @@ def fetch_embedding_models():
76
  print(f"动态获取模型列表失败,回退到静态列表: {e}")
77
  return STATIC_MODELS
78
 
79
- # ---------- API 端点 ----------
80
  @app.get("/v1/models")
81
  async def list_models():
82
- """
83
- 返回可用模型列表。
84
- 优先动态获取嵌入模型,如果失败则返回静态列表。
85
- """
86
  models = fetch_embedding_models()
87
- # 确保基础聊天模型也出现在列表中(如果动态列表只返回嵌入模型)
88
- chat_models = [m for m in STATIC_MODELS if "embedding" not in m["id"]]
89
- for cm in chat_models:
90
- if not any(m["id"] == cm["id"] for m in models):
91
- models.append(cm)
92
  return JSONResponse({"object": "list", "data": models})
93
 
94
- @app.post("/v1/chat/completions")
95
- async def chat_completions(request: Request):
96
- """OpenAI 兼容的聊天补全端点(非流式)"""
97
- try:
98
- body = await request.json()
99
- model_short = body.get("model", "gemini-2.5-flash")
100
- messages = body.get("messages", [])
101
- temperature = body.get("temperature", 0.7)
102
- max_tokens = body.get("max_tokens", 1000)
103
-
104
- model_full = get_full_model_name(model_short)
105
- contents = convert_openai_messages(messages)
106
-
107
- # 调用 Gemini API
108
- response = client.models.generate_content(
109
- model=model_full,
110
- contents=contents,
111
- config={
112
- "temperature": temperature,
113
- "max_output_tokens": max_tokens,
114
- }
115
- )
116
-
117
- # 构造 OpenAI 兼容响应
118
- choice = {
119
- "index": 0,
120
- "message": {
121
- "role": "assistant",
122
- "content": response.text
123
- },
124
- "finish_reason": "stop"
125
- }
126
- return JSONResponse({
127
- "id": f"chatcmpl-{int(time.time())}",
128
- "object": "chat.completion",
129
- "created": int(time.time()),
130
- "model": model_short,
131
- "choices": [choice],
132
- "usage": {
133
- "prompt_tokens": response.usage_metadata.prompt_token_count,
134
- "completion_tokens": response.usage_metadata.candidates_token_count,
135
- "total_tokens": response.usage_metadata.total_token_count
136
- }
137
- })
138
- except Exception as e:
139
- return JSONResponse({"error": str(e)}, status_code=500)
140
-
141
  @app.post("/v1/embeddings")
142
  async def create_embeddings(request: Request):
143
- """OpenAI 兼容的嵌入端点"""
144
  try:
145
  body = await request.json()
146
  model_short = body.get("model", "gemini-embedding-001")
 
 
147
  input_text = body.get("input", "")
148
- model_full = get_full_model_name(model_short)
149
-
150
  result = client.models.embed_content(
151
  model=model_full,
152
  contents=input_text
 
2
 
3
  WORKDIR /app
4
 
5
+ # 安装依赖
6
  RUN pip install fastapi uvicorn google-genai
7
 
8
+ # 生成 main.py(支持自动获取模型列表)
9
  RUN cat > main.py << 'PYEOF'
10
  from fastapi import FastAPI, Request
11
+ from fastapi.responses import JSONResponse
12
  from google import genai
13
+ import os, uvicorn
14
 
15
  app = FastAPI()
16
  GOOGLE_API_KEY = os.environ["GOOGLE_API_KEY"]
17
  client = genai.Client(api_key=GOOGLE_API_KEY)
18
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  # 静态模型列表:作为 API 调用失败时的后备方案
20
  STATIC_MODELS = [
 
 
 
 
21
  {"id": "gemini-embedding-001", "object": "model", "owned_by": "gemini"},
22
  {"id": "gemini-embedding-2-preview", "object": "model", "owned_by": "gemini"},
23
  ]
24
 
25
+ # 模型名称映射(短名称 -> 完整路径),用于 /v1/embeddings 端点
26
+ MODEL_MAP = {
27
+ "text-embedding-004": "models/text-embedding-004",
28
+ "gemini-embedding-001": "models/gemini-embedding-001",
29
+ "gemini-embedding-2-preview": "models/gemini-embedding-2-preview",
30
+ }
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  def fetch_embedding_models():
33
  """动态获取支持 embedContent 的 Gemini Embedding 模型列表"""
 
48
  print(f"动态获取模型列表失败,回退到静态列表: {e}")
49
  return STATIC_MODELS
50
 
 
51
  @app.get("/v1/models")
52
  async def list_models():
 
 
 
 
53
  models = fetch_embedding_models()
 
 
 
 
 
54
  return JSONResponse({"object": "list", "data": models})
55
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  @app.post("/v1/embeddings")
57
  async def create_embeddings(request: Request):
 
58
  try:
59
  body = await request.json()
60
  model_short = body.get("model", "gemini-embedding-001")
61
+ # 自动补全模型名称为完整路径
62
+ model_full = MODEL_MAP.get(model_short, f"models/{model_short}")
63
  input_text = body.get("input", "")
 
 
64
  result = client.models.embed_content(
65
  model=model_full,
66
  contents=input_text