Module astrapy.data.cursors.cursor
Classes
class AbstractCursor (*, initial_page_state: str | UnsetType)-
Expand source code
class AbstractCursor(ABC, Generic[TRAW]): """ A cursor obtained from the invocation of a find-type method over a table or a collection. This is the main interface to scroll through the results (resp. rows or documents). This class is not meant to be directly instantiated by the user, rather it is a superclass capturing some basic mechanisms common to all find cursors. Cursors provide a seamless interface to the caller code, allowing iteration over results while chunks of new data (pages) are exchanged periodically with the API. For this reason, cursors internally manage a local buffer that is progressively emptied and re-filled with a new page in a manner hidden from the user -- except, some cursor methods allow to peek into this buffer should it be necessary. """ _state: CursorState _buffer: list[TRAW] _pages_retrieved: int _consumed: int _next_page_state: str | None _last_response_status: dict[str, Any] | None def __init__( self, *, initial_page_state: str | UnsetType, ) -> None: self.rewind(initial_page_state=initial_page_state) def _imprint_internal_state(self, other: AbstractCursor[TRAW]) -> None: """Mutably copy the internal state of this cursor onto another one.""" other._state = self._state other._buffer = self._buffer other._pages_retrieved = self._pages_retrieved other._consumed = self._consumed other._next_page_state = self._next_page_state other._last_response_status = self._last_response_status def _ensure_alive(self) -> None: if self._state == CursorState.CLOSED: raise CursorException( text="Cursor is stopped.", cursor_state=self._state.value, ) def _ensure_idle(self) -> None: if self._state != CursorState.IDLE: raise CursorException( text="Cursor is not idle anymore.", cursor_state=self._state.value, ) @property def state(self) -> CursorState: """ The current state of this cursor. Returns: a value in `astrapy.cursors.CursorState`. """ return self._state @property def consumed(self) -> int: """ The number of items the cursors has yielded, i.e. how many items have been already read by the code consuming the cursor. Returns: consumed: a non-negative integer, the count of items yielded so far. """ return self._consumed @property def cursor_id(self) -> int: """ An integer uniquely identifying this cursor. Returns: cursor_id: an integer number uniquely identifying the cursor. """ return id(self) @property def buffered_count(self) -> int: """ The number of items (documents, rows) currently stored in the client-side buffer of this cursor. Reading this property never triggers new API calls to re-fill the buffer. Returns: buffered_count: a non-negative integer, the amount of items currently stored in the local buffer. """ return len(self._buffer) def close(self) -> None: """ Close the cursor, regardless of its state. A cursor can be closed at any time, possibly discarding the portion of results that has not yet been consumed, if any. This is an in-place modification of the cursor. """ self._state = CursorState.CLOSED self._buffer = [] def rewind( self, *, initial_page_state: str | UnsetType = _UNSET, ) -> None: """ Rewind the cursor, bringing it back to its pristine state of no items retrieved/consumed yet, regardless of its current state. All cursor settings (filter, mapping, projection, etc) are retained. A cursor can be rewound at any time. Keep in mind that, subject to changes occurred on the table or collection the results may be different if a cursor is browsed a second time after rewinding it. Args: initial_page_state: if a value is provided, it must be the `next_page_state` from the response of `fetch_next_page()` called on a cursor with the same settings. In that case, the repositioning of this cursor is such that the next data-fetch will specify the page state to the Data API. This is an in-place modification of the cursor. """ self._state = CursorState.IDLE self._buffer = [] self._pages_retrieved = 0 self._consumed = 0 if initial_page_state is None: msg = "Passing an explicit null for initial_page_state is not allowed." raise ValueError(msg) elif isinstance(initial_page_state, UnsetType): self._next_page_state = None else: self._next_page_state = initial_page_state self._last_response_status = None def consume_buffer(self, n: int | None = None) -> list[TRAW]: """ Consume (return) up to the requested number of buffered items (rows/documents). The returned items are marked as consumed, meaning that subsequently consuming the cursor will start after those items. This method is an in-place modification of the cursor and only concerns the local buffer: it never triggers fetching of new pages from the Data API. This method can be called regardless of the cursor state without exceptions being raised. Args: n: amount of items to return. If omitted, the whole buffer is returned. Returns: list: a list of items (rows/document dictionaries). If there are fewer items than requested, the whole buffer is returned without errors: in particular, if it is empty (such as when the cursor is closed), an empty list is returned. """ _n = n if n is not None else len(self._buffer) if _n < 0: raise ValueError("A negative amount of items was requested.") returned, remaining = self._buffer[:_n], self._buffer[_n:] self._buffer = remaining self._consumed += len(returned) return returnedA cursor obtained from the invocation of a find-type method over a table or a collection. This is the main interface to scroll through the results (resp. rows or documents).
This class is not meant to be directly instantiated by the user, rather it is a superclass capturing some basic mechanisms common to all find cursors.
Cursors provide a seamless interface to the caller code, allowing iteration over results while chunks of new data (pages) are exchanged periodically with the API. For this reason, cursors internally manage a local buffer that is progressively emptied and re-filled with a new page in a manner hidden from the user – except, some cursor methods allow to peek into this buffer should it be necessary.
Ancestors
- abc.ABC
- typing.Generic
Subclasses
- AsyncCollectionFindAndRerankCursor
- CollectionFindAndRerankCursor
- AsyncCollectionFindCursor
- AsyncTableFindCursor
- CollectionFindCursor
- TableFindCursor
Instance variables
prop buffered_count : int-
Expand source code
@property def buffered_count(self) -> int: """ The number of items (documents, rows) currently stored in the client-side buffer of this cursor. Reading this property never triggers new API calls to re-fill the buffer. Returns: buffered_count: a non-negative integer, the amount of items currently stored in the local buffer. """ return len(self._buffer)The number of items (documents, rows) currently stored in the client-side buffer of this cursor. Reading this property never triggers new API calls to re-fill the buffer.
Returns
buffered_count- a non-negative integer, the amount of items currently stored in the local buffer.
prop consumed : int-
Expand source code
@property def consumed(self) -> int: """ The number of items the cursors has yielded, i.e. how many items have been already read by the code consuming the cursor. Returns: consumed: a non-negative integer, the count of items yielded so far. """ return self._consumedThe number of items the cursors has yielded, i.e. how many items have been already read by the code consuming the cursor.
Returns
consumed- a non-negative integer, the count of items yielded so far.
prop cursor_id : int-
Expand source code
@property def cursor_id(self) -> int: """ An integer uniquely identifying this cursor. Returns: cursor_id: an integer number uniquely identifying the cursor. """ return id(self)An integer uniquely identifying this cursor.
Returns
cursor_id- an integer number uniquely identifying the cursor.
prop state : CursorState-
Expand source code
@property def state(self) -> CursorState: """ The current state of this cursor. Returns: a value in `astrapy.cursors.CursorState`. """ return self._state
Methods
def close(self) ‑> None-
Expand source code
def close(self) -> None: """ Close the cursor, regardless of its state. A cursor can be closed at any time, possibly discarding the portion of results that has not yet been consumed, if any. This is an in-place modification of the cursor. """ self._state = CursorState.CLOSED self._buffer = []Close the cursor, regardless of its state. A cursor can be closed at any time, possibly discarding the portion of results that has not yet been consumed, if any.
This is an in-place modification of the cursor.
def consume_buffer(self, n: int | None = None) ‑> list[~TRAW]-
Expand source code
def consume_buffer(self, n: int | None = None) -> list[TRAW]: """ Consume (return) up to the requested number of buffered items (rows/documents). The returned items are marked as consumed, meaning that subsequently consuming the cursor will start after those items. This method is an in-place modification of the cursor and only concerns the local buffer: it never triggers fetching of new pages from the Data API. This method can be called regardless of the cursor state without exceptions being raised. Args: n: amount of items to return. If omitted, the whole buffer is returned. Returns: list: a list of items (rows/document dictionaries). If there are fewer items than requested, the whole buffer is returned without errors: in particular, if it is empty (such as when the cursor is closed), an empty list is returned. """ _n = n if n is not None else len(self._buffer) if _n < 0: raise ValueError("A negative amount of items was requested.") returned, remaining = self._buffer[:_n], self._buffer[_n:] self._buffer = remaining self._consumed += len(returned) return returnedConsume (return) up to the requested number of buffered items (rows/documents). The returned items are marked as consumed, meaning that subsequently consuming the cursor will start after those items.
This method is an in-place modification of the cursor and only concerns the local buffer: it never triggers fetching of new pages from the Data API.
This method can be called regardless of the cursor state without exceptions being raised.
Args
n- amount of items to return. If omitted, the whole buffer is returned.
Returns
list- a list of items (rows/document dictionaries). If there are fewer items than requested, the whole buffer is returned without errors: in particular, if it is empty (such as when the cursor is closed), an empty list is returned.
def rewind(self, *, initial_page_state: str | UnsetType = (unset)) ‑> None-
Expand source code
def rewind( self, *, initial_page_state: str | UnsetType = _UNSET, ) -> None: """ Rewind the cursor, bringing it back to its pristine state of no items retrieved/consumed yet, regardless of its current state. All cursor settings (filter, mapping, projection, etc) are retained. A cursor can be rewound at any time. Keep in mind that, subject to changes occurred on the table or collection the results may be different if a cursor is browsed a second time after rewinding it. Args: initial_page_state: if a value is provided, it must be the `next_page_state` from the response of `fetch_next_page()` called on a cursor with the same settings. In that case, the repositioning of this cursor is such that the next data-fetch will specify the page state to the Data API. This is an in-place modification of the cursor. """ self._state = CursorState.IDLE self._buffer = [] self._pages_retrieved = 0 self._consumed = 0 if initial_page_state is None: msg = "Passing an explicit null for initial_page_state is not allowed." raise ValueError(msg) elif isinstance(initial_page_state, UnsetType): self._next_page_state = None else: self._next_page_state = initial_page_state self._last_response_status = NoneRewind the cursor, bringing it back to its pristine state of no items retrieved/consumed yet, regardless of its current state. All cursor settings (filter, mapping, projection, etc) are retained.
A cursor can be rewound at any time. Keep in mind that, subject to changes occurred on the table or collection the results may be different if a cursor is browsed a second time after rewinding it.
Args
initial_page_state- if a value is provided, it must be the
next_page_statefrom the response offetch_next_page()called on a cursor with the same settings. In that case, the repositioning of this cursor is such that the next data-fetch will specify the page state to the Data API.
This is an in-place modification of the cursor.
class CursorState (*args, **kwds)-
Expand source code
class CursorState(Enum): """ This enum expresses the possible states for a `Cursor`. Values: IDLE: Iteration over results has not started yet (alive=T, started=F) STARTED: Iteration has started, *can* still yield results (alive=T, started=T) CLOSED: Finished/forcibly stopped. Won't return more documents (alive=F) """ # Iteration over results has not started yet (alive=T, started=F) IDLE = "idle" # Iteration has started, *can* still yield results (alive=T, started=T) STARTED = "started" # Finished/forcibly stopped. Won't return more documents (alive=F) CLOSED = "closed"This enum expresses the possible states for a
Cursor.Values
IDLE: Iteration over results has not started yet (alive=T, started=F) STARTED: Iteration has started, can still yield results (alive=T, started=T) CLOSED: Finished/forcibly stopped. Won't return more documents (alive=F)
Ancestors
- enum.Enum
Class variables
var CLOSED-
The type of the None singleton.
var IDLE-
The type of the None singleton.
var STARTED-
The type of the None singleton.