Skip to content

feat(local-session): HTTP API to start, upload to and stop a local session - #10

Open
Rahulkaushik01 wants to merge 1 commit into
feat/local-session-ingest-and-lifecyclefrom
feat/local-session-api
Open

feat(local-session): HTTP API to start, upload to and stop a local session#10
Rahulkaushik01 wants to merge 1 commit into
feat/local-session-ingest-and-lifecyclefrom
feat/local-session-api

Conversation

@Rahulkaushik01

Copy link
Copy Markdown
Collaborator

Stacked PR 3 of 4 — base feat/local-session-ingest-and-lifecycle. Merge PRs 1–2 first.

Summary

The HTTP surface the desktop talks to: start a session, upload audio chunks, stop, and read
the transcript.

Problem

The desktop must stay dumb — capture and upload only. If it performed segmentation or
transcription locally we would have to ship and maintain that logic across Windows, macOS and
Linux, and hold STT credentials on the client. All intelligence belongs server-side, reusing
the pipeline meeting bots already use.

How it works

  • start creates the Bot, Recording and the mic/system participants, and configures an
    audio-only MP3 recording transcribed by ElevenLabs with an optional language_code.
    Speaker labels are optional: a single-mic in-person recording has nothing to distinguish,
    so it sends no name and gets no label; an online meeting labels the mic "You" and the system
    track "Others", which yields "me vs them" attribution for free — no diarization service needed.
  • audio accepts short PCM segments tagged with source, a monotonic sequence and
    offset_ms. It validates strictly — source, sample rate, non-negative integers, even byte
    length, and a size cap — because a malformed upload would otherwise raise deep inside the VAD.
    Chunks are queued and drained off-request, so the desktop never blocks on transcription.
  • stop finalizes the session; transcript reuses the existing bot transcript view unchanged.

Changes made

File Lines Purpose
bots/local_session_api_views.py +191 start / audio / stop endpoints
bots/local_session_api_urls.py +28 routes
attendee/urls.py +1 include the new routes

Total: +220 / −0 (220 changed lines), 1 commit.

Testing performed

  • ruff checkAll checks passed; ruff format --checkclean
  • python manage.py checkno issues
  • 33/33 end-to-end checks through the live pipeline:
    • start → 201, local_ id prefix, state READY, type LOCAL, language_code forwarded,
      2 participants created, recording IN_PROGRESS
    • 5 validation failures → 400 (bad source, bad sample rate, negative ints, odd byte
      length, missing audio) and oversize → 413
    • 3 cross-project isolation checks → 404
    • chunk uploads → 202, and a replayed chunk is dropped
    • real-audio lifecycle → ENDED, transcript contains text
    • mic labelled "You", system labelled "Others"; blank-name case yields no label
    • idempotent double-stop
    • delete_dataDATA_DELETED, utterances removed

Coding-guidelines compliance

  • File size (§2): largest new file 191 lines (≤ 250 preferred). No file in this PR exceeds
    any limit.
  • Functions (§6): ⚠️ LocalSessionAudioView.post is 54 lines (over the 50 guidance) because
    of exhaustive request validation. Recommend extracting the validation block in a follow-up.
  • Constants (§5): SUPPORTED_SAMPLE_RATES, MAX_SEGMENT_BYTES, LOCAL_SESSION_MEETING_URL,
    participant UUID/name constants — no magic values.
  • Error handling (§12): every failure returns an explicit, user-readable message with the
    correct status code; nothing fails silently.
  • Validation / permissions (§10): validation and cross-project isolation are covered by tests.
  • Security (§8): no secrets; authentication reuses the existing project API-key class.
  • No dead code / debug logs / unused imports (§15).

Risks / notes

  • Endpoints are authenticated by project API key only in this PR; per-user ownership arrives
    in PR 4. No production clients exist yet, so there is no real exposure window — but PR 4 should
    land before release.
  • Bot.meeting_url is non-nullable, so a local session carries the sentinel "local_recording",
    exactly as app sessions use "app_session".

…ssion

The desktop is deliberately dumb: it captures audio and uploads it, and the
server does all the segmentation and transcription.

* start creates the Bot, Recording and the mic/system participants. Speaker
  labels are optional -- a single-mic in-person recording has nothing to
  distinguish, so it sends no name and gets no label, while an online meeting
  labels the mic "You" and the system track "Others".
* audio accepts short PCM segments tagged with a monotonic sequence and an
  offset_ms measured from the start of the session. Uploads are queued and
  drained off-request so the desktop never waits on transcription.
* stop finalizes the session; transcript reuses the bot transcript view.

Co-Authored-By: Claude <noreply@anthropic.com>
@Rahulkaushik01
Rahulkaushik01 requested a review from hd1801 July 20, 2026 07:05
@Rahulkaushik01 Rahulkaushik01 self-assigned this Jul 20, 2026
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