Skip to content

feat(api): update API spec from langfuse/langfuse 51cf9d9#1763

Merged
LysanderKie merged 1 commit into
mainfrom
api-spec-bot-51cf9d9
Jul 16, 2026
Merged

feat(api): update API spec from langfuse/langfuse 51cf9d9#1763
LysanderKie merged 1 commit into
mainfrom
api-spec-bot-51cf9d9

Conversation

@langfuse-bot

@langfuse-bot langfuse-bot commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Greptile Summary

This is a Fern-generated API spec update that adds a new dashboards module to the unstable SDK, enabling full CRUD for dashboards and their placements, and refines the existing dashboard_widgets API.

  • New dashboards module: adds DashboardsClient / AsyncDashboardsClient and their raw counterparts, supporting list, create, get, update, delete for dashboards and add_placement, update_placement, delete_placement for the 12-column grid-placement model.
  • dashboard_widgets updates: description and chart_config are now optional in create/update requests; min_version is removed; DashboardWidget.view now uses DashboardWidgetViewWithLegacy to accommodate legacy traces widgets returned in list responses; a list endpoint and UpdateDashboardWidgetRequest type are added.
  • Registry updates: langfuse/api/unstable/__init__.py correctly exports all new types in TYPE_CHECKING, _dynamic_imports, and __all__.

Confidence Score: 4/5

Safe to merge; all changes are auto-generated from the API spec and follow existing conventions.

The new dashboards client and type definitions are well-structured and mirror the existing dashboard_widgets conventions exactly. The two flagged issues — lazy imports inside property methods and unreachable duplicate error handlers — are both inherited from the Fern code-generator and appear identically in pre-existing files. No correctness or data-integrity problems were found in the new code.

langfuse/api/unstable/dashboards/raw_client.py has unreachable commons error handlers for status codes 400/401/403/405 in every endpoint, matching the same pattern in the pre-existing dashboard_widgets/raw_client.py.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant DashboardsClient
    participant RawDashboardsClient
    participant LangfuseAPI

    User->>DashboardsClient: list(page, limit)
    DashboardsClient->>RawDashboardsClient: list(page, limit)
    RawDashboardsClient->>LangfuseAPI: GET /api/public/unstable/dashboards
    LangfuseAPI-->>RawDashboardsClient: HttpResponse[DashboardList]
    RawDashboardsClient-->>DashboardsClient: HttpResponse[DashboardList]
    DashboardsClient-->>User: DashboardList

    User->>DashboardsClient: create(name, description, definition, filters)
    DashboardsClient->>RawDashboardsClient: create(...)
    RawDashboardsClient->>LangfuseAPI: POST /api/public/unstable/dashboards
    LangfuseAPI-->>RawDashboardsClient: HttpResponse[Dashboard]
    RawDashboardsClient-->>DashboardsClient: HttpResponse[Dashboard]
    DashboardsClient-->>User: Dashboard

    User->>DashboardsClient: add_placement(dashboard_id, request)
    Note over request: CreateDashboardPlacementRequest_Widget or _Preset
    DashboardsClient->>RawDashboardsClient: add_placement(dashboard_id, request)
    RawDashboardsClient->>LangfuseAPI: "POST /api/public/unstable/dashboards/{id}/placements"
    LangfuseAPI-->>RawDashboardsClient: HttpResponse[DashboardPlacement]
    RawDashboardsClient-->>DashboardsClient: HttpResponse[DashboardPlacement]
    DashboardsClient-->>User: DashboardPlacement
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant DashboardsClient
    participant RawDashboardsClient
    participant LangfuseAPI

    User->>DashboardsClient: list(page, limit)
    DashboardsClient->>RawDashboardsClient: list(page, limit)
    RawDashboardsClient->>LangfuseAPI: GET /api/public/unstable/dashboards
    LangfuseAPI-->>RawDashboardsClient: HttpResponse[DashboardList]
    RawDashboardsClient-->>DashboardsClient: HttpResponse[DashboardList]
    DashboardsClient-->>User: DashboardList

    User->>DashboardsClient: create(name, description, definition, filters)
    DashboardsClient->>RawDashboardsClient: create(...)
    RawDashboardsClient->>LangfuseAPI: POST /api/public/unstable/dashboards
    LangfuseAPI-->>RawDashboardsClient: HttpResponse[Dashboard]
    RawDashboardsClient-->>DashboardsClient: HttpResponse[Dashboard]
    DashboardsClient-->>User: Dashboard

    User->>DashboardsClient: add_placement(dashboard_id, request)
    Note over request: CreateDashboardPlacementRequest_Widget or _Preset
    DashboardsClient->>RawDashboardsClient: add_placement(dashboard_id, request)
    RawDashboardsClient->>LangfuseAPI: "POST /api/public/unstable/dashboards/{id}/placements"
    LangfuseAPI-->>RawDashboardsClient: HttpResponse[DashboardPlacement]
    RawDashboardsClient-->>DashboardsClient: HttpResponse[DashboardPlacement]
    DashboardsClient-->>User: DashboardPlacement
