Skip to content

Add sign-in session and sign-in event methods - #2083

Merged
manuaero merged 1 commit into
developfrom
feat/sign-in-sessions
Oct 16, 2026
Merged

manuaero merged 1 commit into
developfrom
feat/sign-in-sessions

Conversation

@manuaero

@manuaero manuaero commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Description

Labelbox's Performance REST API now gives organization admins the sign-in history of their own members (Labelbox/intelligence#31588, #31590, live in production since 2026-10-15). This adds it to the SDK. No ticket.

# Sessions that started in a period (at most 31 days), oldest first
for s in client.get_sign_in_sessions("2026-10-15", "2026-10-21", user_group_ids=[group]):
    print(s.user_id, s.started_at, s.start_kind, s.status, s.ended_at, s.end_reason, s.end_derived)

# Sign-ins and sign-outs as a feed, for incremental pulls
events = client.get_sign_in_events("2026-10-15", "2026-10-21", types=["SIGN_OUT"], include_derived=False)
for e in events:
    print(e.type, e.occurred_at, e.end_reason)
print(events.complete_through)  # set once the feed has been read to the end

What's added:

  • Client.get_sign_in_sessions(start_date, end_date, user_ids=None, user_group_ids=None, status=None, page_size=100) and Client.get_sign_in_events(start_date, end_date, user_ids=None, user_group_ids=None, types=None, include_derived=True, page_size=100). Filters take IDs or SDK objects, and an empty list raises ValueError, like the existing performance methods.
  • Typed rows SignInSession and SignInEvent, and enums SignInSessionStatus, SignInStartKind, SignInEndReason, SignInEventType. Unknown fields are ignored. The docstrings say what a derived end (MAX_DURATION_REACHED, end_derived=True) means: the latest the session could last, not when the member stopped working. They also say that duration_seconds is not time worked.
  • Cursor paging: these endpoints page by an opaque cursor with no total. PerformanceCursorRows follows it as you iterate, requests nothing until then, and starts again on a second pass. SignInEventRows adds complete_through, taken from the last page.
  • Exported from labelbox and listed in the Sphinx performance.rst. The version and changelog are left to the Prep PR.

Readable only with the organization-wide permission to view all performance; only sessions started in the caller's organization are listed.

Checked against production

The branch's methods were run against production with a real API key (counts only):

  • 4,533 sessions of 3,315 members read across pages, in order, no duplicates; a second pass gives the same rows.
  • status open + ended add up to all; user_ids returns only that member.
  • 5,653 events, none after complete_through, which is None until read to the end; types=[SIGN_OUT], include_derived=False returns 1,143 recorded sign-outs and no derived ones.
  • An empty list raises ValueError before any request; a 40-day window raises InvalidQueryError naming endDate.

Tests

tests/unit/schema/test_performance.py: 154 tests pass, about 54 of them new. They cover:

  • parameter names, and that each parameter is sent only when given;
  • empty lists, and UserGroup objects;
  • enums and strings, with lower-case status;
  • includeDerived sent only when false;
  • cursor paging, laziness and a second pass;
  • complete_through;
  • derived and open sessions, a null email, and unknown fields;
  • 400 and 403 mapped to the SDK's exceptions.

The important tests were checked to fail without the change. ruff@0.8.4 format and check, and mypy, are clean.

Before opening, the change and its guide were reviewed against the API code by four independent reviewers, each finding checked by two more. The upheld findings (wording about the 84-hour maximum, durations, naive datetimes, and who is listed) are fixed, and the fixes were checked again.

The user guide is Labelbox/lbx-docs-mintlify#301, to merge once 7.15.0 is on PyPI. Release as 7.15.0 after this merges.

Type of change

  • New feature (non-breaking change which adds functionality)

All Submissions

  • Have you followed the guidelines in our Contributing document?
  • Have you provided a description?
  • Are your changes properly formatted?

New Feature Submissions

  • Does your submission pass tests?
  • Have you added thorough tests for your new feature?
  • Have you commented your code, particularly in hard-to-understand areas?
  • Have you added a Docstring?

Changes to Core Features

  • Have you written new tests for your core changes, as applicable?
  • Have you successfully run tests with your changes locally?

🤖 Generated with Claude Code

Client.get_sign_in_sessions and Client.get_sign_in_events read the
Performance API's /workspace/sign-in-sessions and /workspace/sign-in-events:
the sign-in history of the organization's own members, for callers with the
organization-wide permission to view all performance.

Both page by the API's opaque nextCursor, which has no total, through a new
PerformanceCursorRows. SignInEventRows adds complete_through, taken from the
last page once the feed has been read to the end. Rows are typed as
SignInSession and SignInEvent, with str enums for status, start kind, end
reason and event type. The status filter is sent in lower case, as the API
takes it; a session's own status is in capitals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@manuaero
manuaero requested a review from a team as a code owner October 15, 2026 23:58
@manuaero
manuaero merged commit eef2fac into develop Oct 16, 2026
41 of 44 checks passed
@manuaero
manuaero deleted the feat/sign-in-sessions branch October 16, 2026 18:12
@manuaero manuaero mentioned this pull request Oct 16, 2026

This branch was previously deployed

1 inactive deployment
Test-PyPI — 8e7b9dc5 Deployed Oct 15, 2026 by manuaero via test-pypi #2541
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