ctfy.sdk.admin_resources.competition_applications

client.admin.competition_applications — people asking to be let into a private competition, and the organisers' answer (plan L2).

 1"""``client.admin.competition_applications`` — people asking to be let
 2into a private competition, and the organisers' answer (plan L2)."""
 3
 4from __future__ import annotations
 5
 6from typing import Any
 7
 8from ctfy.core.enums import ReviewStatus
 9from ctfy.sdk._helpers import PagedList, _extract_items, _raise_for_status
10from ctfy.sdk.base import BaseHttpClient
11from ctfy.server.models import CompetitionApplicationRow
12
13
14class AdminCompetitionApplicationsResource:
15    """Read one competition's applications and rule on them. For its
16    organisers — whoever may invite (global admins and the event's full
17    organisers); a roster reviewer may not, since an approval *is* an
18    invitation."""
19
20    def __init__(self, http: BaseHttpClient) -> None:
21        self._http = http
22
23    def list(
24        self,
25        competition_id: str,
26        *,
27        status: ReviewStatus | None = None,
28        offset: int = 0,
29        limit: int = 50,
30    ) -> PagedList[CompetitionApplicationRow]:
31        """The queue, oldest first; ``status`` narrows the page and its
32        ``total`` alike. ``invited`` on each row is whether the person
33        holds an invitation *now* — distinct from ``status == "approved"``
34        once an invitation is revoked."""
35        params: dict[str, Any] = {"offset": offset, "limit": limit}
36        if status is not None:
37            params["status"] = status
38        resp = self._http.request(
39            "GET", f"/admin/competitions/{competition_id}/applications", params=params
40        )
41        _raise_for_status(resp)
42        return _extract_items(resp.json(), CompetitionApplicationRow)
43
44    def approve(self, competition_id: str, user_id: str) -> CompetitionApplicationRow:
45        """Let them in: writes their invitation and sends the invitation
46        mail. Once — a second verdict is ``application_already_decided``."""
47        return self._review(competition_id, user_id, {"status": "approved"})
48
49    def reject(self, competition_id: str, user_id: str, note: str) -> CompetitionApplicationRow:
50        """Turn them down, saying why. Final for the application — the
51        person cannot send it again, and you can still invite them — so
52        ``note`` is required (``application_review_note_required``)."""
53        return self._review(competition_id, user_id, {"status": "rejected", "note": note})
54
55    def _review(
56        self, competition_id: str, user_id: str, body: dict[str, str]
57    ) -> CompetitionApplicationRow:
58        resp = self._http.request(
59            "POST",
60            f"/admin/competitions/{competition_id}/applications/{user_id}/review",
61            json=body,
62        )
63        _raise_for_status(resp)
64        return CompetitionApplicationRow.model_validate(resp.json())
class AdminCompetitionApplicationsResource:
15class AdminCompetitionApplicationsResource:
16    """Read one competition's applications and rule on them. For its
17    organisers — whoever may invite (global admins and the event's full
18    organisers); a roster reviewer may not, since an approval *is* an
19    invitation."""
20
21    def __init__(self, http: BaseHttpClient) -> None:
22        self._http = http
23
24    def list(
25        self,
26        competition_id: str,
27        *,
28        status: ReviewStatus | None = None,
29        offset: int = 0,
30        limit: int = 50,
31    ) -> PagedList[CompetitionApplicationRow]:
32        """The queue, oldest first; ``status`` narrows the page and its
33        ``total`` alike. ``invited`` on each row is whether the person
34        holds an invitation *now* — distinct from ``status == "approved"``
35        once an invitation is revoked."""
36        params: dict[str, Any] = {"offset": offset, "limit": limit}
37        if status is not None:
38            params["status"] = status
39        resp = self._http.request(
40            "GET", f"/admin/competitions/{competition_id}/applications", params=params
41        )
42        _raise_for_status(resp)
43        return _extract_items(resp.json(), CompetitionApplicationRow)
44
45    def approve(self, competition_id: str, user_id: str) -> CompetitionApplicationRow:
46        """Let them in: writes their invitation and sends the invitation
47        mail. Once — a second verdict is ``application_already_decided``."""
48        return self._review(competition_id, user_id, {"status": "approved"})
49
50    def reject(self, competition_id: str, user_id: str, note: str) -> CompetitionApplicationRow:
51        """Turn them down, saying why. Final for the application — the
52        person cannot send it again, and you can still invite them — so
53        ``note`` is required (``application_review_note_required``)."""
54        return self._review(competition_id, user_id, {"status": "rejected", "note": note})
55
56    def _review(
57        self, competition_id: str, user_id: str, body: dict[str, str]
58    ) -> CompetitionApplicationRow:
59        resp = self._http.request(
60            "POST",
61            f"/admin/competitions/{competition_id}/applications/{user_id}/review",
62            json=body,
63        )
64        _raise_for_status(resp)
65        return CompetitionApplicationRow.model_validate(resp.json())

Read one competition's applications and rule on them. For its organisers — whoever may invite (global admins and the event's full organisers); a roster reviewer may not, since an approval is an invitation.

AdminCompetitionApplicationsResource(http: ctfy.sdk.base.BaseHttpClient)
21    def __init__(self, http: BaseHttpClient) -> None:
22        self._http = http
def list( self, competition_id: str, *, status: Optional[Literal['pending', 'approved', 'rejected']] = None, offset: int = 0, limit: int = 50) -> ctfy.sdk._helpers.PagedList[ctfy.server.models.CompetitionApplicationRow]:
24    def list(
25        self,
26        competition_id: str,
27        *,
28        status: ReviewStatus | None = None,
29        offset: int = 0,
30        limit: int = 50,
31    ) -> PagedList[CompetitionApplicationRow]:
32        """The queue, oldest first; ``status`` narrows the page and its
33        ``total`` alike. ``invited`` on each row is whether the person
34        holds an invitation *now* — distinct from ``status == "approved"``
35        once an invitation is revoked."""
36        params: dict[str, Any] = {"offset": offset, "limit": limit}
37        if status is not None:
38            params["status"] = status
39        resp = self._http.request(
40            "GET", f"/admin/competitions/{competition_id}/applications", params=params
41        )
42        _raise_for_status(resp)
43        return _extract_items(resp.json(), CompetitionApplicationRow)

The queue, oldest first; status narrows the page and its total alike. invited on each row is whether the person holds an invitation now — distinct from status == "approved" once an invitation is revoked.

def approve( self, competition_id: str, user_id: str) -> ctfy.server.models.CompetitionApplicationRow:
45    def approve(self, competition_id: str, user_id: str) -> CompetitionApplicationRow:
46        """Let them in: writes their invitation and sends the invitation
47        mail. Once — a second verdict is ``application_already_decided``."""
48        return self._review(competition_id, user_id, {"status": "approved"})

Let them in: writes their invitation and sends the invitation mail. Once — a second verdict is application_already_decided.

def reject( self, competition_id: str, user_id: str, note: str) -> ctfy.server.models.CompetitionApplicationRow:
50    def reject(self, competition_id: str, user_id: str, note: str) -> CompetitionApplicationRow:
51        """Turn them down, saying why. Final for the application — the
52        person cannot send it again, and you can still invite them — so
53        ``note`` is required (``application_review_note_required``)."""
54        return self._review(competition_id, user_id, {"status": "rejected", "note": note})

Turn them down, saying why. Final for the application — the person cannot send it again, and you can still invite them — so note is required (application_review_note_required).