Skip to content

Add org description (org_info) support to SDK and CLI#320

Merged
maximelb merged 2 commits into
masterfrom
org-set-description
Jul 23, 2026
Merged

Add org description (org_info) support to SDK and CLI#320
maximelb merged 2 commits into
masterfrom
org-set-description

Conversation

@maximelb

Copy link
Copy Markdown
Contributor

Summary

Answers a support question: how to set an organization's description (org info) via the Python SDK.

The description is only exposed by the backend as an optional side-effect of the org rename endpoint (POST /v1/orgs/{oid}/name), which requires a non-empty name. Previously there was no way to set it from the SDK/CLI — Organization.rename() dropped the description param and there was no dedicated helper.

Changes

  • Organization.rename(new_name, description=None) — optionally forwards a description to the rename endpoint.
  • Organization.set_description(description) — reads the org's current name via get_info() and re-submits it unchanged, so only the description is updated. This is the ergonomic "just set the description on an existing org" call.
  • CLI:
    • limacharlie org rename --name ... --description ...
    • new limacharlie org set-description --description ...
  • Unit tests (rename with/without description, set_description reuse-name + missing-name error) and CHANGELOG entry.

Notes

  • These are thin, honest wrappers over POST /v1/orgs/{oid}/name (perm billing.ctrl, rate-limited 3/hour server-side).
  • The backend skips an empty description and treats the description write as best-effort, so this does not add clear-description semantics the server doesn't support.
  • Read the value back via Organization.get_info()["desc"].

🤖 Generated with Claude Code

The organization description ("org info") is only exposed by the backend as
an optional side-effect of the org rename endpoint (POST /v1/orgs/{oid}/name),
which requires a non-empty name. There was no way to set it from the Python
SDK/CLI: Organization.rename() dropped the description and there was no
dedicated helper.

- Organization.rename(new_name, description=None): optionally forwards a
  description to the rename endpoint.
- Organization.set_description(description): reads the org's current name and
  re-submits it unchanged so only the description is updated.
- CLI: `limacharlie org rename --description ...` and new
  `limacharlie org set-description --description ...`.
- Unit tests + CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SM95Gx4iwyHN4Yf8HaVmKU
lcbill
lcbill previously approved these changes Jul 23, 2026
@maximelb

Copy link
Copy Markdown
Contributor Author

Auto code review

No blocking issues found. Two independent bug/correctness passes plus manual verification confirmed: ApiError resolves, get_info().get(\"name\") matches the backend GET /orgs/{oid} schema, query_params shape is accepted, CLI callbacks wire correctly (verified end-to-end with a mocked org), no regression to existing rename callers, and all tests pass (266 unit tests, none skipped).

Two non-blocking notes — both inherent to reusing the rate-limited rename endpoint (the backend only exposes the description as a side-effect of rename), not defects in this code:

  1. set_description() reads the current name then re-submits it, so a concurrent rename in the (3/hour rate-limited) window between the two calls could be reverted. Acceptable given the backend contract; documented behavior.

Returns:
dict: API response.
"""
current_name = self.get_info().get("name")
if not current_name:
from ..errors import ApiError
raise ApiError("could not resolve current organization name to set description")
return self.rename(current_name, description=description)

  1. An empty --description / set_description(\"\") is a silent server-side no-op (the backend skips empty descriptions), so it cannot clear a description and the CLI reports success without warning. Matches the documented backend contract.

register_explain("org.set-description", _EXPLAIN_SET_DESCRIPTION)
@group.command("set-description")
@click.option("--description", required=True, help="New description (org info) for the organization.")
@pass_context
def set_description(ctx: click.Context, description: str) -> None:
org = _get_org(ctx)

The lazy-loading regression test pins the exact subcommand set for each
group; the new `org set-description` command must be added to EXPECTED_SUBCOMMANDS
or test_subcommands_match[org] fails.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SM95Gx4iwyHN4Yf8HaVmKU
@maximelb
maximelb requested a review from a team July 23, 2026 18:06
@maximelb
maximelb merged commit f36c5ba into master Jul 23, 2026
6 checks passed
@maximelb
maximelb deleted the org-set-description branch July 23, 2026 18:14
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