Skip to content

Commit

Permalink
restructed the folder structure
Browse files Browse the repository at this point in the history
  • Loading branch information
chandralegend committed Sep 13, 2024
1 parent 542188d commit 3166922
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 86 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
</picture>

[![PyPI version](https://img.shields.io/pypi/v/semantix.svg)](https://pypi.org/project/semantix/) [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/chandralegend/semantix/blob/main/try.ipynb) ![License](https://img.shields.io/badge/License-MIT-blue.svg)
</div>

Semantix provides a simple but powerful way to infuse meaning into functions, variables and classes to leverage the power of Large Language models to generate structured typed outputs without the need of JSON Schema or any other abstractions.
Semantix provides a simple but powerful way to infuse meaning into functions, variables and classes to leverage the power of Large Language models to generate structured typed outputs `without the need of JSON Schema or any other abstractions.`

</div>

## Key Features:

Expand Down
9 changes: 5 additions & 4 deletions examples/personality_finder_vision.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from semantix import Semantic, with_llm
from semantix.llms.openai import OpenAI
from semantix.media import Image
from enum import Enum
from typing import List

from semantix import Semantic, with_llm
from semantix.llms.openai import OpenAI
from semantix.types import Image

llm = OpenAI()


Expand Down Expand Up @@ -61,5 +62,5 @@ def get_person_info(


if __name__ == "__main__":
person_obj = get_person_info(img=Image("mandela.jpg"))
person_obj = get_person_info(img=Image("examples/mandela.jpg"))
print(person_obj)
5 changes: 2 additions & 3 deletions semantix/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Semantix is a Python library that give superpowers to your code."""

from semantix.decorators import tool, with_llm
from semantix.media import Image, Video
from semantix.types import Semantic, SemanticClass
from semantix.types.semantic import Semantic, SemanticClass

__all__ = ["Semantic", "with_llm", "tool", "Image", "Video", "SemanticClass"]
__all__ = ["Semantic", "with_llm", "tool", "SemanticClass"]
3 changes: 2 additions & 1 deletion semantix/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
PromptInfo,
)
from semantix.llms.base import BaseLLM
from semantix.types import Information, OutputHint, Semantic, Tool, TypeExplanation
from semantix.types.prompt import Information, OutputHint, Tool, TypeExplanation
from semantix.types.semantic import Semantic
from semantix.utils import get_semstr


Expand Down
2 changes: 1 addition & 1 deletion semantix/inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import List

from semantix.llms.base import BaseLLM
from semantix.types import Information, OutputHint, Tool, TypeExplanation
from semantix.types.prompt import Information, OutputHint, Tool, TypeExplanation


class PromptInfo:
Expand Down
5 changes: 5 additions & 0 deletions semantix/types/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Type definitions for Semantix."""

from semantix.types.media import Image, Video

__all__ = ["Image", "Video"]
4 changes: 2 additions & 2 deletions semantix/media.py → semantix/types/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ def __init__(self, file_path: str) -> None:
"""Initializes the Image class."""
assert (
PILImage is not None
), "Please install the required dependencies by running `pip install mtllm[image]`."
), "Please install the required dependencies by running `pip install semantix[image]`."
self.file_path = file_path

def process(self) -> Tuple[str, str]:
"""Processes the image and returns a base64 encoded image and its format."""
assert (
PILImage is not None
), "Please install the required dependencies by running `pip install mtllm[image]`."
), "Please install the required dependencies by running `pip install semantix[image]`."
image = PILImage.open(self.file_path)
img_format = image.format
with BytesIO() as buffer:
Expand Down
76 changes: 3 additions & 73 deletions semantix/types.py → semantix/types/prompt.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
"""This module contains the classes and functions to represent the types and information needed for the library."""
"""Module to represent the prompt types."""

import inspect
import sys
from enum import Enum
from types import FrameType
from typing import Any, Callable, Dict, Generic, List, Type, TypeVar, Union
from typing import Any, Callable, Dict, List, Type, Union

from semantix.types.semantic import Semantic
from semantix.utils import (
extract_non_primary_type,
get_object_string,
Expand All @@ -14,75 +13,6 @@
)


T = TypeVar("T")


class SemanticMeta(type):
"""Metaclass for the Semantic class."""

def __new__(
mcs, name: str, bases: tuple, namespace: dict, **kwargs: dict # noqa: N804
) -> Any: # noqa: ANN401
"""Creates a new instance of the class."""
cls = super().__new__(mcs, name, bases, namespace)
if "meaning" in kwargs and hasattr(cls, "meaning"):
cls._meaning = kwargs["meaning"] # type: ignore
return cls

def __getitem__(cls, params: tuple) -> Type[T]:
"""Get the item from the class."""
if not isinstance(params, tuple) or len(params) != 2:
raise TypeError("Semantic requires two parameters: type and meaning")
typ, meaning = params
curr_frame = inspect.currentframe()
if curr_frame:
frame = curr_frame.f_back
if not frame:
raise Exception("Cannot get the current frame.")
var_name = list(frame.f_locals.keys())[-1]
# Set the meaning of the variable in the module's global scope
if var_name:
setattr(
sys.modules[frame.f_globals["__name__"]], f"{var_name}_meaning", meaning
)
return type(
f"MT_{get_type(typ)}", (cls,), {"wrapped_type": typ, "_meaning": meaning}
)


class Semantic(Generic[T], metaclass=SemanticMeta):
"""Class to represent the semantic type."""

wrapped_type: Type[T]
_meaning: str = ""

def __new__(cls, *args: list, **kwargs: dict) -> Any: # noqa: ANN401
"""Creates a new instance of the class."""
return cls.wrapped_type(*args, **kwargs)

def __instancecheck__(self, instance: Any) -> bool: # noqa: ANN401
"""Check if the instance is of the class."""
return isinstance(instance, self.wrapped_type)

def __subclasscheck__(self, subclass: Type) -> bool:
"""Check if the subclass is of the class."""
return issubclass(subclass, self.wrapped_type)

def __repr__(self) -> str:
"""Get the representation of the class."""
return f"{self.wrapped_type.__name__} {self._meaning}"


class SemanticClass:
"""Class to represent the semantic class."""

@classmethod
def init(cls, *args: list, **kwargs: dict) -> Any: # noqa: ANN401
"""Initialize the class."""
# TODO: Implement the initialization of the class with llms
return cls.__class__(*args, **kwargs)


class TypeExplanation:
"""Class to represent the type explanation."""

Expand Down
76 changes: 76 additions & 0 deletions semantix/types/semantic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""This module contains the classes and functions to represent the types and information needed for the library."""

import inspect
import sys
from typing import Any, Generic, Type, TypeVar

from semantix.utils import get_type


T = TypeVar("T")


class SemanticMeta(type):
"""Metaclass for the Semantic class."""

def __new__(
mcs, name: str, bases: tuple, namespace: dict, **kwargs: dict # noqa: N804
) -> Any: # noqa: ANN401
"""Creates a new instance of the class."""
cls = super().__new__(mcs, name, bases, namespace)
if "meaning" in kwargs and hasattr(cls, "meaning"):
cls._meaning = kwargs["meaning"] # type: ignore
return cls

def __getitem__(cls, params: tuple) -> Type[T]:
"""Get the item from the class."""
if not isinstance(params, tuple) or len(params) != 2:
raise TypeError("Semantic requires two parameters: type and meaning")
typ, meaning = params
curr_frame = inspect.currentframe()
if curr_frame:
frame = curr_frame.f_back
if not frame:
raise Exception("Cannot get the current frame.")
var_name = list(frame.f_locals.keys())[-1]
# Set the meaning of the variable in the module's global scope
if var_name:
setattr(
sys.modules[frame.f_globals["__name__"]], f"{var_name}_meaning", meaning
)
return type(
f"MT_{get_type(typ)}", (cls,), {"wrapped_type": typ, "_meaning": meaning}
)


class Semantic(Generic[T], metaclass=SemanticMeta):
"""Class to represent the semantic type."""

wrapped_type: Type[T]
_meaning: str = ""

def __new__(cls, *args: list, **kwargs: dict) -> Any: # noqa: ANN401
"""Creates a new instance of the class."""
return cls.wrapped_type(*args, **kwargs)

def __instancecheck__(self, instance: Any) -> bool: # noqa: ANN401
"""Check if the instance is of the class."""
return isinstance(instance, self.wrapped_type)

def __subclasscheck__(self, subclass: Type) -> bool:
"""Check if the subclass is of the class."""
return issubclass(subclass, self.wrapped_type)

def __repr__(self) -> str:
"""Get the representation of the class."""
return f"{self.wrapped_type.__name__} {self._meaning}"


class SemanticClass:
"""Class to represent the semantic class."""

@classmethod
def init(cls, *args: list, **kwargs: dict) -> Any: # noqa: ANN401
"""Initialize the class."""
# TODO: Implement the initialization of the class with llms
return cls.__class__(*args, **kwargs)

0 comments on commit 3166922

Please sign in to comment.