huijio commited on
Commit
e5f75ff
·
verified ·
1 Parent(s): b1618f2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +89 -45
app.py CHANGED
@@ -1,92 +1,136 @@
1
- import os
2
- import uuid
3
- from datetime import datetime
4
- from typing import List
5
-
6
- from dotenv import load_dotenv
7
  from fastapi import FastAPI, HTTPException, Depends, Security
8
  from fastapi.security import APIKeyHeader
9
  from fastapi.responses import JSONResponse
10
  from pydantic import BaseModel
11
- import uvicorn
12
- from huggingface_hub import InferenceClient
 
 
 
 
13
 
14
  # Load environment variables
15
  load_dotenv()
16
 
17
- app = FastAPI()
 
18
 
19
  # Configuration
20
  API_KEY_NAME = "X-API-KEY"
21
- API_KEYS = os.getenv("API_KEYS", "").split(",")
22
- HF_MODEL = os.getenv("HF_MODEL_NAME", "deepseek-ai/deepseek-llm-7b")
23
- HF_TOKEN = os.getenv("HF_API_TOKEN")
24
 
25
- # Initialize Hugging Face client
26
- client = InferenceClient(token=HF_TOKEN)
 
 
 
 
 
 
27
 
28
- # Security
29
  api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)
30
 
31
  async def get_api_key(api_key: str = Security(api_key_header)):
32
  if not api_key:
33
- raise HTTPException(status_code=401, detail="API key is missing")
 
 
 
34
  if api_key not in API_KEYS:
35
- raise HTTPException(status_code=401, detail="Invalid API key")
 
 
 
36
  return api_key
37
 
38
- class Message(BaseModel):
 
39
  role: str
40
  content: str
41
 
42
- class ChatRequest(BaseModel):
43
- messages: List[Message]
44
- model: str = HF_MODEL
45
  temperature: float = 0.7
46
- max_tokens: int = 200
47
 
 
48
  @app.get("/")
49
  async def health_check():
50
- return {"status": "running", "timestamp": datetime.now().isoformat()}
51
 
 
52
  @app.post("/v1/chat/completions")
53
  async def chat_completion(
54
- request: ChatRequest,
55
  api_key: str = Depends(get_api_key)
56
  ):
57
  try:
58
- # Format messages for HF inference
59
- prompt = "\n".join(
60
- f"{msg.role}: {msg.content}"
61
- for msg in request.messages
62
- )
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
- # Call Hugging Face model
65
- response = client.text_generation(
66
- prompt=prompt,
67
- model=request.model,
68
- temperature=request.temperature,
69
- max_new_tokens=request.max_tokens
 
 
 
 
 
70
  )
71
 
 
 
 
 
 
 
 
72
  return JSONResponse({
73
- "id": str(uuid.uuid4()),
74
  "object": "chat.completion",
75
  "created": int(datetime.now().timestamp()),
76
  "model": request.model,
77
  "choices": [{
 
78
  "message": {
79
  "role": "assistant",
80
- "content": response.strip()
81
- }
82
- }]
 
 
 
 
 
 
83
  })
 
 
 
84
  except Exception as e:
85
  raise HTTPException(status_code=500, detail=str(e))
86
 
87
- if __name__ == "__main__":
88
- uvicorn.run(
89
- app,
90
- host="0.0.0.0",
91
- port=int(os.getenv("PORT", 7860))
92
- )
 
 
 
 
 
 
 
1
  from fastapi import FastAPI, HTTPException, Depends, Security
2
  from fastapi.security import APIKeyHeader
3
  from fastapi.responses import JSONResponse
4
  from pydantic import BaseModel
5
+ import requests
6
+ import uuid
7
+ import os
8
+ from datetime import datetime
9
+ from fastapi.middleware.cors import CORSMiddleware
10
+ from dotenv import load_dotenv
11
 
12
  # Load environment variables
13
  load_dotenv()
14
 
15
+ # Initialize FastAPI app
16
+ app = FastAPI(title="MultiChatAI to OpenAI API Wrapper")
17
 
18
  # Configuration
19
  API_KEY_NAME = "X-API-KEY"
