Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ description = "With CocoIndex, users declare the transformation, CocoIndex creat
authors = [{ name = "CocoIndex", email = "cocoindex.io@gmail.com" }]
readme = "README.md"
requires-python = ">=3.11"
dependencies = ["sentence-transformers>=3.3.1", "click>=8.1.8", "rich>=14.0.0", "python-dotenv>=1.1.0"]
dependencies = [
"sentence-transformers>=3.3.1",
"click>=8.1.8",
"rich>=14.0.0",
"python-dotenv>=1.1.0",
]
license = "Apache-2.0"
urls = { Homepage = "https://cocoindex.io/" }

Expand All @@ -23,4 +28,9 @@ module-name = "cocoindex._engine"
features = ["pyo3/extension-module"]

[project.optional-dependencies]
test = ["pytest"]
test = ["pytest"]

[tool.mypy]
python_version = "3.11"
# Disable for not as we have missing type annotations. See https://github.com/cocoindex-io/cocoindex/issues/539
# strict = true
2 changes: 1 addition & 1 deletion python/cocoindex/auth_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from dataclasses import dataclass
from typing import Generic, TypeVar

from . import _engine
from . import _engine # type: ignore
from .convert import dump_engine_object

T = TypeVar("T")
Expand Down
11 changes: 6 additions & 5 deletions python/cocoindex/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ def _load_user_app(app_target: str) -> types.ModuleType:
raise ImportError(f"Could not create spec for file: {app_path}")
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
if spec.loader is None:
raise ImportError(f"Could not create loader for file: {app_path}")
spec.loader.exec_module(module)
return module
except (ImportError, FileNotFoundError, PermissionError) as e:
Expand Down Expand Up @@ -145,20 +147,21 @@ def ls(app_target: str | None):
If APP_TARGET is omitted, lists all flows that have a persisted
setup in the backend.
"""
persisted_flow_names = flow_names_with_setup()
if app_target:
app_ref = _get_app_ref_from_specifier(app_target)
_load_user_app(app_ref)

current_flow_names = set(flow.flow_names())
persisted_flow_names = set(flow_names_with_setup())

if not current_flow_names:
click.echo(f"No flows are defined in '{app_ref}'.")
return

has_missing = False
persisted_flow_names_set = set(persisted_flow_names)
for name in sorted(current_flow_names):
if name in persisted_flow_names:
if name in persisted_flow_names_set:
click.echo(name)
else:
click.echo(f"{name} [+]")
Expand All @@ -170,13 +173,11 @@ def ls(app_target: str | None):
click.echo(' [+]: Flows present in the current process, but missing setup.')

else:
persisted_flow_names = sorted(flow_names_with_setup())

if not persisted_flow_names:
click.echo("No persisted flow setups found in the backend.")
return

for name in persisted_flow_names:
for name in sorted(persisted_flow_names):
click.echo(name)

@cli.command()
Expand Down
13 changes: 6 additions & 7 deletions python/cocoindex/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import uuid

from enum import Enum
from typing import Any, Callable, get_origin
from typing import Any, Callable, get_origin, Mapping
from .typing import analyze_type_info, encode_enriched_type, is_namedtuple_type, TABLE_TYPES, KEY_FIELD_NAME


Expand Down Expand Up @@ -104,21 +104,20 @@ def _make_engine_struct_value_decoder(

src_name_to_idx = {f['name']: i for i, f in enumerate(src_fields)}

is_dataclass = dataclasses.is_dataclass(dst_struct_type)
is_namedtuple = is_namedtuple_type(dst_struct_type)

if is_dataclass:
parameters: Mapping[str, inspect.Parameter]
if dataclasses.is_dataclass(dst_struct_type):
parameters = inspect.signature(dst_struct_type).parameters
elif is_namedtuple:
elif is_namedtuple_type(dst_struct_type):
defaults = getattr(dst_struct_type, '_field_defaults', {})
fields = getattr(dst_struct_type, '_fields', ())
parameters = {
name: inspect.Parameter(
name=name,
kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
default=defaults.get(name, inspect.Parameter.empty),
annotation=dst_struct_type.__annotations__.get(name, inspect.Parameter.empty)
)
for name in dst_struct_type._fields
for name in fields
}
else:
raise ValueError(f"Unsupported struct type: {dst_struct_type}")
Expand Down
2 changes: 1 addition & 1 deletion python/cocoindex/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from rich.text import Text
from rich.tree import Tree

from . import _engine
from . import _engine # type: ignore
from . import index
from . import op
from . import setting
Expand Down
3 changes: 2 additions & 1 deletion python/cocoindex/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import warnings
from typing import Callable, Any

from . import _engine, flow, query, setting
from . import _engine # type: ignore
from . import flow, query, setting
from .convert import dump_engine_object


Expand Down
8 changes: 4 additions & 4 deletions python/cocoindex/op.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from .typing import encode_enriched_type, resolve_forward_ref
from .convert import encode_engine_value, make_engine_value_decoder
from . import _engine
from . import _engine # type: ignore

class OpCategory(Enum):
"""The category of the operation."""
Expand Down Expand Up @@ -101,7 +101,7 @@ def behavior_version(self):

class _WrappedClass(executor_cls, _Fallback):
_args_decoders: list[Callable[[Any], Any]]
_kwargs_decoders: dict[str, Callable[[str, Any], Any]]
_kwargs_decoders: dict[str, Callable[[Any], Any]]
_acall: Callable

def __init__(self, spec):
Expand Down Expand Up @@ -247,13 +247,13 @@ def __call__(self, *args, **kwargs):
return fn(*args, **kwargs)

class _Spec(FunctionSpec):
pass
def __call__(self, *args, **kwargs):
return fn(*args, **kwargs)

_Spec.__name__ = op_name
_Spec.__doc__ = fn.__doc__
_Spec.__module__ = fn.__module__
_Spec.__qualname__ = fn.__qualname__
_Spec.__wrapped__ = fn

_register_op_factory(
category=OpCategory.FUNCTION,
Expand Down
2 changes: 1 addition & 1 deletion python/cocoindex/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from . import flow as fl
from . import index
from . import _engine
from . import _engine # type: ignore

_handlers_lock = Lock()
_handlers: dict[str, _engine.SimpleSemanticsQueryHandler] = {}
Expand Down
2 changes: 1 addition & 1 deletion python/cocoindex/setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from . import flow
from . import setting
from . import _engine
from . import _engine # type: ignore

def sync_setup() -> _engine.SetupStatus:
flow.ensure_all_flows_built()
Expand Down
7 changes: 5 additions & 2 deletions python/cocoindex/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import types
import inspect
import uuid
from typing import Annotated, NamedTuple, Any, TypeVar, TYPE_CHECKING, overload, Sequence, Protocol, Generic, Literal
from typing import Annotated, NamedTuple, Any, TypeVar, TYPE_CHECKING, overload, Sequence, Generic, Literal, Protocol

class VectorInfo(NamedTuple):
dim: int | None
Expand Down Expand Up @@ -34,8 +34,11 @@ def __init__(self, key: str, value: Any):
T_co = TypeVar('T_co', covariant=True)
Dim_co = TypeVar('Dim_co', bound=int, covariant=True)

class Vector(Sequence[T_co], Generic[T_co, Dim_co], Protocol):
class Vector(Protocol, Generic[T_co, Dim_co]):
"""Vector[T, Dim] is a special typing alias for a list[T] with optional dimension info"""
def __getitem__(self, index: int) -> T_co: ...
def __len__(self) -> int: ...

else:
class Vector: # type: ignore[unreachable]
""" A special typing alias for a list[T] with optional dimension info """
Expand Down