Metadata-Version: 2.5
Name: circle-so-cli
Version: 0.4.0
Summary: CLI toolkit for managing Circle.so communities at scale
Project-URL: Homepage, https://github.com/boiyelove/circle-so
Project-URL: Repository, https://github.com/boiyelove/circle-so
Project-URL: Issues, https://github.com/boiyelove/circle-so/issues
Project-URL: Changelog, https://github.com/boiyelove/circle-so/blob/main/docs/ROADMAP.md
Project-URL: SDK, https://pypi.org/project/circle-so-python-sdk/
Author: Damilola Afolabi
License-Expression: MIT
License-File: LICENSE
Keywords: bulk-operations,circle,circle-admin,circle-api,circle-so,circle.so,cli,community,community-management,management,member-management
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Systems Administration
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: circle-so-python-sdk>=0.1.5
Requires-Dist: click>=8.0
Requires-Dist: python-dotenv>=1.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Description-Content-Type: text/markdown

# circle-so

CLI toolkit for managing Circle.so communities at scale.

Built on top of [circle-so-python-sdk](https://github.com/boiyelove/circle-so-python-sdk).

## Installation

```bash
pip install circle-so
```

## Quick Start

```bash
export CIRCLE_API_TOKEN="your_token"

# Spaces
circle-so spaces list --prefix kcna
circle-so spaces search "KCNA 048"
circle-so spaces lock --prefix kcna
circle-so spaces rename 1761784 --name "KCNA 072" --slug "kcna-072"

# Members
circle-so members import learners.csv
circle-so members audit --prefix kcna --cache
circle-so members add learners.csv --space "KCNA 048"
circle-so members fix-missing --dry-run
circle-so members move --from "KCNA 046" --to "KCNA 073" --max 100

# Moderators
circle-so moderators verify moderators.csv
circle-so moderators add moderators.csv

# Reports
circle-so report counts --prefix kcna
circle-so report inactive
circle-so report missing
circle-so report export moves

# Posts and comments
circle-so posts create --space 1761803 --title "Hello" --body "World"
circle-so posts create --space 1761803 --title "Hello" --body-file post.txt
circle-so posts update 34771554 --title "New Title"
circle-so posts comment 34771554 "Nice post!"
circle-so posts comments 34771554
circle-so posts delete-comment 110399141

# Events (must target an event-type space -- see `events list` without --space)
circle-so events list
circle-so events list --space 2793409
circle-so events create --space 2793409 --name "Expert Session" --starts-at 2026-08-13T15:00:00Z --duration-minutes 60 --url https://meet.google.com/xxx-xxxx-xxx --host "Jane Doe" --cover-image flyer.png
circle-so events update 35393641 --space 2793409 --name "New Title" --cover-image flyer.png
circle-so events delete 35393641 --space 2793409
circle-so events rsvp 35393641 learner@example.com
circle-so events attendees 35393641
circle-so events unrsvp 35393641 learner@example.com
```

> **Note:** `events create --draft` is confirmed to work against the live API (the event is created and fetchable by id), but draft events never show up in `events list` -- Circle's `list_events` silently drops them regardless of any status filter. Track ids yourself if you need to find a draft again. See [circle-so-python-sdk's limitations doc](https://github.com/boiyelove/circle-so-python-sdk/blob/main/docs/limitations.md#events) for detail, including the endpoint coverage breakdown (every documented Admin V2 events route is implemented; recurring/paywall/attendee-invite fields work via generic passthrough with no typed validation).

```bash
# Member tags
circle-so tags list
circle-so tags create "KCNA Mentor 2026"
circle-so tags add 14357 mentor@example.com
circle-so tags members 14357
circle-so tags remove 14357 mentor@example.com
circle-so tags delete 14357

# Courses (sections, lessons, progress)
circle-so courses sections list --space 1379864
circle-so courses sections create --name "Module 1" --space 1379864
circle-so courses lessons list --section 324454
circle-so courses lessons create --name "Lesson 1" --section 324454
circle-so courses progress 1198265 learner@example.com --status completed

# Access groups (permission groups)
circle-so access-groups list
circle-so access-groups create "Program Assistants" --description "Assistant moderators"
circle-so access-groups add 1 assistant@example.com
circle-so access-groups members 1
circle-so access-groups member-groups 42

# Forms, segments, invites, leaderboard, flagged content, live rooms
circle-so misc forms-list
circle-so misc segments-list
circle-so misc segments-create --title "Active Mentors"
circle-so misc invites-list
circle-so misc leaderboard
circle-so misc flagged-list
circle-so misc flagged-report --content-id 123 --content-type post --reason spam
circle-so misc live-rooms-list
```

> **Note:** `tags members` fetches Circle's unfiltered global tagged-members feed and filters client-side using each record's own `member_tag_id` -- Circle's `member_tag_id` query parameter is silently ignored server-side (confirmed via direct API test). See [circle-so-python-sdk's limitations doc](https://github.com/boiyelove/circle-so-python-sdk/blob/main/docs/limitations.md#tags).

> **Note:** `misc leaderboard` requires Gamification to be enabled for the community -- it returns an `AuthenticationError` otherwise, even with a valid admin token. Not a bug in this CLI; verified against a real community.

> **Note:** Circle's comment API is plain-text only and strips all newlines with no replacement -- the SDK auto-flattens multi-line/markdown comment bodies into a single line so nothing gets jammed together. See [circle-so-python-sdk's limitations doc](https://github.com/boiyelove/circle-so-python-sdk/blob/main/docs/limitations.md#comments) for detail. There's also no comment-edit endpoint; use `delete-comment` + `comment` to "edit."

## Configuration

Set via environment variables or `.env` file:

```bash
CIRCLE_API_TOKEN=your_token
CIRCLE_COMMUNITY_URL=https://your-community.circle.so
CIRCLE_SO_DB=./circle-so.db
CIRCLE_SO_DATA_DIR=~/Documents/Example-Community-Data
```

### Token Types

Different commands require different tokens:

| Commands | Token needed | Source |
|----------|-------------|--------|
| `spaces`, `members`, `moderators`, `report`, `posts`, `events`, `tags`, `courses`, `access-groups`, `misc` | Admin API token | Circle Admin > Settings > API |
| `chat` (list, read, send, unread) | Headless Auth token | Circle Admin > Developers > Headless Auth |

The `chat` commands also require your Circle email via `--email` or `CIRCLE_USER_EMAIL`:

```bash
export CIRCLE_API_TOKEN="your_headless_token"
export CIRCLE_USER_EMAIL="you@example.com"

circle-so chat list
circle-so chat unread
circle-so chat read <uuid>
circle-so chat send <uuid> "Your message"
```

The headless token generates a short-lived Bearer access token for your account, giving access to your DMs, notifications, and posts as yourself.

## License

MIT
