ctfy.sdk.admin_resources.challenge_schedule
client.admin.challenge_schedule — when each challenge of a competition
appears and shuts, and the one-click release (#2093).
1"""``client.admin.challenge_schedule`` — when each challenge of a competition 2appears and shuts, and the one-click release (#2093).""" 3 4from __future__ import annotations 5 6from collections.abc import Sequence 7from datetime import datetime 8from typing import Any, Final 9 10from ctfy.sdk._helpers import _raise_for_status 11from ctfy.sdk.base import BaseHttpClient 12from ctfy.server.models import CompetitionChallengeSchedule 13 14 15class _Unset: 16 """The argument was not passed — distinct from ``None``, which clears.""" 17 18 def __repr__(self) -> str: 19 return "UNSET" 20 21 22UNSET: Final = _Unset() 23 24 25class AdminChallengeScheduleResource: 26 """Read and edit one competition's per-challenge release schedule. For 27 its organisers (global admins and the event's own competition admins).""" 28 29 def __init__(self, http: BaseHttpClient) -> None: 30 self._http = http 31 32 def get(self, competition_id: str) -> CompetitionChallengeSchedule: 33 """Every challenge of the competition with its batch, reveal and 34 close time; ``released`` / ``closed`` are read from the clock.""" 35 resp = self._http.request("GET", f"/admin/competitions/{competition_id}/challenge-schedule") 36 _raise_for_status(resp) 37 return CompetitionChallengeSchedule.model_validate(resp.json()) 38 39 def update( 40 self, 41 competition_id: str, 42 *, 43 challenge_ids: Sequence[str] = (), 44 in_batch: str = "", 45 batch: str | _Unset = UNSET, 46 reveal_at: datetime | _Unset | None = UNSET, 47 close_at: datetime | _Unset | None = UNSET, 48 release_now: bool = False, 49 ) -> CompetitionChallengeSchedule: 50 """Set the schedule of several challenges at once. 51 52 Select with ``challenge_ids`` and/or ``in_batch`` (every challenge 53 now in that batch). Partial: only what you pass is sent, and ``None`` 54 clears a time (``""`` clears the batch). ``release_now`` reveals them 55 at the instant the request is served. 56 """ 57 payload: dict[str, Any] = { 58 "challenge_ids": list(challenge_ids), 59 "in_batch": in_batch, 60 "release_now": release_now, 61 } 62 if not isinstance(batch, _Unset): 63 payload["batch"] = batch 64 if not isinstance(reveal_at, _Unset): 65 payload["reveal_at"] = reveal_at.isoformat() if reveal_at else None 66 if not isinstance(close_at, _Unset): 67 payload["close_at"] = close_at.isoformat() if close_at else None 68 resp = self._http.request( 69 "PATCH", f"/admin/competitions/{competition_id}/challenge-schedule", json=payload 70 ) 71 _raise_for_status(resp) 72 return CompetitionChallengeSchedule.model_validate(resp.json())
UNSET: Final =
UNSET
class
AdminChallengeScheduleResource:
26class AdminChallengeScheduleResource: 27 """Read and edit one competition's per-challenge release schedule. For 28 its organisers (global admins and the event's own competition admins).""" 29 30 def __init__(self, http: BaseHttpClient) -> None: 31 self._http = http 32 33 def get(self, competition_id: str) -> CompetitionChallengeSchedule: 34 """Every challenge of the competition with its batch, reveal and 35 close time; ``released`` / ``closed`` are read from the clock.""" 36 resp = self._http.request("GET", f"/admin/competitions/{competition_id}/challenge-schedule") 37 _raise_for_status(resp) 38 return CompetitionChallengeSchedule.model_validate(resp.json()) 39 40 def update( 41 self, 42 competition_id: str, 43 *, 44 challenge_ids: Sequence[str] = (), 45 in_batch: str = "", 46 batch: str | _Unset = UNSET, 47 reveal_at: datetime | _Unset | None = UNSET, 48 close_at: datetime | _Unset | None = UNSET, 49 release_now: bool = False, 50 ) -> CompetitionChallengeSchedule: 51 """Set the schedule of several challenges at once. 52 53 Select with ``challenge_ids`` and/or ``in_batch`` (every challenge 54 now in that batch). Partial: only what you pass is sent, and ``None`` 55 clears a time (``""`` clears the batch). ``release_now`` reveals them 56 at the instant the request is served. 57 """ 58 payload: dict[str, Any] = { 59 "challenge_ids": list(challenge_ids), 60 "in_batch": in_batch, 61 "release_now": release_now, 62 } 63 if not isinstance(batch, _Unset): 64 payload["batch"] = batch 65 if not isinstance(reveal_at, _Unset): 66 payload["reveal_at"] = reveal_at.isoformat() if reveal_at else None 67 if not isinstance(close_at, _Unset): 68 payload["close_at"] = close_at.isoformat() if close_at else None 69 resp = self._http.request( 70 "PATCH", f"/admin/competitions/{competition_id}/challenge-schedule", json=payload 71 ) 72 _raise_for_status(resp) 73 return CompetitionChallengeSchedule.model_validate(resp.json())
Read and edit one competition's per-challenge release schedule. For its organisers (global admins and the event's own competition admins).
33 def get(self, competition_id: str) -> CompetitionChallengeSchedule: 34 """Every challenge of the competition with its batch, reveal and 35 close time; ``released`` / ``closed`` are read from the clock.""" 36 resp = self._http.request("GET", f"/admin/competitions/{competition_id}/challenge-schedule") 37 _raise_for_status(resp) 38 return CompetitionChallengeSchedule.model_validate(resp.json())
Every challenge of the competition with its batch, reveal and
close time; released / closed are read from the clock.
def
update( self, competition_id: str, *, challenge_ids: Sequence[str] = (), in_batch: str = '', batch: str | ctfy.sdk.admin_resources.challenge_schedule._Unset = UNSET, reveal_at: datetime.datetime | ctfy.sdk.admin_resources.challenge_schedule._Unset | None = UNSET, close_at: datetime.datetime | ctfy.sdk.admin_resources.challenge_schedule._Unset | None = UNSET, release_now: bool = False) -> ctfy.server.models.CompetitionChallengeSchedule:
40 def update( 41 self, 42 competition_id: str, 43 *, 44 challenge_ids: Sequence[str] = (), 45 in_batch: str = "", 46 batch: str | _Unset = UNSET, 47 reveal_at: datetime | _Unset | None = UNSET, 48 close_at: datetime | _Unset | None = UNSET, 49 release_now: bool = False, 50 ) -> CompetitionChallengeSchedule: 51 """Set the schedule of several challenges at once. 52 53 Select with ``challenge_ids`` and/or ``in_batch`` (every challenge 54 now in that batch). Partial: only what you pass is sent, and ``None`` 55 clears a time (``""`` clears the batch). ``release_now`` reveals them 56 at the instant the request is served. 57 """ 58 payload: dict[str, Any] = { 59 "challenge_ids": list(challenge_ids), 60 "in_batch": in_batch, 61 "release_now": release_now, 62 } 63 if not isinstance(batch, _Unset): 64 payload["batch"] = batch 65 if not isinstance(reveal_at, _Unset): 66 payload["reveal_at"] = reveal_at.isoformat() if reveal_at else None 67 if not isinstance(close_at, _Unset): 68 payload["close_at"] = close_at.isoformat() if close_at else None 69 resp = self._http.request( 70 "PATCH", f"/admin/competitions/{competition_id}/challenge-schedule", json=payload 71 ) 72 _raise_for_status(resp) 73 return CompetitionChallengeSchedule.model_validate(resp.json())
Set the schedule of several challenges at once.
Select with challenge_ids and/or in_batch (every challenge
now in that batch). Partial: only what you pass is sent, and None
clears a time ("" clears the batch). release_now reveals them
at the instant the request is served.