Skip to content

Commit 150289e

Browse files
committed
chore: add mypy
1 parent 22aaed7 commit 150289e

File tree

15 files changed

+301
-137
lines changed

15 files changed

+301
-137
lines changed

langfuse/_client/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ def __init__(
159159
media_upload_thread_count: Optional[int] = None,
160160
sample_rate: Optional[float] = None,
161161
mask: Optional[MaskFunction] = None,
162-
):
162+
) -> None:
163163
self._host = host or os.environ.get(LANGFUSE_HOST, "https://cloud.langfuse.com")
164164
self._environment = environment or os.environ.get(LANGFUSE_TRACING_ENVIRONMENT)
165165
self._mask = mask

langfuse/_client/datasets.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def run(
9191
run_name: str,
9292
run_metadata: Optional[Any] = None,
9393
run_description: Optional[str] = None,
94-
):
94+
) -> Any:
9595
"""Create a context manager for the dataset item run that links the execution to a Langfuse trace.
9696
9797
This method is a context manager that creates a trace for the dataset run and yields a span

langfuse/_client/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from opentelemetry.sdk.trace import ReadableSpan
1212

1313

14-
def span_formatter(span: ReadableSpan):
14+
def span_formatter(span: ReadableSpan) -> str:
1515
parent_id = (
1616
otel_trace_api.format_span_id(span.parent.span_id) if span.parent else None
1717
)

langfuse/_utils/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
log = logging.getLogger("langfuse")
1010

1111

12-
def _get_timestamp():
12+
def _get_timestamp() -> datetime:
1313
return datetime.now(timezone.utc)
1414

1515

1616
def _create_prompt_context(
1717
prompt: typing.Optional[PromptClient] = None,
18-
):
18+
) -> typing.Dict[str, typing.Optional[str]]:
1919
if prompt is not None and not prompt.is_fallback:
2020
return {"prompt_version": prompt.version, "prompt_name": prompt.name}
2121

langfuse/_utils/environment.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""@private"""
22

33
import os
4+
from typing import Optional
45

56
common_release_envs = [
67
# Render
@@ -26,7 +27,7 @@
2627
]
2728

2829

29-
def get_common_release_envs():
30+
def get_common_release_envs() -> Optional[str]:
3031
for env in common_release_envs:
3132
if env in os.environ:
3233
return os.environ[env]

langfuse/_utils/error_logging.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import functools
22
import logging
3-
from typing import List, Optional
3+
from typing import Any, Callable, List, Optional
44

55
logger = logging.getLogger("langfuse")
66

77

8-
def catch_and_log_errors(func):
8+
def catch_and_log_errors(func: Callable[..., Any]) -> Callable[..., Any]:
99
"""Catch all exceptions and log them. Do NOT re-raise the exception."""
1010

1111
@functools.wraps(func)
12-
def wrapper(*args, **kwargs):
12+
def wrapper(*args: Any, **kwargs: Any) -> Any:
1313
try:
1414
return func(*args, **kwargs)
1515
except Exception as e:
@@ -18,14 +18,17 @@ def wrapper(*args, **kwargs):
1818
return wrapper
1919

2020

21-
def auto_decorate_methods_with(decorator, exclude: Optional[List[str]] = []):
21+
def auto_decorate_methods_with(
22+
decorator: Callable[[Any], Any], exclude: Optional[List[str]] = None
23+
) -> Callable[[Any], Any]:
2224
"""Class decorator to automatically apply a given decorator to all
2325
methods of a class.
2426
"""
2527

26-
def class_decorator(cls):
28+
def class_decorator(cls: Any) -> Any:
29+
exclude_list = exclude or []
2730
for attr_name, attr_value in cls.__dict__.items():
28-
if attr_name in exclude:
31+
if attr_name in exclude_list:
2932
continue
3033
if callable(attr_value):
3134
# Wrap callable attributes (methods) with the decorator

langfuse/_utils/prompt_cache.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from datetime import datetime
66
from queue import Empty, Queue
77
from threading import Thread
8-
from typing import Dict, List, Optional, Set
8+
from typing import Any, Dict, List, Optional, Set
99

