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 PagedList, _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( 21 self, category: str = "", offset: int = 0, limit: int = 50 22 ) -> PagedList[ScoreboardEntry]: 23 params: dict[str, Any] = {"offset": offset, "limit": limit} 24 if category: 25 params["category"] = category 26 resp = self._http.request("GET", "/scoreboard", params=params) 27 _raise_for_status(resp) 28 return _extract_items(resp.json(), ScoreboardEntry) 29 30 def challenge_stats(self, offset: int = 0, limit: int = 50) -> PagedList[ChallengeStats]: 31 resp = self._http.request( 32 "GET", "/scoreboard/challenges", params={"offset": offset, "limit": limit} 33 ) 34 _raise_for_status(resp) 35 return _extract_items(resp.json(), ChallengeStats) 36 37 def history( 38 self, 39 *, 40 team_id: str = "", 41 days: int = 30, 42 offset: int = 0, 43 limit: int = 50, 44 ) -> PagedList[ScoreboardSnapshotState]: 45 """Persisted scoreboard snapshots (rank-over-time). Filter to 46 one team with ``team_id``.""" 47 params: dict[str, Any] = {"days": days, "offset": offset, "limit": limit} 48 if team_id: 49 params["team_id"] = team_id 50 resp = self._http.request("GET", "/scoreboard/history", params=params) 51 _raise_for_status(resp) 52 return _extract_items(resp.json(), ScoreboardSnapshotState) 53 54 def users(self, offset: int = 0, limit: int = 50) -> PagedList[UserScoreboardEntry]: 55 """Per-user (not per-team) global standings.""" 56 resp = self._http.request( 57 "GET", "/scoreboard/users", params={"offset": offset, "limit": limit} 58 ) 59 _raise_for_status(resp) 60 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( 22 self, category: str = "", offset: int = 0, limit: int = 50 23 ) -> PagedList[ScoreboardEntry]: 24 params: dict[str, Any] = {"offset": offset, "limit": limit} 25 if category: 26 params["category"] = category 27 resp = self._http.request("GET", "/scoreboard", params=params) 28 _raise_for_status(resp) 29 return _extract_items(resp.json(), ScoreboardEntry) 30 31 def challenge_stats(self, offset: int = 0, limit: int = 50) -> PagedList[ChallengeStats]: 32 resp = self._http.request( 33 "GET", "/scoreboard/challenges", params={"offset": offset, "limit": limit} 34 ) 35 _raise_for_status(resp) 36 return _extract_items(resp.json(), ChallengeStats) 37 38 def history( 39 self, 40 *, 41 team_id: str = "", 42 days: int = 30, 43 offset: int = 0, 44 limit: int = 50, 45 ) -> PagedList[ScoreboardSnapshotState]: 46 """Persisted scoreboard snapshots (rank-over-time). Filter to 47 one team with ``team_id``.""" 48 params: dict[str, Any] = {"days": days, "offset": offset, "limit": limit} 49 if team_id: 50 params["team_id"] = team_id 51 resp = self._http.request("GET", "/scoreboard/history", params=params) 52 _raise_for_status(resp) 53 return _extract_items(resp.json(), ScoreboardSnapshotState) 54 55 def users(self, offset: int = 0, limit: int = 50) -> PagedList[UserScoreboardEntry]: 56 """Per-user (not per-team) global standings.""" 57 resp = self._http.request( 58 "GET", "/scoreboard/users", params={"offset": offset, "limit": limit} 59 ) 60 _raise_for_status(resp) 61 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) -> ctfy.sdk._helpers.PagedList[ctfy.server.models.ScoreboardEntry]:
21 def get( 22 self, category: str = "", offset: int = 0, limit: int = 50 23 ) -> PagedList[ScoreboardEntry]: 24 params: dict[str, Any] = {"offset": offset, "limit": limit} 25 if category: 26 params["category"] = category 27 resp = self._http.request("GET", "/scoreboard", params=params) 28 _raise_for_status(resp) 29 return _extract_items(resp.json(), ScoreboardEntry)
def
challenge_stats( self, offset: int = 0, limit: int = 50) -> ctfy.sdk._helpers.PagedList[ctfy.server.models.ChallengeStats]:
def
history( self, *, team_id: str = '', days: int = 30, offset: int = 0, limit: int = 50) -> ctfy.sdk._helpers.PagedList[ctfy.core.state.models.ScoreboardSnapshotState]:
38 def history( 39 self, 40 *, 41 team_id: str = "", 42 days: int = 30, 43 offset: int = 0, 44 limit: int = 50, 45 ) -> PagedList[ScoreboardSnapshotState]: 46 """Persisted scoreboard snapshots (rank-over-time). Filter to 47 one team with ``team_id``.""" 48 params: dict[str, Any] = {"days": days, "offset": offset, "limit": limit} 49 if team_id: 50 params["team_id"] = team_id 51 resp = self._http.request("GET", "/scoreboard/history", params=params) 52 _raise_for_status(resp) 53 return _extract_items(resp.json(), ScoreboardSnapshotState)
Persisted scoreboard snapshots (rank-over-time). Filter to
one team with team_id.
def
users( self, offset: int = 0, limit: int = 50) -> ctfy.sdk._helpers.PagedList[ctfy.server.models.UserScoreboardEntry]:
55 def users(self, offset: int = 0, limit: int = 50) -> PagedList[UserScoreboardEntry]: 56 """Per-user (not per-team) global standings.""" 57 resp = self._http.request( 58 "GET", "/scoreboard/users", params={"offset": offset, "limit": limit} 59 ) 60 _raise_for_status(resp) 61 return _extract_items(resp.json(), UserScoreboardEntry)
Per-user (not per-team) global standings.