Merge branch 'main' of github.com:stuartgo/anansyTypes
This commit is contained in:
commit
7d9f4d02d6
8 files changed
+61
-243
No files matched your search
@@ -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"
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -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]]
|
||||
|
||||
@@ -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",
|
||||
]
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -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,
|
||||
)
|
||||
@@ -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"],
|
||||
)
|
||||
@@ -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
|
||||
Reference in new issue
Block a user