1010
from langfuse.model import PromptClient
1111

@@ -39,7 +39,7 @@ def __init__(self, queue: Queue, identifier: int):
3939
self._queue = queue
4040
self._identifier = identifier
4141

42-
def run(self):
42+
def run(self) -> None:
4343
while self.running:
4444
try:
4545
task = self._queue.get(timeout=1)
@@ -58,7 +58,7 @@ def run(self):
5858
except Empty:
5959
pass
6060

61-
def pause(self):
61+
def pause(self) -> None:
6262
"""Pause the consumer."""
6363
self.running = False
6464

@@ -83,7 +83,7 @@ def __init__(self, threads: int = 1):
8383

8484
atexit.register(self.shutdown)
8585

86-
def add_task(self, key: str, task):
86+
def add_task(self, key: str, task: Any) -> None:
8787
if key not in self._processing_keys:
8888
self._log.debug(f"Adding prompt cache refresh task for key: {key}")
8989
self._processing_keys.add(key)
@@ -97,8 +97,8 @@ def add_task(self, key: str, task):
9797
def active_tasks(self) -> int:
9898
return len(self._processing_keys)
9999

100-
def _wrap_task(self, key: str, task):
101-
def wrapped():
100+
def _wrap_task(self, key: str, task: Any) -> Any:
101+
def wrapped() -> None:
102102
self._log.debug(f"Refreshing prompt cache for key: {key}")
103103
try:
104104
task()
@@ -108,7 +108,7 @@ def wrapped():
108108

109109
return wrapped
110110

