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().

ScoreboardResource(http: ctfy.sdk.base.BaseHttpClient)
18    def __init__(self, http: BaseHttpClient) -> None:
19        self._http = http
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]:
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)
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.

def users( self, offset: int = 0, limit: int = 50) -> list[ctfy.server.models.UserScoreboardEntry]:
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.