promptlayer 1.0.71__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 CHANGED
@@ -1,4 +1,39 @@
1
+ from .exceptions import (
2
+ PromptLayerAPIConnectionError,
3
+ PromptLayerAPIError,
4
+ PromptLayerAPIStatusError,
5
+ PromptLayerAPITimeoutError,
6
+ PromptLayerAuthenticationError,
7
+ PromptLayerBadRequestError,
8
+ PromptLayerConflictError,
9
+ PromptLayerError,
10
+ PromptLayerInternalServerError,
11
+ PromptLayerNotFoundError,
12
+ PromptLayerPermissionDeniedError,
13
+ PromptLayerRateLimitError,
14
+ PromptLayerUnprocessableEntityError,
15
+ PromptLayerValidationError,
16
+ )
1
17
  from .promptlayer import AsyncPromptLayer, PromptLayer
2
18
 
3
- __version__ = "1.0.71"
4
- __all__ = ["PromptLayer", "AsyncPromptLayer", "__version__"]
19
+ __version__ = "1.0.73"
20
+ __all__ = [
21
+ "PromptLayer",
22
+ "AsyncPromptLayer",
23
+ "__version__",
24
+ # Exceptions
25
+ "PromptLayerError",
26
+ "PromptLayerAPIError",
27
+ "PromptLayerBadRequestError",
28
+ "PromptLayerAuthenticationError",
29
+ "PromptLayerPermissionDeniedError",
30
+ "PromptLayerNotFoundError",
31
+ "PromptLayerConflictError",
32
+ "PromptLayerUnprocessableEntityError",
33
+ "PromptLayerRateLimitError",
34
+ "PromptLayerInternalServerError",
35
+ "PromptLayerAPIStatusError",
36
+ "PromptLayerAPIConnectionError",
37
+ "PromptLayerAPITimeoutError",
38
+ "PromptLayerValidationError",
39
+ ]
@@ -0,0 +1,119 @@
1
+ class PromptLayerError(Exception):
2
+ """Base exception for all PromptLayer SDK errors."""
3
+
4
+ def __init__(self, message: str, response=None, body=None):
5
+ super().__init__(message)
6
+ self.message = message
7
+ self.response = response
8
+ self.body = body
9
+
10
+ def __str__(self):
11
+ return self.message
12
+
13
+
14
+ class PromptLayerAPIError(PromptLayerError):
15
+ """Base exception for API-related errors."""
16
+
17
+ pass
18
+
19
+
20
+ class PromptLayerBadRequestError(PromptLayerAPIError):
21
+ """Exception raised for 400 Bad Request errors.
22
+
23
+ Indicates that the request was malformed or contained invalid parameters.
24
+ """
25
+
26
+ pass
27
+
28
+
29
+ class PromptLayerAuthenticationError(PromptLayerAPIError):
30
+ """Exception raised for 401 Unauthorized errors.
31
+
32
+ Indicates that the API key is missing, invalid, or expired.
33
+ """
34
+
35
+ pass
36
+
37
+
38
+ class PromptLayerPermissionDeniedError(PromptLayerAPIError):
39
+ """Exception raised for 403 Forbidden errors.
40
+
41
+ Indicates that the API key doesn't have permission to perform the requested operation.
42
+ """
43
+
44
+ pass
45
+
46
+
47
+ class PromptLayerNotFoundError(PromptLayerAPIError):
48
+ """Exception raised for 404 Not Found errors.
49
+
50
+ Indicates that the requested resource (e.g., prompt template) was not found.
51
+ """
52
+
53
+ pass
54
+
55
+
56
+ class PromptLayerConflictError(PromptLayerAPIError):
57
+ """Exception raised for 409 Conflict errors.
58
+
59
+ Indicates that the request conflicts with the current state of the resource.
60
+ """
61
+
62
+ pass
63
+
64
+
65
+ class PromptLayerUnprocessableEntityError(PromptLayerAPIError):
66
+ """Exception raised for 422 Unprocessable Entity errors.
67
+
68
+ Indicates that the request was well-formed but contains semantic errors.
69
+ """
70
+
71
+ pass
72
+
73
+
74
+ class PromptLayerRateLimitError(PromptLayerAPIError):
75
+ """Exception raised for 429 Too Many Requests errors.
76
+
77
+ Indicates that the API rate limit has been exceeded.
78
+ """
79
+
80
+ pass
81
+
82
+
83
+ class PromptLayerInternalServerError(PromptLayerAPIError):
84
+ """Exception raised for 500+ Internal Server errors.
85
+
86
+ Indicates that the PromptLayer API encountered an internal error.
87
+ """
88
+
89
+ pass
90
+
91
+
92
+ class PromptLayerAPIStatusError(PromptLayerAPIError):
93
+ """Exception raised for other API errors not covered by specific exception classes."""
94
+
95
+ pass
96
+
97
+
98
+ class PromptLayerAPIConnectionError(PromptLayerError):
99
+ """Exception raised when unable to connect to the API.
100
+
101
+ This can be due to network issues, timeouts, or connection errors.
102
+ """
103
+
104
+ pass
105
+
106
+
107
+ class PromptLayerAPITimeoutError(PromptLayerError):
108
+ """Exception raised when an API request times out."""
109
+
110
+ pass
111
+
112
+
113
+ class PromptLayerValidationError(PromptLayerError):
114
+ """Exception raised when input validation fails.
115
+
116
+ This can be due to invalid types, out of range values, or malformed data.
117
+ """
118
+
119
+ pass
@@ -2,19 +2,23 @@ from promptlayer.groups.groups import acreate, create
2
2
 
