From abc8783477266b188719708df9b061e2807745e6 Mon Sep 17 00:00:00 2001 From: Simonas <20096648+simjak@users.noreply.github.com> Date: Wed, 10 Jan 2024 10:54:32 +0200 Subject: [PATCH] feat: compatible with python 3.9 --- .gitignore | 3 +++ .pre-commit-config.yaml | 14 ++++++-------- Makefile | 4 ++-- poetry.lock | 8 ++++---- pyproject.toml | 4 ++-- replace.py | 23 +++++++++++++++++++++++ semantic_router/encoders/bm25.py | 4 ++-- semantic_router/encoders/cohere.py | 7 ++++--- semantic_router/encoders/openai.py | 7 ++++--- semantic_router/hybrid_layer.py | 3 ++- semantic_router/layer.py | 13 +++++++------ semantic_router/llms/base.py | 4 +++- semantic_router/llms/cohere.py | 7 ++++--- semantic_router/llms/openai.py | 11 ++++++----- semantic_router/llms/openrouter.py | 13 +++++++------ semantic_router/route.py | 5 +++-- semantic_router/schema.py | 9 +++++---- semantic_router/utils/llm.py | 5 +++-- test_output.txt | 0 19 files changed, 90 insertions(+), 54 deletions(-) create mode 100644 replace.py delete mode 100644 test_output.txt diff --git a/.gitignore b/.gitignore index cb4c0022..41aac4aa 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,9 @@ venv/ .idea **/__pycache__ **/*.py[cod] +node_modules +package-lock.json +package.json # local env files .env*.local diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 64e5c9e1..daf970d5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ default_language_version: - python: python3.12 + python: python3.9 repos: - repo: meta hooks: @@ -17,14 +17,12 @@ repos: - id: blacken-docs additional_dependencies: [black==22.10.0] - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.0.290 + - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook + rev: v9.11.0 hooks: - - id: ruff - types_or: [ python, pyi, jupyter ] - args: [ --fix ] - - id: ruff-format - types_or: [ python, pyi, jupyter ] + - id: commitlint + stages: [commit-msg] + additional_dependencies: ['@commitlint/config-conventional'] - repo: https://github.com/codespell-project/codespell rev: v2.2.4 diff --git a/Makefile b/Makefile index aeb3d3b1..adf4eb0c 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ format: - poetry run black . + poetry run black --target-version py39 . poetry run ruff --select I --fix . PYTHON_FILES=. @@ -7,7 +7,7 @@ lint: PYTHON_FILES=. lint_diff: PYTHON_FILES=$(shell git diff --name-only --diff-filter=d main | grep -E '\.py$$') lint lint_diff: - poetry run black $(PYTHON_FILES) --check + poetry run black --target-version py39 $(PYTHON_FILES) --check poetry run ruff . poetry run mypy $(PYTHON_FILES) diff --git a/poetry.lock b/poetry.lock index 3b8775c6..3131c0d8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -440,13 +440,13 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "cohere" -version = "4.40" +version = "4.41" description = "Python SDK for the Cohere API" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "cohere-4.40-py3-none-any.whl", hash = "sha256:75dac8369d97fadc05901352d9db64a0ca6cd40c08423f3c4691f57eb7b131e7"}, - {file = "cohere-4.40.tar.gz", hash = "sha256:d9e5c1fa7f80a193c03330a634954b927bf188ead7dcfdb51865480f73aebda8"}, + {file = "cohere-4.41-py3-none-any.whl", hash = "sha256:39470cc412fa96a1c612f522d48d7d86b34b3163a04030cff83ec48ebbaff32f"}, + {file = "cohere-4.41.tar.gz", hash = "sha256:8509ca196dc038eca81e474d3cd5896da2ea168a4d3c578b4cb6969994be34ef"}, ] [package.dependencies] @@ -2696,4 +2696,4 @@ hybrid = ["pinecone-text"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "bd435dd14b07738872f14483a7a781ea4a16394c4739917e487acde26235cfae" +content-hash = "3e3b13e2493e7bef6ef1d9487d4618f834f3387a55379edf63d00f76fe4def0a" diff --git a/pyproject.toml b/pyproject.toml index 90b97835..bbe14c56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,10 +18,10 @@ python = "^3.9" pydantic = "^1.8.2" openai = "^1.3.9" cohere = "^4.32" -numpy = "^1.24.3" -pinecone-text = {version = "^0.7.0", optional = true} +numpy = "^1.25.2" colorlog = "^6.8.0" pyyaml = "^6.0.1" +pinecone-text = {version = "^0.7.1", optional = true, python = "<3.12"} fastembed = {version = "^0.1.3", optional = true, python = "<3.12"} [tool.poetry.extras] diff --git a/replace.py b/replace.py new file mode 100644 index 00000000..d1fbe597 --- /dev/null +++ b/replace.py @@ -0,0 +1,23 @@ +import re +import os + + +def replace_type_hints(file_path): + with open(file_path, "rb") as file: + file_data = file.read() + + # Decode the file data with error handling + file_data = file_data.decode("utf-8", errors="ignore") + + # Regular expression pattern to find '| None' and replace with 'Optional' + file_data = re.sub(r"(\w+)\s*\|\s*None", r"Optional[\1]", file_data) + + with open(file_path, "w") as file: + file.write(file_data) + + +# Walk through the repository and update all .py files +for root, dirs, files in os.walk("/Users/jakit/customers/aurelio/semantic-router"): + for file in files: + if file.endswith(".py"): + replace_type_hints(os.path.join(root, file)) diff --git a/semantic_router/encoders/bm25.py b/semantic_router/encoders/bm25.py index e96e4d7d..11a964b6 100644 --- a/semantic_router/encoders/bm25.py +++ b/semantic_router/encoders/bm25.py @@ -1,11 +1,11 @@ -from typing import Any +from typing import Any, Optional from semantic_router.encoders import BaseEncoder from semantic_router.utils.logger import logger class BM25Encoder(BaseEncoder): - model: Any | None = None + model: Optional[Any] = None idx_mapping: dict[int, int] | None = None type: str = "sparse" diff --git a/semantic_router/encoders/cohere.py b/semantic_router/encoders/cohere.py index 2f80aaaf..ec8ee0f8 100644 --- a/semantic_router/encoders/cohere.py +++ b/semantic_router/encoders/cohere.py @@ -1,4 +1,5 @@ import os +from typing import Optional import cohere @@ -6,13 +7,13 @@ from semantic_router.encoders import BaseEncoder class CohereEncoder(BaseEncoder): - client: cohere.Client | None = None + client: Optional[cohere.Client] = None type: str = "cohere" def __init__( self, - name: str | None = None, - cohere_api_key: str | None = None, + name: Optional[str] = None, + cohere_api_key: Optional[str] = None, score_threshold: float = 0.3, ): if name is None: diff --git a/semantic_router/encoders/openai.py b/semantic_router/encoders/openai.py index 4ec87638..4504fefe 100644 --- a/semantic_router/encoders/openai.py +++ b/semantic_router/encoders/openai.py @@ -7,16 +7,17 @@ from openai.types import CreateEmbeddingResponse from semantic_router.encoders import BaseEncoder from semantic_router.utils.logger import logger +from typing import Optional class OpenAIEncoder(BaseEncoder): - client: openai.Client | None + client: Optional[openai.Client] type: str = "openai" def __init__( self, - name: str | None = None, - openai_api_key: str | None = None, + name: Optional[str] = None, + openai_api_key: Optional[str] = None, score_threshold: float = 0.82, ): if name is None: diff --git a/semantic_router/hybrid_layer.py b/semantic_router/hybrid_layer.py index cd9f7ccb..06862a63 100644 --- a/semantic_router/hybrid_layer.py +++ b/semantic_router/hybrid_layer.py @@ -7,6 +7,7 @@ from semantic_router.encoders import ( ) from semantic_router.route import Route from semantic_router.utils.logger import logger +from typing import Optional class HybridRouteLayer: @@ -29,7 +30,7 @@ class HybridRouteLayer: # self._add_route(route=route) self._add_routes(routes) - def __call__(self, text: str) -> str | None: + def __call__(self, text: str) -> Optional[str]: results = self._query(text) top_class, top_class_scores = self._semantic_classify(results) passed = self._pass_threshold(top_class_scores, self.score_threshold) diff --git a/semantic_router/layer.py b/semantic_router/layer.py index 08261756..e6a214f9 100644 --- a/semantic_router/layer.py +++ b/semantic_router/layer.py @@ -1,5 +1,6 @@ import json import os +from typing import Optional import numpy as np import yaml @@ -52,7 +53,7 @@ class LayerConfig: self, routes: list[Route] = [], encoder_type: str = "openai", - encoder_name: str | None = None, + encoder_name: Optional[str] = None, ): self.encoder_type = encoder_type if encoder_name is None: @@ -131,7 +132,7 @@ class LayerConfig: self.routes.append(route) logger.info(f"Added route `{route.name}`") - def get(self, name: str) -> Route | None: + def get(self, name: str) -> Optional[Route]: for route in self.routes: if route.name == name: return route @@ -147,15 +148,15 @@ class LayerConfig: class RouteLayer: - index: np.ndarray | None = None - categories: np.ndarray | None = None + index: Optional[np.ndarray] = None + categories: Optional[np.ndarray] = None score_threshold: float encoder: BaseEncoder def __init__( self, - encoder: BaseEncoder | None = None, - llm: BaseLLM | None = None, + encoder: Optional[BaseEncoder] = None, + llm: Optional[BaseLLM] = None, routes: list[Route] | None = None, ): logger.info("Initializing RouteLayer") diff --git a/semantic_router/llms/base.py b/semantic_router/llms/base.py index 51db1fd0..bf5f29b6 100644 --- a/semantic_router/llms/base.py +++ b/semantic_router/llms/base.py @@ -1,3 +1,5 @@ +from typing import Optional + from pydantic import BaseModel from semantic_router.schema import Message @@ -9,5 +11,5 @@ class BaseLLM(BaseModel): class Config: arbitrary_types_allowed = True - def __call__(self, messages: list[Message]) -> str | None: + def __call__(self, messages: list[Message]) -> Optional[str]: raise NotImplementedError("Subclasses must implement this method") diff --git a/semantic_router/llms/cohere.py b/semantic_router/llms/cohere.py index 77581700..0ec21f35 100644 --- a/semantic_router/llms/cohere.py +++ b/semantic_router/llms/cohere.py @@ -1,4 +1,5 @@ import os +from typing import Optional import cohere @@ -7,12 +8,12 @@ from semantic_router.schema import Message class CohereLLM(BaseLLM): - client: cohere.Client | None = None + client: Optional[cohere.Client] = None def __init__( self, - name: str | None = None, - cohere_api_key: str | None = None, + name: Optional[str] = None, + cohere_api_key: Optional[str] = None, ): if name is None: name = os.getenv("COHERE_CHAT_MODEL_NAME", "command") diff --git a/semantic_router/llms/openai.py b/semantic_router/llms/openai.py index 43ddd642..d3b215bf 100644 --- a/semantic_router/llms/openai.py +++ b/semantic_router/llms/openai.py @@ -5,17 +5,18 @@ import openai from semantic_router.llms import BaseLLM from semantic_router.schema import Message from semantic_router.utils.logger import logger +from typing import Optional class OpenAILLM(BaseLLM): - client: openai.OpenAI | None - temperature: float | None - max_tokens: int | None + client: Optional[openai.OpenAI] + temperature: Optional[float] + max_tokens: Optional[int] def __init__( self, - name: str | None = None, - openai_api_key: str | None = None, + name: Optional[str] = None, + openai_api_key: Optional[str] = None, temperature: float = 0.01, max_tokens: int = 200, ): diff --git a/semantic_router/llms/openrouter.py b/semantic_router/llms/openrouter.py index 587eeb12..6130e0a7 100644 --- a/semantic_router/llms/openrouter.py +++ b/semantic_router/llms/openrouter.py @@ -5,18 +5,19 @@ import openai from semantic_router.llms import BaseLLM from semantic_router.schema import Message from semantic_router.utils.logger import logger +from typing import Optional class OpenRouterLLM(BaseLLM): - client: openai.OpenAI | None - base_url: str | None - temperature: float | None - max_tokens: int | None + client: Optional[openai.OpenAI] + base_url: Optional[str] + temperature: Optional[float] + max_tokens: Optional[int] def __init__( self, - name: str | None = None, - openrouter_api_key: str | None = None, + name: Optional[str] = None, + openrouter_api_key: Optional[str] = None, base_url: str = "https://openrouter.ai/api/v1", temperature: float = 0.01, max_tokens: int = 200, diff --git a/semantic_router/route.py b/semantic_router/route.py index 0d8269f0..c2b9b3dc 100644 --- a/semantic_router/route.py +++ b/semantic_router/route.py @@ -8,6 +8,7 @@ from semantic_router.llms import BaseLLM from semantic_router.schema import Message, RouteChoice from semantic_router.utils import function_call from semantic_router.utils.logger import logger +from typing import Optional def is_valid(route_config: str) -> bool: @@ -41,9 +42,9 @@ def is_valid(route_config: str) -> bool: class Route(BaseModel): name: str utterances: list[str] - description: str | None = None + description: Optional[str] = None function_schema: dict[str, Any] | None = None - llm: BaseLLM | None = None + llm: Optional[BaseLLM] = None def __call__(self, query: str) -> RouteChoice: if self.function_schema: diff --git a/semantic_router/schema.py b/semantic_router/schema.py index 5e94c23b..9505df24 100644 --- a/semantic_router/schema.py +++ b/semantic_router/schema.py @@ -10,6 +10,7 @@ from semantic_router.encoders import ( OpenAIEncoder, ) from semantic_router.utils.splitters import semantic_splitter +from typing import Optional class EncoderType(Enum): @@ -20,17 +21,17 @@ class EncoderType(Enum): class RouteChoice(BaseModel): - name: str | None = None - function_call: dict | None = None + name: Optional[str] = None + function_call: Optional[dict] = None @dataclass class Encoder: type: EncoderType - name: str | None + name: Optional[str] model: BaseEncoder - def __init__(self, type: str, name: str | None): + def __init__(self, type: str, name: Optional[str]): self.type = EncoderType(type) self.name = name if self.type == EncoderType.HUGGINGFACE: diff --git a/semantic_router/utils/llm.py b/semantic_router/utils/llm.py index e92c1bcf..f0db13c8 100644 --- a/semantic_router/utils/llm.py +++ b/semantic_router/utils/llm.py @@ -3,9 +3,10 @@ import os import openai from semantic_router.utils.logger import logger +from typing import Optional -def llm(prompt: str) -> str | None: +def llm(prompt: str) -> Optional[str]: try: client = openai.OpenAI( base_url="https://openrouter.ai/api/v1", @@ -35,7 +36,7 @@ def llm(prompt: str) -> str | None: # TODO integrate async LLM function -# async def allm(prompt: str) -> str | None: +# async def allm(prompt: str) -> Optional[str]: # try: # client = openai.AsyncOpenAI( # base_url="https://openrouter.ai/api/v1", diff --git a/test_output.txt b/test_output.txt deleted file mode 100644 index e69de29b..00000000 -- GitLab