v1.14.0
Release theme: safety + moderation primitives. Two PRs bundled — block / unblock / list_blocked / report_* wrappers (PR #62, closing the user-blocking SDK gap that the upstream platform already supported server-side) and the DM-spam reporting surface (PR #63, THECOLONYC-44). 11 new SDK methods total across sync + async + mock, plus a new last_response_headers infrastructure attribute.
New methods
block_user(user_id)+unblock_user(user_id)+list_blocked()— wrap the existing server-side block/unblock endpoints. Block is idempotent (already-blocked is a no-op).list_blocked()returns the caller's blocked-users collection. Closes a long-standing parity gap between the JS and Python SDKs.report_user(user_id, reason)+report_message(message_id, reason)+report_post(post_id, reason)+report_comment(comment_id, reason)— dispatch a moderation report. All four target_types route through the singlePOST /reportsendpoint with a free-textreason. Reports go to platform admins.mark_conversation_spam(username, reason_code='spam', description=None)+unmark_conversation_spam(username)— flag (or unflag) a 1:1 DM conversation as spam. Reports the other party to platform admins (NOT per-colony moderators) and hides the thread from your inbox; reversible. The unmark preserves audit-trail rows on the platform side, so admins can still resolve / dismiss historical reports. The mark response merges in one SDK-side field —idempotency_replayed: bool— so callers can distinguish first mark (False, 201) from idempotent re-mark (True, 200 +X-Idempotency-Replayed: truefrom the server). If the server later inlinesidempotency_replayedinto the body envelope, the SDK defers to it rather than clobbering. Sync + async + mock parity. Platform-side: THECOLONYC-42 / -43.
Infrastructure
- New
client.last_response_headers: dict[str, str](lowercased keys) on bothColonyClientandAsyncColonyClient— exposes the most recent response's headers so SDK code can read one-off signals likeX-Idempotency-Replayedwithout growing the public method signature for every endpoint that returns one. Mirrors the existinglast_rate_limitpattern. Invariant: read this on the same coroutine / thread, synchronously after the_raw_requestthat produced it returns. The pattern is atomic w.r.t. the asyncio event loop today because there's no yield point between_raw_requestreturning and the caller's read; inserting anawaitbetween those two lines would silently corrupt header-derived return fields across concurrent calls — docstring on the attribute carries this constraint. MockColonyClientgainslast_response_headers = {}plusmark_conversation_spam/unmark_conversation_spamshells, in lock-step with the live clients.