3
3
 
4
4
  class GroupManager:
5
- def __init__(self, api_key: str):
5
+ def __init__(self, api_key: str, base_url: str, throw_on_error: bool):
6
6
  self.api_key = api_key
7
+ self.base_url = base_url
8
+ self.throw_on_error = throw_on_error
7
9
 
8
10
  def create(self):
9
- return create(self.api_key)
11
+ return create(self.api_key, self.base_url, self.throw_on_error)
10
12
 
11
13
 
12
14
  class AsyncGroupManager:
13
- def __init__(self, api_key: str):
15
+ def __init__(self, api_key: str, base_url: str, throw_on_error: bool):
14
16
  self.api_key = api_key
17
+ self.base_url = base_url
18
+ self.throw_on_error = throw_on_error
15
19
 
16
- async def create(self) -> str:
17
- return await acreate(self.api_key)
20
+ async def create(self):
21
+ return await acreate(self.api_key, self.base_url, self.throw_on_error)
18
22
 
19
23
 
20
24
  __all__ = ["GroupManager", "AsyncGroupManager"]
@@ -1,11 +1,9 @@
1
1
  from promptlayer.utils import apromptlayer_create_group, promptlayer_create_group
2
2
 
3
3
 
4
- def create(api_key: str = None):
5
- """Create a new group."""
6
- return promptlayer_create_group(api_key)
4
+ def create(api_key: str, base_url: str, throw_on_error: bool):
5
+ return promptlayer_create_group(api_key, base_url, throw_on_error)
7
6
 
8
7
 
9
- async def acreate(api_key: str = None) -> str:
10
- """Asynchronously create a new group."""
11
- return await apromptlayer_create_group(api_key)
8
+ async def acreate(api_key: str, base_url: str, throw_on_error: bool):
9
+ return await apromptlayer_create_group(api_key, base_url, throw_on_error)
@@ -6,6 +6,7 @@ from typing import Any, Dict, List, Literal, Optional, Union
6
6
 
7
7
  import nest_asyncio
8
8
 
9
+ from promptlayer import exceptions as _exceptions
9
10
  from promptlayer.groups import AsyncGroupManager, GroupManager
10
11
  from promptlayer.promptlayer_base import PromptLayerBase
11
12
  from promptlayer.promptlayer_mixins import PromptLayerMixin
