From 079711d4ad6670be4aa00cbc6e16d561e4e96872 Mon Sep 17 00:00:00 2001 From: Ishita Singh Date: Thu, 29 Oct 2026 11:26:27 +0530 Subject: [PATCH] feat(python): list registered embedding functions Closes #1605. Adds `EmbeddingFunctionRegistry.list_functions()` to expose registered lookup names in registration order without accessing `_functions`. The method returns an independent snapshot, and every returned name can be passed to `get()`. Tests cover empty registries, aliases and class names, registration order, snapshot isolation, and reset. --- python/python/lancedb/embeddings/registry.py | 19 +++++++ .../tests/test_embedding_registry_listing.py | 55 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 python/python/tests/test_embedding_registry_listing.py diff --git a/python/python/lancedb/embeddings/registry.py b/python/python/lancedb/embeddings/registry.py index 728ff36da..a7093094d 100644 --- a/python/python/lancedb/embeddings/registry.py +++ b/python/python/lancedb/embeddings/registry.py @@ -101,6 +101,25 @@ class EmbeddingFunctionRegistry: """ return self._functions[name] + def list_functions(self) -> list[str]: + """List the names of registered embedding functions. + + Returns + ------- + list[str] + Registered aliases, or class names for functions registered without + an alias, in registration order. Each name can be passed to + :meth:`get`. The returned list is a copy; changing it does not + change the registry. + + Examples + -------- + >>> registry = get_registry() + >>> "openai" in registry.list_functions() + True + """ + return list(self._functions) + def parse_functions( self, metadata: Optional[Dict[bytes, bytes]] ) -> Dict[str, "EmbeddingFunctionConfig"]: diff --git a/python/python/tests/test_embedding_registry_listing.py b/python/python/tests/test_embedding_registry_listing.py new file mode 100644 index 000000000..4f7189a7b --- /dev/null +++ b/python/python/tests/test_embedding_registry_listing.py @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright The LanceDB Authors + +from lancedb.embeddings import EmbeddingFunctionRegistry, TextEmbeddingFunction + + +class ExampleEmbedding(TextEmbeddingFunction): + def ndims(self): + return 2 + + def generate_embeddings(self, texts): + return [[1.0, 0.0] for _ in texts] + + +class OtherEmbedding(ExampleEmbedding): + pass + + +def test_list_functions_empty_registry(): + registry = EmbeddingFunctionRegistry() + assert registry.list_functions() == [] + + +def test_list_functions_names_and_registration_order(): + registry = EmbeddingFunctionRegistry() + registry.register("custom-embedding")(ExampleEmbedding) + registry.register()(OtherEmbedding) + + assert registry.list_functions() == ["custom-embedding", "OtherEmbedding"] + assert [registry.get(name) for name in registry.list_functions()] == [ + ExampleEmbedding, + OtherEmbedding, + ] + + +def test_list_functions_returns_independent_snapshot(): + registry = EmbeddingFunctionRegistry() + registry.register("first")(ExampleEmbedding) + names = registry.list_functions() + names.append("not-registered") + assert registry.list_functions() == ["first"] + + registry.register("second")(OtherEmbedding) + assert names == ["first", "not-registered"] + assert registry.list_functions() == ["first", "second"] + + +def test_list_functions_after_reset(): + registry = EmbeddingFunctionRegistry() + registry.register("custom-embedding")(ExampleEmbedding) + names = registry.list_functions() + registry.reset() + + assert registry.list_functions() == [] + assert names == ["custom-embedding"]