Skip to content

Commit 165adfb

Browse files
authored
feat(integrations): add auth check to openai and langchain (#199)
1 parent cfbda9a commit 165adfb

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed

langfuse/callback.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ def __init__(
5151
self.trace = statefulClient
5252
self.runs = {}
5353
self.rootSpan = None
54+
self.langfuse = None
5455

5556
elif statefulClient and isinstance(statefulClient, StatefulSpanClient):
5657
self.runs = {}
5758
self.rootSpan = statefulClient
59+
self.langfuse = None
5860
self.trace = StatefulTraceClient(
5961
statefulClient.client,
6062
statefulClient.trace_id,
@@ -98,6 +100,22 @@ def flush(self):
98100
else:
99101
self.log.debug("There was no trace yet, hence no flushing possible.")
100102

103+
def auth_check(self):
104+
if self.langfuse is not None:
105+
return self.langfuse.auth_check()
106+
elif self.trace is not None:
107+
projects = self.trace.client.projects.get()
108+
if len(projects.data) == 0:
109+
raise Exception("No projects found for the keys.")
110+
return True
111+
elif self.rootSpan is not None:
112+
projects = self.rootSpan.client.projects.get()
113+
if len(projects) == 0:
114+
raise Exception("No projects found for the keys.")
115+
return True
116+
117+
return False
118+
101119
def setNextSpan(self, id: str):
102120
self.nextSpanId = id
103121

langfuse/openai.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,3 +346,10 @@ def register_tracing(self):
346346

347347
modifier = OpenAILangfuse()
348348
modifier.register_tracing()
349+
350+
351+
def auth_check():
352+
if modifier._langfuse is None:
353+
modifier.initialize()
354+
355+
return modifier._langfuse.auth_check()

tests/test_openai.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import pytest
33
from langfuse.client import Langfuse
44
from langfuse.model import CreateTrace
5-
from langfuse.openai import _is_openai_v1, _is_streaming_response, openai, AsyncOpenAI, AzureOpenAI, AsyncAzureOpenAI
5+
from langfuse.openai import _is_openai_v1, _is_streaming_response, openai, AsyncOpenAI, AzureOpenAI, AsyncAzureOpenAI, auth_check
66
from openai import APIConnectionError
77

88
from tests.utils import create_uuid, get_api

tests/test_sdk_setup.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
from langfuse.callback import CallbackHandler
1111

1212
from langfuse.client import Langfuse
13+
from langfuse.model import CreateTrace
1314
from tests.test_task_manager import get_host
14-
from langfuse.openai import _is_openai_v1, openai
15+
from langfuse.openai import _is_openai_v1, auth_check, openai
1516

1617
chat_func = openai.chat.completions.create if _is_openai_v1() else openai.ChatCompletion.create
1718

@@ -226,6 +227,27 @@ def test_openai_default():
226227
os.environ["LANGFUSE_HOST"] = host
227228

228229

230+
def test_openai_auth_check():
231+
assert auth_check() is True
232+
233+
234+
def test_openai_auth_check_failing_key():
235+
secret_key = os.environ["LANGFUSE_SECRET_KEY"]
236+
os.environ.pop("LANGFUSE_SECRET_KEY")
237+
238+
importlib.reload(langfuse)
239+
importlib.reload(langfuse.openai)
240+
241+
from langfuse.openai import openai
242+
243+
openai.langfuse_secret_key = "test"
244+
245+
with pytest.raises(UnauthorizedError):
246+
auth_check()
247+
248+
os.environ["LANGFUSE_SECRET_KEY"] = secret_key
249+
250+
229251
def test_openai_configured(httpserver: HTTPServer):
230252
httpserver.expect_request("/api/public/ingestion", method="POST").respond_with_response(Response(status=200))
231253
host = get_host(httpserver.url_for("/api/public/ingestion"))
@@ -270,6 +292,7 @@ def test_openai_configured(httpserver: HTTPServer):
270292

271293
def test_client_init_workers_5():
272294
langfuse = Langfuse(threads=5)
295+
langfuse.flush()
273296

274297
assert langfuse.task_manager._threads == 5
275298

@@ -287,16 +310,54 @@ def test_auth_check():
287310

288311
assert langfuse.auth_check() is True
289312

313+
langfuse.flush()
314+
290315

291316
def test_wrong_key_auth_check():
292317
langfuse = Langfuse(debug=False, secret_key="test")
293318

294319
with pytest.raises(UnauthorizedError):
295320
langfuse.auth_check()
296321

322+
langfuse.flush()
323+
324+
325+
def test_auth_check_callback():
326+
langfuse = CallbackHandler(debug=False)
327+
328+
assert langfuse.auth_check() is True
329+
langfuse.flush()
330+
331+
332+
def test_auth_check_callback_stateful():
333+
langfuse = Langfuse(debug=False)
334+
trace = langfuse.trace(CreateTrace(name="name"))
335+
handler = trace.get_langchain_handler()
336+
337+
assert handler.auth_check() is True
338+
handler.flush()
339+
340+
341+
def test_wrong_key_auth_check_callback():
342+
langfuse = CallbackHandler(debug=False, secret_key="test")
343+
344+
with pytest.raises(UnauthorizedError):
345+
langfuse.auth_check()
346+
langfuse.flush()
347+
297348

298349
def test_wrong_url_auth_check():
299350
langfuse = Langfuse(debug=False, host="http://localhost:4000/")
300351

301352
with pytest.raises(httpx.ConnectError):
302353
langfuse.auth_check()
354+
355+
langfuse.flush()
356+
357+
358+
def test_wrong_url_auth_check_callback():
359+
langfuse = CallbackHandler(debug=False, host="http://localhost:4000/")
360+
361+
with pytest.raises(httpx.ConnectError):
362+
langfuse.auth_check()
363+
langfuse.flush()

0 commit comments

Comments
 (0)