@@ -26,6 +27,10 @@ from promptlayer.utils import (
26
27
  logger = logging.getLogger(__name__)
27
28
 
28
29
 
30
+ def get_base_url(base_url: Union[str, None]):
31
+ return base_url or os.environ.get("PROMPTLAYER_BASE_URL", "https://api.promptlayer.com")
32
+
33
+
29
34
  def is_workflow_results_dict(obj: Any) -> bool:
30
35
  if not isinstance(obj, dict):
31
36
  return False
@@ -50,8 +55,10 @@ def is_workflow_results_dict(obj: Any) -> bool:
50
55
  class PromptLayer(PromptLayerMixin):
51
56
  def __init__(
52
57
  self,
53
- api_key: str = None,
58
+ api_key: Union[str, None] = None,
54
59
  enable_tracing: bool = False,
60
+ base_url: Union[str, None] = None,
61
+ throw_on_error: bool = True,
55
62
  ):
56
63
  if api_key is None:
57
64
  api_key = os.environ.get("PROMPTLAYER_API_KEY")
@@ -62,11 +69,15 @@ class PromptLayer(PromptLayerMixin):
62
69
  "Please set the PROMPTLAYER_API_KEY environment variable or pass the api_key parameter."
63
70
  )
64
71
 
72
+ self.base_url = get_base_url(base_url)
65
73
  self.api_key = api_key
66
- self.templates = TemplateManager(api_key)
67
- self.group = GroupManager(api_key)
68
- self.tracer_provider, self.tracer = self._initialize_tracer(api_key, enable_tracing)
69
- self.track = TrackManager(api_key)
74
+ self.throw_on_error = throw_on_error
75
+ self.templates = TemplateManager(api_key, self.base_url, self.throw_on_error)
76
+ self.group = GroupManager(api_key, self.base_url, self.throw_on_error)
77
+ self.tracer_provider, self.tracer = self._initialize_tracer(
78
+ api_key, self.base_url, self.throw_on_error, enable_tracing
79
+ )
80
+ self.track = TrackManager(api_key, self.base_url, self.throw_on_error)
70
81
 
71
82
  def __getattr__(
72
83
  self,
@@ -75,15 +86,18 @@ class PromptLayer(PromptLayerMixin):
75
86
  if name == "openai":
76
87
  import openai as openai_module
77
88
 
78
- return PromptLayerBase(openai_module, function_name="openai", api_key=self.api_key, tracer=self.tracer)
89
+ return PromptLayerBase(
90
+ self.api_key, self.base_url, openai_module, function_name="openai", tracer=self.tracer
91
+ )
79
92
  elif name == "anthropic":
80
93
  import anthropic as anthropic_module
81
94
 
82
95
  return PromptLayerBase(
96
+ self.api_key,
97
+ self.base_url,
83
98
  anthropic_module,
84
99
  function_name="anthropic",
85
100
  provider_type="anthropic",
86
- api_key=self.api_key,
87
101
  tracer=self.tracer,
88
102
  )
89
103
  else:
@@ -108,7 +122,7 @@ class PromptLayer(PromptLayerMixin):
108
122
  pl_run_span_id,
109
123
  **body,
110
124
  )
111
- return track_request(**track_request_kwargs)
125
+ return track_request(self.base_url, self.throw_on_error, **track_request_kwargs)
112
126
 
113
127
  return _track_request
114
128
 
@@ -138,6 +152,12 @@ class PromptLayer(PromptLayerMixin):
138
152
  model_parameter_overrides=model_parameter_overrides,
139
153
  )
140
154
  prompt_blueprint = self.templates.get(prompt_name, get_prompt_template_params)
155
+ if not prompt_blueprint:
156
+ raise _exceptions.PromptLayerNotFoundError(
157
+ f"Prompt template '{prompt_name}' not found.",
158
+ response=None,
159
+ body=None,
160
+ )
141
161
  prompt_blueprint_model = self._validate_and_extract_model_from_prompt_blueprint(
142
162
  prompt_blueprint=prompt_blueprint, prompt_name=prompt_name
143
163
  )
@@ -212,7 +232,7 @@ class PromptLayer(PromptLayerMixin):
212
232
  metadata=metadata,
213
233
  **body,
214
234
  )
215
- return track_request(**track_request_kwargs)
235
+ return track_request(self.base_url, self.throw_on_error, **track_request_kwargs)
216
236
 
