ctfy.sdk.admin_resources.announcements
client.admin.announcements — platform announcement CRUD (admin).
1"""``client.admin.announcements`` — platform announcement CRUD (admin).""" 2 3from __future__ import annotations 4 5import builtins 6from datetime import datetime 7from typing import Any 8 9from ctfy.sdk._helpers import _raise_for_status 10from ctfy.sdk.base import BaseHttpClient 11from ctfy.server.models import AnnouncementInfo 12 13 14class AdminAnnouncementsResource: 15 """Post / edit / delete platform-wide announcements.""" 16 17 def __init__(self, http: BaseHttpClient) -> None: 18 self._http = http 19 20 def list(self, offset: int = 0, limit: int = 50) -> builtins.list[AnnouncementInfo]: 21 """Every announcement (active + scheduled + expired).""" 22 resp = self._http.request( 23 "GET", "/admin/announcements", params={"offset": offset, "limit": limit} 24 ) 25 _raise_for_status(resp) 26 return [AnnouncementInfo.model_validate(a) for a in resp.json()["items"]] 27 28 def create( 29 self, 30 *, 31 title: str, 32 body: str = "", 33 severity: str = "info", 34 starts_at: datetime | None = None, 35 ends_at: datetime | None = None, 36 ) -> AnnouncementInfo: 37 """Post a platform-wide announcement. ``None`` time fields = 38 live immediately / never expires. Requires super-admin.""" 39 resp = self._http.request( 40 "POST", 41 "/admin/announcements", 42 json={ 43 "title": title, 44 "body": body, 45 "severity": severity, 46 "starts_at": starts_at.isoformat() if starts_at else None, 47 "ends_at": ends_at.isoformat() if ends_at else None, 48 }, 49 ) 50 _raise_for_status(resp) 51 return AnnouncementInfo.model_validate(resp.json()) 52 53 def update(self, announcement_id: str, **fields: Any) -> AnnouncementInfo: 54 """PATCH any subset of ``title`` / ``body`` / ``severity`` / 55 ``starts_at`` / ``ends_at``. Omit a field to leave it.""" 56 resp = self._http.request("PATCH", f"/admin/announcements/{announcement_id}", json=fields) 57 _raise_for_status(resp) 58 return AnnouncementInfo.model_validate(resp.json()) 59 60 def delete(self, announcement_id: str) -> None: 61 """Hard-delete one announcement.""" 62 resp = self._http.request("DELETE", f"/admin/announcements/{announcement_id}") 63 _raise_for_status(resp)
class
AdminAnnouncementsResource:
15class AdminAnnouncementsResource: 16 """Post / edit / delete platform-wide announcements.""" 17 18 def __init__(self, http: BaseHttpClient) -> None: 19 self._http = http 20 21 def list(self, offset: int = 0, limit: int = 50) -> builtins.list[AnnouncementInfo]: 22 """Every announcement (active + scheduled + expired).""" 23 resp = self._http.request( 24 "GET", "/admin/announcements", params={"offset": offset, "limit": limit} 25 ) 26 _raise_for_status(resp) 27 return [AnnouncementInfo.model_validate(a) for a in resp.json()["items"]] 28 29 def create( 30 self, 31 *, 32 title: str, 33 body: str = "", 34 severity: str = "info", 35 starts_at: datetime | None = None, 36 ends_at: datetime | None = None, 37 ) -> AnnouncementInfo: 38 """Post a platform-wide announcement. ``None`` time fields = 39 live immediately / never expires. Requires super-admin.""" 40 resp = self._http.request( 41 "POST", 42 "/admin/announcements", 43 json={ 44 "title": title, 45 "body": body, 46 "severity": severity, 47 "starts_at": starts_at.isoformat() if starts_at else None, 48 "ends_at": ends_at.isoformat() if ends_at else None, 49 }, 50 ) 51 _raise_for_status(resp) 52 return AnnouncementInfo.model_validate(resp.json()) 53 54 def update(self, announcement_id: str, **fields: Any) -> AnnouncementInfo: 55 """PATCH any subset of ``title`` / ``body`` / ``severity`` / 56 ``starts_at`` / ``ends_at``. Omit a field to leave it.""" 57 resp = self._http.request("PATCH", f"/admin/announcements/{announcement_id}", json=fields) 58 _raise_for_status(resp) 59 return AnnouncementInfo.model_validate(resp.json()) 60 61 def delete(self, announcement_id: str) -> None: 62 """Hard-delete one announcement.""" 63 resp = self._http.request("DELETE", f"/admin/announcements/{announcement_id}") 64 _raise_for_status(resp)
Post / edit / delete platform-wide announcements.
21 def list(self, offset: int = 0, limit: int = 50) -> builtins.list[AnnouncementInfo]: 22 """Every announcement (active + scheduled + expired).""" 23 resp = self._http.request( 24 "GET", "/admin/announcements", params={"offset": offset, "limit": limit} 25 ) 26 _raise_for_status(resp) 27 return [AnnouncementInfo.model_validate(a) for a in resp.json()["items"]]
Every announcement (active + scheduled + expired).
def
create( self, *, title: str, body: str = '', severity: str = 'info', starts_at: datetime.datetime | None = None, ends_at: datetime.datetime | None = None) -> ctfy.server.models.AnnouncementInfo:
29 def create( 30 self, 31 *, 32 title: str, 33 body: str = "", 34 severity: str = "info", 35 starts_at: datetime | None = None, 36 ends_at: datetime | None = None, 37 ) -> AnnouncementInfo: 38 """Post a platform-wide announcement. ``None`` time fields = 39 live immediately / never expires. Requires super-admin.""" 40 resp = self._http.request( 41 "POST", 42 "/admin/announcements", 43 json={ 44 "title": title, 45 "body": body, 46 "severity": severity, 47 "starts_at": starts_at.isoformat() if starts_at else None, 48 "ends_at": ends_at.isoformat() if ends_at else None, 49 }, 50 ) 51 _raise_for_status(resp) 52 return AnnouncementInfo.model_validate(resp.json())
Post a platform-wide announcement. None time fields =
live immediately / never expires. Requires super-admin.
54 def update(self, announcement_id: str, **fields: Any) -> AnnouncementInfo: 55 """PATCH any subset of ``title`` / ``body`` / ``severity`` / 56 ``starts_at`` / ``ends_at``. Omit a field to leave it.""" 57 resp = self._http.request("PATCH", f"/admin/announcements/{announcement_id}", json=fields) 58 _raise_for_status(resp) 59 return AnnouncementInfo.model_validate(resp.json())
PATCH any subset of title / body / severity /
starts_at / ends_at. Omit a field to leave it.