@@ -39,6 +39,7 @@ def __init__(
39
39
langsmith_api_key : Optional [str ] = None ,
40
40
langsmith_project : Optional [str ] = None ,
41
41
langsmith_base_url : Optional [str ] = None ,
42
+ langsmith_sampling_rate : Optional [float ] = None ,
42
43
** kwargs ,
43
44
):
44
45
self .flush_lock = asyncio .Lock ()
@@ -49,7 +50,8 @@ def __init__(
49
50
langsmith_base_url = langsmith_base_url ,
50
51
)
51
52
self .sampling_rate : float = (
52
- float (os .getenv ("LANGSMITH_SAMPLING_RATE" )) # type: ignore
53
+ langsmith_sampling_rate
54
+ or float (os .getenv ("LANGSMITH_SAMPLING_RATE" )) # type: ignore
53
55
if os .getenv ("LANGSMITH_SAMPLING_RATE" ) is not None
54
56
and os .getenv ("LANGSMITH_SAMPLING_RATE" ).strip ().isdigit () # type: ignore
55
57
else 1.0
@@ -76,26 +78,14 @@ def get_credentials_from_env(
76
78
langsmith_base_url : Optional [str ] = None ,
77
79
) -> LangsmithCredentialsObject :
78
80
_credentials_api_key = langsmith_api_key or os .getenv ("LANGSMITH_API_KEY" )
79
- if _credentials_api_key is None :
80
- raise Exception (
81
- "Invalid Langsmith API Key given. _credentials_api_key=None."
82
- )
83
81
_credentials_project = (
84
82
langsmith_project or os .getenv ("LANGSMITH_PROJECT" ) or "litellm-completion"
85
83
)
86
- if _credentials_project is None :
87
- raise Exception (
88
- "Invalid Langsmith API Key given. _credentials_project=None."
89
- )
90
84
_credentials_base_url = (
91
85
langsmith_base_url
92
86
or os .getenv ("LANGSMITH_BASE_URL" )
93
87
or "https://api.smith.langchain.com"
94
88
)
95
- if _credentials_base_url is None :
96
- raise Exception (
97
- "Invalid Langsmith API Key given. _credentials_base_url=None."
98
- )
99
89
100
90
return LangsmithCredentialsObject (
101
91
LANGSMITH_API_KEY = _credentials_api_key ,
@@ -200,12 +190,7 @@ def _prepare_log_data(
200
190
201
191
def log_success_event (self , kwargs , response_obj , start_time , end_time ):
202
192
try :
203
- sampling_rate = (
204
- float (os .getenv ("LANGSMITH_SAMPLING_RATE" )) # type: ignore
205
- if os .getenv ("LANGSMITH_SAMPLING_RATE" ) is not None
206
- and os .getenv ("LANGSMITH_SAMPLING_RATE" ).strip ().isdigit () # type: ignore
207
- else 1.0
208
- )
193
+ sampling_rate = self ._get_sampling_rate_to_use_for_request (kwargs = kwargs )
209
194
random_sample = random .random ()
210
195
if random_sample > sampling_rate :
211
196
verbose_logger .info (
@@ -219,6 +204,7 @@ def log_success_event(self, kwargs, response_obj, start_time, end_time):
219
204
kwargs ,
220
205
response_obj ,
221
206
)
207
+
222
208
credentials = self ._get_credentials_to_use_for_request (kwargs = kwargs )
223
209
data = self ._prepare_log_data (
224
210
kwargs = kwargs ,
@@ -245,7 +231,7 @@ def log_success_event(self, kwargs, response_obj, start_time, end_time):
245
231
246
232
async def async_log_success_event (self , kwargs , response_obj , start_time , end_time ):
247
233
try :
248
- sampling_rate = self .sampling_rate
234
+ sampling_rate = self ._get_sampling_rate_to_use_for_request ( kwargs = kwargs )
249
235
random_sample = random .random ()
250
236
if random_sample > sampling_rate :
251
237
verbose_logger .info (
@@ -286,7 +272,7 @@ async def async_log_success_event(self, kwargs, response_obj, start_time, end_ti
286
272
)
287
273
288
274
async def async_log_failure_event (self , kwargs , response_obj , start_time , end_time ):
289
- sampling_rate = self .sampling_rate
275
+ sampling_rate = self ._get_sampling_rate_to_use_for_request ( kwargs = kwargs )
290
276
random_sample = random .random ()
291
277
if random_sample > sampling_rate :
292
278
verbose_logger .info (
@@ -417,6 +403,17 @@ def _group_batches_by_credentials(self) -> Dict[CredentialsKey, BatchGroup]:
417
403
418
404
for queue_object in self .log_queue :
419
405
credentials = queue_object ["credentials" ]
406
+ # if credential missing, skip - log warning
407
+ if (
408
+ credentials ["LANGSMITH_API_KEY" ] is None
409
+ or credentials ["LANGSMITH_PROJECT" ] is None
410
+ ):
411
+ verbose_logger .warning (
412
+ "Langsmith Logging - credentials missing - api_key: %s, project: %s" ,
413
+ credentials ["LANGSMITH_API_KEY" ],
414
+ credentials ["LANGSMITH_PROJECT" ],
415
+ )
416
+ continue
420
417
key = CredentialsKey (
421
418
api_key = credentials ["LANGSMITH_API_KEY" ],
422
419
project = credentials ["LANGSMITH_PROJECT" ],
@@ -432,6 +429,19 @@ def _group_batches_by_credentials(self) -> Dict[CredentialsKey, BatchGroup]:
432
429
433
430
return log_queue_by_credentials
434
431
432
+ def _get_sampling_rate_to_use_for_request (self , kwargs : Dict [str , Any ]) -> float :
433
+ standard_callback_dynamic_params : Optional [StandardCallbackDynamicParams ] = (
434
+ kwargs .get ("standard_callback_dynamic_params" , None )
435
+ )
436
+ sampling_rate : float = self .sampling_rate
437
+ if standard_callback_dynamic_params is not None :
438
+ _sampling_rate = standard_callback_dynamic_params .get (
439
+ "langsmith_sampling_rate"
440
+ )
441
+ if _sampling_rate is not None :
442
+ sampling_rate = float (_sampling_rate )
443
+ return sampling_rate
444
+
435
445
def _get_credentials_to_use_for_request (
436
446
self , kwargs : Dict [str , Any ]
437
447
) -> LangsmithCredentialsObject :
@@ -442,9 +452,9 @@ def _get_credentials_to_use_for_request(
442
452
443
453
Otherwise, use the default credentials.
444
454
"""
445
- standard_callback_dynamic_params : Optional [
446
- StandardCallbackDynamicParams
447
- ] = kwargs . get ( "standard_callback_dynamic_params" , None )
455
+ standard_callback_dynamic_params : Optional [StandardCallbackDynamicParams ] = (
456
+ kwargs . get ( "standard_callback_dynamic_params" , None )
457
+ )
448
458
if standard_callback_dynamic_params is not None :
449
459
credentials = self .get_credentials_from_env (
450
460
langsmith_api_key = standard_callback_dynamic_params .get (
0 commit comments