217
237
  def run(
218
238
  self,
@@ -277,12 +297,14 @@ class PromptLayer(PromptLayerMixin):
277
297
 
278
298
  results = asyncio.run(
279
299
  arun_workflow_request(
300
+ api_key=self.api_key,
301
+ base_url=self.base_url,
302
+ throw_on_error=self.throw_on_error,
280
303
  workflow_id_or_name=_get_workflow_workflow_id_or_name(workflow_id_or_name, workflow_name),
281
304
  input_variables=input_variables or {},
282
305
  metadata=metadata,
283
306
  workflow_label_name=workflow_label_name,
284
307
  workflow_version_number=workflow_version,
285
- api_key=self.api_key,
286
308
  return_all_outputs=return_all_outputs,
287
309
  )
288
310
  )
@@ -290,10 +312,16 @@ class PromptLayer(PromptLayerMixin):
290
312
  if not return_all_outputs and is_workflow_results_dict(results):
291
313
  output_nodes = [node_data for node_data in results.values() if node_data.get("is_output_node")]
292
314
  if not output_nodes:
293
- raise Exception("Output nodes not found: %S", json.dumps(results, indent=4))
315
+ raise _exceptions.PromptLayerNotFoundError(
316
+ f"Output nodes not found: {json.dumps(results, indent=4)}", response=None, body=results
317
+ )
294
318
 
295
319
  if not any(node.get("status") == "SUCCESS" for node in output_nodes):
296
- raise Exception("None of the output nodes have succeeded", json.dumps(results, indent=4))
320
+ raise _exceptions.PromptLayerAPIError(
321
+ f"None of the output nodes have succeeded: {json.dumps(results, indent=4)}",
322
+ response=None,
323
+ body=results,
324
+ )
297
325
 
298
326
  return results
299
327
  except Exception as ex:
@@ -301,7 +329,9 @@ class PromptLayer(PromptLayerMixin):
301
329
  if RERAISE_ORIGINAL_EXCEPTION:
302
330
  raise
303
331
  else:
304
- raise Exception(f"Error running workflow: {str(ex)}") from ex
332
+ raise _exceptions.PromptLayerAPIError(
333
+ f"Error running workflow: {str(ex)}", response=None, body=None
334
+ ) from ex
305
335
 
306
336
  def log_request(
307
337
  self,
@@ -330,6 +360,8 @@ class PromptLayer(PromptLayerMixin):
330
360
  ):
331
361
  return util_log_request(
332
362
  self.api_key,
363
+ self.base_url,
364
+ throw_on_error=self.throw_on_error,
333
365
  provider=provider,
334
366
  model=model,
335
367
  input=input,
@@ -355,8 +387,10 @@ class PromptLayer(PromptLayerMixin):
355
387
  class AsyncPromptLayer(PromptLayerMixin):
356
388
  def __init__(
357
389
  self,
358
- api_key: str = None,
390
+ api_key: Union[str, None] = None,
359
391
  enable_tracing: bool = False,
392
+ base_url: Union[str, None] = None,
393
+ throw_on_error: bool = True,
360
394
  ):
361
395
  if api_key is None:
362
396
  api_key = os.environ.get("PROMPTLAYER_API_KEY")
@@ -367,31 +401,33 @@ class AsyncPromptLayer(PromptLayerMixin):
367
401
  "Please set the PROMPTLAYER_API_KEY environment variable or pass the api_key parameter."
368
402
  )
369
403
 
404
+ self.base_url = get_base_url(base_url)
370
405
  self.api_key = api_key
371
- self.templates = AsyncTemplateManager(api_key)
372
- self.group = AsyncGroupManager(api_key)
373
- self.tracer_provider, self.tracer = self._initialize_tracer(api_key, enable_tracing)
374
- self.track = AsyncTrackManager(api_key)
406
+ self.throw_on_error = throw_on_error
407
+ self.templates = AsyncTemplateManager(api_key, self.base_url, self.throw_on_error)
408
+ self.group = AsyncGroupManager(api_key, self.base_url, self.throw_on_error)
409
+ self.tracer_provider, self.tracer = self._initialize_tracer(
410
+ api_key, self.base_url, self.throw_on_error, enable_tracing
411
+ )
412
+ self.track = AsyncTrackManager(api_key, self.base_url, self.throw_on_error)
375
413
 
376
414
  def __getattr__(self, name: Union[Literal["openai"], Literal["anthropic"], Literal["prompts"]]):
377
415
  if name == "openai":
378
416
  import openai as openai_module
379
417
 
380
418
  openai = PromptLayerBase(
381
- openai_module,
382
- function_name="openai",
383
- api_key=self.api_key,
384
- tracer=self.tracer,
419
+ self.api_key, self.base_url, openai_module, function_name="openai", tracer=self.tracer
385
420
  )
386
421
  return openai
387
422
  elif name == "anthropic":
388
423
  import anthropic as anthropic_module
389
424
 
390
425
  anthropic = PromptLayerBase(
426
+ self.api_key,
427
+ self.base_url,
391
428
  anthropic_module,
392
429
  function_name="anthropic",
393
430
  provider_type="anthropic",
394
- api_key=self.api_key,
395
431
  tracer=self.tracer,
396
432
  )
397
433
  return anthropic
@@ -413,12 +449,14 @@ class AsyncPromptLayer(PromptLayerMixin):
413
449
  ) -> Union[Dict[str, Any], Any]:
