proxyllm-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- proxyllm_sdk-0.1.0/PKG-INFO +24 -0
- proxyllm_sdk-0.1.0/README.md +14 -0
- proxyllm_sdk-0.1.0/proxyllm/__init__.py +3 -0
- proxyllm_sdk-0.1.0/proxyllm/client.py +104 -0
- proxyllm_sdk-0.1.0/proxyllm_sdk.egg-info/PKG-INFO +24 -0
- proxyllm_sdk-0.1.0/proxyllm_sdk.egg-info/SOURCES.txt +8 -0
- proxyllm_sdk-0.1.0/proxyllm_sdk.egg-info/dependency_links.txt +1 -0
- proxyllm_sdk-0.1.0/proxyllm_sdk.egg-info/top_level.txt +1 -0
- proxyllm_sdk-0.1.0/pyproject.toml +17 -0
- proxyllm_sdk-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: proxyllm-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the ProxyLLM OpenAI-compatible gateway.
|
|
5
|
+
Author: ProxyLLM
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: proxyllm,openai,llm
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# ProxyLLM Python SDK
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from proxyllm import ProxyLLMClient
|
|
15
|
+
|
|
16
|
+
client = ProxyLLMClient(api_key="pk_...")
|
|
17
|
+
|
|
18
|
+
completion = client.chat.completions.create(
|
|
19
|
+
model="gpt-4o-mini",
|
|
20
|
+
messages=[{"role": "user", "content": "Say hello."}],
|
|
21
|
+
)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Set `PROXYLLM_BASE_URL` to override the default `https://proxyllm.ericslab.ai/v1`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# ProxyLLM Python SDK
|
|
2
|
+
|
|
3
|
+
```python
|
|
4
|
+
from proxyllm import ProxyLLMClient
|
|
5
|
+
|
|
6
|
+
client = ProxyLLMClient(api_key="pk_...")
|
|
7
|
+
|
|
8
|
+
completion = client.chat.completions.create(
|
|
9
|
+
model="gpt-4o-mini",
|
|
10
|
+
messages=[{"role": "user", "content": "Say hello."}],
|
|
11
|
+
)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Set `PROXYLLM_BASE_URL` to override the default `https://proxyllm.ericslab.ai/v1`.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Any, Dict, Iterable, Mapping, Optional
|
|
7
|
+
from urllib.error import HTTPError
|
|
8
|
+
from urllib.request import Request, urlopen
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ProxyLLMError(Exception):
|
|
12
|
+
def __init__(self, message: str, status_code: int, body: Any):
|
|
13
|
+
super().__init__(message)
|
|
14
|
+
self.status_code = status_code
|
|
15
|
+
self.body = body
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class _ChatCompletions:
|
|
20
|
+
client: "ProxyLLMClient"
|
|
21
|
+
|
|
22
|
+
def create(self, **params: Any) -> Any:
|
|
23
|
+
return self.client.post("/chat/completions", params)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class _Chat:
|
|
28
|
+
client: "ProxyLLMClient"
|
|
29
|
+
|
|
30
|
+
def __post_init__(self) -> None:
|
|
31
|
+
self.completions = _ChatCompletions(self.client)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class _Models:
|
|
36
|
+
client: "ProxyLLMClient"
|
|
37
|
+
|
|
38
|
+
def list(self) -> Any:
|
|
39
|
+
return self.client.get("/models")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ProxyLLMClient:
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
api_key: Optional[str] = None,
|
|
46
|
+
base_url: Optional[str] = None,
|
|
47
|
+
default_headers: Optional[Mapping[str, str]] = None,
|
|
48
|
+
timeout: float = 60,
|
|
49
|
+
) -> None:
|
|
50
|
+
key = api_key or os.getenv("PROXYLLM_API_KEY")
|
|
51
|
+
if not key:
|
|
52
|
+
raise ValueError("ProxyLLM API key required. Pass api_key or set PROXYLLM_API_KEY.")
|
|
53
|
+
self.api_key = key
|
|
54
|
+
self.base_url = (base_url or os.getenv("PROXYLLM_BASE_URL") or "https://proxyllm.ericslab.ai/v1").rstrip("/")
|
|
55
|
+
self.default_headers = dict(default_headers or {})
|
|
56
|
+
self.timeout = timeout
|
|
57
|
+
self.chat = _Chat(self)
|
|
58
|
+
self.models = _Models(self)
|
|
59
|
+
|
|
60
|
+
def get(self, path: str) -> Any:
|
|
61
|
+
return self.request("GET", path)
|
|
62
|
+
|
|
63
|
+
def post(self, path: str, body: Mapping[str, Any]) -> Any:
|
|
64
|
+
return self.request("POST", path, body)
|
|
65
|
+
|
|
66
|
+
def request(self, method: str, path: str, body: Optional[Mapping[str, Any]] = None) -> Any:
|
|
67
|
+
payload = None if body is None else json.dumps(body).encode("utf-8")
|
|
68
|
+
headers = {
|
|
69
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
70
|
+
"Content-Type": "application/json",
|
|
71
|
+
**self.default_headers,
|
|
72
|
+
}
|
|
73
|
+
req = Request(f"{self.base_url}{path}", data=payload, method=method, headers=headers)
|
|
74
|
+
try:
|
|
75
|
+
with urlopen(req, timeout=self.timeout) as res:
|
|
76
|
+
return _decode(res.read())
|
|
77
|
+
except HTTPError as exc:
|
|
78
|
+
raw = exc.read()
|
|
79
|
+
body_obj = _decode(raw)
|
|
80
|
+
raise ProxyLLMError(_error_message(body_obj, exc.reason), exc.code, body_obj) from exc
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _decode(raw: bytes) -> Any:
|
|
84
|
+
if not raw:
|
|
85
|
+
return {}
|
|
86
|
+
text = raw.decode("utf-8")
|
|
87
|
+
try:
|
|
88
|
+
return json.loads(text)
|
|
89
|
+
except json.JSONDecodeError:
|
|
90
|
+
return text
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _error_message(body: Any, fallback: str) -> str:
|
|
94
|
+
if isinstance(body, dict):
|
|
95
|
+
error = body.get("error")
|
|
96
|
+
if isinstance(error, dict) and error.get("message"):
|
|
97
|
+
return str(error["message"])
|
|
98
|
+
if error:
|
|
99
|
+
return str(error)
|
|
100
|
+
if body.get("message"):
|
|
101
|
+
return str(body["message"])
|
|
102
|
+
if isinstance(body, str) and body:
|
|
103
|
+
return body
|
|
104
|
+
return fallback
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: proxyllm-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for the ProxyLLM OpenAI-compatible gateway.
|
|
5
|
+
Author: ProxyLLM
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: proxyllm,openai,llm
|
|
8
|
+
Requires-Python: >=3.9
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# ProxyLLM Python SDK
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from proxyllm import ProxyLLMClient
|
|
15
|
+
|
|
16
|
+
client = ProxyLLMClient(api_key="pk_...")
|
|
17
|
+
|
|
18
|
+
completion = client.chat.completions.create(
|
|
19
|
+
model="gpt-4o-mini",
|
|
20
|
+
messages=[{"role": "user", "content": "Say hello."}],
|
|
21
|
+
)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Set `PROXYLLM_BASE_URL` to override the default `https://proxyllm.ericslab.ai/v1`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
proxyllm
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "proxyllm-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python client for the ProxyLLM OpenAI-compatible gateway."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "ProxyLLM" }]
|
|
13
|
+
keywords = ["proxyllm", "openai", "llm"]
|
|
14
|
+
|
|
15
|
+
[tool.setuptools.packages.find]
|
|
16
|
+
where = ["."]
|
|
17
|
+
include = ["proxyllm*"]
|