Skip to content

Conversation

@langfuse-bot
Copy link
Collaborator

@langfuse-bot langfuse-bot commented Jan 7, 2026

Important

Add expand_metadata parameter to get_many in ObservationsV2Client and AsyncObservationsV2Client for full metadata retrieval and update models to ensure metadata is non-optional.

  • API Changes:
    • Add expand_metadata parameter to get_many() in ObservationsV2Client and AsyncObservationsV2Client to retrieve full metadata values.
    • Update reference.md to document expand_metadata usage.
  • Model Changes:
    • Change metadata field to non-optional in BaseScore, BaseScoreV1, Comment, Dataset, DatasetItem, DatasetRun, DatasetRunItem, Model, Observation, Score_Numeric, Score_Categorical, Score_Boolean, ScoreConfig, ScoreV1_Numeric, ScoreV1_Categorical, ScoreV1_Boolean, Session, Trace, TraceWithDetails, TraceWithFullDetails, Usage, and GetScoresResponseData classes.
  • Documentation:
    • Update docstrings in client.py to include expand_metadata parameter details.

This description was created by Ellipsis for fb0e3dc. You can customize this summary. It will automatically update as commits are pushed.

Disclaimer: Experimental PR review

Greptile Summary

Updated API spec from langfuse/langfuse commit 41f064c, bringing type definitions in sync with the backend API. The changes include added documentation strings, a new expandMetadata parameter for the observations API, and critically, multiple fields changed from optional to required across core types (Observation, Trace, Score, DatasetItem, Usage, BaseScore).

Key Changes:

  • Added expandMetadata parameter to observations API for retrieving full metadata values without truncation
  • Enhanced documentation with docstrings across multiple type definitions
  • Breaking Change Risk: Multiple fields converted from Optional[Type] with default=None to required Type without defaults, including:
    • Observation: model_parameters, input, metadata, output, usage, usage_details, cost_details, environment
    • Trace: tags, public, environment
    • Score variants: metadata, environment
    • DatasetItem: input, expected_output, metadata
    • Usage: input, output, total
    • BaseScore: metadata, environment

Critical Concern:
If the Langfuse API doesn't guarantee these fields are always present in responses, this update will cause Pydantic validation errors during deserialization, breaking existing client code. The removal of default=None from pydantic_v1.Field() makes these fields strictly required.

Recommendation:
Verify that the backend API (commit 41f064c) always returns these now-required fields in all responses, or revert the fields to optional with appropriate defaults to maintain backward compatibility.

Confidence Score: 2/5

  • This PR introduces potential breaking changes that could cause runtime validation errors
  • Score reflects the high risk of breaking changes from converting optional fields to required fields without defaults. While the code is auto-generated and syntactically correct, if the backend API doesn't guarantee these fields are always present, client applications will experience validation failures. The changes to Observation, Trace, Score, and other core types affect critical SDK functionality.
  • langfuse/api/resources/commons/types/observation.py, langfuse/api/resources/commons/types/trace.py, langfuse/api/resources/commons/types/score.py, langfuse/api/resources/commons/types/base_score.py, langfuse/api/resources/commons/types/dataset_item.py, and langfuse/api/resources/commons/types/usage.py require verification that the API always returns the newly required fields

Important Files Changed

Filename Overview
langfuse/api/resources/commons/types/observation.py Changed multiple fields from Optional to required (typing.Any or specific types), which could break deserialization if API doesn't return these fields
langfuse/api/resources/commons/types/base_score.py Added docstrings and changed metadata and environment from optional to required fields
langfuse/api/resources/commons/types/dataset_item.py Changed input, expected_output, and metadata from optional to required, added docstrings
langfuse/api/resources/commons/types/usage.py Changed input, output, and total from optional to required, removed ModelUsageUnit import and changed unit type to Optional[str]
langfuse/api/resources/commons/types/trace.py Changed tags, public, and environment from optional to required fields
langfuse/api/resources/commons/types/score.py Changed metadata and environment from optional to required in all three Score union variants (Numeric, Categorical, Boolean)
langfuse/api/resources/observations_v_2/client.py Added new expand_metadata parameter to allow retrieving full metadata values without truncation

Sequence Diagram

sequenceDiagram
    participant API as Langfuse API
    participant Client as Python SDK Client
    participant Models as Pydantic Models
    participant User as User Application

    Note over API,Models: API Spec Update Flow

    API->>Client: API spec updated (41f064c)
    Client->>Models: Generate updated types
    
    Note over Models: Key Changes:<br/>- Fields: Optional → Required<br/>- Added docstrings<br/>- New expandMetadata param

    User->>Client: Fetch observations/scores/traces
    Client->>API: GET request with params
    API-->>Client: JSON response
    Client->>Models: Deserialize to Pydantic models
    
    alt All required fields present
        Models-->>Client: Success
        Client-->>User: Typed objects returned
    else Required field missing
        Models-->>Client: ValidationError
        Client-->>User: Error propagated
    end

    Note over User,Models: Breaking Change Risk:<br/>If API doesn't return newly<br/>required fields, deserialization fails
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20 files reviewed, 14 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +57 to 60
model_parameters: typing.Any = pydantic_v1.Field(alias="modelParameters")
"""
The parameters of the model used for the observation
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed from Optional[typing.Dict[str, MapValue]] with default=None to required typing.Any field. If the API response doesn't include modelParameters, Pydantic validation will fail during deserialization.

Suggested change
model_parameters: typing.Any = pydantic_v1.Field(alias="modelParameters")
"""
The parameters of the model used for the observation
"""
model_parameters: typing.Any = pydantic_v1.Field(default=None, alias="modelParameters")

Does the API always return modelParameters, metadata, input, output, usage, usageDetails, costDetails, and environment fields in observation responses?

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/observation.py
Line: 57:60

Comment:
**logic:** Changed from `Optional[typing.Dict[str, MapValue]]` with `default=None` to required `typing.Any` field. If the API response doesn't include `modelParameters`, Pydantic validation will fail during deserialization.

```suggestion
    model_parameters: typing.Any = pydantic_v1.Field(default=None, alias="modelParameters")
```

 Does the API always return modelParameters, metadata, input, output, usage, usageDetails, costDetails, and environment fields in observation responses?

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +62 to 65
input: typing.Any = pydantic_v1.Field()
"""
The input data of the observation
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed from optional to required field without default value. This will cause validation errors if API responses don't include input.

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/observation.py
Line: 62:65