414
450
  try:
415
451
  return await arun_workflow_request(
452
+ api_key=self.api_key,
453
+ base_url=self.base_url,
454
+ throw_on_error=self.throw_on_error,
416
455
  workflow_id_or_name=_get_workflow_workflow_id_or_name(workflow_id_or_name, workflow_name),
417
456
  input_variables=input_variables or {},
418
457
  metadata=metadata,
419
458
  workflow_label_name=workflow_label_name,
420
459
  workflow_version_number=workflow_version,
421
- api_key=self.api_key,
422
460
  return_all_outputs=return_all_outputs,
423
461
  )
424
462
  except Exception as ex:
@@ -426,7 +464,9 @@ class AsyncPromptLayer(PromptLayerMixin):
426
464
  if RERAISE_ORIGINAL_EXCEPTION:
427
465
  raise
428
466
  else:
429
- raise Exception(f"Error running workflow: {str(ex)}")
467
+ raise _exceptions.PromptLayerAPIError(
468
+ f"Error running workflow: {str(ex)}", response=None, body=None
469
+ ) from ex
430
470
 
431
471
  async def run(
432
472
  self,
@@ -491,6 +531,8 @@ class AsyncPromptLayer(PromptLayerMixin):
491
531
  ):
492
532
  return await autil_log_request(
493
533
  self.api_key,
534
+ self.base_url,
535
+ throw_on_error=self.throw_on_error,
494
536
  provider=provider,
495
537
  model=model,
496
538
  input=input,
@@ -530,7 +572,7 @@ class AsyncPromptLayer(PromptLayerMixin):
530
572
  pl_run_span_id,
531
573
  **body,
532
574
  )
533
- return await atrack_request(**track_request_kwargs)
575
+ return await atrack_request(self.base_url, self.throw_on_error, **track_request_kwargs)
534
576
 
535
577
  return _track_request
536
578
 
@@ -554,7 +596,7 @@ class AsyncPromptLayer(PromptLayerMixin):
554
596
  metadata=metadata,
555
597
  **body,
556
598
  )
557
- return await atrack_request(**track_request_kwargs)
599
+ return await atrack_request(self.base_url, self.throw_on_error, **track_request_kwargs)
558
600
 
559
601
  async def _run_internal(
560
602
  self,
@@ -582,6 +624,12 @@ class AsyncPromptLayer(PromptLayerMixin):
582
624
  model_parameter_overrides=model_parameter_overrides,
583
625
  )
584
626
  prompt_blueprint = await self.templates.get(prompt_name, get_prompt_template_params)
627
+ if not prompt_blueprint:
628
+ raise _exceptions.PromptLayerNotFoundError(
629
+ f"Prompt template '{prompt_name}' not found.",
630
+ response=None,
631
+ body=None,
632
+ )
585
633
  prompt_blueprint_model = self._validate_and_extract_model_from_prompt_blueprint(
586
634
  prompt_blueprint=prompt_blueprint, prompt_name=prompt_name
587
635
  )
@@ -631,6 +679,6 @@ class AsyncPromptLayer(PromptLayerMixin):
631
679
 
