Skip to content

feat(notebooks): add create and update commands#62

Merged
platinummonkey merged 11 commits intodatadog-labs:mainfrom
jakedgy:feat/notebooks-create-update
Feb 14, 2026
Merged

feat(notebooks): add create and update commands#62
platinummonkey merged 11 commits intodatadog-labs:mainfrom
jakedgy:feat/notebooks-create-update

Conversation

@jakedgy
Copy link
Contributor

@jakedgy jakedgy commented Feb 14, 2026

Summary

Adds create and update subcommands to pup notebooks, completing the full CRUD surface for the Notebooks API. The primary goal is enabling agents (e.g., Claude Code) to programmatically create and update notebooks with investigation findings that can be attached to incident post-mortems.

Motivation

Notebooks are a natural fit for agent-assisted investigations — they combine graphs, logs, and narrative text. With create and update, an agent can:

  1. Create a notebook to document an ongoing investigation
  2. Append findings (markdown cells, graph widgets) as it works
  3. Hand off the notebook to a human for review or attach it to a post-mortem

Only list, get, and delete existed before this PR.

Design Decisions

JSON body via --body flag — Both commands accept --body @file.json (file) or --body - (stdin). This was chosen over individual flags (e.g., --title, --cell) because:

  • Notebooks have complex nested structure (cells with typed definitions, time ranges, etc.)
  • Agents construct JSON programmatically — a single JSON body is the most natural interface
  • It maps 1:1 to the Datadog API request types, avoiding abstraction mismatch

Full replacement for updatesupdate replaces the entire notebook body (PUT semantics), matching the Datadog API. The expected agent workflow is GET → modify → PUT.

No confirmation prompt on update — Updates are reversible (just update again), so no prompt. This keeps automation frictionless. delete retains its existing confirmation.

OAuth fallback to API keys — The Notebooks API is a V1 endpoint that does not support OAuth2. All five notebook commands use getClientForEndpoint() to automatically fall back to API key authentication. During testing we found that getClientForEndpoint was calling client.New (which prefers OAuth), causing 403s. This is fixed by adding a dedicated apiKeyClientFactory that calls client.NewWithAPIKeys to force API key auth for fallback endpoints.

Usage

# Create from file
pup notebooks create --body @notebook.json

# Create from stdin (agent pipes JSON)
cat notebook.json | pup notebooks create --body -

# Update (full replacement)
pup notebooks get 12345 -o json > notebook.json
# ... modify notebook.json ...
pup notebooks update 12345 --body @updated.json

# Delete
pup notebooks delete 12345

Changes

cmd/notebooks.go

  • Add readBody helper — parses @file / - stdin, validates JSON
  • Add create and update commands with --body flag (required)
  • Switch all five commands from getClient() to getClientForEndpoint() for V1 OAuth fallback
  • Switch all five commands to formatAPIError for consistent error handling
  • Switch list/get from fmt.Println to printOutput for testability
  • Switch delete from fmt.Scanln to readConfirmation() and fmt.Printf/Print to printOutput
  • Update help text: OAuth not supported, API keys required; add examples for create/update/delete

cmd/notebooks_test.go

  • 10 new tests: readBody (file, stdin, missing file, invalid JSON file, invalid JSON stdin, empty value), create command structure + body-required, update command structure + body-required
  • Updated subcommand registration test for all 5 commands

cmd/root.go

  • Add defaultAPIKeyClientFactory using client.NewWithAPIKeys and apiKeyClientFactory injection point
  • Fix getClientForEndpoint to use apiKeyClientFactory instead of clientFactory for endpoints without OAuth support

cmd/api_keys_test.go

  • Update setupTestClient to mock and restore apiKeyClientFactory alongside clientFactory

Testing

  • All new tests pass: go test ./cmd/ -run TestNotebooks -v and go test ./cmd/ -run TestReadBody -v
  • Full suite passes with race detection: go test -race ./...
  • readBody tested via table-driven tests covering file read, stdin read, missing file, and invalid JSON for both input methods
  • Verified notebook commands no longer 403 when using API key fallback

🤖 Generated with Claude Code

jakedgy and others added 7 commits February 13, 2026 21:52
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jakedgy jakedgy requested a review from a team as a code owner February 14, 2026 03:54
The Notebooks V1 API doesn't support OAuth authentication. Register
all notebook endpoints in the auth validator fallback registry and
switch all commands to use getClientForEndpoint() for automatic
API key fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jakedgy jakedgy marked this pull request as draft February 14, 2026 04:07
getClientForEndpoint was calling client.New which prefers OAuth over
API keys, causing 403s on endpoints without OAuth support. Add an
apiKeyClientFactory injection point that uses NewWithAPIKeys to force
API key auth for fallback endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jakedgy jakedgy marked this pull request as ready for review February 14, 2026 04:12
jakedgy and others added 2 commits February 13, 2026 22:17
- Switch list/get from fmt.Println to printOutput for testability
- Switch delete from fmt.Scanln to readConfirmation (uses inputReader)
- Switch delete from fmt.Printf/Print to printOutput
- Update auth description: OAuth not supported, API keys required
- Simplify BodyRequired test to use ValidateRequiredFlags directly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace inline error formatting with formatAPIError for richer
  user-facing error messages (status-specific hints for 401, 403, etc.)
- Add create, update, and delete examples to long description
- Add TestNotebooksUpdateCmd_BodyRequired for symmetry with create

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@platinummonkey
Copy link
Collaborator

platinummonkey commented Feb 14, 2026

Thanks! The CI error is a configuration error on my end, will take care of this when I'm at my desk

@jakedgy
Copy link
Contributor Author

jakedgy commented Feb 14, 2026

Thanks! The CI error is a configuration error on my end, will take care of this when I'm at my desk

No worries! These commands are pretty narrowly focused for agents. I don't think that end users will care too much about editing a notebook with the CLI.

I tried it with an investigation using Pup and capturing findings in a notebook, and it was chef kiss.

@platinummonkey
Copy link
Collaborator

platinummonkey commented Feb 14, 2026

okay main should have a fix for this in general, I've tested this and looks great, going to merge it!

@platinummonkey platinummonkey merged commit 9357896 into datadog-labs:main Feb 14, 2026
10 of 13 checks passed
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.

2 participants

Comments