ctfy.sdk.resources.scoreboard
client.scoreboard — global standings, per-challenge stats, snapshots.
1"""``client.scoreboard`` — global standings, per-challenge stats, snapshots.""" 2 3from __future__ import annotations 4 5from typing import Any 6 7from ctfy.core.state.models import ScoreboardSnapshotState 8from ctfy.sdk._helpers import _extract_items, _raise_for_status 9from ctfy.sdk.base import BaseHttpClient 10from ctfy.server.models import ChallengeStats, ScoreboardEntry, UserScoreboardEntry 11 12 13class ScoreboardResource: 14 """Global (admin/snapshot) scoreboard surface. Per-competition standings 15 live on :meth:`CompetitionsResource.scoreboard`.""" 16 17 def __init__(self, http: BaseHttpClient) -> None: 18 self._http = http 19 20 def get(self, category: str = "", offset: int = 0, limit: int = 50) -> list[ScoreboardEntry]: 21 params: dict[str, Any] = {"offset": offset, "limit": limit} 22 if category: 23 params["category"] = category 24 resp = self._http.request("GET", "/scoreboard", params=params) 25 _raise_for_status(resp) 26 return _extract_items(resp.json(), ScoreboardEntry) 27 28 def challenge_stats(self, offset: int = 0, limit: int = 50) -> list[ChallengeStats]: 29 resp = self._http.request( 30 "GET", "/scoreboard/challenges", params={"offset": offset, "limit": limit} 31 ) 32 _raise_for_status(resp) 33 return _extract_items(resp.json(), ChallengeStats) 34 35 def history( 36 self, 37 *, 38 team_id: str = "", 39 days: int = 30, 40 offset: int = 0, 41 limit: int = 50, 42 ) -> list[ScoreboardSnapshotState]: 43 """Persisted scoreboard snapshots (rank-over-time). Filter to 44 one team with ``team_id``.""" 45 params: dict[str, Any] = {"days": days, "offset": offset, "limit": limit} 46 if team_id: 47 params["team_id"] = team_id 48 resp = self._http.request("GET", "/scoreboard/history", params=params) 49 _raise_for_status(resp) 50 return _extract_items(resp.json(), ScoreboardSnapshotState) 51 52 def users(self, offset: int = 0, limit: int = 50) -> list[UserScoreboardEntry]: 53 """Per-user (not per-team) global standings.""" 54 resp = self._http.request( 55 "GET", "/scoreboard/users", params={"offset": offset, "limit": limit} 56 ) 57 _raise_for_status(resp) 58 return _extract_items(resp.json(), UserScoreboardEntry)
class
ScoreboardResource:
14class ScoreboardResource: 15 """Global (admin/snapshot) scoreboard surface. Per-competition standings 16 live on :meth:`CompetitionsResource.scoreboard`.""" 17 18 def __init__(self, http: BaseHttpClient) -> None: 19 self._http = http 20 21 def get(self, category: str = "", offset: int = 0, limit: int = 50) -> list[ScoreboardEntry]: 22 params: dict[str, Any] = {"offset": offset, "limit": limit} 23 if category: 24 params["category"] = category 25 resp = self._http.request("GET", "/scoreboard", params=params) 26 _raise_for_status(resp) 27 return _extract_items(resp.json(), ScoreboardEntry) 28 29 def challenge_stats(self, offset: int = 0, limit: int = 50) -> list[ChallengeStats]: 30 resp = self._http.request( 31 "GET", "/scoreboard/challenges", params={"offset": offset, "limit": limit} 32 ) 33 _raise_for_status(resp) 34 return _extract_items(resp.json(), ChallengeStats) 35 36 def history( 37 self, 38 *, 39 team_id: str = "", 40 days: int = 30, 41 offset: int = 0, 42 limit: int = 50, 43 ) -> list[ScoreboardSnapshotState]: 44 """Persisted scoreboard snapshots (rank-over-time). Filter to 45 one team with ``team_id``.""" 46 params: dict[str, Any] = {"days": days, "offset": offset, "limit": limit} 47 if team_id: 48 params["team_id"] = team_id 49 resp = self._http.request("GET", "/scoreboard/history", params=params) 50 _raise_for_status(resp) 51 return _extract_items(resp.json(), ScoreboardSnapshotState) 52 53 def users(self, offset: int = 0, limit: int = 50) -> list[UserScoreboardEntry]: 54 """Per-user (not per-team) global standings.""" 55 resp = self._http.request( 56 "GET", "/scoreboard/users", params={"offset": offset, "limit": limit} 57 ) 58 _raise_for_status(resp) 59 return _extract_items(resp.json(), UserScoreboardEntry)
Global (admin/snapshot) scoreboard surface. Per-competition standings
live on CompetitionsResource.scoreboard().
def
get( self, category: str = '', offset: int = 0, limit: int = 50) -> list[ctfy.server.models.ScoreboardEntry]:
21 def get(self, category: str = "", offset: int = 0, limit: int = 50) -> list[ScoreboardEntry]: 22 params: dict[str, Any] = {"offset": offset, "limit": limit} 23 if category: 24 params["category"] = category 25 resp = self._http.request("GET", "/scoreboard", params=params) 26 _raise_for_status(resp) 27 return _extract_items(resp.json(), ScoreboardEntry)
def
challenge_stats( self, offset: int = 0, limit: int = 50) -> list[ctfy.server.models.ChallengeStats]:
def
history( self, *, team_id: str = '', days: int = 30, offset: int = 0, limit: int = 50) -> list[ctfy.core.state.models.ScoreboardSnapshotState]:
36 def history( 37 self, 38 *, 39 team_id: str = "", 40 days: int = 30, 41 offset: int = 0, 42 limit: int = 50, 43 ) -> list[ScoreboardSnapshotState]: 44 """Persisted scoreboard snapshots (rank-over-time). Filter to 45 one team with ``team_id``.""" 46 params: dict[str, Any] = {"days": days, "offset": offset, "limit": limit} 47 if team_id: 48 params["team_id"] = team_id 49 resp = self._http.request("GET", "/scoreboard/history", params=params) 50 _raise_for_status(resp) 51 return _extract_items(resp.json(), ScoreboardSnapshotState)
Persisted scoreboard snapshots (rank-over-time). Filter to
one team with team_id.
53 def users(self, offset: int = 0, limit: int = 50) -> list[UserScoreboardEntry]: 54 """Per-user (not per-team) global standings.""" 55 resp = self._http.request( 56 "GET", "/scoreboard/users", params={"offset": offset, "limit": limit} 57 ) 58 _raise_for_status(resp) 59 return _extract_items(resp.json(), UserScoreboardEntry)
Per-user (not per-team) global standings.