Refactor API structure: move chat functionality to v1 router, implement dependency injection for OpenAI client, and set up application state management
Build and Push Agent API / build (push) Successful in 6s
Build and Push Agent API / build (push) Successful in 6s
This commit is contained in:
@@ -1,7 +0,0 @@
|
|||||||
from openai import OpenAI
|
|
||||||
from .config import DEEPSEEK_API_KEY
|
|
||||||
|
|
||||||
client = OpenAI(
|
|
||||||
api_key=DEEPSEEK_API_KEY,
|
|
||||||
base_url="https://api.deepseek.com"
|
|
||||||
)
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
from fastapi import FastAPI
|
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from .core.llm import client
|
|
||||||
|
|
||||||
app = FastAPI()
|
|
||||||
|
|
||||||
app.add_middleware(
|
|
||||||
CORSMiddleware,
|
|
||||||
allow_origins=["*"],
|
|
||||||
allow_credentials=True,
|
|
||||||
allow_methods=["*"],
|
|
||||||
allow_headers=["*"],
|
|
||||||
)
|
|
||||||
|
|
||||||
class ChatRequest(BaseModel):
|
|
||||||
message: str
|
|
||||||
session_id: str | None = None
|
|
||||||
|
|
||||||
|
|
||||||
def run_agent(message: str, session_id: str | None = None):
|
|
||||||
response = client.chat.completions.create(
|
|
||||||
model="deepseek-chat",
|
|
||||||
messages=[
|
|
||||||
{"role": "system", "content": "You are a helpful agent."},
|
|
||||||
{"role": "user", "content": message}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
return response.choices[0].message.content
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/")
|
|
||||||
def root():
|
|
||||||
return {"status": "ok"}
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/chat")
|
|
||||||
def chat(req: ChatRequest):
|
|
||||||
response = run_agent(req.message, req.session_id)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"response": response,
|
|
||||||
"session_id": req.session_id
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@app.get("/v1/models")
|
|
||||||
def list_models():
|
|
||||||
return {
|
|
||||||
"object": "list",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"id": "agent-model",
|
|
||||||
"object": "model",
|
|
||||||
"created": 0,
|
|
||||||
"owned_by": "local-agent"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
@app.get("/models")
|
|
||||||
def legacy_models():
|
|
||||||
return list_models()
|
|
||||||
|
|
||||||
@app.post("/chat/completions")
|
|
||||||
def chat_completions(req: dict):
|
|
||||||
messages = req["messages"]
|
|
||||||
user_message = messages[-1]["content"]
|
|
||||||
|
|
||||||
response = run_agent(user_message)
|
|
||||||
|
|
||||||
return {
|
|
||||||
"id": "chatcmpl-local",
|
|
||||||
"object": "chat.completion",
|
|
||||||
"choices": [
|
|
||||||
{
|
|
||||||
"index": 0,
|
|
||||||
"message": {
|
|
||||||
"role": "assistant",
|
|
||||||
"content": response
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
from fastapi import Request
|
||||||
|
from openai import OpenAI
|
||||||
|
|
||||||
|
|
||||||
|
def get_llm_client(request: Request) -> OpenAI:
|
||||||
|
"""FastAPI dependency – returns the singleton OpenAI client from app.state."""
|
||||||
|
return request.app.state.llm_client
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
from fastapi import APIRouter, Body, Depends
|
||||||
|
from openai import OpenAI
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from api.dependencies import get_llm_client
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
|
||||||
|
class ChatRequest(BaseModel):
|
||||||
|
message: str
|
||||||
|
session_id: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
def run_agent(client: OpenAI, message: str, session_id: str | None = None) -> str:
|
||||||
|
response = client.chat.completions.create(
|
||||||
|
model="deepseek-chat",
|
||||||
|
messages=[
|
||||||
|
{"role": "system", "content": "You are a helpful agent."},
|
||||||
|
{"role": "user", "content": message},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
return response.choices[0].message.content
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/")
|
||||||
|
def root():
|
||||||
|
return {"status": "ok"}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/chat")
|
||||||
|
def chat(req: ChatRequest, client: OpenAI = Depends(get_llm_client)):
|
||||||
|
response = run_agent(client, req.message, req.session_id)
|
||||||
|
return {"response": response, "session_id": req.session_id}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/models")
|
||||||
|
def list_models():
|
||||||
|
return {
|
||||||
|
"object": "list",
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "agent-model",
|
||||||
|
"object": "model",
|
||||||
|
"created": 0,
|
||||||
|
"owned_by": "local-agent",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/chat/completions")
|
||||||
|
def chat_completions(
|
||||||
|
payload: dict = Body(...),
|
||||||
|
client: OpenAI = Depends(get_llm_client),
|
||||||
|
):
|
||||||
|
messages = payload["messages"]
|
||||||
|
user_message = messages[-1]["content"]
|
||||||
|
response = run_agent(client, user_message)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"id": "chatcmpl-local",
|
||||||
|
"object": "chat.completion",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"message": {"role": "assistant", "content": response},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
@@ -2,6 +2,6 @@ from dotenv import load_dotenv
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import os
|
import os
|
||||||
|
|
||||||
load_dotenv(Path(__file__).resolve().parent.parent.parent / ".env")
|
load_dotenv(Path(__file__).resolve().parent.parent / ".env")
|
||||||
|
|
||||||
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")
|
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
from openai import OpenAI
|
||||||
|
|
||||||
|
|
||||||
|
def create_client(api_key: str) -> OpenAI:
|
||||||
|
"""Factory for an OpenAI-compatible client pointed at DeepSeek."""
|
||||||
|
return OpenAI(
|
||||||
|
api_key=api_key,
|
||||||
|
base_url="https://api.deepseek.com",
|
||||||
|
)
|
||||||
+1
-1
@@ -10,4 +10,4 @@ COPY . /Agents
|
|||||||
|
|
||||||
ENV PYTHONPATH=/Agents
|
ENV PYTHONPATH=/Agents
|
||||||
|
|
||||||
CMD ["uvicorn", "agent_api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
from fastapi import FastAPI
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
|
||||||
|
from api.v1.chat import router as v1_router
|
||||||
|
from core.config import DEEPSEEK_API_KEY
|
||||||
|
from core.llm import create_client
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Middleware
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Singletons (stored on app.state so every module can reach them via Depends)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
app.state.llm_client = create_client(DEEPSEEK_API_KEY)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Routers
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
app.include_router(v1_router, prefix="/v1")
|
||||||
Reference in New Issue
Block a user