feat(api): update API spec from langfuse/langfuse 5633a79#1762
feat(api): update API spec from langfuse/langfuse 5633a79#1762langfuse-bot wants to merge 1 commit into
Conversation
|
@claude review |
| if _response.status_code == 400: | ||
| raise Error( | ||
| headers=dict(_response.headers), | ||
| body=typing.cast( | ||
| typing.Any, | ||
| parse_obj_as( | ||
| type_=typing.Any, # type: ignore | ||
| object_=_response.json(), | ||
| ), | ||
| ), | ||
| ) | ||
| if _response.status_code == 401: | ||
| raise commons_errors_unauthorized_error_UnauthorizedError( | ||
| headers=dict(_response.headers), | ||
| body=typing.cast( | ||
| typing.Any, | ||
| parse_obj_as( | ||
| type_=typing.Any, # type: ignore | ||
| object_=_response.json(), | ||
| ), | ||
| ), | ||
| ) | ||
| if _response.status_code == 403: | ||
| raise commons_errors_access_denied_error_AccessDeniedError( | ||
| headers=dict(_response.headers), | ||
| body=typing.cast( | ||
| typing.Any, | ||
| parse_obj_as( | ||
| type_=typing.Any, # type: ignore | ||
| object_=_response.json(), | ||
| ), | ||
| ), | ||
| ) | ||
| if _response.status_code == 405: | ||
| raise commons_errors_method_not_allowed_error_MethodNotAllowedError( | ||
| headers=dict(_response.headers), | ||
| body=typing.cast( | ||
| typing.Any, | ||
| parse_obj_as( | ||
| type_=typing.Any, # type: ignore | ||
| object_=_response.json(), | ||
| ), | ||
| ), | ||
| ) |
There was a problem hiding this comment.
Dead code: duplicate status code handlers (400/401/403/405)
Each handler method in both dashboards/raw_client.py and dashboard_widgets/raw_client.py checks status codes 400, 401, 403, and 405 twice in sequence. Since the first matching if block raises immediately, the second group of handlers for those same codes (using the commons_errors exception types) is permanently unreachable. Only the 404 NotFoundError from the second group is reachable (because 404 isn't present in the first group). This pattern repeats across all ~16 handler methods in the new dashboards/raw_client.py and continues into the modified dashboard_widgets/raw_client.py. Since this is Fern-generated code the fix belongs upstream in the API generator template, but it is worth tracking.
Prompt To Fix With AI
This is a comment left during a code review.
Path: langfuse/api/unstable/dashboards/raw_client.py
Line: 171-214
Comment:
**Dead code: duplicate status code handlers (400/401/403/405)**
Each handler method in both `dashboards/raw_client.py` and `dashboard_widgets/raw_client.py` checks status codes 400, 401, 403, and 405 twice in sequence. Since the first matching `if` block raises immediately, the second group of handlers for those same codes (using the `commons_errors` exception types) is permanently unreachable. Only the 404 `NotFoundError` from the second group is reachable (because 404 isn't present in the first group). This pattern repeats across all ~16 handler methods in the new `dashboards/raw_client.py` and continues into the modified `dashboard_widgets/raw_client.py`. Since this is Fern-generated code the fix belongs upstream in the API generator template, but it is worth tracking.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
LGTM — this is an auto-generated Fern SDK update mirroring an upstream API spec change (dashboards/dashboard-widgets endpoints), consistent with the recurring "update API spec" PRs already merged in this repo's history.
Extended reasoning...
Overview
This PR is entirely auto-generated (Fern) client code regenerated from an updated langfuse/langfuse API spec. It adds a new dashboards resource (list/create/get/update/delete + placement management) and extends dashboard_widgets with list/get/update/delete, plus a new DashboardWidgetChartConfigInput type that makes chartConfig/description optional on create and removes the `minVersion" field from responses. All files carry the "This file was auto-generated by Fern from our API Definition" header, and the diff follows the exact repetitive raw_client/client/types scaffolding pattern seen in prior merged PRs in this repo's history (e.g. 9593d37, 2f3d7c0).
Security risks
None identified. This is typed request/response plumbing over httpx with no auth, crypto, or permission logic — it only shapes HTTP calls and pydantic models for a REST API client.
Level of scrutiny
Low-to-mechanical. This class of PR (spec-driven SDK regeneration) is generated by tooling, not hand-written, and this repo has a track record of merging these without incident. The bug hunting system found no issues, and the two candidate issues it investigated (missing camelCase aliases on the new input type, and DashboardDefinition reusing the placement output type for create/update input) were both ruled out as non-issues.
Other factors
The change is additive (new dashboards module, new optional fields) and one field removal (widget response no longer includes minVersion) that mirrors the corresponding server-side API contract change — since this is a generated client mirroring the server spec, there's no drift risk to reconcile. No hand-written logic changes are present that would benefit from deeper human review.
Greptile Summary
This PR syncs Fern-generated Python API bindings from the langfuse/langfuse upstream (commit 5633a79), adding a new
dashboardsmodule and expanding the existingdashboard_widgetsmodule with list/get/update/delete operations.dashboardsmodule (raw_client.py,client.py, 13 type files): covers full CRUD for dashboards and their placements (widget tiles and preset tiles), using a discriminated union forDashboardPlacement.dashboard_widgetsmodule: addslist,get,update,deletemethods; new typesDashboardWidgetChartConfigInput,DashboardWidgetList,DeleteDashboardWidgetResponse,UpdateDashboardWidgetRequest; switches the create endpoint to acceptDashboardWidgetChartConfigInputinstead ofDashboardWidgetChartConfig.__init__.pyupdates: all new and changed types are re-exported under theTYPE_CHECKINGguard, consistent with existing patterns.Confidence Score: 4/5
Safe to merge. This is entirely Fern-generated code syncing new dashboard and dashboard-placement API endpoints; no handwritten logic is changed.
The only finding is dead code in the generated error-handler chains: status codes 400/401/403/405 are matched by an unstable_errors block first, so the subsequent commons_errors fallback for those same codes is never reached. This is a code-generator artifact present in existing files too; it does not alter runtime behaviour for callers.
langfuse/api/unstable/dashboards/raw_client.py and langfuse/api/unstable/dashboard_widgets/raw_client.py contain the duplicate error-handler blocks worth tracking upstream in the Fern template.
Sequence Diagram
%%{init: {'theme': 'neutral'}}%% sequenceDiagram participant Caller participant DashboardsClient participant RawDashboardsClient participant HTTPClient participant LangfuseAPI Caller->>DashboardsClient: list(page, limit) DashboardsClient->>RawDashboardsClient: list(page, limit) RawDashboardsClient->>HTTPClient: GET /api/public/unstable/dashboards HTTPClient->>LangfuseAPI: HTTP Request LangfuseAPI-->>HTTPClient: 200 DashboardList / 4xx Error HTTPClient-->>RawDashboardsClient: _response RawDashboardsClient-->>DashboardsClient: HttpResponse[DashboardList] DashboardsClient-->>Caller: DashboardList Caller->>DashboardsClient: create(name, definition) DashboardsClient->>RawDashboardsClient: create(name, definition) RawDashboardsClient->>HTTPClient: POST /api/public/unstable/dashboards HTTPClient->>LangfuseAPI: HTTP Request LangfuseAPI-->>HTTPClient: 201 Dashboard / 4xx Error HTTPClient-->>RawDashboardsClient: _response RawDashboardsClient-->>DashboardsClient: HttpResponse[Dashboard] DashboardsClient-->>Caller: Dashboard Caller->>DashboardsClient: create_placement(dashboard_id, ...) DashboardsClient->>RawDashboardsClient: create_placement(...) RawDashboardsClient->>HTTPClient: "POST /api/public/unstable/dashboards/{id}/placements" HTTPClient->>LangfuseAPI: HTTP Request LangfuseAPI-->>HTTPClient: 201 DashboardPlacement / 4xx Error HTTPClient-->>RawDashboardsClient: _response RawDashboardsClient-->>DashboardsClient: HttpResponse[DashboardPlacement] DashboardsClient-->>Caller: 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 Caller participant DashboardsClient participant RawDashboardsClient participant HTTPClient participant LangfuseAPI Caller->>DashboardsClient: list(page, limit) DashboardsClient->>RawDashboardsClient: list(page, limit) RawDashboardsClient->>HTTPClient: GET /api/public/unstable/dashboards HTTPClient->>LangfuseAPI: HTTP Request LangfuseAPI-->>HTTPClient: 200 DashboardList / 4xx Error HTTPClient-->>RawDashboardsClient: _response RawDashboardsClient-->>DashboardsClient: HttpResponse[DashboardList] DashboardsClient-->>Caller: DashboardList Caller->>DashboardsClient: create(name, definition) DashboardsClient->>RawDashboardsClient: create(name, definition) RawDashboardsClient->>HTTPClient: POST /api/public/unstable/dashboards HTTPClient->>LangfuseAPI: HTTP Request LangfuseAPI-->>HTTPClient: 201 Dashboard / 4xx Error HTTPClient-->>RawDashboardsClient: _response RawDashboardsClient-->>DashboardsClient: HttpResponse[Dashboard] DashboardsClient-->>Caller: Dashboard Caller->>DashboardsClient: create_placement(dashboard_id, ...) DashboardsClient->>RawDashboardsClient: create_placement(...) RawDashboardsClient->>HTTPClient: "POST /api/public/unstable/dashboards/{id}/placements" HTTPClient->>LangfuseAPI: HTTP Request LangfuseAPI-->>HTTPClient: 201 DashboardPlacement / 4xx Error HTTPClient-->>RawDashboardsClient: _response RawDashboardsClient-->>DashboardsClient: HttpResponse[DashboardPlacement] DashboardsClient-->>Caller: DashboardPlacementPrompt To Fix All With AI
Reviews (1): Last reviewed commit: "feat(api): update API spec from langfuse..." | Re-trigger Greptile