111-
def shutdown(self):
111+
def shutdown(self) -> None:
112112
self._log.debug(
113113
f"Shutting down prompt refresh task manager, {len(self._consumers)} consumers,..."
114114
)
@@ -146,19 +146,19 @@ def __init__(
146146
def get(self, key: str) -> Optional[PromptCacheItem]:
147147
return self._cache.get(key, None)
148148

149-
def set(self, key: str, value: PromptClient, ttl_seconds: Optional[int]):
149+
def set(self, key: str, value: PromptClient, ttl_seconds: Optional[int]) -> None:
150150
if ttl_seconds is None:
151151
ttl_seconds = DEFAULT_PROMPT_CACHE_TTL_SECONDS
152152

153153
self._cache[key] = PromptCacheItem(value, ttl_seconds)
154154

155-
def invalidate(self, prompt_name: str):
155+
def invalidate(self, prompt_name: str) -> None:
156156
"""Invalidate all cached prompts with the given prompt name."""
157157
for key in list(self._cache):
158158
if key.startswith(prompt_name):
159159
del self._cache[key]
160160

161-
def add_refresh_prompt_task(self, key: str, fetch_func):
161+
def add_refresh_prompt_task(self, key: str, fetch_func: Any) -> None:
162162
self._log.debug(f"Submitting refresh task for key: {key}")
163163
self._task_manager.add_task(key, fetch_func)
164164

langfuse/_utils/serializer.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,26 @@
2121
try:
2222
from langchain.load.serializable import Serializable
2323
except ImportError:
24-
# If Serializable is not available, set it to NoneType
25-
Serializable = type(None)
24+
# If Serializable is not available, set it to a placeholder type
25+
class Serializable:
26+
pass
27+
2628

2729
# Attempt to import numpy
2830
try:
2931
import numpy as np
3032
except ImportError:
31-
np = None
33+
np = None # type: ignore
3234

3335
logger = getLogger(__name__)
3436

3537

3638
class EventSerializer(JSONEncoder):
37-
def __init__(self, *args, **kwargs):
39+
def __init__(self, *args: Any, **kwargs: Any) -> None:
3840
super().__init__(*args, **kwargs)
3941
self.seen = set() # Track seen objects to detect circular references
4042

41-
def default(self, obj: Any):
43+
def default(self, obj: Any) -> Any:
4244
try:
4345
if isinstance(obj, (datetime)):
4446
# Timezone-awareness check

langfuse/langchain/CallbackHandler.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,10 @@ def on_chain_start(
186186
def _register_langfuse_prompt(
187187
self,
188188
*,
189-
run_id,
189+
run_id: UUID,
190190
parent_run_id: Optional[UUID],
191191
metadata: Optional[Dict[str, Any]],
192-
):
192+
) -> None:
193193
"""We need to register any passed Langfuse prompt to the parent_run_id so that we can link following generations with that prompt.
194194
195195
If parent_run_id is None, we are at the root of a trace and should not attempt to register the prompt, as there will be no LLM invocation following it.
@@ -209,7 +209,7 @@ def _register_langfuse_prompt(
209209
registered_prompt = self.prompt_to_parent_run_map[parent_run_id]
210210
self.prompt_to_parent_run_map[run_id] = registered_prompt
211211

212-
def _deregister_langfuse_prompt(self, run_id: Optional[UUID]):
212+
def _deregister_langfuse_prompt(self, run_id: Optional[UUID]) -> None:
213213
if run_id in self.prompt_to_parent_run_map:
214214
del self.prompt_to_parent_run_map[run_id]
215215

@@ -751,7 +751,7 @@ def _log_debug_event(
751751
)
752752

753753

754-
def _extract_raw_response(last_response):
754+
def _extract_raw_response(last_response: Any) -> Any:
755755
"""Extract the response from the last response of the LLM call."""
756756
# We return the text of the response if not empty
757757
if last_response.text is not None and last_response.text.strip() != "":
@@ -764,11 +764,13 @@ def _extract_raw_response(last_response):
764764
return ""
765765

766766

767-
def _flatten_comprehension(matrix):
767+
def _flatten_comprehension(matrix: Any) -> List[Any]:
768768
return [item for row in matrix for item in row]
769769

770770

771-
def _parse_usage_model(usage: typing.Union[pydantic.BaseModel, dict]):
771+
def _parse_usage_model(
772+
usage: typing.Union[pydantic.BaseModel, dict],
773+
) -> typing.Optional[typing.Dict[str, typing.Any]]:
772774
# maintains a list of key translations. For each key, the usage model is checked
773775
# and a new object will be created with the new key if the key exists in the usage model
774776
# All non matched keys will remain on the object.
@@ -891,7 +893,7 @@ def _parse_usage_model(usage: typing.Union[pydantic.BaseModel, dict]):
891893
return usage_model if usage_model else None
892894

893895

894-
def _parse_usage(response: LLMResult):
896+
def _parse_usage(response: LLMResult) -> typing.Optional[typing.Dict[str, typing.Any]]:
895897
# langchain-anthropic uses the usage field
896898
llm_usage_keys = ["token_usage", "usage"]
897899
llm_usage = None
@@ -938,7 +940,7 @@ def _parse_usage(response: LLMResult):
938940
return llm_usage
939941

940942

941-
def _parse_model(response: LLMResult):
943+
def _parse_model(response: LLMResult) -> typing.Optional[str]:
942944
# langchain-anthropic uses the usage field
943945
llm_model_keys = ["model_name"]
944946
llm_model = None
@@ -951,14 +953,18 @@ def _parse_model(response: LLMResult):
951953
return llm_model
952954

953955

954-
def _parse_model_name_from_metadata(metadata: Optional[Dict[str, Any]]):
956+
def _parse_model_name_from_metadata(
957+
metadata: Optional[Dict[str, Any]],
958+
) -> typing.Optional[str]:
955959
if metadata is None or not isinstance(metadata, dict):
956960
return None
957961

958962
return metadata.get("ls_model_name", None)
959963

960964

961-
def _strip_langfuse_keys_from_dict(metadata: Optional[Dict[str, Any]]):
965+
def _strip_langfuse_keys_from_dict(
966+
metadata: Optional[Dict[str, Any]],
967+
) -> Optional[Dict[str, Any]]:
962968
if metadata is None or not isinstance(metadata, dict):
963969
return metadata
964970

0 commit comments

Comments
 (0)