ctfy.sdk.resources.search
client.search -- global search (#2112), the same read as the web panel.
1"""``client.search`` -- global search (#2112), the same read as the web panel.""" 2 3from __future__ import annotations 4 5from typing import Any 6 7from ctfy.sdk._helpers import _raise_for_status 8from ctfy.sdk.base import BaseHttpClient 9from ctfy.server.models import SearchGroupName, SearchResponse, SearchScope 10 11 12class SearchResource: 13 """Find competitions, challenges and teams by name. 14 15 Everything returned is something the caller can open: the server decides 16 it with the same rules as the matching list routes (hidden events, the 17 start gate, anonymous entrants, silent exercises), so an agent sees 18 exactly what its human would. 19 """ 20 21 def __init__(self, http: BaseHttpClient) -> None: 22 self._http = http 23 24 def query( 25 self, 26 q: str, 27 *, 28 scope: SearchScope | str = SearchScope.ALL, 29 competition_id: str = "", 30 group: SearchGroupName | str | None = None, 31 limit: int = 4, 32 offset: int = 0, 33 ) -> SearchResponse: 34 """Groups of matches for ``q``, each with at most ``limit`` rows and 35 the ``total`` that match. 36 37 ``scope="competition"`` (with ``competition_id``) searches one event; 38 ``"all"`` searches everywhere, listing ``competition_id``'s 39 challenges first. Name a ``group`` and an ``offset`` to page one 40 section. Challenges match on title, id, tag and category, never on 41 the description. 42 """ 43 params: dict[str, Any] = { 44 "q": q, 45 "scope": str(scope), 46 "limit": limit, 47 "offset": offset, 48 } 49 if competition_id: 50 params["competition_id"] = competition_id 51 if group is not None: 52 params["group"] = str(group) 53 resp = self._http.request("GET", "/search", params=params) 54 _raise_for_status(resp) 55 return SearchResponse.model_validate(resp.json())
class
SearchResource:
13class SearchResource: 14 """Find competitions, challenges and teams by name. 15 16 Everything returned is something the caller can open: the server decides 17 it with the same rules as the matching list routes (hidden events, the 18 start gate, anonymous entrants, silent exercises), so an agent sees 19 exactly what its human would. 20 """ 21 22 def __init__(self, http: BaseHttpClient) -> None: 23 self._http = http 24 25 def query( 26 self, 27 q: str, 28 *, 29 scope: SearchScope | str = SearchScope.ALL, 30 competition_id: str = "", 31 group: SearchGroupName | str | None = None, 32 limit: int = 4, 33 offset: int = 0, 34 ) -> SearchResponse: 35 """Groups of matches for ``q``, each with at most ``limit`` rows and 36 the ``total`` that match. 37 38 ``scope="competition"`` (with ``competition_id``) searches one event; 39 ``"all"`` searches everywhere, listing ``competition_id``'s 40 challenges first. Name a ``group`` and an ``offset`` to page one 41 section. Challenges match on title, id, tag and category, never on 42 the description. 43 """ 44 params: dict[str, Any] = { 45 "q": q, 46 "scope": str(scope), 47 "limit": limit, 48 "offset": offset, 49 } 50 if competition_id: 51 params["competition_id"] = competition_id 52 if group is not None: 53 params["group"] = str(group) 54 resp = self._http.request("GET", "/search", params=params) 55 _raise_for_status(resp) 56 return SearchResponse.model_validate(resp.json())
Find competitions, challenges and teams by name.
Everything returned is something the caller can open: the server decides it with the same rules as the matching list routes (hidden events, the start gate, anonymous entrants, silent exercises), so an agent sees exactly what its human would.
def
query( self, q: str, *, scope: ctfy.server.models.SearchScope | str = <SearchScope.ALL: 'all'>, competition_id: str = '', group: ctfy.server.models.SearchGroupName | str | None = None, limit: int = 4, offset: int = 0) -> ctfy.server.models.SearchResponse:
25 def query( 26 self, 27 q: str, 28 *, 29 scope: SearchScope | str = SearchScope.ALL, 30 competition_id: str = "", 31 group: SearchGroupName | str | None = None, 32 limit: int = 4, 33 offset: int = 0, 34 ) -> SearchResponse: 35 """Groups of matches for ``q``, each with at most ``limit`` rows and 36 the ``total`` that match. 37 38 ``scope="competition"`` (with ``competition_id``) searches one event; 39 ``"all"`` searches everywhere, listing ``competition_id``'s 40 challenges first. Name a ``group`` and an ``offset`` to page one 41 section. Challenges match on title, id, tag and category, never on 42 the description. 43 """ 44 params: dict[str, Any] = { 45 "q": q, 46 "scope": str(scope), 47 "limit": limit, 48 "offset": offset, 49 } 50 if competition_id: 51 params["competition_id"] = competition_id 52 if group is not None: 53 params["group"] = str(group) 54 resp = self._http.request("GET", "/search", params=params) 55 _raise_for_status(resp) 56 return SearchResponse.model_validate(resp.json())
Groups of matches for q, each with at most limit rows and
the total that match.
scope="competition" (with competition_id) searches one event;
"all" searches everywhere, listing competition_id's
challenges first. Name a group and an offset to page one
section. Challenges match on title, id, tag and category, never on
the description.