Loading
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
langfuse/api/unstable/client.py:54-59
**Imports placed inside methods instead of module top**

The new `dashboards` properties in both `UnstableClient` and `AsyncUnstableClient` perform a runtime `from .dashboards.client import DashboardsClient` inside the property body. Per the project's coding rule, imports should be moved to the top of the module. Both existing sub-clients (`dashboard_widgets`, `evaluation_rules`, `evaluators`) follow the same lazy-import pattern in this file, so the same concern applies to those too — this PR adds two more occurrences of it.

### Issue 2 of 2
langfuse/api/unstable/dashboards/raw_client.py:177-230
**Duplicate status-code handlers are unreachable dead code**

Each endpoint in `RawDashboardsClient` (and `AsyncRawDashboardsClient`) checks `_response.status_code == 400`, `401`, `403`, and `405` twice: first raising an `unstable` error type, then raising the corresponding `commons` error type. Because the first matching `if` block raises an exception, the second block for those same codes is never evaluated. The `commons_errors_unauthorized_error_UnauthorizedError`, `commons_errors_access_denied_error_AccessDeniedError`, `commons_errors_method_not_allowed_error_MethodNotAllowedError`, and `Error` (for 400) handlers will never fire. The identical pattern already exists in `dashboard_widgets/raw_client.py`, so this appears to be a Fern code-generation artifact.

Reviews (1): Last reviewed commit: "feat(api): update API spec from langfuse..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Context used:

  • Rule used - Move imports to the top of the module instead of p... (source)

Learned From
langfuse/langfuse-python#1387

@langfuse-bot
langfuse-bot requested a review from LysanderKie July 16, 2026 11:33
@github-actions

Copy link
Copy Markdown

@claude review

Comment thread langfuse/api/unstable/dashboards/raw_client.py

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — auto-generated API client update, consistent with prior spec-sync PRs.

Extended reasoning...

Overview

This PR is a fully auto-generated update to the langfuse/api/unstable client, regenerated by Fern from an updated OpenAPI spec (langfuse/langfuse commit 51cf9d9). It adds a new dashboards resource (CRUD + placement management) and extends dashboard_widgets with list/get/update/delete endpoints, plus supporting pydantic models (DashboardWidgetChartConfigInput, DashboardWidgetViewWithLegacy, list/response wrapper types, etc.). No hand-written logic is introduced — every file carries the # This file was auto-generated by Fern header and follows the exact structural pattern of the existing generated client code (raw_client/client split, error-branch cascades, dynamic imports in __init__.py).

Security risks

None identified. This is a typed HTTP client wrapper around an already-existing public API surface; there's no new auth, crypto, or permission logic. Request/response bodies are serialized via the existing convert_and_respect_annotation_metadata/jsonable_encoder utilities used throughout the rest of the SDK.

Level of scrutiny

Low-to-moderate is appropriate: this is machine-generated SDK boilerplate mirroring a server-side API contract, still under an explicit unstable namespace with docstrings noting the surface may change. The repo's history shows a recurring pattern of these "update API spec" PRs being merged directly (e.g. commits 9593d37, dcad5d1) without deep hand review, since correctness is governed by the Fern codegen pipeline and the upstream OpenAPI spec rather than by logic written in this repo.

Other factors

The bug-hunting pass found no issues, and the few candidate concerns raised (mandatory vs. optional placement fields in DashboardDefinition, missing camelCase aliases on some widget chart config fields) were investigated and refuted — they reflect the OpenAPI spec's intentional shape (response models require full grid coordinates while create-request models allow server-generated defaults) rather than bugs in the generated code. No CODEOWNERS-restricted or hand-maintained logic is touched.

@LysanderKie
LysanderKie merged commit 25257a5 into main Jul 16, 2026
21 checks passed
@LysanderKie
LysanderKie deleted the api-spec-bot-51cf9d9 branch July 16, 2026 12:13
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.

2 participants