-
Notifications
You must be signed in to change notification settings - Fork 261
feat(api): update API spec from langfuse/langfuse 6603be6 #1612
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
77acd98
a9d9697
5d14025
8c0272e
19fe363
5e63dcf
e6d4c1f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,13 +12,15 @@ class ScoreDataType(enum.StrEnum): | |
| BOOLEAN = "BOOLEAN" | ||
| CATEGORICAL = "CATEGORICAL" | ||
| CORRECTION = "CORRECTION" | ||
| TEXT = "TEXT" | ||
|
|
||
| def visit( | ||
| self, | ||
| numeric: typing.Callable[[], T_Result], | ||
| boolean: typing.Callable[[], T_Result], | ||
| categorical: typing.Callable[[], T_Result], | ||
| correction: typing.Callable[[], T_Result], | ||
| text: typing.Callable[[], T_Result], | ||
| ) -> T_Result: | ||
| if self is ScoreDataType.NUMERIC: | ||
| return numeric() | ||
|
Comment on lines
18
to
26
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔴 The visit() methods on ScoreDataType and ScoreConfigDataType add a new mandatory text parameter without a default value, which will raise TypeError at the call site for any existing user code that calls these methods without the new text argument. Any SDK consumer who uses visit()-based score type dispatch (e.g. score_data_type.visit(numeric=..., boolean=..., categorical=..., correction=...)) will have silently broken code after upgrading to this version — this breaking change should be explicitly called out in a changelog entry or semver bump. Extended reasoning...What the bug is and how it manifests The ScoreDataType.visit() method in langfuse/api/commons/types/score_data_type.py previously accepted four callables: numeric, boolean, categorical, and correction. This PR adds a fifth mandatory parameter text with no default value. Similarly, ScoreConfigDataType.visit() in score_config_data_type.py previously took three callables and now requires a fourth mandatory text parameter. Python raises TypeError at the call site when any required keyword argument is missing, regardless of which enum value self currently holds. The specific code path that triggers it Any existing caller that pattern-matches on score types via visit() will fail at runtime: # Previously valid; now raises TypeError on upgrade:
score_data_type.visit(
numeric=lambda: "numeric",
boolean=lambda: "bool",
categorical=lambda: "cat",
correction=lambda: "corr",
)
# TypeError: visit() missing 1 required keyword argument: textPython validates all required arguments before dispatching the call, so even if the ScoreDataType value is NUMERIC and text would never be invoked, the TypeError is raised immediately at the call site. Addressing the refutation The refuter is correct that the Fern exhaustive visitor pattern is intentionally designed this way: adding a new enum value is a breaking change for visit() callers, and requiring the new handler prevents silent misbehavior (where TEXT scores would be silently ignored). Adding text=None as a default would indeed be a regression — code that does not handle TEXT scores would silently produce wrong results. So the code itself is correct per Fern design contract. Why this still deserves attention While the code behavior is intentional, the practical impact is real: this is a breaking change on the public langfuse.api surface. The methods are exported via langfuse/api/init.py and langfuse/api/commons/init.py. Any user who has written visit()-based dispatch code will encounter a runtime TypeError after upgrading. The PR description says no manually editable code was modified, which is accurate but does not negate the user-visible break. Impact SDK users who use the Fern client low-level visit() pattern for exhaustive score-type dispatch will have broken code after upgrading. The high-level Langfuse() client does not call visit() internally, so server-side functionality works correctly. The impact is limited to users of the langfuse.api low-level layer who pattern-match on ScoreDataType or ScoreConfigDataType values. Step-by-step proof
How to address The code change itself is correct per Fern exhaustive visitor design. The appropriate remedy is not to change the generated code, but to ensure this breaking change is documented explicitly in the CHANGELOG as a breaking change requiring a major or minor semver bump, and that a migration note is added instructing users to add text=lambda: ... handlers to all visit() call sites. |
||
|
|
@@ -28,3 +30,5 @@ def visit( | |
| return categorical() | ||
| if self is ScoreDataType.CORRECTION: | ||
| return correction() | ||
| if self is ScoreDataType.TEXT: | ||
| return text() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # This file was auto-generated by Fern from our API Definition. | ||
|
|
||
| import typing | ||
|
|
||
| import pydantic | ||
| import typing_extensions | ||
| from ...core.serialization import FieldMetadata | ||
| from .base_score import BaseScore | ||
|
|
||
|
|
||
| class TextScore(BaseScore): | ||
| string_value: typing_extensions.Annotated[ | ||
| str, FieldMetadata(alias="stringValue") | ||
| ] = pydantic.Field() | ||
| """ | ||
| The text content of the score (1-500 characters) | ||
| """ | ||
|
|
||
| model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( | ||
| extra="allow", frozen=True | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # This file was auto-generated by Fern from our API Definition. | ||
|
|
||
| import typing | ||
|
|
||
| import pydantic | ||
| import typing_extensions | ||
| from ...core.serialization import FieldMetadata | ||
| from .base_score_v1 import BaseScoreV1 | ||
|
|
||
|
|
||
| class TextScoreV1(BaseScoreV1): | ||
| string_value: typing_extensions.Annotated[ | ||
| str, FieldMetadata(alias="stringValue") | ||
| ] = pydantic.Field() | ||
| """ | ||
| The text content of the score (1-500 characters) | ||
| """ | ||
|
|
||
| model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict( | ||
| extra="allow", frozen=True | ||
| ) |
Uh oh!
There was an error while loading. Please reload this page.