632
680
  return {
633
681
  "request_id": request_log.get("request_id", None),
634
- "raw_response": request_response,
682
+ "raw_response": response,
635
683
  "prompt_blueprint": request_log.get("prompt_blueprint", None),
636
684
  }
@@ -2,6 +2,7 @@ import datetime
2
2
  import inspect
3
3
  import re
4
4
 
5
+ from promptlayer import exceptions as _exceptions
5
6
  from promptlayer.utils import async_wrapper, promptlayer_api_handler
6
7
 
7
8
 
@@ -13,14 +14,16 @@ class PromptLayerBase(object):
13
14
  "_provider_type",
14
15
  "_api_key",
15
16
  "_tracer",
17
+ "_base_url",
16
18
  ]
17
19
 
18
- def __init__(self, obj, function_name="", provider_type="openai", api_key=None, tracer=None):
20
+ def __init__(self, api_key: str, base_url: str, obj, function_name="", provider_type="openai", tracer=None):
19
21
  object.__setattr__(self, "_obj", obj)
20
22
  object.__setattr__(self, "_function_name", function_name)
21
23
  object.__setattr__(self, "_provider_type", provider_type)
22
24
  object.__setattr__(self, "_api_key", api_key)
23
25
  object.__setattr__(self, "_tracer", tracer)
26
+ object.__setattr__(self, "_base_url", base_url)
24
27
 
25
28
  def __getattr__(self, name):
26
29
  attr = getattr(object.__getattribute__(self, "_obj"), name)
@@ -41,10 +44,11 @@ class PromptLayerBase(object):
41
44
  )
42
45
  ):
43
46
  return PromptLayerBase(
47
+ object.__getattribute__(self, "_api_key"),
48
+ object.__getattribute__(self, "_base_url"),
44
49
  attr,
45
50
  function_name=f"{object.__getattribute__(self, '_function_name')}.{name}",
46
51
  provider_type=object.__getattribute__(self, "_provider_type"),
47
- api_key=object.__getattribute__(self, "_api_key"),
48
52
  tracer=object.__getattribute__(self, "_tracer"),
49
53
  )
50
54
  return attr
@@ -58,7 +62,7 @@ class PromptLayerBase(object):
58
62
  def __call__(self, *args, **kwargs):
59
63
  tags = kwargs.pop("pl_tags", None)
60
64
  if tags is not None and not isinstance(tags, list):
61
- raise Exception("pl_tags must be a list of strings.")
65
+ raise _exceptions.PromptLayerValidationError("pl_tags must be a list of strings.", response=None, body=None)
62
66
 
63
67
  return_pl_id = kwargs.pop("return_pl_id", False)
64
68
  request_start_time = datetime.datetime.now().timestamp()
@@ -75,10 +79,11 @@ class PromptLayerBase(object):
75
79
 
76
80
  if inspect.isclass(function_object):
77
81
  result = PromptLayerBase(
82
+ object.__getattribute__(self, "_api_key"),
83
+ object.__getattribute__(self, "_base_url"),
78
84
  function_object(*args, **kwargs),
79
85
  function_name=function_name,
80
86
  provider_type=object.__getattribute__(self, "_provider_type"),
81
- api_key=object.__getattribute__(self, "_api_key"),
82
87
  tracer=tracer,
83
88
  )
84
89
  llm_request_span.set_attribute("function_output", str(result))
@@ -88,13 +93,14 @@ class PromptLayerBase(object):
88
93
 
89
94
  if inspect.iscoroutinefunction(function_object) or inspect.iscoroutine(function_response):
