-
Notifications
You must be signed in to change notification settings - Fork 0
/
anthropic_proxy.py
54 lines (40 loc) · 1.66 KB
/
anthropic_proxy.py
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
from typing import Any, Dict, Iterable, Optional, List, Union
from pydantic import BaseModel
from starlette.responses import StreamingResponse
from fastapi import FastAPI
from anthropic import AsyncAnthropic, MessageStreamEvent
from anthropic.resources.messages import MessageParam, ModelParam, MetadataParam, TextBlockParam, ToolChoiceParam, ToolParam
app = FastAPI(title="Anthropic-compatible API")
# data models
class Message(BaseModel):
role: str
content: str
class ChatCompletionRequest(BaseModel):
max_tokens: int
messages: Iterable[MessageParam]
model: ModelParam
metadata: Optional[MetadataParam] = None
stop_sequences: Optional[List[str]] = None
stream: Optional[bool] = False
system: Optional[Union[str, Iterable[TextBlockParam]]] = None
temperature: Optional[float] = None
tool_choice: Optional[ToolChoiceParam] = None
tools: Optional[Iterable[ToolParam]] = None
top_k: Optional[int] = None
top_p: Optional[float] = None
client = AsyncAnthropic(api_key="...")
@app.post("/v1/messages")
async def chat_completions(request: ChatCompletionRequest):
if request.stream:
stream = await client.messages.create(**request.model_dump(exclude_none=True))
async def _gen():
event: MessageStreamEvent
async for event in stream:
yield f"data: {event.model_dump_json()}\n\n"
yield "data: [DONE]"
return StreamingResponse(_gen(), media_type="text/event-stream")
else:
return await client.messages.create(**request.model_dump(exclude_none=True))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8081)