Skip to content

Commit 7d40639

Browse files
committed
chore: restore endpoint
1 parent 25598aa commit 7d40639

File tree

8 files changed

+134
-81
lines changed

8 files changed

+134
-81
lines changed

cases.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<<<<<<< HEAD
12
from orquesta_sdk.helpers import orquesta_openai_parameters_mapper
23

34
import os
@@ -7,11 +8,24 @@
78
from orquesta_sdk.remoteconfigs import OrquestaRemoteConfigRequest
89

910
api_key = os.environ.get("ORQUESTA_API_KEY", "__API_KEY__")
11+
=======
12+
import os
13+
14+
from orquesta_sdk import OrquestaClient, OrquestaClientOptions
15+
from orquesta_sdk.endpoints import OrquestaEndpoint, OrquestaEndpointRequest
16+
from orquesta_sdk.exceptions import OrquestaException
17+
18+
api_key = os.environ.get(
19+
"ORQUESTA_API_KEY",
20+
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3b3Jrc3BhY2VJZCI6IjhkMjZjODdkLTU1YzUtNDM0My1hYmI0LWM0YTAxYjFhNDVhMSIsImlhdCI6MTY5Nzk3NzgyMDE3M30.01jUpko1fW5mP7rlvME7NfEnrDocfSm7UWNSaE8iEZY",
21+
)
22+
>>>>>>> 113e75d ( cd /Users/tony/Projects/orquesta/orquesta-python ; /usr/bin/env /Users/tony/Projects/orquesta/orquesta-python/venv/bin/python /Users/tony/.vscode/extensions/ms-python.python-2023.18.0/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher 51707 -- /Users/tony/Projects/orquesta/orquesta-python/cases.py)
1023

1124
options = OrquestaClientOptions(api_key=api_key, ttl=3600, environment="production")
1225

1326
client = OrquestaClient(options)
1427

28+
<<<<<<< HEAD
1529
request = OrquestaPromptRequest(
1630
key="prompt_key",
1731
context={"environments": "production", "workspaceId": "soql1odAABC2"},
@@ -30,3 +44,19 @@
3044
)
3145

3246
print(prompt.value)
47+
=======
48+
request = OrquestaEndpointRequest(
49+
key="chat-multimodel",
50+
)
51+
52+
53+
stream_generator = client.endpoints.stream(request)
54+
55+
try:
56+
for chunk in stream_generator:
57+
print("Received data:", chunk.content)
58+
except OrquestaException as e:
59+
print("Error:", e)
60+
except Exception as e:
61+
print("Error:", e)
62+
>>>>>>> 113e75d ( cd /Users/tony/Projects/orquesta/orquesta-python ; /usr/bin/env /Users/tony/Projects/orquesta/orquesta-python/venv/bin/python /Users/tony/.vscode/extensions/ms-python.python-2023.18.0/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher 51707 -- /Users/tony/Projects/orquesta/orquesta-python/cases.py)

orquesta_sdk/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
class OrquestaInvalidAPIException(BaseException):
1111
"""Raised if the provider API key is invalid."""
12+
1213
pass
1314

1415

@@ -20,6 +21,6 @@ def __init__(self, options: OrquestaClientOptions):
2021
if not api_key:
2122
raise OrquestaInvalidAPIException("The provided API key is invalid.")
2223

23-
self.endpoints = OrquestaEndpoints(options, cache)
24+
self.endpoints = OrquestaEndpoints(options)
2425
self.prompts = OrquestaPrompts(options, cache)
2526
self.remoteconfigs = OrquestaRemoteConfigs(options, cache)

orquesta_sdk/endpoints.py

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
from typing import Any, Dict, Optional
22

3-
from .cache import CacheStore
3+
from .exceptions import OrquestaException
44
from .options import OrquestaClientOptions
5-
from .request import post, ENDPOINTS_API, METRICS_API
6-
from reactivex import create, Observable
7-
8-
from .utils import extract_json
5+
from .request import ENDPOINTS_API, METRICS_API, post
6+
from .utils import extract_json, notify_error
97

108

119
class OrquestaEndpointRequest:
@@ -77,9 +75,8 @@ def add_metrics(self, metrics: OrquestaEndpointMetrics) -> None:
7775

7876

7977
class OrquestaEndpoints:
80-
def __init__(self, options: OrquestaClientOptions, cache: CacheStore):
78+
def __init__(self, options: OrquestaClientOptions):
8179
self.__options = options
82-
self.__cache = cache
8380

