From c0d896262f4d1de35756fbfc7ba9c7755bbd138e Mon Sep 17 00:00:00 2001 From: stuartgo Date: Tue, 24 Feb 2026 19:04:48 +0100 Subject: [PATCH 01/19] change embedding serialisation --- anansyTypes/structures/embedding.py | 68 ++++++++++------------------- 1 file changed, 22 insertions(+), 46 deletions(-) diff --git a/anansyTypes/structures/embedding.py b/anansyTypes/structures/embedding.py index ef50d69..929d5e2 100644 --- a/anansyTypes/structures/embedding.py +++ b/anansyTypes/structures/embedding.py @@ -1,55 +1,31 @@ -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 +from pydantic import BaseModel +from pydantic_core import core_schema +from typing_extensions import Annotated -@dataclass(frozen=True) -class Embedding: - data: Tensor[torch.Tensor | np.ndarray[Any, Any], tuple, Literal["int32", "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." - ) - +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 \ No newline at end of file From 2774c707ead0cf347c41bfb4ffcc9ba412078ab8 Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 13:04:54 +0100 Subject: [PATCH 02/19] rewrote the structures --- anansyTypes/structures/embedding.py | 5 +- anansyTypes/structures/lexeme.py | 75 ++++++----------------------- anansyTypes/structures/word.py | 32 +----------- 3 files changed, 19 insertions(+), 93 deletions(-) diff --git a/anansyTypes/structures/embedding.py b/anansyTypes/structures/embedding.py index 929d5e2..33caa29 100644 --- a/anansyTypes/structures/embedding.py +++ b/anansyTypes/structures/embedding.py @@ -3,7 +3,7 @@ import torch from pydantic import BaseModel from pydantic_core import core_schema from typing_extensions import Annotated - +import numpy as np class TensorPydantic: @classmethod @@ -28,4 +28,5 @@ Tensor = Annotated[torch.Tensor, TensorPydantic] class Embedding(BaseModel): - data: Tensor \ No newline at end of file + data: Tensor + \ No newline at end of file diff --git a/anansyTypes/structures/lexeme.py b/anansyTypes/structures/lexeme.py index ee54362..25c1a10 100644 --- a/anansyTypes/structures/lexeme.py +++ b/anansyTypes/structures/lexeme.py @@ -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) \ No newline at end of file diff --git a/anansyTypes/structures/word.py b/anansyTypes/structures/word.py index cf998c9..b4dc073 100644 --- a/anansyTypes/structures/word.py +++ b/anansyTypes/structures/word.py @@ -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 \ No newline at end of file From 50767fed4042dd3d46d6f7cf44c64a2caf2e3043 Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 14:03:05 +0100 Subject: [PATCH 03/19] remoed from_dict and use constructor in lexeme from_dict --- anansyTypes/structures/lexeme.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anansyTypes/structures/lexeme.py b/anansyTypes/structures/lexeme.py index 25c1a10..b891a53 100644 --- a/anansyTypes/structures/lexeme.py +++ b/anansyTypes/structures/lexeme.py @@ -17,7 +17,7 @@ class Lexeme(BaseModel,ABC): return cls( id=data["id"], content=data["content"], - embedding=Embedding.from_dict(data["embedding"]), + embedding=Embedding(data["embedding"]), original_content=data["original_content"], ) def __new__(cls, *args, **kwargs): From f91c4f6b20868ed58b8b0b64645e4bb0c6dc20d8 Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 14:13:00 +0100 Subject: [PATCH 04/19] add from_dict back in --- anansyTypes/structures/embedding.py | 5 +++++ anansyTypes/structures/lexeme.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/anansyTypes/structures/embedding.py b/anansyTypes/structures/embedding.py index 33caa29..b396863 100644 --- a/anansyTypes/structures/embedding.py +++ b/anansyTypes/structures/embedding.py @@ -29,4 +29,9 @@ 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)) + \ No newline at end of file diff --git a/anansyTypes/structures/lexeme.py b/anansyTypes/structures/lexeme.py index b891a53..25c1a10 100644 --- a/anansyTypes/structures/lexeme.py +++ b/anansyTypes/structures/lexeme.py @@ -17,7 +17,7 @@ class Lexeme(BaseModel,ABC): return cls( id=data["id"], content=data["content"], - embedding=Embedding(data["embedding"]), + embedding=Embedding.from_dict(data["embedding"]), original_content=data["original_content"], ) def __new__(cls, *args, **kwargs): From 7cc7d05fc679d959832ed217c00029551876883a Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 14:24:36 +0100 Subject: [PATCH 05/19] fix phrase with new lexeme verion --- anansyTypes/structures/phrase.py | 39 +------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/anansyTypes/structures/phrase.py b/anansyTypes/structures/phrase.py index e1403e2..c226c88 100644 --- a/anansyTypes/structures/phrase.py +++ b/anansyTypes/structures/phrase.py @@ -7,49 +7,12 @@ 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"]) + return cls(id=data["id"], content=data["content"],embedding=None) 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": From 3e4bb3ba9ed2afc89cd006105d7786fb2246d055 Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 14:36:32 +0100 Subject: [PATCH 06/19] new approach to noembeddingphrase --- anansyTypes/structures/phrase.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/anansyTypes/structures/phrase.py b/anansyTypes/structures/phrase.py index c226c88..efd3be2 100644 --- a/anansyTypes/structures/phrase.py +++ b/anansyTypes/structures/phrase.py @@ -7,10 +7,12 @@ import numpy as np class NoEmbeddingPhrase(Lexeme): - @classmethod - def from_dict(cls, data: dict) -> "NoEmbeddingPhrase": - return cls(id=data["id"], content=data["content"],embedding=None) + def __init__(self, id: str, content: str): + super().__init__(id=id, content=content, embedding=None) + @property + def embedding(self): + return None class Phrase(Lexeme): From 1fb00514949c5e9c13426df1b0f3ad435dfd1b4f Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 15:11:42 +0100 Subject: [PATCH 07/19] Make noembeddingphrase just initialise with an empty tensor --- anansyTypes/structures/phrase.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/anansyTypes/structures/phrase.py b/anansyTypes/structures/phrase.py index efd3be2..9d225bf 100644 --- a/anansyTypes/structures/phrase.py +++ b/anansyTypes/structures/phrase.py @@ -1,5 +1,6 @@ from typing import List, Any from pydantic_core import core_schema +import torch from .lexeme import Lexeme from .embedding import Embedding @@ -8,11 +9,9 @@ import numpy as np class NoEmbeddingPhrase(Lexeme): def __init__(self, id: str, content: str): - super().__init__(id=id, content=content, embedding=None) + #initialised with empty embedding + super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=content) - @property - def embedding(self): - return None class Phrase(Lexeme): From 4edcd667ffb75b176bfe6e839a0f19e12ec775e6 Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 15:20:39 +0100 Subject: [PATCH 08/19] add original_content arg to noembeddingphrase --- anansyTypes/structures/phrase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anansyTypes/structures/phrase.py b/anansyTypes/structures/phrase.py index 9d225bf..54ac358 100644 --- a/anansyTypes/structures/phrase.py +++ b/anansyTypes/structures/phrase.py @@ -8,9 +8,9 @@ import numpy as np class NoEmbeddingPhrase(Lexeme): - def __init__(self, id: str, content: str): + def __init__(self, id: str, content: str,original_content: str): #initialised with empty embedding - super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=content) + super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=original_content) class Phrase(Lexeme): From c41246a6001f2f2bac1730dc0abc3d4d78661248 Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 15:29:11 +0100 Subject: [PATCH 09/19] remove original_content arg --- anansyTypes/structures/phrase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anansyTypes/structures/phrase.py b/anansyTypes/structures/phrase.py index 54ac358..9d225bf 100644 --- a/anansyTypes/structures/phrase.py +++ b/anansyTypes/structures/phrase.py @@ -8,9 +8,9 @@ import numpy as np class NoEmbeddingPhrase(Lexeme): - def __init__(self, id: str, content: str,original_content: str): + def __init__(self, id: str, content: str): #initialised with empty embedding - super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=original_content) + super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=content) class Phrase(Lexeme): From d51322d34f55145a8ebc7cdcae79dc7adc57585c Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 15:37:27 +0100 Subject: [PATCH 10/19] add original_content back in, fuuuuuuck --- anansyTypes/structures/phrase.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/anansyTypes/structures/phrase.py b/anansyTypes/structures/phrase.py index 9d225bf..54ac358 100644 --- a/anansyTypes/structures/phrase.py +++ b/anansyTypes/structures/phrase.py @@ -8,9 +8,9 @@ import numpy as np class NoEmbeddingPhrase(Lexeme): - def __init__(self, id: str, content: str): + def __init__(self, id: str, content: str,original_content: str): #initialised with empty embedding - super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=content) + super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=original_content) class Phrase(Lexeme): From 15afc9d48177fb6a0fe501c3cf8a79d28d32ae7b Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 15:46:21 +0100 Subject: [PATCH 11/19] add from_dict in noembeddingphrase --- anansyTypes/structures/phrase.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/anansyTypes/structures/phrase.py b/anansyTypes/structures/phrase.py index 54ac358..c032944 100644 --- a/anansyTypes/structures/phrase.py +++ b/anansyTypes/structures/phrase.py @@ -12,6 +12,13 @@ class NoEmbeddingPhrase(Lexeme): #initialised with empty embedding super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=original_content) + @classmethod + def from_dict(cls, data: dict) -> "NoEmbeddingPhrase": + return cls( + id=data["id"], + content=data["content"], + original_content=data["original_content"], + ) class Phrase(Lexeme): @@ -20,6 +27,7 @@ class Phrase(Lexeme): return cls( id=data["id"], content=data["content"], + original_content=data["original_content"], embedding=Embedding.from_dict(data["embedding"]), ) @@ -30,5 +38,6 @@ class Phrase(Lexeme): return cls( id=phrase.id, content=phrase.content, + original_content=phrase.original_content, embedding=embedding, ) From 15a06521b3995dd3cfb1cfe358b3c7f89c1cc8ca Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 15:56:17 +0100 Subject: [PATCH 12/19] add model validator that removes embedding field passed --- anansyTypes/structures/phrase.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/anansyTypes/structures/phrase.py b/anansyTypes/structures/phrase.py index c032944..4bd91a7 100644 --- a/anansyTypes/structures/phrase.py +++ b/anansyTypes/structures/phrase.py @@ -1,4 +1,5 @@ from typing import List, Any +from pydantic import model_validator from pydantic_core import core_schema import torch @@ -19,6 +20,12 @@ class NoEmbeddingPhrase(Lexeme): content=data["content"], original_content=data["original_content"], ) + @model_validator(mode="before") + @classmethod + def ignore_embedding(cls, values): + # Remove embedding from incoming data + values.pop("embedding", None) + return values class Phrase(Lexeme): From ed01ec414e538ee3e848785261760ca8a6331ebc Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 16:05:49 +0100 Subject: [PATCH 13/19] fuck noembeddingphrase --- anansyTypes/schemas.py | 4 +-- anansyTypes/structures/phrase.py | 54 ++++++++++++++++---------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/anansyTypes/schemas.py b/anansyTypes/schemas.py index 0457c34..719d7b7 100644 --- a/anansyTypes/schemas.py +++ b/anansyTypes/schemas.py @@ -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]] diff --git a/anansyTypes/structures/phrase.py b/anansyTypes/structures/phrase.py index 4bd91a7..08f85ee 100644 --- a/anansyTypes/structures/phrase.py +++ b/anansyTypes/structures/phrase.py @@ -8,24 +8,24 @@ from .embedding import Embedding import numpy as np -class NoEmbeddingPhrase(Lexeme): - def __init__(self, id: str, content: str,original_content: str): - #initialised with empty embedding - super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=original_content) +# class NoEmbeddingPhrase(Lexeme): +# def __init__(self, id: str, content: str,original_content: str): +# #initialised with empty embedding +# super().__init__(id=id, content=content, embedding=Embedding(data=torch.tensor([])), original_content=original_content) - @classmethod - def from_dict(cls, data: dict) -> "NoEmbeddingPhrase": - return cls( - id=data["id"], - content=data["content"], - original_content=data["original_content"], - ) - @model_validator(mode="before") - @classmethod - def ignore_embedding(cls, values): - # Remove embedding from incoming data - values.pop("embedding", None) - return values +# @classmethod +# def from_dict(cls, data: dict) -> "NoEmbeddingPhrase": +# return cls( +# id=data["id"], +# content=data["content"], +# original_content=data["original_content"], +# ) +# @model_validator(mode="before") +# @classmethod +# def ignore_embedding(cls, values): +# # Remove embedding from incoming data +# values.pop("embedding", None) +# return values class Phrase(Lexeme): @@ -38,13 +38,13 @@ class Phrase(Lexeme): embedding=Embedding.from_dict(data["embedding"]), ) - @classmethod - def from_noembeddingphrase( - cls, phrase: NoEmbeddingPhrase, embedding: Embedding - ) -> "Phrase": - return cls( - id=phrase.id, - content=phrase.content, - original_content=phrase.original_content, - embedding=embedding, - ) + # @classmethod + # def from_noembeddingphrase( + # cls, phrase: NoEmbeddingPhrase, embedding: Embedding + # ) -> "Phrase": + # return cls( + # id=phrase.id, + # content=phrase.content, + # original_content=phrase.original_content, + # embedding=embedding, + # ) From a0f3fa492f3ba0b8f45792ca24ae1fbdc47bb97f Mon Sep 17 00:00:00 2001 From: stuartgo Date: Wed, 25 Feb 2026 16:11:23 +0100 Subject: [PATCH 14/19] completely remove noembeddingphrase --- anansyTypes/__init__.py | 3 +-- anansyTypes/schemas.py | 2 +- anansyTypes/structures/__init__.py | 3 +-- anansyTypes/structures/lexeme.py | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/anansyTypes/__init__.py b/anansyTypes/__init__.py index e52d7e0..7d245de 100644 --- a/anansyTypes/__init__.py +++ b/anansyTypes/__init__.py @@ -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", diff --git a/anansyTypes/schemas.py b/anansyTypes/schemas.py index 719d7b7..0050e55 100644 --- a/anansyTypes/schemas.py +++ b/anansyTypes/schemas.py @@ -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 diff --git a/anansyTypes/structures/__init__.py b/anansyTypes/structures/__init__.py index 22bf775..7ac324a 100644 --- a/anansyTypes/structures/__init__.py +++ b/anansyTypes/structures/__init__.py @@ -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", ] diff --git a/anansyTypes/structures/lexeme.py b/anansyTypes/structures/lexeme.py index 25c1a10..f460b33 100644 --- a/anansyTypes/structures/lexeme.py +++ b/anansyTypes/structures/lexeme.py @@ -19,7 +19,7 @@ class Lexeme(BaseModel,ABC): 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") From 3e07027aa56226d5b2e3195d8222a79ce4a8aa6d Mon Sep 17 00:00:00 2001 From: stuartgo Date: Thu, 26 Feb 2026 10:02:56 +0100 Subject: [PATCH 15/19] change symbol to use str object instead of bytes --- anansyTypes/structures/symbol.py | 52 ++------------------------------ 1 file changed, 3 insertions(+), 49 deletions(-) diff --git a/anansyTypes/structures/symbol.py b/anansyTypes/structures/symbol.py index fa211f9..770138c 100644 --- a/anansyTypes/structures/symbol.py +++ b/anansyTypes/structures/symbol.py @@ -1,6 +1,7 @@ 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 @@ -8,54 +9,7 @@ import base64 @dataclass -class Symbol: +class Symbol(BaseModel): id: int label: str - image: bytes - - @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: str # Base64-encoded PNG image data From a750653b3bcf12b7812243fe674922958d5324aa Mon Sep 17 00:00:00 2001 From: stuartgo Date: Thu, 26 Feb 2026 10:14:06 +0100 Subject: [PATCH 16/19] remove data class decorator from symbol --- anansyTypes/structures/symbol.py | 1 - 1 file changed, 1 deletion(-) diff --git a/anansyTypes/structures/symbol.py b/anansyTypes/structures/symbol.py index 770138c..b96c4bf 100644 --- a/anansyTypes/structures/symbol.py +++ b/anansyTypes/structures/symbol.py @@ -8,7 +8,6 @@ from pydantic_core import core_schema import base64 -@dataclass class Symbol(BaseModel): id: int label: str From 34384ba8285abd47e17d2757d8f16db91e602b6d Mon Sep 17 00:00:00 2001 From: stuartgo Date: Thu, 26 Feb 2026 10:22:11 +0100 Subject: [PATCH 17/19] add from dict to symbol --- anansyTypes/structures/symbol.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/anansyTypes/structures/symbol.py b/anansyTypes/structures/symbol.py index b96c4bf..2416da4 100644 --- a/anansyTypes/structures/symbol.py +++ b/anansyTypes/structures/symbol.py @@ -12,3 +12,11 @@ class Symbol(BaseModel): id: int label: str image: str # Base64-encoded PNG image data + + + def from_dict(cls, data: dict) -> "Symbol": + return cls( + id=data["id"], + label=data["label"], + image=data["image"], + ) \ No newline at end of file From 05488acd23db4f2eae958f19a065c0ba1934bf30 Mon Sep 17 00:00:00 2001 From: stuartgo Date: Thu, 26 Feb 2026 10:30:12 +0100 Subject: [PATCH 18/19] add decordator to from dict in syumbol --- anansyTypes/structures/symbol.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anansyTypes/structures/symbol.py b/anansyTypes/structures/symbol.py index 2416da4..28d7e44 100644 --- a/anansyTypes/structures/symbol.py +++ b/anansyTypes/structures/symbol.py @@ -13,7 +13,7 @@ class Symbol(BaseModel): label: str image: str # Base64-encoded PNG image data - + @classmethod def from_dict(cls, data: dict) -> "Symbol": return cls( id=data["id"], From 5e18bdd7dac7333850a6f1e5f7dc705675f547e3 Mon Sep 17 00:00:00 2001 From: stuartgo Date: Fri, 27 Feb 2026 11:55:30 +0100 Subject: [PATCH 19/19] add currency and subscriptiontype to init --- anansyTypes/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/anansyTypes/__init__.py b/anansyTypes/__init__.py index 7d245de..2a00b1d 100644 --- a/anansyTypes/__init__.py +++ b/anansyTypes/__init__.py @@ -26,6 +26,8 @@ __all__ = [ "PreprocessorType", "SymbolProvider", "Language", + "Currency", + "SubscriptionType" ]