Comment:
**logic:** Changed from optional to required field without default value. This will cause validation errors if API responses don't include `input`.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +72 to 75
metadata: typing.Any = pydantic_v1.Field()
"""
Additional metadata of the observation
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed from optional to required without default. Will fail validation if metadata is missing from API response.

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/observation.py
Line: 72:75

Comment:
**logic:** Changed from optional to required without default. Will fail validation if `metadata` is missing from API response.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +77 to 80
output: typing.Any = pydantic_v1.Field()
"""
The output data of the observation
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed from optional to required without default. Will fail validation if output is missing from API response.

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/observation.py
Line: 77:80

Comment:
**logic:** Changed from optional to required without default. Will fail validation if `output` is missing from API response.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +82 to 85
usage: Usage = pydantic_v1.Field()
"""
(Deprecated. Use usageDetails and costDetails instead.) The usage data of the observation
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed from optional to required without default. Will fail validation if deprecated usage field is missing from API response.

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/observation.py
Line: 82:85

Comment:
**logic:** Changed from optional to required without default. Will fail validation if deprecated `usage` field is missing from API response.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +71 to 74
environment: str = pydantic_v1.Field()
"""
The environment from which this score originated. Can be any lowercase alphanumeric string with hyphens and underscores that does not start with 'langfuse'.
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed from Optional[str] with default=None to required str without default. Will fail validation if environment is missing from API response.

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/base_score.py
Line: 71:74

Comment:
**logic:** Changed from `Optional[str]` with `default=None` to required `str` without default. Will fail validation if `environment` is missing from API response.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +14 to +27
input: typing.Any = pydantic_v1.Field()
"""
Input data for the dataset item
"""

expected_output: typing.Any = pydantic_v1.Field(alias="expectedOutput")
"""
Expected output for the dataset item
"""

metadata: typing.Any = pydantic_v1.Field()
"""
Metadata associated with the dataset item
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed input, expected_output, and metadata from optional to required without defaults. These fields now must be present in all API responses or deserialization will fail.

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/dataset_item.py
Line: 14:27

Comment:
**logic:** Changed `input`, `expected_output`, and `metadata` from optional to required without defaults. These fields now must be present in all API responses or deserialization will fail.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +15 to 28
input: int = pydantic_v1.Field()
"""
Number of input units (e.g. tokens)
"""

output: typing.Optional[int] = pydantic_v1.Field(default=None)
output: int = pydantic_v1.Field()
"""
Number of output units (e.g. tokens)
"""

total: typing.Optional[int] = pydantic_v1.Field(default=None)
total: int = pydantic_v1.Field()
"""
Defaults to input+output if not set
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed input, output, and total from optional to required without defaults. Since this is a deprecated type, existing API responses that omit these fields will now fail validation.

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/usage.py
Line: 15:28

Comment:
**logic:** Changed `input`, `output`, and `total` from optional to required without defaults. Since this is a deprecated type, existing API responses that omit these fields will now fail validation.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +63 to 76
tags: typing.List[str] = pydantic_v1.Field()
"""
The tags associated with the trace. Can be an array of strings or null.
The tags associated with the trace.
"""

public: typing.Optional[bool] = pydantic_v1.Field(default=None)
public: bool = pydantic_v1.Field()
"""
Public traces are accessible via url without login
"""

environment: typing.Optional[str] = pydantic_v1.Field(default=None)
environment: str = pydantic_v1.Field()
"""
The environment from which this trace originated. Can be any lowercase alphanumeric string with hyphens and underscores that does not start with 'langfuse'.
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed tags, public, and environment from optional to required without defaults. API responses missing these fields will fail validation.

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/trace.py
Line: 63:76

Comment:
**logic:** Changed `tags`, `public`, and `environment` from optional to required without defaults. API responses missing these fields will fail validation.

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +35 to +38
metadata: typing.Any
config_id: typing.Optional[str] = pydantic_v1.Field(alias="configId", default=None)
queue_id: typing.Optional[str] = pydantic_v1.Field(alias="queueId", default=None)
environment: typing.Optional[str] = None
environment: str
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Changed metadata from Optional[typing.Any] = None to required typing.Any without default, and environment from Optional[str] = None to required str without default. This pattern is repeated in all three Score variants (Numeric, Categorical, Boolean). API responses missing these fields will fail validation.

Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/resources/commons/types/score.py
Line: 35:38

Comment:
**logic:** Changed `metadata` from `Optional[typing.Any] = None` to required `typing.Any` without default, and `environment` from `Optional[str] = None` to required `str` without default. This pattern is repeated in all three Score variants (Numeric, Categorical, Boolean). API responses missing these fields will fail validation.

How can I resolve this? If you propose a fix, please make it concise.

@Steffen911 Steffen911 requested a review from hassiebp January 7, 2026 14:07
@hassiebp hassiebp merged commit c7b6e12 into main Jan 8, 2026
12 checks passed
@hassiebp hassiebp deleted the api-spec-bot-41f064c branch January 8, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants