Module: protocols

Expand source code
# Copyright (C) 2023-present The Project Contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import datetime as dt
from enum import Enum
from typing import Any
from typing import Dict
from typing import List
from typing import Literal
from typing import Protocol
from typing import Tuple
from typing import Type
from typing import TypeGuard
from typing import TypeVar
from typing import runtime_checkable
from uuid import UUID

TPrimitive = str | float | bool | int | dt.date | dt.time | dt.datetime | UUID | bytes | None
"""Supported primitive value types for serialized data in dictionary format."""

TDataField = Dict[str, "TDataField"] | List["TDataField"] | TPrimitive | Enum | None
"""Supported field types for serialized data in dictionary format."""

TDataDict = Dict[str, TDataField]
"""Serialized data in dictionary format."""

TKeyField = Dict[str, "TKeyField"] | TPrimitive | Enum
"""Supported field types for serialized key in dictionary format."""

TKeyDict = Dict[str, TKeyField]
"""Serialized key in dictionary format."""

TStamp = dt.datetime | UUID | None
"""Timestamp or time-ordered globally unique identifier in UUID7 format."""  # TODO: Confirm UUID format to use

TQuery = Tuple[
    Type,  # Query type and its descendents will be returned by the query. It must include all query and order fields.
    Dict[str, Any],  # NoSQL query conditions in MongoDB format.
    Dict[str, Literal[1, -1]],  # NoSQL query order in MongoDB format.
]
"""NoSQL query data in MongoDB format."""

TRecord = TypeVar("TRecord")
"""Generic type parameter for the record."""

TKey = TypeVar("TKey")
"""Generic type parameter for the key."""

TEnum = TypeVar("TEnum", bound=Enum)
"""Generic type parameter for an enum."""


@runtime_checkable
class KeyProtocol(Protocol):
    """Protocol implemented by keys and also required for records which are derived from keys."""

    @classmethod
    def get_key_type(cls) -> Type:
        """Return key type even when called from a record."""


class RecordProtocol(KeyProtocol):
    """Protocol implemented by records but not keys."""

    def get_key(self) -> KeyProtocol:
        """Return a new key object whose fields populated from self, do not return self."""


class InitProtocol:
    """Protocol implemented by objects that require initialization."""

    def init(self) -> None:
        """Same as __init__ but can be used when field values are set both during and after construction."""


class ValidateProtocol:
    """Protocol implemented by objects that support validation."""

    def validate(self) -> None:
        """Confirm that previously set fields correspond to a valid object state."""


def is_record(type_or_obj: Any) -> TypeGuard[RecordProtocol]:
    """Check if type or object is a key (supports RecordProtocol) based on the presence of 'get_key' attribute."""
    return hasattr(type_or_obj, "get_key")


def is_key(type_or_obj: Any) -> TypeGuard[KeyProtocol]:
    """
    Check if type or object is a key (supports KeyProtocol) but not a record (does not support RecordProtocol)
    based on the presence of 'get_key_type' attribute and the absence of 'get_key' attribute.
    """
    return hasattr(type_or_obj, "get_key_type") and not hasattr(type_or_obj, "get_key")


def has_init(type_or_obj: Any) -> TypeGuard[InitProtocol]:
    """Check if type or object requires initialization (InitProtocol) based on the presence of 'init' attribute."""
    return hasattr(type_or_obj, "init")


def has_validate(type_or_obj: Any) -> TypeGuard[ValidateProtocol]:
    """Check if type or object supports validation (ValidateProtocol) based on the presence of 'validate' attribute."""
    return hasattr(type_or_obj, "validate")

Global variables

var TDataDict

Serialized data in dictionary format.

var TDataField

Supported field types for serialized data in dictionary format.

var TEnum

Generic type parameter for an enum.

var TKey

Generic type parameter for the key.

var TKeyDict

Serialized key in dictionary format.

var TKeyField

Supported field types for serialized key in dictionary format.

var TPrimitive

Supported primitive value types for serialized data in dictionary format.

var TQuery

NoSQL query data in MongoDB format.

var TRecord

Generic type parameter for the record.

var TStamp

Timestamp or time-ordered globally unique identifier in UUID7 format.

Functions

def has_init(type_or_obj: Any) -> TypeGuard[InitProtocol]

Check if type or object requires initialization (InitProtocol) based on the presence of ‘init’ attribute.

def has_validate(type_or_obj: Any) -> TypeGuard[ValidateProtocol]

Check if type or object supports validation (ValidateProtocol) based on the presence of ‘validate’ attribute.

def is_key(type_or_obj: Any) -> TypeGuard[KeyProtocol]

Check if type or object is a key (supports KeyProtocol) but not a record (does not support RecordProtocol) based on the presence of ‘get_key_type’ attribute and the absence of ‘get_key’ attribute.

def is_record(type_or_obj: Any) -> TypeGuard[RecordProtocol]

Check if type or object is a key (supports RecordProtocol) based on the presence of ‘get_key’ attribute.

Classes

class InitProtocol

Protocol implemented by objects that require initialization.

Expand source code
class InitProtocol:
    """Protocol implemented by objects that require initialization."""

    def init(self) -> None:
        """Same as __init__ but can be used when field values are set both during and after construction."""

Methods

def init(self) -> None

Same as init but can be used when field values are set both during and after construction.

class KeyProtocol (*args, **kwargs)

Protocol implemented by keys and also required for records which are derived from keys.

Expand source code
@runtime_checkable
class KeyProtocol(Protocol):
    """Protocol implemented by keys and also required for records which are derived from keys."""

    @classmethod
    def get_key_type(cls) -> Type:
        """Return key type even when called from a record."""

Ancestors

  • typing.Protocol
  • typing.Generic

Subclasses

Static methods

def get_key_type() -> Type

Return key type even when called from a record.

class RecordProtocol (*args, **kwargs)

Protocol implemented by records but not keys.

Expand source code
class RecordProtocol(KeyProtocol):
    """Protocol implemented by records but not keys."""

    def get_key(self) -> KeyProtocol:
        """Return a new key object whose fields populated from self, do not return self."""

Ancestors

Static methods

def get_key_type() -> Type

Inherited from: KeyProtocol.get_key_type

Return key type even when called from a record.

Methods

def get_key(self) -> KeyProtocol

Return a new key object whose fields populated from self, do not return self.

class ValidateProtocol

Protocol implemented by objects that support validation.

Expand source code
class ValidateProtocol:
    """Protocol implemented by objects that support validation."""

    def validate(self) -> None:
        """Confirm that previously set fields correspond to a valid object state."""

Methods

def validate(self) -> None

Confirm that previously set fields correspond to a valid object state.