Source code for cybsi.api.search.stored_queries

import uuid
from typing import Any, Dict, List, Optional

from .. import RefView
from ..api import Tag
from ..error import CybsiError, SemanticError, SemanticErrorCodes
from ..internal import BaseAPI, JsonObjectForm, JsonObjectView
from ..pagination import Cursor, Page
from ..view import _TaggedRefView
from .enums import QueryCompatibility
from .error import CybsiLangErrorCodes


[docs] class StoredQueriesAPI(BaseAPI): """Stored queries API.""" _path = "/search/stored-queries" _validate_path = "/search/query"
[docs] def register(self, stored_query: "StoredQueryForm") -> RefView: """Register a stored query. Note: Calls `POST /search/stored-queries`. Args: stored_query: Stored query registration form. Returns: Reference to a registered stored query. Raises: :class:`~cybsi.api.error.ConflictError`: Stored query with such name already exists. :class:`~cybsi.api.error.SemanticError`: Form contains logic errors. Note: Semantic error codes specific for this method: * :attr:`~cybsi.api.error.SemanticErrorCodes.InvalidQueryText` """ r = self._connector.do_post(path=self._path, json=stored_query.json()) return RefView(r.json())
[docs] def view(self, query_uuid: uuid.UUID) -> "StoredQueryView": """Get a stored query view. Note: Calls `GET /search/stored-queries/{query_uuid}`. Args: query_uuid: Stored query uuid. Returns: View of the stored query. Raises: :class:`~cybsi.api.error.NotFoundError`: Stored query not found. """ path = f"{self._path}/{query_uuid}" r = self._connector.do_get(path) return StoredQueryView(r)
[docs] def validate( self, text: str, compatibility: QueryCompatibility ) -> "StoredQueryValidationView": """Validates search query. Note: Calls `PUT /search/query`. Args: text: Text of the query. compatibility: Compatibility scope for query text. Returns: View of the validation results. """ data = {"text": text, "compatibility": compatibility.value} r = self._connector.do_put(self._validate_path, data) return StoredQueryValidationView(r.json())
[docs] def edit( self, query_uuid: uuid.UUID, tag: Tag, *, name: Optional[str] = None, text: Optional[str] = None, ) -> None: """Edit the stored query. Note: Calls `PATCH /search/stored-queries/{query_uuid}`. Args: query_uuid: Stored query uuid. tag: :attr:`StoredQueryView.tag` value. Use :meth:`view` to retrieve it. name: New stored query name, non-empty if not :data:`None`. text: New stored query text, non-empty if not :data:`None`. Raises: :class:`~cybsi.api.error.InvalidRequestError`: Provided arguments have invalid values. :class:`~cybsi.api.error.NotFoundError`: Stored query not found. :class:`~cybsi.api.error.ConflictError`: Stored query with such name already exists. :class:`~cybsi.api.error.ResourceModifiedError`: Stored query changed since last request. Update tag and retry. :class:`~cybsi.api.error.SemanticError`: Form contains logic errors. Note: Semantic error codes specific for this method: * :attr:`~cybsi.api.error.SemanticErrorCodes.InvalidQueryText` * :attr:`~cybsi.api.error.SemanticErrorCodes.InvalidStoredQuery` """ form: Dict[str, Any] = {} if name is not None: form["name"] = name if text is not None: form["text"] = text path = f"{self._path}/{query_uuid}" self._connector.do_patch(path=path, tag=tag, json=form)
[docs] def delete( self, query_uuid: uuid.UUID, ) -> None: """Delete stored query. .. versionadded:: 2.13 Note: Calls `DELETE /search/stored-queries/{query_uuid}`. Args: query_uuid: Stored query uuid. Raises: :class:`~cybsi.api.error.NotFoundError`: Stored query not found. :class:`~cybsi.api.error.SemanticError`: Request contains logic errors. Note: Semantic error codes specific for this method: * :attr:`~cybsi.api.error.SemanticErrorCodes.StoredQueryIsLocked` """ path = f"{self._path}/{query_uuid}" self._connector.do_delete(path=path)
[docs] def filter( self, *, user_uuid: Optional[uuid.UUID] = None, query_name: Optional[str] = None, is_replist_compatible: Optional[bool] = None, cursor: Optional[Cursor] = None, limit: Optional[int] = None, ) -> Page["StoredQueryFilterView"]: """Get page of filtered stored queries list. Note: Calls `GET /search/stored-queries` Args: user_uuid: User's identifier. Filter stored queries by author's id. query_name: Filter stored queries by specified substring (case-insensitive). Substring length must be in range [1, 250]. is_replist_compatible: Filter stored queries by replist compatibility flag. cursor: Page cursor. limit: Page limit. Returns: Page of filtered stored queries list and next page cursor. Raises: :class:`~cybsi.api.error.SemanticError`: query arguments contain errors. Note: Semantic error codes specific for this method: * :attr:`~cybsi.api.error.SemanticErrorCodes.UserNotFound` """ params: Dict[str, Any] = {} if user_uuid is not None: params["userUUID"] = str(user_uuid) if query_name is not None: params["queryName"] = query_name if is_replist_compatible is not None: params["isReplistCompatible"] = is_replist_compatible if cursor: params["cursor"] = str(cursor) if limit: params["limit"] = str(limit) resp = self._connector.do_get(self._path, params=params) page = Page(self._connector.do_get, resp, StoredQueryFilterView) return page
[docs] class StoredQueryForm(JsonObjectForm): """Stored query form. This is the form you need to fill to register stored query. Args: name: Name of the stored query, non-empty. text: Text of the stored query, non-empty. """ def __init__(self, name: str, text: str): super().__init__() self._data["name"] = name self._data["text"] = text
[docs] class StoredQueryValidationView(JsonObjectView): """View of a search query validation, as retrieved by :meth:`StoredQueriesAPI.validate`.""" @property def errors(self) -> List["CybsiLangErrorView"]: """Errors.""" return [CybsiLangErrorView(err) for err in self._get("errors")] @property def warnings(self) -> List["CybsiLangErrorView"]: """Warnings.""" return [CybsiLangErrorView(warn) for warn in self._get("warnings")]
[docs] class CybsiLangErrorView(JsonObjectView): """View of a search query validation errors."""
[docs] @classmethod def from_semantic_error(cls, exc: SemanticError) -> "CybsiLangErrorView": """Extract CybsiLang error from semantic error. Args: exc: SemanticError exception. Note: Only :attr:`~cybsi.api.error.SemanticErrorCodes.InvalidQueryText` can be unwrapped """ if exc.code == SemanticErrorCodes.InvalidQueryText: return cls(exc.content["details"]) raise CybsiError("unexpected error code")
@property def code(self) -> CybsiLangErrorCodes: """Code. See :class:`~cybsi.api.search.error.CybsiLangErrorCodes` for all available error codes """ return CybsiLangErrorCodes(self._get("code")) @property def message(self) -> str: """Message.""" return self._get("message") @property def details_raw(self) -> Dict[str, Any]: """Details.""" return self._get("details") @property def position(self) -> "ErrorPosition": """Position of the error start.""" return ErrorPosition(self._get("position")) @property def until_position(self) -> "ErrorPosition": """Position of the error end. Points to a symbol next to the last symbol of the error. """ return ErrorPosition(self._get("untilPosition"))
[docs] class ErrorPosition(JsonObjectView): """Error position.""" @property def line(self) -> int: """Line. Starts from 1.""" return self._get("line") @property def column(self) -> int: """Column. Relative position from start of line. Starts from 1.""" return self._get("column") @property def offset(self) -> int: """Offset. Absolute position from start of query text. Starts from 0.""" return self._get("offset")
[docs] class StoredQueryCommonView(RefView): """Stored query short view, as retrieved by :meth:`~cybsi.api.replist.ReplistsAPI.view`.""" @property def name(self) -> str: """Query name.""" return self._get("name")
[docs] class StoredQueryFilterView(StoredQueryCommonView): """Filter view of a stored query, as retrieved by :meth:`StoredQueriesAPI.filter`.""" @property def text(self) -> str: """Query text.""" return self._get("text") @property def author(self) -> RefView: """User, author of the query.""" return RefView(self._get("author")) @property def is_replist_compatible(self) -> bool: """Replist compatibility flag.""" return self._get("isReplistCompatible")
[docs] class StoredQueryView(_TaggedRefView, StoredQueryFilterView): """View of a stored query, as retrieved by :meth:`StoredQueriesAPI.view`."""