90
95
  return async_wrapper(
96
+ object.__getattribute__(self, "_api_key"),
97
+ object.__getattribute__(self, "_base_url"),
91
98
  function_response,
92
99
  return_pl_id,
93
100
  request_start_time,
94
101
  function_name,
95
102
  object.__getattribute__(self, "_provider_type"),
96
103
  tags,
97
- api_key=object.__getattribute__(self, "_api_key"),
98
104
  llm_request_span_id=llm_request_span_id,
99
105
  tracer=tracer, # Pass the tracer to async_wrapper
100
106
  *args,
@@ -103,6 +109,8 @@ class PromptLayerBase(object):
103
109
 
104
110
  request_end_time = datetime.datetime.now().timestamp()
105
111
  result = promptlayer_api_handler(
112
+ object.__getattribute__(self, "_api_key"),
113
+ object.__getattribute__(self, "_base_url"),
106
114
  function_name,
107
115
  object.__getattribute__(self, "_provider_type"),
108
116
  args,
@@ -111,7 +119,6 @@ class PromptLayerBase(object):
111
119
  function_response,
112
120
  request_start_time,
113
121
  request_end_time,
114
- object.__getattribute__(self, "_api_key"),
115
122
  return_pl_id=return_pl_id,
116
123
  llm_request_span_id=llm_request_span_id,
117
124
  )
@@ -121,29 +128,33 @@ class PromptLayerBase(object):
121
128
  # Without tracing
122
129
  if inspect.isclass(function_object):
123
130
  return PromptLayerBase(
131
+ object.__getattribute__(self, "_api_key"),
132
+ object.__getattribute__(self, "_base_url"),
124
133
  function_object(*args, **kwargs),
125
134
  function_name=function_name,
126
135
  provider_type=object.__getattribute__(self, "_provider_type"),
127
- api_key=object.__getattribute__(self, "_api_key"),
128
136
  )
129
137
 
130
138
  function_response = function_object(*args, **kwargs)
131
139
 
132
140
  if inspect.iscoroutinefunction(function_object) or inspect.iscoroutine(function_response):
133
141
  return async_wrapper(
142
+ object.__getattribute__(self, "_api_key"),
143
+ object.__getattribute__(self, "_base_url"),
134
144
  function_response,
135
145
  return_pl_id,
136
146
  request_start_time,
137
147
  function_name,
138
148
  object.__getattribute__(self, "_provider_type"),
139
149
  tags,
140
- api_key=object.__getattribute__(self, "_api_key"),
141
150
  *args,
142
151
  **kwargs,
143
152
  )
144
153
 
145
154
  request_end_time = datetime.datetime.now().timestamp()
146
155
  return promptlayer_api_handler(
156
+ object.__getattribute__(self, "_api_key"),
157
+ object.__getattribute__(self, "_base_url"),
147
158
  function_name,
148
159
  object.__getattribute__(self, "_provider_type"),
149
160
  args,
@@ -152,6 +163,5 @@ class PromptLayerBase(object):
152
163
  function_response,
153
164
  request_start_time,
154
165
  request_end_time,
155
- object.__getattribute__(self, "_api_key"),
156
166
  return_pl_id=return_pl_id,
157
167
  )
@@ -262,11 +262,13 @@ AMAP_PROVIDER_TO_FUNCTION = {
262
262
 
263
263
  class PromptLayerMixin:
264
264
  @staticmethod
265
- def _initialize_tracer(api_key: str = None, enable_tracing: bool = False):
265
+ def _initialize_tracer(api_key: str, base_url: str, throw_on_error: bool, enable_tracing: bool = False):
266
266
  if enable_tracing:
267
267
  resource = Resource(attributes={ResourceAttributes.SERVICE_NAME: "prompt-layer-library"})
268
268
  tracer_provider = TracerProvider(resource=resource)
269
- promptlayer_exporter = PromptLayerSpanExporter(api_key=api_key)
269
+ promptlayer_exporter = PromptLayerSpanExporter(
270
+ api_key=api_key, base_url=base_url, throw_on_error=throw_on_error
271
+ )
270
272
  span_processor = BatchSpanProcessor(promptlayer_exporter)
271
273
  tracer_provider.add_span_processor(span_processor)
272
274
  tracer = tracer_provider.get_tracer(__name__)
@@ -317,7 +319,7 @@ class PromptLayerMixin:
317
319
  function_kwargs = deepcopy(prompt_blueprint["llm_kwargs"])
318
320
  function_kwargs["stream"] = stream
319
321
  provider = prompt_blueprint_model["provider"]
320
- api_type = prompt_blueprint_model["api_type"]
322
+ api_type = prompt_blueprint_model.get("api_type", "chat-completions")
321
323
 
322
324
  if custom_provider := prompt_blueprint.get("custom_provider"):
323
325
  provider = custom_provider["client"]