feat(api): update API spec from langfuse/langfuse 51cf9d9#1763
Conversation
|
@claude review |
There was a problem hiding this comment.
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.
Greptile Summary
This is a Fern-generated API spec update that adds a new
dashboardsmodule to the unstable SDK, enabling full CRUD for dashboards and their placements, and refines the existingdashboard_widgetsAPI.dashboardsmodule: addsDashboardsClient/AsyncDashboardsClientand their raw counterparts, supportinglist,create,get,update,deletefor dashboards andadd_placement,update_placement,delete_placementfor the 12-column grid-placement model.dashboard_widgetsupdates:descriptionandchart_configare now optional in create/update requests;min_versionis removed;DashboardWidget.viewnow usesDashboardWidgetViewWithLegacyto accommodate legacytraceswidgets returned in list responses; alistendpoint andUpdateDashboardWidgetRequesttype are added.langfuse/api/unstable/__init__.pycorrectly exports all new types inTYPE_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%%{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: DashboardPlacementPrompt To Fix All With AI
Reviews (1): Last reviewed commit: "feat(api): update API spec from langfuse..." | Re-trigger Greptile
Context used:
Learned From
langfuse/langfuse-python#1387