20
+ API_KEYS = os.getenv("API_KEYS", "").split(",") # Comma-separated list from .env
 
 
21
 
22
+ # Configure CORS - adjust these based on your needs
23
+ app.add_middleware(
24
+ CORSMiddleware,
25
+ allow_origins=["*"],
26
+ allow_credentials=True,
27
+ allow_methods=["*"],
28
+ allow_headers=["*"],
29
+ )
30
 
31
+ # Security setup
32
  api_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)
33
 
34
  async def get_api_key(api_key: str = Security(api_key_header)):
35
  if not api_key:
36
+ raise HTTPException(
37
+ status_code=401,
38
+ detail="API key is missing"
39
+ )
40
  if api_key not in API_KEYS:
41
+ raise HTTPException(
42
+ status_code=401,
43
+ detail="Invalid API key"
44
+ )
45
  return api_key
46
 
47
+ # Request models
48
+ class ChatMessage(BaseModel):
49
  role: str
50
  content: str
51
 
52
+ class ChatCompletionRequest(BaseModel):
53
+ model: str = "deepseek-ai/DeepSeek-V3"
54
+ messages: list[ChatMessage]
55
  temperature: float = 0.7
56
+ max_tokens: int = None
57
 
58
+ # Health check endpoint
59
  @app.get("/")
60
  async def health_check():
61
+ return {"status": "OK", "service": "MultiChatAI Proxy", "timestamp": datetime.now().isoformat()}
62
 
63
+ # Main API endpoint
64
  @app.post("/v1/chat/completions")
65
  async def chat_completion(
66
+ request: ChatCompletionRequest,
67
  api_key: str = Depends(get_api_key)
68
  ):
69
  try:
70
+ # Prepare request for MultiChatAI
71
+ multi_chat_body = {
72
+ "chatSettings": {
73
+ "model": request.model,
74
+ "prompt": "You are a helpful AI assistant.",
75
+ "temperature": request.temperature,
76
+ "contextLength": 32000,
77
+ "includeProfileContext": True,
78
+ "includeWorkspaceInstructions": True,
79
+ "embeddingsProvider": "openai"
80
+ },
81
+ "messages": [
82
+ {"role": "system", "content": f"Today is {datetime.now().strftime('%m/%d/%Y')}.\nYou are a helpful AI assistant."},
83
+ *[{"role": msg.role, "content": msg.content} for msg in request.messages]
84
+ ],
85
+ "customModelId": ""
86
+ }
87
 
88
+ headers = {
89
+ "accept": "application/json",
90
+ "content-type": "application/json",
91
+ }
92
+
93
+ # Call MultiChatAI API
94
+ response = requests.post(
95
+ "https://www.multichatai.com/api/chat/deepinfra",
96
+ headers=headers,
97
+ json=multi_chat_body,
98
+ timeout=30
99
  )
100
 
101
+ if not response.ok:
102
+ raise HTTPException(
103
+ status_code=response.status_code,
104
+ detail=f"MultiChatAI API error: {response.text}"
105
+ )
106
+
107
+ # Format response in OpenAI style
108
  return JSONResponse({
109
+ "id": f"chatcmpl-{uuid.uuid4()}",
110
  "object": "chat.completion",
111
  "created": int(datetime.now().timestamp()),
112
  "model": request.model,
113
  "choices": [{
114
+ "index": 0,
115
  "message": {
116
  "role": "assistant",
117
+ "content": response.text.strip()
118
+ },
119
+ "finish_reason": "stop"
120
+ }],
121
+ "usage": {
122
+ "prompt_tokens": 0,
123
+ "completion_tokens": 0,
124
+ "total_tokens": 0
125
+ }
126
  })
127
+
128
+ except requests.Timeout:
129
+ raise HTTPException(status_code=504, detail="Upstream service timeout")
130
  except Exception as e:
131
  raise HTTPException(status_code=500, detail=str(e))
132
 
133
+ # Add this if you need to support OPTIONS requests
134
+ @app.options("/v1/chat/completions")
135
+ async def options_handler():
136
+ return JSONResponse(content={}, status_code=200)