Merge branch 'main' of github.com:stuartgo/anansyTypes

This commit is contained in:
Christoph Eder committed 2026-03-03 16:38:14 +01:00
commit 7d9f4d02d6
8 files changed
+61 -243

No files matched your search

+3 -2
View File
@@ -1,6 +1,6 @@
from .enums import *
from .schemas import *
from .structures import Embedding, Word, Symbol, Phrase,Lexeme,NoEmbeddingPhrase
from .structures import Embedding, Word, Symbol, Phrase,Lexeme
__all__ = [
@@ -11,7 +11,6 @@ __all__ = [
"Symbol",
"Phrase",
"Lexeme",
"NoEmbeddingPhrase",
"EmbedRequest",
"EmbeddingResponse",
"ResponseRequest",
@@ -28,6 +27,8 @@ __all__ = [
"SymbolProvider",
"Language",
"DiscountType",
"Currency",
"SubscriptionType"
]
+3 -3
View File
@@ -2,7 +2,7 @@ from pydantic import BaseModel as PydanticBaseModel
from typing import List, Any, Dict, Optional,Union
from .structures import Embedding,Word, Symbol,Phrase,NoEmbeddingPhrase
from .structures import Embedding,Word, Symbol,Phrase
from pydantic import field_validator, ConfigDict
from pydantic_tensor import Tensor
import torch
@@ -50,10 +50,10 @@ class GetSimilarWordRequest(ModifiedBaseModel):
embedding: Embedding
class GetAllPhrasesResponse(ModifiedBaseModel):
phrases: Optional[List[NoEmbeddingPhrase]]
phrases: Optional[List[Phrase]]
class GetFullPhrasesRequest(ModifiedBaseModel):
phrases: List[NoEmbeddingPhrase]
phrases: List[Phrase]
class GetFullPhrasesResponse(ModifiedBaseModel):
phrases: Optional[List[Phrase]]
+1 -2
View File
@@ -2,7 +2,7 @@ from .embedding import Embedding
from .lexeme import Lexeme
from .word import Word
from .symbol import Symbol
from .phrase import Phrase,NoEmbeddingPhrase
from .phrase import Phrase
__all__ = [
@@ -11,5 +11,4 @@ __all__ = [
"Word",
"Symbol",
"Phrase",
"NoEmbeddingPhrase",
]
+29 -47
View File
@@ -1,55 +1,37 @@
from __future__ import annotations
from dataclasses import dataclass
import numpy as np
from pydantic_tensor import Tensor
from typing import Any
import torch
from typing import Any, Literal
@dataclass(frozen=True)
class Embedding:
data: Tensor[torch.Tensor | np.ndarray[Any], tuple, Literal["int64"]]
def compare(self, other: Embedding) -> float:
"""
Compare this embedding with another embedding.
"""
if isinstance(self.data, np.ndarray) and isinstance(other.data, np.ndarray):
# Simple example: L2 distance (Euclidean distance)
return np.linalg.norm(self.data - other.data)
# Fallback or error if not implemented for other types (e.g., torch.Tensor)
raise NotImplementedError(
"Comparison must be implemented for all supported data types."
)
from pydantic import BaseModel
from pydantic_core import core_schema
from typing_extensions import Annotated
import numpy as np
class TensorPydantic:
@classmethod
def from_dict(cls, data: dict) -> "Embedding":
return cls(data=np.array(data["data"], dtype=np.float32))
def __get_pydantic_core_schema__(cls, source, handler):
def validate(v: Any):
if isinstance(v, torch.Tensor):
return v
if isinstance(v, list):
return torch.tensor(v, dtype=torch.float32)
raise TypeError(f"Cannot convert {type(v)} to torch.Tensor")
@classmethod
def __get_pydantic_core_schema__(cls, source_type: Any, handler):
from pydantic_core import core_schema
def validate_embedding(value):
if isinstance(value, cls):
return value
if isinstance(value, dict):
return cls.from_dict(value)
raise ValueError(f"Cannot convert {type(value)} to Embedding")
python_schema = core_schema.with_info_plain_validator_function(
lambda value, _: validate_embedding(value),
return core_schema.json_or_python_schema(
json_schema=core_schema.list_schema(core_schema.any_schema()),
python_schema=core_schema.no_info_plain_validator_function(validate),
serialization=core_schema.plain_serializer_function_ser_schema(
lambda x: {"data": x.data.tolist()},
when_used="json",
lambda t: t.detach().cpu().tolist()
),
)
return core_schema.json_or_python_schema(
json_schema=core_schema.typed_dict_schema({
'data': core_schema.typed_dict_field(core_schema.list_schema())
}),
python_schema=python_schema,
)
Tensor = Annotated[torch.Tensor, TensorPydantic]
class Embedding(BaseModel):
data: Tensor
@classmethod
def from_dict(cls, data: dict) -> "Embedding":
return cls(data=torch.tensor(data["data"], dtype=torch.float32))
+16 -61
View File
@@ -1,71 +1,26 @@
from abc import ABC, abstractmethod
from typing import List, Union, Any
from dataclasses import dataclass
from pydantic import BaseModel
from .embedding import Embedding
@dataclass
class Lexeme(ABC):
class Lexeme(BaseModel,ABC):
id: int
@property
@abstractmethod
def content(self) -> Union[str, List[str]]:
"""Text content of the lexeme."""
pass
content: Union[str, List[str]]
original_content: Union[str, List[str]]
embedding: Embedding
@property
@abstractmethod
def original_content(self) -> Union[str, List[str]]:
"""Original text content of the lexeme."""
pass
@property
@abstractmethod
def embedding(self) -> Embedding:
"""Embedding(s) associated with the lexeme."""
pass
@classmethod
@abstractmethod
def from_dict(cls, data: dict) -> "Lexeme":
"""Create instance from dictionary."""
pass
@classmethod
def __get_pydantic_core_schema__(cls, source_type: Any, handler):
from pydantic_core import core_schema
def validate_lexeme(value):
if isinstance(value, cls):
return value
if isinstance(value, dict):
return cls.from_dict(value)
raise ValueError(f"Cannot convert {type(value)} to {cls.__name__}")
python_schema = core_schema.with_info_plain_validator_function(
lambda value, _: validate_lexeme(value),
serialization=core_schema.plain_serializer_function_ser_schema(
lambda x: {
"id": x.id,
"content": x.content,
"original_content": x.original_content,
"embedding": {"data": x.embedding.data.tolist()},
},
when_used="json",
),
)
return core_schema.json_or_python_schema(
json_schema=core_schema.typed_dict_schema(
{
"id": core_schema.typed_dict_field(core_schema.int_schema()),
"original_content": core_schema.typed_dict_field(core_schema.str_schema()),
"content": core_schema.typed_dict_field(core_schema.str_schema()),
"embedding": core_schema.typed_dict_field(
handler.generate_schema(Embedding)
),
}
),
python_schema=python_schema,
)
return cls(
id=data["id"],
content=data["content"],
embedding=Embedding.from_dict(data["embedding"]),
original_content=data["original_content"],
)
def __new__(cls, *args, **kwargs):
if cls is Lexeme:
raise TypeError("Lexeme cannot be instantiated, use a subclass instead")
return super().__new__(cls)
+3 -53
View File
@@ -1,70 +1,20 @@
from typing import List, Any
from pydantic import model_validator
from pydantic_core import core_schema
import torch
from .lexeme import Lexeme
from .embedding import Embedding
import numpy as np
class NoEmbeddingPhrase(Lexeme):
def __init__(self, id: int, content: str):
self.id = id
self._content = content
self._original_content = content
self._embedding = np.array([]) # Placeholder to avoid attribute errors
@property
def content(self) -> str:
return self._content
@property
def original_content(self) -> str:
#temporarily return content as original_content
return self._content
@property
def embedding(self) -> Embedding:
return self._embedding
@classmethod
def from_dict(cls, data: dict) -> "NoEmbeddingPhrase":
return cls(id=data["id"], content=data["content"])
class Phrase(Lexeme):
def __init__(self, id: int, content: str, embedding: Embedding):
self.id = id
self._content = content
self._original_content = content
self._embedding = embedding
@property
def content(self) -> str:
return self._content
@property
def original_content(self) -> str:
#temporarily return content as original_content
return self._content
@property
def embedding(self) -> Embedding:
return self._embedding
@classmethod
def from_dict(cls, data: dict) -> "Phrase":
return cls(
id=data["id"],
content=data["content"],
original_content=data["original_content"],
embedding=Embedding.from_dict(data["embedding"]),
)
@classmethod
def from_noembeddingphrase(
cls, phrase: NoEmbeddingPhrase, embedding: Embedding
) -> "Phrase":
return cls(
id=phrase.id,
content=phrase.content,
embedding=embedding,
)
+5 -44
View File
@@ -1,61 +1,22 @@
from dataclasses import dataclass
from typing import Any
import numpy as np
from pydantic import BaseModel
from pydantic_tensor import Tensor
from typing import Any, Literal
from pydantic_core import core_schema
import base64
@dataclass
class Symbol:
class Symbol(BaseModel):
id: int
label: str
image: bytes
image: str # Base64-encoded PNG image data
@classmethod
def from_dict(cls, data: dict) -> "Symbol":
if isinstance(data["image"], str):
image_bytes = base64.b64decode(data["image"])
else:
image_bytes = bytes(data["image"])
return cls(
id=data["id"],
label=data["label"],
image=image_bytes,
)
@classmethod
def __get_pydantic_core_schema__(cls, source_type: Any, handler):
from pydantic_core import core_schema
def validate_symbol(value):
if isinstance(value, cls):
return value
if isinstance(value, dict):
return cls.from_dict(value)
raise ValueError(f"Cannot convert {type(value)} to Symbol")
python_schema = core_schema.with_info_plain_validator_function(
lambda value, _: validate_symbol(value),
serialization=core_schema.plain_serializer_function_ser_schema(
lambda x: {
"id": x.id,
"label": x.label,
"image": base64.b64encode(x.image).decode("utf-8"),
},
when_used="json",
),
)
return core_schema.json_or_python_schema(
json_schema=core_schema.typed_dict_schema(
{
"id": core_schema.typed_dict_field(core_schema.int_schema()),
"label": core_schema.typed_dict_field(core_schema.str_schema()),
"image": core_schema.typed_dict_field(core_schema.str_schema()),
}
),
python_schema=python_schema,
)
image=data["image"],
)
+1 -31
View File
@@ -5,34 +5,4 @@ from pydantic_core import core_schema
class Word(Lexeme):
def __init__(self, word_id: int, content: str,original_content: str, embedding: Embedding):
self.id = word_id
self._content = content
self._original_content = original_content
self._embedding = embedding
@property
def content(self) -> str:
return self._content
@property
def original_content(self) -> str:
return self._original_content
@property
def embedding(self) -> Embedding:
return self._embedding
def __str__(self):
return self.content
def __repr__(self):
return self.__str__()
@classmethod
def from_dict(cls, data: dict) -> "Word":
return cls(
word_id=data["id"],
content=data["content"],
embedding=Embedding.from_dict(data["embedding"]),
original_content=data["original_content"],
)
pass