Skip to content

feat(api): update API spec from langfuse/langfuse f73fd25#1735

Closed
langfuse-bot wants to merge 1 commit into
mainfrom
api-spec-bot-f73fd25
Closed

feat(api): update API spec from langfuse/langfuse f73fd25#1735
langfuse-bot wants to merge 1 commit into
mainfrom
api-spec-bot-f73fd25

Conversation

@langfuse-bot

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

Copy link
Copy Markdown
Collaborator

Greptile Summary

This PR is an automated API spec sync from langfuse/langfuse@f73fd25, adding a new dashboard_widgets subpackage under the unstable API surface and updating the blob storage integration with a new RUNNING sync status and a documentation refinement for export_start_date.

  • New dashboard_widgets API: Adds DashboardWidgetsClient (sync + async) and a full set of supporting types (DashboardWidget, DashboardWidgetChartConfig, chart type/view/metric enums, etc.) for creating reusable dashboard widgets via POST /api/public/unstable/dashboard-widgets.
  • BlobStorageSyncStatus update: Introduces a RUNNING enum value and clarifies the idle state description; all visit() dispatch methods are updated accordingly.
  • Documentation update: Adds a constraint note (Must not be in the future, 27 h tolerance) to export_start_date across all four client files.

Confidence Score: 4/5

Safe to merge for most callers — the new dashboard_widgets endpoint works correctly for success paths; only the error-handling branch for certain HTTP error codes is affected by the dead-code duplication.

The raw_client error-dispatch blocks for 400, 401, 403, and 405 are duplicated, meaning the commons_errors_* variants of those handlers and the different body types they would raise are silently swallowed. Any caller that catches commons_errors_unauthorized_error_UnauthorizedError or Error for these codes will never see them — they will always get the unstable_errors_* types instead. The happy path and the 404/429/500 handlers are unaffected.

langfuse/api/unstable/dashboard_widgets/raw_client.py — both the sync and async create() methods contain unreachable error handlers that may hide the intended error types for HTTP 400/401/403/405 responses.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Caller
    participant DashboardWidgetsClient
    participant RawDashboardWidgetsClient
    participant LangfuseAPI as Langfuse API

    Caller->>DashboardWidgetsClient: create(name, view, dimensions, metrics, filters, chart_type, chart_config)
    DashboardWidgetsClient->>RawDashboardWidgetsClient: create(...)
    RawDashboardWidgetsClient->>LangfuseAPI: POST /api/public/unstable/dashboard-widgets
    LangfuseAPI-->>RawDashboardWidgetsClient: 200 DashboardWidget / 4xx/5xx error
    alt 200 OK
        RawDashboardWidgetsClient-->>DashboardWidgetsClient: HttpResponse[DashboardWidget]
        DashboardWidgetsClient-->>Caller: DashboardWidget
    else 400/401/403/405 (first handler fires, second block unreachable)
        RawDashboardWidgetsClient-->>Caller: "raise unstable_errors_* error"
    else 404 NotFoundError
        RawDashboardWidgetsClient-->>Caller: raise NotFoundError
    else 429/500
        RawDashboardWidgetsClient-->>Caller: raise TooManyRequestsError / InternalServerError
    end
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 Caller
    participant DashboardWidgetsClient
    participant RawDashboardWidgetsClient
    participant LangfuseAPI as Langfuse API

    Caller->>DashboardWidgetsClient: create(name, view, dimensions, metrics, filters, chart_type, chart_config)
    DashboardWidgetsClient->>RawDashboardWidgetsClient: create(...)
    RawDashboardWidgetsClient->>LangfuseAPI: POST /api/public/unstable/dashboard-widgets
    LangfuseAPI-->>RawDashboardWidgetsClient: 200 DashboardWidget / 4xx/5xx error
    alt 200 OK
        RawDashboardWidgetsClient-->>DashboardWidgetsClient: HttpResponse[DashboardWidget]
        DashboardWidgetsClient-->>Caller: DashboardWidget
    else 400/401/403/405 (first handler fires, second block unreachable)
        RawDashboardWidgetsClient-->>Caller: "raise unstable_errors_* error"
    else 404 NotFoundError
        RawDashboardWidgetsClient-->>Caller: raise NotFoundError
    else 429/500
        RawDashboardWidgetsClient-->>Caller: raise TooManyRequestsError / InternalServerError
    end
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/dashboard_widgets/raw_client.py:843-897
**Unreachable duplicate error handlers for 400/401/403/405**

Status codes 400, 401, 403, and 405 are already handled in the first `if` block (lines 777–820) with `raise` statements, so the identical checks at lines 843–876 (using `commons_errors_*` types) will never execute — the first matching handler has already raised before this block is reached. Only the 404 → `NotFoundError` handler at the end is reachable from this second block. The unreachable handlers also use different error types (`Error`, `commons_errors_unauthorized_error_UnauthorizedError`, etc.) than the first block, so if the intent was to raise those types, they are effectively silenced. The same pattern is duplicated in `AsyncRawDashboardWidgetsClient.create` (lines ~1077–1131).

### Issue 2 of 2
langfuse/api/unstable/client.py:225-229
**Import placed inside a property method**

The `from .dashboard_widgets.client import DashboardWidgetsClient` import is placed inside the `dashboard_widgets` property body rather than at the top of the module. This violates the project's rule to keep imports at module scope. The same pattern is also present in the `async` variant's `dashboard_widgets` property (lines ~250–254). The existing `evaluation_rules` and `evaluators` lazy-load properties follow the same convention, so this is a continuation of an existing pattern, but it still conflicts with the team's stated rule.

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

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 nimarb July 3, 2026 14:22
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

@claude review

@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.

Auto-generated Fern SDK update: new dashboard_widgets unstable subclient, added RUNNING sync-status variant, and docstring tweaks — mechanical and safe.

Extended reasoning...

Overview

This PR is a Fern-generated SDK update mirroring the upstream langfuse/langfuse spec at f73fd25. It's entirely under langfuse/api/ (auto-generated code). Two functional additions: (1) a new RUNNING variant on BlobStorageSyncStatus with the corresponding visit() callable added, and (2) a new unstable/dashboard_widgets subclient exposing a single create endpoint plus supporting types/enums. The rest are docstring clarifications for export_start_date.

Security risks

None. This is API client scaffolding — no auth logic, no crypto, no user-input parsing beyond pydantic validation of the same shapes upstream defines. New endpoint requires the existing auth chain used by other unstable endpoints.

Level of scrutiny

Low. All files carry the Fern auto-generated banner and follow the exact patterns already present in sibling subclients (evaluators, evaluation_rules). The RUNNING enum addition is additive and the visit() update correctly threads the new callable through in the right position matching enum declaration order. Dashboard widget types are straightforward pydantic models with proper field aliases.

Other factors

No bugs were surfaced by the bug hunter. No CODEOWNER-sensitive paths touched — this is the standard periodic SDK-regeneration PR pattern for this repo. The visit() signature change on BlobStorageSyncStatus is technically a breaking change for any caller that passes positional callables, but this is auto-generated from the upstream spec and consistent with how the SDK maintainer handles enum evolution.

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.

1 participant