Skip to content

Commit 9777059

Browse files
authored
Merge pull request #94 from tharropoulos/nl-language
feat: add natural language search
2 parents 945f166 + ca6def8 commit 9777059

File tree

8 files changed

+713
-0
lines changed

8 files changed

+713
-0
lines changed

src/typesense/client.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
from typesense.keys import Keys
4747
from typesense.metrics import Metrics
4848
from typesense.multi_search import MultiSearch
49+
from typesense.nl_search_models import NLSearchModels
4950
from typesense.operations import Operations
5051
from typesense.stemming import Stemming
5152
from typesense.stopwords import Stopwords
@@ -107,6 +108,7 @@ def __init__(self, config_dict: ConfigDict) -> None:
107108
self.stopwords = Stopwords(self.api_call)
108109
self.metrics = Metrics(self.api_call)
109110
self.conversations_models = ConversationsModels(self.api_call)
111+
self.nl_search_models = NLSearchModels(self.api_call)
110112

111113
def typed_collection(
112114
self,

src/typesense/nl_search_model.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""
2+
This module provides functionality for managing individual NL search models in Typesense.
3+
4+
Classes:
5+
- NLSearchModel: Handles operations related to a specific NL search model.
6+
7+
Methods:
8+
- __init__: Initializes the NLSearchModel object.
9+
- _endpoint_path: Constructs the API endpoint path for this specific NL search model.
10+
- retrieve: Retrieves the details of this specific NL search model.
11+
- update: Updates this specific NL search model.
12+
- delete: Deletes this specific NL search model.
13+
14+
The NLSearchModel class interacts with the Typesense API to manage operations on a
15+
specific NL search model. It provides methods to retrieve, update,
16+
and delete individual models.
17+
18+
This module uses type hinting and is compatible with Python 3.11+ as well as earlier
19+
versions through the use of the typing_extensions library.
20+
"""
21+
22+
from typesense.api_call import ApiCall
23+
from typesense.types.nl_search_model import (
24+
NLSearchModelDeleteSchema,
25+
NLSearchModelSchema,
26+
NLSearchModelUpdateSchema,
27+
)
28+
29+
30+
class NLSearchModel:
31+
"""
32+
Class for managing individual NL search models in Typesense.
33+
34+
This class provides methods to interact with a specific NL search model,
35+
including retrieving, updating, and deleting it.
36+
37+
Attributes:
38+
model_id (str): The ID of the NL search model.
39+
api_call (ApiCall): The API call object for making requests.
40+
"""
41+
42+
def __init__(self, api_call: ApiCall, model_id: str) -> None:
43+
"""
44+
Initialize the NLSearchModel object.
45+
46+
Args:
47+
api_call (ApiCall): The API call object for making requests.
48+
model_id (str): The ID of the NL search model.
49+
"""
50+
self.model_id = model_id
51+
self.api_call = api_call
52+
53+
def retrieve(self) -> NLSearchModelSchema:
54+
"""
55+
Retrieve this specific NL search model.
56+
57+
Returns:
58+
NLSearchModelSchema: The schema containing the NL search model details.
59+
"""
60+
response = self.api_call.get(
61+
self._endpoint_path,
62+
as_json=True,
63+
entity_type=NLSearchModelSchema,
64+
)
65+
return response
66+
67+
def update(self, model: NLSearchModelUpdateSchema) -> NLSearchModelSchema:
68+
"""
69+
Update this specific NL search model.
70+
71+
Args:
72+
model (NLSearchModelUpdateSchema):
73+
The schema containing the updated model details.
74+
75+
Returns:
76+
NLSearchModelSchema: The schema containing the updated NL search model.
77+
"""
78+
response: NLSearchModelSchema = self.api_call.put(
79+
self._endpoint_path,
80+
body=model,
81+
entity_type=NLSearchModelSchema,
82+
)
83+
return response
84+
85+
def delete(self) -> NLSearchModelDeleteSchema:
86+
"""
87+
Delete this specific NL search model.
88+
89+
Returns:
90+
NLSearchModelDeleteSchema: The schema containing the deletion response.
91+
"""
92+
response: NLSearchModelDeleteSchema = self.api_call.delete(
93+
self._endpoint_path,
94+
entity_type=NLSearchModelDeleteSchema,
95+
)
96+
return response
97+
98+
@property
99+
def _endpoint_path(self) -> str:
100+
"""
101+
Construct the API endpoint path for this specific NL search model.
102+
103+
Returns:
104+
str: The constructed endpoint path.
105+
"""
106+
from typesense.nl_search_models import NLSearchModels
107+
108+
return "/".join([NLSearchModels.resource_path, self.model_id])

src/typesense/nl_search_models.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
"""
2+
This module provides functionality for managing NL search models in Typesense.
3+
4+
Classes:
5+
- NLSearchModels: Handles operations related to NL search models.
6+
7+
Methods:
8+
- __init__: Initializes the NLSearchModels object.
9+
- __getitem__: Retrieves or creates an NLSearchModel object for a given model_id.
10+
- create: Creates a new NL search model.
11+
- retrieve: Retrieves all NL search models.
12+
13+
Attributes:
14+
- resource_path: The API resource path for NL search models operations.
15+
16+
The NLSearchModels class interacts with the Typesense API to manage
17+
NL search model operations.
18+
19+
It provides methods to create and retrieve NL search models, as well as access
20+
individual NLSearchModel objects.
21+
22+
This module uses type hinting and is compatible with Python 3.11+ as well as earlier
23+
versions through the use of the typing_extensions library.
24+
"""
25+
26+
import sys
27+
28+
from typesense.api_call import ApiCall
29+
from typesense.types.nl_search_model import (
30+
NLSearchModelCreateSchema,
31+
NLSearchModelSchema,
32+
NLSearchModelsRetrieveSchema,
33+
)
34+
35+
if sys.version_info > (3, 11):
36+
import typing
37+
else:
38+
import typing_extensions as typing
39+
40+
from typesense.nl_search_model import NLSearchModel
41+
42+
43+
class NLSearchModels(object):
44+
"""
45+
Class for managing NL search models in Typesense.
46+
47+
This class provides methods to interact with NL search models, including
48+
creating, retrieving, and accessing individual models.
49+
50+
Attributes:
51+
resource_path (str): The API resource path for NL search models operations.
52+
api_call (ApiCall): The API call object for making requests.
53+
nl_search_models (Dict[str, NLSearchModel]):
54+
A dictionary of NLSearchModel objects.
55+
"""
56+
57+
resource_path: typing.Final[str] = "/nl_search_models"
58+
59+
def __init__(self, api_call: ApiCall) -> None:
60+
"""
61+
Initialize the NLSearchModels object.
62+
63+
Args:
64+
api_call (ApiCall): The API call object for making requests.
65+
"""
66+
self.api_call = api_call
67+
self.nl_search_models: typing.Dict[str, NLSearchModel] = {}
68+
69+
def __getitem__(self, model_id: str) -> NLSearchModel:
70+
"""
71+
Get or create an NLSearchModel object for a given model_id.
72+
73+
Args:
74+
model_id (str): The ID of the NL search model.
75+
76+
Returns:
77+
NLSearchModel: The NLSearchModel object for the given ID.
78+
"""
79+
if model_id not in self.nl_search_models:
80+
self.nl_search_models[model_id] = NLSearchModel(
81+
self.api_call,
82+
model_id,
83+
)
84+
return self.nl_search_models[model_id]
85+
86+
def create(self, model: NLSearchModelCreateSchema) -> NLSearchModelSchema:
87+
"""
88+
Create a new NL search model.
89+
90+
Args:
91+
model (NLSearchModelCreateSchema):
92+
The schema for creating the NL search model.
93+
94+
Returns:
95+
NLSearchModelSchema: The created NL search model.
96+
"""
97+
response = self.api_call.post(
98+
endpoint=NLSearchModels.resource_path,
99+
entity_type=NLSearchModelSchema,
100+
as_json=True,
101+
body=model,
102+
)
103+
return response
104+
105+
def retrieve(self) -> NLSearchModelsRetrieveSchema:
106+
"""
107+
Retrieve all NL search models.
108+
109+
Returns:
110+
NLSearchModelsRetrieveSchema: A list of all NL search models.
111+
"""
112+
response: NLSearchModelsRetrieveSchema = self.api_call.get(
113+
endpoint=NLSearchModels.resource_path,
114+
entity_type=NLSearchModelsRetrieveSchema,
115+
as_json=True,
116+
)
117+
return response

src/typesense/types/document.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,23 @@ class CachingParameters(typing.TypedDict):
569569
cache_ttl: typing.NotRequired[int]
570570

571571

572+
class NLLanguageParameters(typing.TypedDict):
573+
"""
574+
Parameters regarding [caching search results](https://typesense.org/docs/26.0/api/search.html#caching-parameters).
575+
576+
Attributes:
577+
nl_query_prompt_cache_ttl (int): The duration (in seconds) that determines how long the schema prompts are cached.
578+
nl_query (bool): Whether to use natural language in the query or not.
579+
nl_model_id (str): The ID of the natural language model to use for the query.
580+
nl_query_debug (bool): Whether to return the raw LLM response or not.
581+
"""
582+
583+
nl_query_prompt_cache_ttl: typing.NotRequired[int]
584+
nl_query: typing.NotRequired[bool]
585+
nl_model_id: typing.NotRequired[str]
586+
nl_query_debug: typing.NotRequired[bool]
587+
588+
572589
class SearchParameters(
573590
RequiredSearchParameters,
574591
QueryParameters,
@@ -580,6 +597,7 @@ class SearchParameters(
580597
ResultsParameters,
581598
TypoToleranceParameters,
582599
CachingParameters,
600+
NLLanguageParameters,
583601
):
584602
"""Parameters for searching documents."""
585603

@@ -823,6 +841,38 @@ class Conversation(typing.TypedDict):
823841
query: str
824842

825843

844+
class LLMResponse(typing.TypedDict):
845+
"""
846+
Schema for a raw LLM response.
847+
848+
Attributes:
849+
content (str): Content of the LLM response.
850+
extraction_method (str): Extraction method of the LLM response (e.g. "regex").
851+
model (str): Model used to generate the response.
852+
"""
853+
854+
content: str
855+
extraction_method: str
856+
model: str
857+
858+
859+
class ParsedNLQuery(typing.TypedDict):
860+
"""
861+
Schema for a parsed natural language query.
862+
863+
Attributes:
864+
parse_time_ms (int): Parse time in milliseconds.
865+
generated_params (SearchParameters): Generated parameters.
866+
augmented_params (SearchParameters): Augmented parameters.
867+
llm_response (LLMResponse): Raw LLM response.
868+
"""
869+
870+
parse_time_ms: int
871+
generated_params: SearchParameters
872+
augmented_params: SearchParameters
873+
llm_response: typing.NotRequired[LLMResponse]
874+
875+
826876
class SearchResponse(typing.Generic[TDoc], typing.TypedDict):
827877
"""
828878
Schema for a search response.
@@ -838,6 +888,7 @@ class SearchResponse(typing.Generic[TDoc], typing.TypedDict):
838888
hits (list[Hit[TDoc]]): List of hits in the search results.
839889
grouped_hits (list[GroupedHit[TDoc]]): List of grouped hits in the search results.
840890
conversation (Conversation): Conversation in the search results.
891+
parsed_nl_query (ParsedNLQuery): Information about the natural language query
841892
"""
842893

843894
facet_counts: typing.List[SearchResponseFacetCountSchema]
@@ -850,6 +901,7 @@ class SearchResponse(typing.Generic[TDoc], typing.TypedDict):
850901
hits: typing.List[Hit[TDoc]]
851902
grouped_hits: typing.NotRequired[typing.List[GroupedHit[TDoc]]]
852903
conversation: typing.NotRequired[Conversation]
904+
parsed_nl_query: typing.NotRequired[ParsedNLQuery]
853905

854906

855907
class DeleteSingleDocumentParameters(typing.TypedDict):

0 commit comments

Comments
 (0)