8481
def query(
8582
self,
@@ -91,6 +88,9 @@ def query(
9188
body=request.to_dict(),
9289
)
9390

91+
if response.ok is None or response.status_code != 200:
92+
notify_error(response)
93+
9494
data = response.json()
9595

9696
return OrquestaEndpoint(
@@ -100,35 +100,24 @@ def query(
100100
trace_id=data.get("trace_id"),
101101
)
102102

103-
def stream(self, request: OrquestaEndpointRequest) -> Observable[OrquestaEndpoint]:
104-
def handle_stream(observer, _):
105-
with post(
106-
url=ENDPOINTS_API,
107-
api_key=self.__options.api_key,
108-
body=request.to_dict(),
109-
stream=True,
110-
) as response:
111-
if response.ok is None or response.status_code != 200:
112-
observer.on_error(response.json())
113-
return
114-
115-
for line in response.iter_lines():
116-
if line:
117-
data = extract_json(line)
118-
119-
if data.get("is_final") or "[DONE]" in line.decode("utf-8"):
120-
observer.on_completed()
121-
break
122-
123-
if data:
124-
endpoint_chunk = OrquestaEndpoint(
125-
self.__options,
126-
content=data.get("content"),
127-
is_final=data.get("is_final"),
128-
trace_id=data.get("trace_id"),
129-
)
130-
observer.on_next(endpoint_chunk)
131-
132-
source = create(handle_stream)
133-
134-
return source
103+
def stream(self, request: OrquestaEndpointRequest):
104+
with post(
105+
url=ENDPOINTS_API,
106+
api_key=self.__options.api_key,
107+
body=request.to_dict(),
108+
stream=True,
109+
) as response:
110+
if response.ok is None or response.status_code != 200:
111+
notify_error(response)
112+
113+
for line in response.iter_lines():
114+
if line:
115+
data = extract_json(line)
116+
117+
if data:
118+
yield OrquestaEndpoint(
119+
self.__options,
120+
content=data.get("content"),
121+
is_final=data.get("is_final"),
122+
trace_id=data.get("trace_id"),
123+
)

orquesta_sdk/exceptions.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from typing import Optional
2+
3+
4+
class OrquestaException(Exception):
5+
def __init__(
6+
self,
7+
name: str,
8+
message: str,
9+
code: str,
10+
provider_error_message: Optional[str] = None,
11+
) -> None:
12+
super().__init__(message)
13+
self.message = message
14+
self.name = name
15+
self.provider_error_message = provider_error_message
16+
self.code = code
17+
18+
def __str__(self) -> str:
19+
return f"{self.code}: {self.message}"

orquesta_sdk/prompts.py

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import time
22
from typing import Any, Dict, Optional
33

4+
from orquesta_sdk.utils import notify_error
5+
46
from .cache import CacheStore
57
from .options import OrquestaClientOptions
68
from .request import PROMPTS_API, post, METRICS_API
@@ -21,11 +23,11 @@ class OrquestaPromptRequest:
2123
"""
2224

2325
def __init__(
24-
self,
25-
key: str,
26-
context: Optional[Dict[str, Any]] = None,
27-
variables: Optional[Dict[str, Any]] = None,
28-
metadata: Optional[Dict[str, Any]] = None
26+
self,
27+
key: str,
28+
context: Optional[Dict[str, Any]] = None,
29+
variables: Optional[Dict[str, Any]] = None,
30+
metadata: Optional[Dict[str, Any]] = None,
2931
):
3032
"""
3133
Initializes a new OrquestaPromptRequest instance.
@@ -70,10 +72,10 @@ def to_dict(self):
7072

7173
class OrquestaPromptMetricsEconomics:
7274
def __init__(
73-
self,
74-
prompt_tokens: Optional[int],
75-
completion_tokens: int,
76-
total_tokens: Optional[int],
75+
self,
76+
prompt_tokens: Optional[int],
77+
completion_tokens: int,
78+
total_tokens: Optional[int],
7779
):
7880
"""
7981
Initializes an instance of the OrquestaPromptMetricsEconomics class.
@@ -94,12 +96,12 @@ def __init__(
9496

9597
class OrquestaPromptMetrics:
9698
def __init__(
97-
self,
98-
score: Optional[float] = None,
99-
latency: Optional[int] = None,
100-
metadata: Optional[Dict[str, Any]] = None,
101-
llm_response: Optional[str] = None,
102-
economics: Optional[OrquestaPromptMetricsEconomics] = None,
99+
self,
100+
score: Optional[float] = None,
101+
latency: Optional[int] = None,
102+
metadata: Optional[Dict[str, Any]] = None,
103+
llm_response: Optional[str] = None,
104+
economics: Optional[OrquestaPromptMetricsEconomics] = None,
103105
):
104106
self.score = score
105107
self.latency = latency
@@ -126,10 +128,10 @@ def to_dict(self):
126128

127129
class OrquestaPrompt:
128130
def __init__(
129-
self,
130-
options: OrquestaClientOptions,
131-
value: Any,
132-
trace_id: Optional[str],
131+
self,
132+
options: OrquestaClientOptions,
133+
value: Any,
134+
trace_id: Optional[str],
133135
):
134136
self.__options = options
135137
self.value = value
@@ -138,13 +140,9 @@ def __init__(
138140

139141
def add_metrics(self, metrics: OrquestaPromptMetrics) -> None:
140142
body = metrics.to_dict()
141-
body['trace_id'] = self.trace_id
143+
body["trace_id"] = self.trace_id
142144

143-
return post(
144-
api_key=self.__options.api_key,
145-
url=METRICS_API,
146-
body=body
147-
)
145+
return post(api_key=self.__options.api_key, url=METRICS_API, body=body)
148146

149147

150148
class OrquestaPrompts:
@@ -153,10 +151,9 @@ def __init__(self, options: OrquestaClientOptions, cache: CacheStore):
153151
self.__cache = cache
154152

155153
def query(
156-
self,
157-
request: OrquestaPromptRequest,
154+
self,
155+
request: OrquestaPromptRequest,
158156
) -> OrquestaPrompt:
159-
160157
context = request.context or {}
161158

162159
cached_result = self.__cache.get(request.key, context)
@@ -165,17 +162,18 @@ def query(
165162
return cached_result.result
166163

167164
response = post(
168-
url=PROMPTS_API,
169-
api_key=self.__options.api_key,
170-
body=request.to_dict()
165+
url=PROMPTS_API, api_key=self.__options.api_key, body=request.to_dict()
171166
)
172167

168+
if response.ok is None or response.status_code != 200:
169+
notify_error(response)
170+
173171
data = response.json().get(request.key, {})
174172

175173
prompt = OrquestaPrompt(
176174
options=self.__options,
177175
value=data.get("value"),
178-
trace_id=data.get("trace_id")
176+
trace_id=data.get("trace_id"),
179177
)
180178

181179
if prompt.trace_id and prompt.value is not None:

orquesta_sdk/request.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ def post(url: str, api_key: str, body: dict, stream=False, environment=None):
1717
"User-Agent": "orquesta/{};python".format(__version__),
1818
}
1919

20-
if stream:
21-
headers["Accept"] = "text/event-stream"
22-
body["stream"] = True
23-
2420
if environment:
2521
if body.get("context", None) is None:
2622
body["context"] = {"environments": [environment]}
2723
else:
2824
body["context"]["environments"] = [environment]
2925

30-
response = requests.post(url, json=body, headers=headers)
31-
return response
26+
if stream:
27+
headers["Accept"] = "text/event-stream"
28+
body["stream"] = True
29+
return requests.post(url, json=body, headers=headers, stream=True)
30+
31+
return requests.post(url, json=body, headers=headers)

orquesta_sdk/utils.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import json
22

3+
from .exceptions import OrquestaException
4+
35

46
def are_object_equals(dict1, dict2):
57
if isinstance(dict1, dict) and isinstance(dict2, dict):
@@ -27,10 +29,11 @@ def are_object_equals(dict1, dict2):
2729
def dict_cleanup(input_dict):
2830
return {k: v for k, v in input_dict.items() if v is not None}
2931

32+
3033
def extract_json(byte_string):
3134
try:
32-
decoded_string = byte_string.decode('utf-8')
33-
if decoded_string.startswith('data: '):
35+
decoded_string = byte_string.decode("utf-8")
36+
if decoded_string.startswith("data: "):
3437
json_str = decoded_string[6:] # Remove the 'data: ' prefix
3538
json_obj = json.loads(json_str)
3639
return json_obj
@@ -40,3 +43,17 @@ def extract_json(byte_string):
4043
return None
4144
except UnicodeDecodeError:
4245
return None
46+
47+
48+
def notify_error(response):
49+
error = response.json()
50+
51+
if "error" not in error and "message" not in error:
52+
response.raise_for_status()
53+
54+
raise OrquestaException(
55+
name=error["name"],
56+
message=error["message"],
57+
provider_error_message=error.get("provider_error_message", None),
58+
code=error["error_code"],
59+
)

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ readme = "README.md"
2525
[tool.poetry.dependencies]
2626
python = ">=3.7,<4.0.0"
2727
requests = "^2.28.2"
28-
reactivex = "^4.0.4"
2928

3029
[tool.poetry.dev-dependencies]
3130
black = "^21.9b0"

0 commit comments

Comments
 (0)