promptlayer 1.0.72__py3-none-any.whl → 1.0.73__py3-none-any.whl
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.
Potentially problematic release.
This version of promptlayer might be problematic. Click here for more details.
- promptlayer/__init__.py +37 -2
- promptlayer/exceptions.py +119 -0
- promptlayer/groups/__init__.py +6 -4
- promptlayer/groups/groups.py +4 -4
- promptlayer/promptlayer.py +59 -18
- promptlayer/promptlayer_base.py +2 -1
- promptlayer/promptlayer_mixins.py +4 -2
- promptlayer/span_exporter.py +16 -7
- promptlayer/templates.py +9 -7
- promptlayer/track/__init__.py +28 -10
- promptlayer/track/track.py +45 -26
- promptlayer/utils.py +554 -246
- {promptlayer-1.0.72.dist-info → promptlayer-1.0.73.dist-info}/METADATA +2 -1
- promptlayer-1.0.73.dist-info/RECORD +23 -0
- promptlayer-1.0.72.dist-info/RECORD +0 -22
- {promptlayer-1.0.72.dist-info → promptlayer-1.0.73.dist-info}/WHEEL +0 -0
- {promptlayer-1.0.72.dist-info → promptlayer-1.0.73.dist-info}/licenses/LICENSE +0 -0
promptlayer/utils.py
CHANGED
|
@@ -5,7 +5,6 @@ import functools
|
|
|
5
5
|
import json
|
|
6
6
|
import logging
|
|
7
7
|
import os
|
|
8
|
-
import sys
|
|
9
8
|
import types
|
|
10
9
|
from contextlib import asynccontextmanager
|
|
11
10
|
from copy import deepcopy
|
|
@@ -26,7 +25,15 @@ from centrifuge import (
|
|
|
26
25
|
SubscriptionState,
|
|
27
26
|
)
|
|
28
27
|
from opentelemetry import context, trace
|
|
28
|
+
from tenacity import (
|
|
29
|
+
before_sleep_log,
|
|
30
|
+
retry,
|
|
31
|
+
retry_if_exception,
|
|
32
|
+
stop_after_attempt,
|
|
33
|
+
wait_exponential,
|
|
34
|
+
)
|
|
29
35
|
|
|
36
|
+
from promptlayer import exceptions as _exceptions
|
|
30
37
|
from promptlayer.types import RequestLog
|
|
31
38
|
from promptlayer.types.prompt_template import (
|
|
32
39
|
GetPromptTemplate,
|
|
@@ -37,7 +44,6 @@ from promptlayer.types.prompt_template import (
|
|
|
37
44
|
)
|
|
38
45
|
|
|
39
46
|
# Configuration
|
|
40
|
-
|
|
41
47
|
RERAISE_ORIGINAL_EXCEPTION = os.getenv("PROMPTLAYER_RE_RAISE_ORIGINAL_EXCEPTION", "False").lower() == "true"
|
|
42
48
|
RAISE_FOR_STATUS = os.getenv("PROMPTLAYER_RAISE_FOR_STATUS", "False").lower() == "true"
|
|
43
49
|
DEFAULT_HTTP_TIMEOUT = 5
|
|
@@ -58,6 +64,34 @@ class FinalOutputCode(Enum):
|
|
|
58
64
|
EXCEEDS_SIZE_LIMIT = "EXCEEDS_SIZE_LIMIT"
|
|
59
65
|
|
|
60
66
|
|
|
67
|
+
def should_retry_error(exception):
|
|
68
|
+
"""Check if an exception should trigger a retry.
|
|
69
|
+
|
|
70
|
+
Only retries on server errors (5xx) and rate limits (429).
|
|
71
|
+
"""
|
|
72
|
+
if hasattr(exception, "response"):
|
|
73
|
+
response = exception.response
|
|
74
|
+
if hasattr(response, "status_code"):
|
|
75
|
+
status_code = response.status_code
|
|
76
|
+
if status_code >= 500 or status_code == 429:
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
if isinstance(exception, (_exceptions.PromptLayerInternalServerError, _exceptions.PromptLayerRateLimitError)):
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def retry_on_api_error(func):
|
|
86
|
+
return retry(
|
|
87
|
+
retry=retry_if_exception(should_retry_error),
|
|
88
|
+
stop=stop_after_attempt(4), # 4 total attempts (1 initial + 3 retries)
|
|
89
|
+
wait=wait_exponential(multiplier=2, max=15), # 2s, 4s, 8s
|
|
90
|
+
before_sleep=before_sleep_log(logger, logging.WARNING),
|
|
91
|
+
reraise=True,
|
|
92
|
+
)(func)
|
|
93
|
+
|
|
94
|
+
|
|
61
95
|
def _get_http_timeout():
|
|
62
96
|
try:
|
|
63
97
|
return float(os.getenv("PROMPTLAYER_HTTP_TIMEOUT", DEFAULT_HTTP_TIMEOUT))
|
|
@@ -90,7 +124,8 @@ async def _get_final_output(
|
|
|
90
124
|
headers=headers,
|
|
91
125
|
params={"workflow_version_execution_id": execution_id, "return_all_outputs": return_all_outputs},
|
|
92
126
|
)
|
|
93
|
-
response.
|
|
127
|
+
if response.status_code != 200:
|
|
128
|
+
raise_on_bad_response(response, "PromptLayer had the following error while getting workflow results")
|
|
94
129
|
return response.json()
|
|
95
130
|
|
|
96
131
|
|
|
@@ -104,10 +139,8 @@ async def _resolve_workflow_id(base_url: str, workflow_id_or_name: Union[int, st
|
|
|
104
139
|
async with _make_httpx_client() as client:
|
|
105
140
|
# TODO(dmu) MEDIUM: Generalize the way we make async calls to PromptLayer API and reuse it everywhere
|
|
106
141
|
response = await client.get(f"{base_url}/workflows/{workflow_id_or_name}", headers=headers)
|
|
107
|
-
if
|
|
108
|
-
response
|
|
109
|
-
elif response.status_code != 200:
|
|
110
|
-
raise_on_bad_response(response, "PromptLayer had the following error while running your workflow")
|
|
142
|
+
if response.status_code != 200:
|
|
143
|
+
raise_on_bad_response(response, "PromptLayer had the following error while resolving workflow")
|
|
111
144
|
|
|
112
145
|
return response.json()["workflow"]["id"]
|
|
113
146
|
|
|
@@ -120,9 +153,7 @@ async def _get_ably_token(base_url: str, channel_name, authentication_headers):
|
|
|
120
153
|
headers=authentication_headers,
|
|
121
154
|
params={"capability": channel_name},
|
|
122
155
|
)
|
|
123
|
-
if
|
|
124
|
-
response.raise_for_status()
|
|
125
|
-
elif response.status_code != 201:
|
|
156
|
+
if response.status_code != 201:
|
|
126
157
|
raise_on_bad_response(
|
|
127
158
|
response,
|
|
128
159
|
"PromptLayer had the following error while getting WebSocket token",
|
|
@@ -130,12 +161,11 @@ async def _get_ably_token(base_url: str, channel_name, authentication_headers):
|
|
|
130
161
|
return response.json()
|
|
131
162
|
except Exception as ex:
|
|
132
163
|
error_message = f"Failed to get WebSocket token: {ex}"
|
|
133
|
-
print(error_message) # TODO(dmu) MEDIUM: Remove prints in favor of logging
|
|
134
164
|
logger.exception(error_message)
|
|
135
165
|
if RERAISE_ORIGINAL_EXCEPTION:
|
|
136
166
|
raise
|
|
137
167
|
else:
|
|
138
|
-
raise
|
|
168
|
+
raise _exceptions.PromptLayerAPIError(error_message, response=None, body=None) from ex
|
|
139
169
|
|
|
140
170
|
|
|
141
171
|
def _make_message_listener(base_url: str, results_future, execution_id_future, return_all_outputs, headers):
|
|
@@ -197,22 +227,19 @@ async def _post_workflow_id_run(
|
|
|
197
227
|
try:
|
|
198
228
|
async with _make_httpx_client() as client:
|
|
199
229
|
response = await client.post(url, json=payload, headers=authentication_headers)
|
|
200
|
-
if
|
|
201
|
-
response.raise_for_status()
|
|
202
|
-
elif response.status_code != 201:
|
|
230
|
+
if response.status_code != 201:
|
|
203
231
|
raise_on_bad_response(response, "PromptLayer had the following error while running your workflow")
|
|
204
232
|
|
|
205
233
|
result = response.json()
|
|
206
234
|
if warning := result.get("warning"):
|
|
207
|
-
|
|
235
|
+
logger.warning(f"{warning}")
|
|
208
236
|
except Exception as ex:
|
|
209
237
|
error_message = f"Failed to run workflow: {str(ex)}"
|
|
210
|
-
print(error_message) # TODO(dmu) MEDIUM: Remove prints in favor of logging
|
|
211
238
|
logger.exception(error_message)
|
|
212
239
|
if RERAISE_ORIGINAL_EXCEPTION:
|
|
213
240
|
raise
|
|
214
241
|
else:
|
|
215
|
-
raise
|
|
242
|
+
raise _exceptions.PromptLayerAPIError(error_message, response=None, body=None) from ex
|
|
216
243
|
|
|
217
244
|
return result.get("workflow_version_execution_id")
|
|
218
245
|
|
|
@@ -222,7 +249,9 @@ async def _wait_for_workflow_completion(channel, results_future, message_listene
|
|
|
222
249
|
try:
|
|
223
250
|
return await asyncio.wait_for(results_future, timeout)
|
|
224
251
|
except asyncio.TimeoutError:
|
|
225
|
-
raise
|
|
252
|
+
raise _exceptions.PromptLayerAPITimeoutError(
|
|
253
|
+
"Workflow execution did not complete properly", response=None, body=None
|
|
254
|
+
)
|
|
226
255
|
finally:
|
|
227
256
|
channel.unsubscribe(SET_WORKFLOW_COMPLETE_MESSAGE, message_listener)
|
|
228
257
|
|
|
@@ -270,10 +299,12 @@ async def centrifugo_subscription(client: Client, topic: str, message_listener:
|
|
|
270
299
|
await subscription.unsubscribe()
|
|
271
300
|
|
|
272
301
|
|
|
302
|
+
@retry_on_api_error
|
|
273
303
|
async def arun_workflow_request(
|
|
274
304
|
*,
|
|
275
305
|
api_key: str,
|
|
276
306
|
base_url: str,
|
|
307
|
+
throw_on_error: bool,
|
|
277
308
|
workflow_id_or_name: Optional[Union[int, str]] = None,
|
|
278
309
|
input_variables: Dict[str, Any],
|
|
279
310
|
metadata: Optional[Dict[str, Any]] = None,
|
|
@@ -490,43 +521,57 @@ def promptlayer_api_request(
|
|
|
490
521
|
request_response, "WARNING: While logging your request PromptLayer had the following error"
|
|
491
522
|
)
|
|
492
523
|
except Exception as e:
|
|
493
|
-
|
|
524
|
+
logger.warning(f"While logging your request PromptLayer had the following error: {e}")
|
|
494
525
|
if request_response is not None and return_pl_id:
|
|
495
526
|
return request_response.json().get("request_id")
|
|
496
527
|
|
|
497
528
|
|
|
498
|
-
|
|
529
|
+
@retry_on_api_error
|
|
530
|
+
def track_request(base_url: str, throw_on_error: bool, **body):
|
|
499
531
|
try:
|
|
500
532
|
response = requests.post(
|
|
501
533
|
f"{base_url}/track-request",
|
|
502
534
|
json=body,
|
|
503
535
|
)
|
|
504
536
|
if response.status_code != 200:
|
|
505
|
-
|
|
506
|
-
response,
|
|
507
|
-
|
|
537
|
+
if throw_on_error:
|
|
538
|
+
raise_on_bad_response(response, "PromptLayer had the following error while tracking your request")
|
|
539
|
+
else:
|
|
540
|
+
warn_on_bad_response(
|
|
541
|
+
response, f"PromptLayer had the following error while tracking your request: {response.text}"
|
|
542
|
+
)
|
|
508
543
|
return response.json()
|
|
509
544
|
except requests.exceptions.RequestException as e:
|
|
510
|
-
|
|
545
|
+
if throw_on_error:
|
|
546
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
547
|
+
f"PromptLayer had the following error while tracking your request: {e}", response=None, body=None
|
|
548
|
+
) from e
|
|
549
|
+
logger.warning(f"While logging your request PromptLayer had the following error: {e}")
|
|
511
550
|
return {}
|
|
512
551
|
|
|
513
552
|
|
|
514
|
-
|
|
553
|
+
@retry_on_api_error
|
|
554
|
+
async def atrack_request(base_url: str, throw_on_error: bool, **body: Any) -> Dict[str, Any]:
|
|
515
555
|
try:
|
|
516
556
|
async with _make_httpx_client() as client:
|
|
517
557
|
response = await client.post(
|
|
518
558
|
f"{base_url}/track-request",
|
|
519
559
|
json=body,
|
|
520
560
|
)
|
|
521
|
-
if
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
561
|
+
if response.status_code != 200:
|
|
562
|
+
if throw_on_error:
|
|
563
|
+
raise_on_bad_response(response, "PromptLayer had the following error while tracking your request")
|
|
564
|
+
else:
|
|
565
|
+
warn_on_bad_response(
|
|
566
|
+
response, f"PromptLayer had the following error while tracking your request: {response.text}"
|
|
567
|
+
)
|
|
527
568
|
return response.json()
|
|
528
569
|
except httpx.RequestError as e:
|
|
529
|
-
|
|
570
|
+
if throw_on_error:
|
|
571
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
572
|
+
f"PromptLayer had the following error while tracking your request: {e}", response=None, body=None
|
|
573
|
+
) from e
|
|
574
|
+
logger.warning(f"While logging your request PromptLayer had the following error: {e}")
|
|
530
575
|
return {}
|
|
531
576
|
|
|
532
577
|
|
|
@@ -558,7 +603,10 @@ def promptlayer_api_request_async(
|
|
|
558
603
|
)
|
|
559
604
|
|
|
560
605
|
|
|
561
|
-
|
|
606
|
+
@retry_on_api_error
|
|
607
|
+
def promptlayer_get_prompt(
|
|
608
|
+
api_key: str, base_url: str, throw_on_error: bool, prompt_name, version: int = None, label: str = None
|
|
609
|
+
):
|
|
562
610
|
"""
|
|
563
611
|
Get a prompt from the PromptLayer library
|
|
564
612
|
version: version of the prompt to get, None for latest
|
|
@@ -571,18 +619,31 @@ def promptlayer_get_prompt(api_key: str, base_url: str, prompt_name, version: in
|
|
|
571
619
|
params={"prompt_name": prompt_name, "version": version, "label": label},
|
|
572
620
|
)
|
|
573
621
|
except Exception as e:
|
|
574
|
-
|
|
622
|
+
if throw_on_error:
|
|
623
|
+
raise _exceptions.PromptLayerAPIError(
|
|
624
|
+
f"PromptLayer had the following error while getting your prompt: {e}", response=None, body=None
|
|
625
|
+
) from e
|
|
626
|
+
logger.warning(f"PromptLayer had the following error while getting your prompt: {e}")
|
|
627
|
+
return None
|
|
575
628
|
if request_response.status_code != 200:
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
629
|
+
if throw_on_error:
|
|
630
|
+
raise_on_bad_response(
|
|
631
|
+
request_response,
|
|
632
|
+
"PromptLayer had the following error while getting your prompt",
|
|
633
|
+
)
|
|
634
|
+
else:
|
|
635
|
+
warn_on_bad_response(
|
|
636
|
+
request_response,
|
|
637
|
+
"WARNING: PromptLayer had the following error while getting your prompt",
|
|
638
|
+
)
|
|
639
|
+
return None
|
|
580
640
|
|
|
581
641
|
return request_response.json()
|
|
582
642
|
|
|
583
643
|
|
|
644
|
+
@retry_on_api_error
|
|
584
645
|
def promptlayer_publish_prompt(
|
|
585
|
-
api_key: str, base_url: str, prompt_name, prompt_template, commit_message, tags, metadata=None
|
|
646
|
+
api_key: str, base_url: str, throw_on_error: bool, prompt_name, prompt_template, commit_message, tags, metadata=None
|
|
586
647
|
):
|
|
587
648
|
try:
|
|
588
649
|
request_response = requests.post(
|
|
@@ -597,16 +658,31 @@ def promptlayer_publish_prompt(
|
|
|
597
658
|
},
|
|
598
659
|
)
|
|
599
660
|
except Exception as e:
|
|
600
|
-
|
|
661
|
+
if throw_on_error:
|
|
662
|
+
raise _exceptions.PromptLayerAPIError(
|
|
663
|
+
f"PromptLayer had the following error while publishing your prompt: {e}", response=None, body=None
|
|
664
|
+
) from e
|
|
665
|
+
logger.warning(f"PromptLayer had the following error while publishing your prompt: {e}")
|
|
666
|
+
return False
|
|
601
667
|
if request_response.status_code != 200:
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
668
|
+
if throw_on_error:
|
|
669
|
+
raise_on_bad_response(
|
|
670
|
+
request_response,
|
|
671
|
+
"PromptLayer had the following error while publishing your prompt",
|
|
672
|
+
)
|
|
673
|
+
else:
|
|
674
|
+
warn_on_bad_response(
|
|
675
|
+
request_response,
|
|
676
|
+
"WARNING: PromptLayer had the following error while publishing your prompt",
|
|
677
|
+
)
|
|
678
|
+
return False
|
|
606
679
|
return True
|
|
607
680
|
|
|
608
681
|
|
|
609
|
-
|
|
682
|
+
@retry_on_api_error
|
|
683
|
+
def promptlayer_track_prompt(
|
|
684
|
+
api_key: str, base_url: str, throw_on_error: bool, request_id, prompt_name, input_variables, version, label
|
|
685
|
+
):
|
|
610
686
|
try:
|
|
611
687
|
request_response = requests.post(
|
|
612
688
|
f"{base_url}/library-track-prompt",
|
|
@@ -620,20 +696,28 @@ def promptlayer_track_prompt(api_key: str, base_url: str, request_id, prompt_nam
|
|
|
620
696
|
},
|
|
621
697
|
)
|
|
622
698
|
if request_response.status_code != 200:
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
699
|
+
if throw_on_error:
|
|
700
|
+
raise_on_bad_response(
|
|
701
|
+
request_response,
|
|
702
|
+
"While tracking your prompt PromptLayer had the following error",
|
|
703
|
+
)
|
|
704
|
+
else:
|
|
705
|
+
warn_on_bad_response(
|
|
706
|
+
request_response,
|
|
707
|
+
"WARNING: While tracking your prompt PromptLayer had the following error",
|
|
708
|
+
)
|
|
709
|
+
return False
|
|
628
710
|
except Exception as e:
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
711
|
+
if throw_on_error:
|
|
712
|
+
raise _exceptions.PromptLayerAPIError(
|
|
713
|
+
f"While tracking your prompt PromptLayer had the following error: {e}", response=None, body=None
|
|
714
|
+
) from e
|
|
715
|
+
logger.warning(f"While tracking your prompt PromptLayer had the following error: {e}")
|
|
633
716
|
return False
|
|
634
717
|
return True
|
|
635
718
|
|
|
636
719
|
|
|
720
|
+
@retry_on_api_error
|
|
637
721
|
async def apromptlayer_track_prompt(
|
|
638
722
|
api_key: str,
|
|
639
723
|
base_url: str,
|
|
@@ -642,6 +726,7 @@ async def apromptlayer_track_prompt(
|
|
|
642
726
|
input_variables: Dict[str, Any],
|
|
643
727
|
version: Optional[int] = None,
|
|
644
728
|
label: Optional[str] = None,
|
|
729
|
+
throw_on_error: bool = True,
|
|
645
730
|
) -> bool:
|
|
646
731
|
url = f"{base_url}/library-track-prompt"
|
|
647
732
|
payload = {
|
|
@@ -656,25 +741,28 @@ async def apromptlayer_track_prompt(
|
|
|
656
741
|
async with _make_httpx_client() as client:
|
|
657
742
|
response = await client.post(url, json=payload)
|
|
658
743
|
|
|
659
|
-
if
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
744
|
+
if response.status_code != 200:
|
|
745
|
+
if throw_on_error:
|
|
746
|
+
raise_on_bad_response(response, "While tracking your prompt, PromptLayer had the following error")
|
|
747
|
+
else:
|
|
748
|
+
warn_on_bad_response(
|
|
749
|
+
response,
|
|
750
|
+
"WARNING: While tracking your prompt, PromptLayer had the following error",
|
|
751
|
+
)
|
|
752
|
+
return False
|
|
667
753
|
except httpx.RequestError as e:
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
754
|
+
if throw_on_error:
|
|
755
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
756
|
+
f"While tracking your prompt PromptLayer had the following error: {e}", response=None, body=None
|
|
757
|
+
) from e
|
|
758
|
+
logger.warning(f"While tracking your prompt PromptLayer had the following error: {e}")
|
|
672
759
|
return False
|
|
673
760
|
|
|
674
761
|
return True
|
|
675
762
|
|
|
676
763
|
|
|
677
|
-
|
|
764
|
+
@retry_on_api_error
|
|
765
|
+
def promptlayer_track_metadata(api_key: str, base_url: str, throw_on_error: bool, request_id, metadata):
|
|
678
766
|
try:
|
|
679
767
|
request_response = requests.post(
|
|
680
768
|
f"{base_url}/library-track-metadata",
|
|
@@ -685,21 +773,31 @@ def promptlayer_track_metadata(api_key: str, base_url: str, request_id, metadata
|
|
|
685
773
|
},
|
|
686
774
|
)
|
|
687
775
|
if request_response.status_code != 200:
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
776
|
+
if throw_on_error:
|
|
777
|
+
raise_on_bad_response(
|
|
778
|
+
request_response,
|
|
779
|
+
"While tracking your metadata PromptLayer had the following error",
|
|
780
|
+
)
|
|
781
|
+
else:
|
|
782
|
+
warn_on_bad_response(
|
|
783
|
+
request_response,
|
|
784
|
+
"WARNING: While tracking your metadata PromptLayer had the following error",
|
|
785
|
+
)
|
|
786
|
+
return False
|
|
693
787
|
except Exception as e:
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
788
|
+
if throw_on_error:
|
|
789
|
+
raise _exceptions.PromptLayerAPIError(
|
|
790
|
+
f"While tracking your metadata PromptLayer had the following error: {e}", response=None, body=None
|
|
791
|
+
) from e
|
|
792
|
+
logger.warning(f"While tracking your metadata PromptLayer had the following error: {e}")
|
|
698
793
|
return False
|
|
699
794
|
return True
|
|
700
795
|
|
|
701
796
|
|
|
702
|
-
|
|
797
|
+
@retry_on_api_error
|
|
798
|
+
async def apromptlayer_track_metadata(
|
|
799
|
+
api_key: str, base_url: str, throw_on_error: bool, request_id: str, metadata: Dict[str, Any]
|
|
800
|
+
) -> bool:
|
|
703
801
|
url = f"{base_url}/library-track-metadata"
|
|
704
802
|
payload = {
|
|
705
803
|
"request_id": request_id,
|
|
@@ -710,25 +808,31 @@ async def apromptlayer_track_metadata(api_key: str, base_url: str, request_id: s
|
|
|
710
808
|
async with _make_httpx_client() as client:
|
|
711
809
|
response = await client.post(url, json=payload)
|
|
712
810
|
|
|
713
|
-
if
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
811
|
+
if response.status_code != 200:
|
|
812
|
+
if throw_on_error:
|
|
813
|
+
raise_on_bad_response(
|
|
814
|
+
response,
|
|
815
|
+
"While tracking your metadata, PromptLayer had the following error",
|
|
816
|
+
)
|
|
817
|
+
else:
|
|
818
|
+
warn_on_bad_response(
|
|
819
|
+
response,
|
|
820
|
+
"WARNING: While tracking your metadata, PromptLayer had the following error",
|
|
821
|
+
)
|
|
822
|
+
return False
|
|
721
823
|
except httpx.RequestError as e:
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
824
|
+
if throw_on_error:
|
|
825
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
826
|
+
f"While tracking your metadata PromptLayer had the following error: {e}", response=None, body=None
|
|
827
|
+
) from e
|
|
828
|
+
logger.warning(f"While tracking your metadata PromptLayer had the following error: {e}")
|
|
726
829
|
return False
|
|
727
830
|
|
|
728
831
|
return True
|
|
729
832
|
|
|
730
833
|
|
|
731
|
-
|
|
834
|
+
@retry_on_api_error
|
|
835
|
+
def promptlayer_track_score(api_key: str, base_url: str, throw_on_error: bool, request_id, score, score_name):
|
|
732
836
|
try:
|
|
733
837
|
data = {"request_id": request_id, "score": score, "api_key": api_key}
|
|
734
838
|
if score_name is not None:
|
|
@@ -738,23 +842,32 @@ def promptlayer_track_score(api_key: str, base_url: str, request_id, score, scor
|
|
|
738
842
|
json=data,
|
|
739
843
|
)
|
|
740
844
|
if request_response.status_code != 200:
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
845
|
+
if throw_on_error:
|
|
846
|
+
raise_on_bad_response(
|
|
847
|
+
request_response,
|
|
848
|
+
"While tracking your score PromptLayer had the following error",
|
|
849
|
+
)
|
|
850
|
+
else:
|
|
851
|
+
warn_on_bad_response(
|
|
852
|
+
request_response,
|
|
853
|
+
"WARNING: While tracking your score PromptLayer had the following error",
|
|
854
|
+
)
|
|
855
|
+
return False
|
|
746
856
|
except Exception as e:
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
857
|
+
if throw_on_error:
|
|
858
|
+
raise _exceptions.PromptLayerAPIError(
|
|
859
|
+
f"While tracking your score PromptLayer had the following error: {e}", response=None, body=None
|
|
860
|
+
) from e
|
|
861
|
+
logger.warning(f"While tracking your score PromptLayer had the following error: {e}")
|
|
751
862
|
return False
|
|
752
863
|
return True
|
|
753
864
|
|
|
754
865
|
|
|
866
|
+
@retry_on_api_error
|
|
755
867
|
async def apromptlayer_track_score(
|
|
756
868
|
api_key: str,
|
|
757
869
|
base_url: str,
|
|
870
|
+
throw_on_error: bool,
|
|
758
871
|
request_id: str,
|
|
759
872
|
score: float,
|
|
760
873
|
score_name: Optional[str],
|
|
@@ -771,19 +884,24 @@ async def apromptlayer_track_score(
|
|
|
771
884
|
async with _make_httpx_client() as client:
|
|
772
885
|
response = await client.post(url, json=data)
|
|
773
886
|
|
|
774
|
-
if
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
887
|
+
if response.status_code != 200:
|
|
888
|
+
if throw_on_error:
|
|
889
|
+
raise_on_bad_response(
|
|
890
|
+
response,
|
|
891
|
+
"While tracking your score, PromptLayer had the following error",
|
|
892
|
+
)
|
|
893
|
+
else:
|
|
894
|
+
warn_on_bad_response(
|
|
895
|
+
response,
|
|
896
|
+
"WARNING: While tracking your score, PromptLayer had the following error",
|
|
897
|
+
)
|
|
898
|
+
return False
|
|
782
899
|
except httpx.RequestError as e:
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
900
|
+
if throw_on_error:
|
|
901
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
902
|
+
f"PromptLayer had the following error while tracking your score: {str(e)}", response=None, body=None
|
|
903
|
+
) from e
|
|
904
|
+
logger.warning(f"While tracking your score PromptLayer had the following error: {str(e)}")
|
|
787
905
|
return False
|
|
788
906
|
|
|
789
907
|
return True
|
|
@@ -1010,29 +1128,60 @@ async def run_in_thread_async(executor, func, *args, **kwargs):
|
|
|
1010
1128
|
def warn_on_bad_response(request_response, main_message):
|
|
1011
1129
|
if hasattr(request_response, "json"):
|
|
1012
1130
|
try:
|
|
1013
|
-
|
|
1014
|
-
f"{main_message}: {request_response.json().get('message')}",
|
|
1015
|
-
file=sys.stderr,
|
|
1016
|
-
)
|
|
1131
|
+
logger.warning(f"{main_message}: {request_response.json().get('message')}")
|
|
1017
1132
|
except json.JSONDecodeError:
|
|
1018
|
-
|
|
1019
|
-
f"{main_message}: {request_response}",
|
|
1020
|
-
file=sys.stderr,
|
|
1021
|
-
)
|
|
1133
|
+
logger.warning(f"{main_message}: {request_response}")
|
|
1022
1134
|
else:
|
|
1023
|
-
|
|
1135
|
+
logger.warning(f"{main_message}: {request_response}")
|
|
1024
1136
|
|
|
1025
1137
|
|
|
1026
1138
|
def raise_on_bad_response(request_response, main_message):
|
|
1139
|
+
"""Raise an appropriate exception based on the HTTP status code."""
|
|
1140
|
+
status_code = getattr(request_response, "status_code", None)
|
|
1141
|
+
|
|
1142
|
+
body = None
|
|
1143
|
+
error_detail = None
|
|
1027
1144
|
if hasattr(request_response, "json"):
|
|
1028
1145
|
try:
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1146
|
+
body = request_response.json()
|
|
1147
|
+
error_detail = body.get("message") or body.get("error") or body.get("detail")
|
|
1148
|
+
except (json.JSONDecodeError, AttributeError):
|
|
1149
|
+
body = getattr(request_response, "text", str(request_response))
|
|
1150
|
+
error_detail = body
|
|
1151
|
+
else:
|
|
1152
|
+
body = str(request_response)
|
|
1153
|
+
error_detail = body
|
|
1154
|
+
|
|
1155
|
+
if error_detail:
|
|
1156
|
+
err_msg = f"{main_message}: {error_detail}"
|
|
1034
1157
|
else:
|
|
1035
|
-
|
|
1158
|
+
err_msg = main_message
|
|
1159
|
+
|
|
1160
|
+
if status_code == 400:
|
|
1161
|
+
raise _exceptions.PromptLayerBadRequestError(err_msg, response=request_response, body=body)
|
|
1162
|
+
|
|
1163
|
+
if status_code == 401:
|
|
1164
|
+
raise _exceptions.PromptLayerAuthenticationError(err_msg, response=request_response, body=body)
|
|
1165
|
+
|
|
1166
|
+
if status_code == 403:
|
|
1167
|
+
raise _exceptions.PromptLayerPermissionDeniedError(err_msg, response=request_response, body=body)
|
|
1168
|
+
|
|
1169
|
+
if status_code == 404:
|
|
1170
|
+
raise _exceptions.PromptLayerNotFoundError(err_msg, response=request_response, body=body)
|
|
1171
|
+
|
|
1172
|
+
if status_code == 409:
|
|
1173
|
+
raise _exceptions.PromptLayerConflictError(err_msg, response=request_response, body=body)
|
|
1174
|
+
|
|
1175
|
+
if status_code == 422:
|
|
1176
|
+
raise _exceptions.PromptLayerUnprocessableEntityError(err_msg, response=request_response, body=body)
|
|
1177
|
+
|
|
1178
|
+
if status_code == 429:
|
|
1179
|
+
raise _exceptions.PromptLayerRateLimitError(err_msg, response=request_response, body=body)
|
|
1180
|
+
|
|
1181
|
+
if status_code and status_code >= 500:
|
|
1182
|
+
raise _exceptions.PromptLayerInternalServerError(err_msg, response=request_response, body=body)
|
|
1183
|
+
|
|
1184
|
+
raise _exceptions.PromptLayerAPIStatusError(err_msg, response=request_response, body=body)
|
|
1036
1185
|
|
|
1037
1186
|
|
|
1038
1187
|
async def async_wrapper(
|
|
@@ -1080,7 +1229,8 @@ async def async_wrapper(
|
|
|
1080
1229
|
context.detach(token)
|
|
1081
1230
|
|
|
1082
1231
|
|
|
1083
|
-
|
|
1232
|
+
@retry_on_api_error
|
|
1233
|
+
def promptlayer_create_group(api_key: str, base_url: str, throw_on_error: bool):
|
|
1084
1234
|
try:
|
|
1085
1235
|
request_response = requests.post(
|
|
1086
1236
|
f"{base_url}/create-group",
|
|
@@ -1089,18 +1239,29 @@ def promptlayer_create_group(api_key: str, base_url: str):
|
|
|
1089
1239
|
},
|
|
1090
1240
|
)
|
|
1091
1241
|
if request_response.status_code != 200:
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1242
|
+
if throw_on_error:
|
|
1243
|
+
raise_on_bad_response(
|
|
1244
|
+
request_response,
|
|
1245
|
+
"While creating your group PromptLayer had the following error",
|
|
1246
|
+
)
|
|
1247
|
+
else:
|
|
1248
|
+
warn_on_bad_response(
|
|
1249
|
+
request_response,
|
|
1250
|
+
"WARNING: While creating your group PromptLayer had the following error",
|
|
1251
|
+
)
|
|
1252
|
+
return False
|
|
1097
1253
|
except requests.exceptions.RequestException as e:
|
|
1098
|
-
|
|
1099
|
-
|
|
1254
|
+
if throw_on_error:
|
|
1255
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
1256
|
+
f"PromptLayer had the following error while creating your group: {e}", response=None, body=None
|
|
1257
|
+
) from e
|
|
1258
|
+
logger.warning(f"While creating your group PromptLayer had the following error: {e}")
|
|
1259
|
+
return False
|
|
1100
1260
|
return request_response.json()["id"]
|
|
1101
1261
|
|
|
1102
1262
|
|
|
1103
|
-
|
|
1263
|
+
@retry_on_api_error
|
|
1264
|
+
async def apromptlayer_create_group(api_key: str, base_url: str, throw_on_error: bool):
|
|
1104
1265
|
try:
|
|
1105
1266
|
async with _make_httpx_client() as client:
|
|
1106
1267
|
response = await client.post(
|
|
@@ -1110,20 +1271,30 @@ async def apromptlayer_create_group(api_key: str, base_url: str):
|
|
|
1110
1271
|
},
|
|
1111
1272
|
)
|
|
1112
1273
|
|
|
1113
|
-
if
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1274
|
+
if response.status_code != 200:
|
|
1275
|
+
if throw_on_error:
|
|
1276
|
+
raise_on_bad_response(
|
|
1277
|
+
response,
|
|
1278
|
+
"While creating your group, PromptLayer had the following error",
|
|
1279
|
+
)
|
|
1280
|
+
else:
|
|
1281
|
+
warn_on_bad_response(
|
|
1282
|
+
response,
|
|
1283
|
+
"WARNING: While creating your group, PromptLayer had the following error",
|
|
1284
|
+
)
|
|
1285
|
+
return False
|
|
1121
1286
|
return response.json()["id"]
|
|
1122
1287
|
except httpx.RequestError as e:
|
|
1123
|
-
|
|
1288
|
+
if throw_on_error:
|
|
1289
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
1290
|
+
f"PromptLayer had the following error while creating your group: {str(e)}", response=None, body=None
|
|
1291
|
+
) from e
|
|
1292
|
+
logger.warning(f"While creating your group PromptLayer had the following error: {e}")
|
|
1293
|
+
return False
|
|
1124
1294
|
|
|
1125
1295
|
|
|
1126
|
-
|
|
1296
|
+
@retry_on_api_error
|
|
1297
|
+
def promptlayer_track_group(api_key: str, base_url: str, throw_on_error: bool, request_id, group_id):
|
|
1127
1298
|
try:
|
|
1128
1299
|
request_response = requests.post(
|
|
1129
1300
|
f"{base_url}/track-group",
|
|
@@ -1134,18 +1305,29 @@ def promptlayer_track_group(api_key: str, base_url: str, request_id, group_id):
|
|
|
1134
1305
|
},
|
|
1135
1306
|
)
|
|
1136
1307
|
if request_response.status_code != 200:
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1308
|
+
if throw_on_error:
|
|
1309
|
+
raise_on_bad_response(
|
|
1310
|
+
request_response,
|
|
1311
|
+
"While tracking your group PromptLayer had the following error",
|
|
1312
|
+
)
|
|
1313
|
+
else:
|
|
1314
|
+
warn_on_bad_response(
|
|
1315
|
+
request_response,
|
|
1316
|
+
"WARNING: While tracking your group PromptLayer had the following error",
|
|
1317
|
+
)
|
|
1318
|
+
return False
|
|
1142
1319
|
except requests.exceptions.RequestException as e:
|
|
1143
|
-
|
|
1144
|
-
|
|
1320
|
+
if throw_on_error:
|
|
1321
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
1322
|
+
f"PromptLayer had the following error while tracking your group: {e}", response=None, body=None
|
|
1323
|
+
) from e
|
|
1324
|
+
logger.warning(f"While tracking your group PromptLayer had the following error: {e}")
|
|
1325
|
+
return False
|
|
1145
1326
|
return True
|
|
1146
1327
|
|
|
1147
1328
|
|
|
1148
|
-
|
|
1329
|
+
@retry_on_api_error
|
|
1330
|
+
async def apromptlayer_track_group(api_key: str, base_url: str, throw_on_error: bool, request_id, group_id):
|
|
1149
1331
|
try:
|
|
1150
1332
|
payload = {
|
|
1151
1333
|
"api_key": api_key,
|
|
@@ -1159,26 +1341,32 @@ async def apromptlayer_track_group(api_key: str, base_url: str, request_id, grou
|
|
|
1159
1341
|
json=payload,
|
|
1160
1342
|
)
|
|
1161
1343
|
|
|
1162
|
-
if
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1344
|
+
if response.status_code != 200:
|
|
1345
|
+
if throw_on_error:
|
|
1346
|
+
raise_on_bad_response(
|
|
1347
|
+
response,
|
|
1348
|
+
"While tracking your group, PromptLayer had the following error",
|
|
1349
|
+
)
|
|
1350
|
+
else:
|
|
1351
|
+
warn_on_bad_response(
|
|
1352
|
+
response,
|
|
1353
|
+
"WARNING: While tracking your group, PromptLayer had the following error",
|
|
1354
|
+
)
|
|
1355
|
+
return False
|
|
1170
1356
|
except httpx.RequestError as e:
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1357
|
+
if throw_on_error:
|
|
1358
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
1359
|
+
f"PromptLayer had the following error while tracking your group: {str(e)}", response=None, body=None
|
|
1360
|
+
) from e
|
|
1361
|
+
logger.warning(f"While tracking your group PromptLayer had the following error: {e}")
|
|
1175
1362
|
return False
|
|
1176
1363
|
|
|
1177
1364
|
return True
|
|
1178
1365
|
|
|
1179
1366
|
|
|
1367
|
+
@retry_on_api_error
|
|
1180
1368
|
def get_prompt_template(
|
|
1181
|
-
api_key: str, base_url: str, prompt_name: str, params: Union[GetPromptTemplate, None] = None
|
|
1369
|
+
api_key: str, base_url: str, throw_on_error: bool, prompt_name: str, params: Union[GetPromptTemplate, None] = None
|
|
1182
1370
|
) -> GetPromptTemplateResponse:
|
|
1183
1371
|
try:
|
|
1184
1372
|
json_body = {"api_key": api_key}
|
|
@@ -1190,22 +1378,42 @@ def get_prompt_template(
|
|
|
1190
1378
|
json=json_body,
|
|
1191
1379
|
)
|
|
1192
1380
|
if response.status_code != 200:
|
|
1193
|
-
|
|
1381
|
+
if throw_on_error:
|
|
1382
|
+
raise_on_bad_response(
|
|
1383
|
+
response, "PromptLayer had the following error while getting your prompt template"
|
|
1384
|
+
)
|
|
1385
|
+
else:
|
|
1386
|
+
warn_on_bad_response(
|
|
1387
|
+
response, "WARNING: PromptLayer had the following error while getting your prompt template"
|
|
1388
|
+
)
|
|
1389
|
+
return None
|
|
1194
1390
|
|
|
1195
|
-
warning = response.json().get("warning", None)
|
|
1196
|
-
if warning is not None:
|
|
1197
|
-
warn_on_bad_response(
|
|
1198
|
-
warning,
|
|
1199
|
-
"WARNING: While getting your prompt template",
|
|
1200
|
-
)
|
|
1201
1391
|
return response.json()
|
|
1392
|
+
except requests.exceptions.ConnectionError as e:
|
|
1393
|
+
err_msg = f"PromptLayer had the following error while getting your prompt template: {e}"
|
|
1394
|
+
if throw_on_error:
|
|
1395
|
+
raise _exceptions.PromptLayerAPIConnectionError(err_msg, response=None, body=None) from e
|
|
1396
|
+
logger.warning(err_msg)
|
|
1397
|
+
return None
|
|
1398
|
+
except requests.exceptions.Timeout as e:
|
|
1399
|
+
err_msg = f"PromptLayer had the following error while getting your prompt template: {e}"
|
|
1400
|
+
if throw_on_error:
|
|
1401
|
+
raise _exceptions.PromptLayerAPITimeoutError(err_msg, response=None, body=None) from e
|
|
1402
|
+
logger.warning(err_msg)
|
|
1403
|
+
return None
|
|
1202
1404
|
except requests.exceptions.RequestException as e:
|
|
1203
|
-
|
|
1405
|
+
err_msg = f"PromptLayer had the following error while getting your prompt template: {e}"
|
|
1406
|
+
if throw_on_error:
|
|
1407
|
+
raise _exceptions.PromptLayerError(err_msg, response=None, body=None) from e
|
|
1408
|
+
logger.warning(err_msg)
|
|
1409
|
+
return None
|
|
1204
1410
|
|
|
1205
1411
|
|
|
1412
|
+
@retry_on_api_error
|
|
1206
1413
|
async def aget_prompt_template(
|
|
1207
1414
|
api_key: str,
|
|
1208
1415
|
base_url: str,
|
|
1416
|
+
throw_on_error: bool,
|
|
1209
1417
|
prompt_name: str,
|
|
1210
1418
|
params: Union[GetPromptTemplate, None] = None,
|
|
1211
1419
|
) -> GetPromptTemplateResponse:
|
|
@@ -1220,27 +1428,43 @@ async def aget_prompt_template(
|
|
|
1220
1428
|
json=json_body,
|
|
1221
1429
|
)
|
|
1222
1430
|
|
|
1223
|
-
if
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
"WARNING: While getting your prompt template",
|
|
1235
|
-
)
|
|
1431
|
+
if response.status_code != 200:
|
|
1432
|
+
if throw_on_error:
|
|
1433
|
+
raise_on_bad_response(
|
|
1434
|
+
response,
|
|
1435
|
+
"PromptLayer had the following error while getting your prompt template",
|
|
1436
|
+
)
|
|
1437
|
+
else:
|
|
1438
|
+
warn_on_bad_response(
|
|
1439
|
+
response, "WARNING: While getting your prompt template PromptLayer had the following error"
|
|
1440
|
+
)
|
|
1441
|
+
return None
|
|
1236
1442
|
return response.json()
|
|
1443
|
+
except (httpx.ConnectError, httpx.NetworkError) as e:
|
|
1444
|
+
err_msg = f"PromptLayer had the following error while getting your prompt template: {str(e)}"
|
|
1445
|
+
if throw_on_error:
|
|
1446
|
+
raise _exceptions.PromptLayerAPIConnectionError(err_msg, response=None, body=None) from e
|
|
1447
|
+
logger.warning(err_msg)
|
|
1448
|
+
return None
|
|
1449
|
+
except httpx.TimeoutException as e:
|
|
1450
|
+
err_msg = f"PromptLayer had the following error while getting your prompt template: {str(e)}"
|
|
1451
|
+
if throw_on_error:
|
|
1452
|
+
raise _exceptions.PromptLayerAPITimeoutError(err_msg, response=None, body=None) from e
|
|
1453
|
+
logger.warning(err_msg)
|
|
1454
|
+
return None
|
|
1237
1455
|
except httpx.RequestError as e:
|
|
1238
|
-
|
|
1456
|
+
err_msg = f"PromptLayer had the following error while getting your prompt template: {str(e)}"
|
|
1457
|
+
if throw_on_error:
|
|
1458
|
+
raise _exceptions.PromptLayerAPIConnectionError(err_msg, response=None, body=None) from e
|
|
1459
|
+
logger.warning(err_msg)
|
|
1460
|
+
return None
|
|
1239
1461
|
|
|
1240
1462
|
|
|
1463
|
+
@retry_on_api_error
|
|
1241
1464
|
def publish_prompt_template(
|
|
1242
1465
|
api_key: str,
|
|
1243
1466
|
base_url: str,
|
|
1467
|
+
throw_on_error: bool,
|
|
1244
1468
|
body: PublishPromptTemplate,
|
|
1245
1469
|
) -> PublishPromptTemplateResponse:
|
|
1246
1470
|
try:
|
|
@@ -1254,17 +1478,32 @@ def publish_prompt_template(
|
|
|
1254
1478
|
},
|
|
1255
1479
|
)
|
|
1256
1480
|
if response.status_code == 400:
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1481
|
+
if throw_on_error:
|
|
1482
|
+
raise_on_bad_response(
|
|
1483
|
+
response, "PromptLayer had the following error while publishing your prompt template"
|
|
1484
|
+
)
|
|
1485
|
+
else:
|
|
1486
|
+
warn_on_bad_response(
|
|
1487
|
+
response, "WARNING: PromptLayer had the following error while publishing your prompt template"
|
|
1488
|
+
)
|
|
1489
|
+
return None
|
|
1260
1490
|
return response.json()
|
|
1261
1491
|
except requests.exceptions.RequestException as e:
|
|
1262
|
-
|
|
1492
|
+
if throw_on_error:
|
|
1493
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
1494
|
+
f"PromptLayer had the following error while publishing your prompt template: {e}",
|
|
1495
|
+
response=None,
|
|
1496
|
+
body=None,
|
|
1497
|
+
) from e
|
|
1498
|
+
logger.warning(f"PromptLayer had the following error while publishing your prompt template: {e}")
|
|
1499
|
+
return None
|
|
1263
1500
|
|
|
1264
1501
|
|
|
1502
|
+
@retry_on_api_error
|
|
1265
1503
|
async def apublish_prompt_template(
|
|
1266
1504
|
api_key: str,
|
|
1267
1505
|
base_url: str,
|
|
1506
|
+
throw_on_error: bool,
|
|
1268
1507
|
body: PublishPromptTemplate,
|
|
1269
1508
|
) -> PublishPromptTemplateResponse:
|
|
1270
1509
|
try:
|
|
@@ -1279,24 +1518,32 @@ async def apublish_prompt_template(
|
|
|
1279
1518
|
},
|
|
1280
1519
|
)
|
|
1281
1520
|
|
|
1282
|
-
if
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1521
|
+
if response.status_code == 400 or response.status_code != 201:
|
|
1522
|
+
if throw_on_error:
|
|
1523
|
+
raise_on_bad_response(
|
|
1524
|
+
response,
|
|
1525
|
+
"PromptLayer had the following error while publishing your prompt template",
|
|
1526
|
+
)
|
|
1527
|
+
else:
|
|
1528
|
+
warn_on_bad_response(
|
|
1529
|
+
response, "WARNING: PromptLayer had the following error while publishing your prompt template"
|
|
1530
|
+
)
|
|
1531
|
+
return None
|
|
1293
1532
|
return response.json()
|
|
1294
1533
|
except httpx.RequestError as e:
|
|
1295
|
-
|
|
1534
|
+
if throw_on_error:
|
|
1535
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
1536
|
+
f"PromptLayer had the following error while publishing your prompt template: {str(e)}",
|
|
1537
|
+
response=None,
|
|
1538
|
+
body=None,
|
|
1539
|
+
) from e
|
|
1540
|
+
logger.warning(f"PromptLayer had the following error while publishing your prompt template: {e}")
|
|
1541
|
+
return None
|
|
1296
1542
|
|
|
1297
1543
|
|
|
1544
|
+
@retry_on_api_error
|
|
1298
1545
|
def get_all_prompt_templates(
|
|
1299
|
-
api_key: str, base_url: str, page: int = 1, per_page: int = 30, label: str = None
|
|
1546
|
+
api_key: str, base_url: str, throw_on_error: bool, page: int = 1, per_page: int = 30, label: str = None
|
|
1300
1547
|
) -> List[ListPromptTemplateResponse]:
|
|
1301
1548
|
try:
|
|
1302
1549
|
params = {"page": page, "per_page": per_page}
|
|
@@ -1308,17 +1555,31 @@ def get_all_prompt_templates(
|
|
|
1308
1555
|
params=params,
|
|
1309
1556
|
)
|
|
1310
1557
|
if response.status_code != 200:
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1558
|
+
if throw_on_error:
|
|
1559
|
+
raise_on_bad_response(
|
|
1560
|
+
response, "PromptLayer had the following error while getting all your prompt templates"
|
|
1561
|
+
)
|
|
1562
|
+
else:
|
|
1563
|
+
warn_on_bad_response(
|
|
1564
|
+
response, "WARNING: PromptLayer had the following error while getting all your prompt templates"
|
|
1565
|
+
)
|
|
1566
|
+
return []
|
|
1314
1567
|
items = response.json().get("items", [])
|
|
1315
1568
|
return items
|
|
1316
1569
|
except requests.exceptions.RequestException as e:
|
|
1317
|
-
|
|
1570
|
+
if throw_on_error:
|
|
1571
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
1572
|
+
f"PromptLayer had the following error while getting all your prompt templates: {e}",
|
|
1573
|
+
response=None,
|
|
1574
|
+
body=None,
|
|
1575
|
+
) from e
|
|
1576
|
+
logger.warning(f"PromptLayer had the following error while getting all your prompt templates: {e}")
|
|
1577
|
+
return []
|
|
1318
1578
|
|
|
1319
1579
|
|
|
1580
|
+
@retry_on_api_error
|
|
1320
1581
|
async def aget_all_prompt_templates(
|
|
1321
|
-
api_key: str, base_url: str, page: int = 1, per_page: int = 30, label: str = None
|
|
1582
|
+
api_key: str, base_url: str, throw_on_error: bool, page: int = 1, per_page: int = 30, label: str = None
|
|
1322
1583
|
) -> List[ListPromptTemplateResponse]:
|
|
1323
1584
|
try:
|
|
1324
1585
|
params = {"page": page, "per_page": per_page}
|
|
@@ -1331,17 +1592,28 @@ async def aget_all_prompt_templates(
|
|
|
1331
1592
|
params=params,
|
|
1332
1593
|
)
|
|
1333
1594
|
|
|
1334
|
-
if
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1595
|
+
if response.status_code != 200:
|
|
1596
|
+
if throw_on_error:
|
|
1597
|
+
raise_on_bad_response(
|
|
1598
|
+
response,
|
|
1599
|
+
"PromptLayer had the following error while getting all your prompt templates",
|
|
1600
|
+
)
|
|
1601
|
+
else:
|
|
1602
|
+
warn_on_bad_response(
|
|
1603
|
+
response, "WARNING: PromptLayer had the following error while getting all your prompt templates"
|
|
1604
|
+
)
|
|
1605
|
+
return []
|
|
1341
1606
|
items = response.json().get("items", [])
|
|
1342
1607
|
return items
|
|
1343
1608
|
except httpx.RequestError as e:
|
|
1344
|
-
|
|
1609
|
+
if throw_on_error:
|
|
1610
|
+
raise _exceptions.PromptLayerAPIConnectionError(
|
|
1611
|
+
f"PromptLayer had the following error while getting all your prompt templates: {str(e)}",
|
|
1612
|
+
response=None,
|
|
1613
|
+
body=None,
|
|
1614
|
+
) from e
|
|
1615
|
+
logger.warning(f"PromptLayer had the following error while getting all your prompt templates: {e}")
|
|
1616
|
+
return []
|
|
1345
1617
|
|
|
1346
1618
|
|
|
1347
1619
|
def openai_chat_request(client, **kwargs):
|
|
@@ -1475,13 +1747,16 @@ def get_api_key():
|
|
|
1475
1747
|
# raise an error if the api key is not set
|
|
1476
1748
|
api_key = os.environ.get("PROMPTLAYER_API_KEY")
|
|
1477
1749
|
if not api_key:
|
|
1478
|
-
raise
|
|
1479
|
-
"Please set your PROMPTLAYER_API_KEY environment variable or set API KEY in code using 'promptlayer.api_key = <your_api_key>'
|
|
1750
|
+
raise _exceptions.PromptLayerAuthenticationError(
|
|
1751
|
+
"Please set your PROMPTLAYER_API_KEY environment variable or set API KEY in code using 'promptlayer.api_key = <your_api_key>'",
|
|
1752
|
+
response=None,
|
|
1753
|
+
body=None,
|
|
1480
1754
|
)
|
|
1481
1755
|
return api_key
|
|
1482
1756
|
|
|
1483
1757
|
|
|
1484
|
-
|
|
1758
|
+
@retry_on_api_error
|
|
1759
|
+
def util_log_request(api_key: str, base_url: str, throw_on_error: bool, **kwargs) -> Union[RequestLog, None]:
|
|
1485
1760
|
try:
|
|
1486
1761
|
response = requests.post(
|
|
1487
1762
|
f"{base_url}/log-request",
|
|
@@ -1489,21 +1764,26 @@ def util_log_request(api_key: str, base_url: str, **kwargs) -> Union[RequestLog,
|
|
|
1489
1764
|
json=kwargs,
|
|
1490
1765
|
)
|
|
1491
1766
|
if response.status_code != 201:
|
|
1492
|
-
|
|
1493
|
-
response,
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1767
|
+
if throw_on_error:
|
|
1768
|
+
raise_on_bad_response(response, "PromptLayer had the following error while logging your request")
|
|
1769
|
+
else:
|
|
1770
|
+
warn_on_bad_response(
|
|
1771
|
+
response,
|
|
1772
|
+
"WARNING: While logging your request PromptLayer had the following error",
|
|
1773
|
+
)
|
|
1774
|
+
return None
|
|
1497
1775
|
return response.json()
|
|
1498
1776
|
except Exception as e:
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1777
|
+
if throw_on_error:
|
|
1778
|
+
raise _exceptions.PromptLayerAPIError(
|
|
1779
|
+
f"While logging your request PromptLayer had the following error: {e}", response=None, body=None
|
|
1780
|
+
) from e
|
|
1781
|
+
logger.warning(f"While tracking your prompt PromptLayer had the following error: {e}")
|
|
1503
1782
|
return None
|
|
1504
1783
|
|
|
1505
1784
|
|
|
1506
|
-
|
|
1785
|
+
@retry_on_api_error
|
|
1786
|
+
async def autil_log_request(api_key: str, base_url: str, throw_on_error: bool, **kwargs) -> Union[RequestLog, None]:
|
|
1507
1787
|
try:
|
|
1508
1788
|
async with _make_httpx_client() as client:
|
|
1509
1789
|
response = await client.post(
|
|
@@ -1512,17 +1792,21 @@ async def autil_log_request(api_key: str, base_url: str, **kwargs) -> Union[Requ
|
|
|
1512
1792
|
json=kwargs,
|
|
1513
1793
|
)
|
|
1514
1794
|
if response.status_code != 201:
|
|
1515
|
-
|
|
1516
|
-
response,
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1795
|
+
if throw_on_error:
|
|
1796
|
+
raise_on_bad_response(response, "PromptLayer had the following error while logging your request")
|
|
1797
|
+
else:
|
|
1798
|
+
warn_on_bad_response(
|
|
1799
|
+
response,
|
|
1800
|
+
"WARNING: While logging your request PromptLayer had the following error",
|
|
1801
|
+
)
|
|
1802
|
+
return None
|
|
1520
1803
|
return response.json()
|
|
1521
1804
|
except Exception as e:
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1805
|
+
if throw_on_error:
|
|
1806
|
+
raise _exceptions.PromptLayerAPIError(
|
|
1807
|
+
f"While logging your request PromptLayer had the following error: {e}", response=None, body=None
|
|
1808
|
+
) from e
|
|
1809
|
+
logger.warning(f"While tracking your prompt PromptLayer had the following error: {e}")
|
|
1526
1810
|
return None
|
|
1527
1811
|
|
|
1528
1812
|
|
|
@@ -1551,6 +1835,26 @@ async def amistral_request(
|
|
|
1551
1835
|
return await client.chat.complete_async(**function_kwargs)
|
|
1552
1836
|
|
|
1553
1837
|
|
|
1838
|
+
class _GoogleStreamWrapper:
|
|
1839
|
+
"""Wrapper to keep Google client alive during streaming."""
|
|
1840
|
+
|
|
1841
|
+
def __init__(self, stream_generator, client):
|
|
1842
|
+
self._stream = stream_generator
|
|
1843
|
+
self._client = client # Keep client alive
|
|
1844
|
+
|
|
1845
|
+
def __iter__(self):
|
|
1846
|
+
return self._stream.__iter__()
|
|
1847
|
+
|
|
1848
|
+
def __next__(self):
|
|
1849
|
+
return next(self._stream)
|
|
1850
|
+
|
|
1851
|
+
def __aiter__(self):
|
|
1852
|
+
return self._stream.__aiter__()
|
|
1853
|
+
|
|
1854
|
+
async def __anext__(self):
|
|
1855
|
+
return await self._stream.__anext__()
|
|
1856
|
+
|
|
1857
|
+
|
|
1554
1858
|
def google_chat_request(client, **kwargs):
|
|
1555
1859
|
from google.genai.chats import Content
|
|
1556
1860
|
|
|
@@ -1561,7 +1865,8 @@ def google_chat_request(client, **kwargs):
|
|
|
1561
1865
|
chat = client.chats.create(model=model, history=history, config=generation_config)
|
|
1562
1866
|
last_message = history[-1].parts if history else ""
|
|
1563
1867
|
if stream:
|
|
1564
|
-
|
|
1868
|
+
stream_gen = chat.send_message_stream(message=last_message)
|
|
1869
|
+
return _GoogleStreamWrapper(stream_gen, client)
|
|
1565
1870
|
return chat.send_message(message=last_message)
|
|
1566
1871
|
|
|
1567
1872
|
|
|
@@ -1571,7 +1876,8 @@ def google_completions_request(client, **kwargs):
|
|
|
1571
1876
|
contents = kwargs.get("contents", [])
|
|
1572
1877
|
stream = kwargs.pop("stream", False)
|
|
1573
1878
|
if stream:
|
|
1574
|
-
|
|
1879
|
+
stream_gen = client.models.generate_content_stream(model=model, contents=contents, config=config)
|
|
1880
|
+
return _GoogleStreamWrapper(stream_gen, client)
|
|
1575
1881
|
return client.models.generate_content(model=model, contents=contents, config=config)
|
|
1576
1882
|
|
|
1577
1883
|
|
|
@@ -1606,7 +1912,8 @@ async def agoogle_chat_request(client, **kwargs):
|
|
|
1606
1912
|
chat = client.aio.chats.create(model=model, history=history, config=generation_config)
|
|
1607
1913
|
last_message = history[-1].parts[0] if history else ""
|
|
1608
1914
|
if stream:
|
|
1609
|
-
|
|
1915
|
+
stream_gen = await chat.send_message_stream(message=last_message)
|
|
1916
|
+
return _GoogleStreamWrapper(stream_gen, client)
|
|
1610
1917
|
return await chat.send_message(message=last_message)
|
|
1611
1918
|
|
|
1612
1919
|
|
|
@@ -1616,8 +1923,9 @@ async def agoogle_completions_request(client, **kwargs):
|
|
|
1616
1923
|
contents = kwargs.get("contents", [])
|
|
1617
1924
|
stream = kwargs.pop("stream", False)
|
|
1618
1925
|
if stream:
|
|
1619
|
-
|
|
1620
|
-
return
|
|
1926
|
+
stream_gen = await client.aio.models.generate_content_stream(model=model, contents=contents, config=config)
|
|
1927
|
+
return _GoogleStreamWrapper(stream_gen, client)
|
|
1928
|
+
return await client.aio.models.generate_content(model=model, contents=contents, config=config)
|
|
1621
1929
|
|
|
1622
1930
|
|
|
1623
1931
|
AMAP_TYPE_TO_GOOGLE_FUNCTION = {
|