[release-26.05] typesense: 29.0 -> 29.1; python3Packages.typesense: 1.1.1 -> 1.3.0 (#567055)

This commit is contained in:
Peder Bergebakken Sundt
2026-10-01 13:24:29 +00:00
committed by GitHub
6 changed files with 315 additions and 47 deletions

View File

@@ -1,21 +1,21 @@
{
"version": "29.0",
"version": "29.1",
"platforms": {
"aarch64-linux": {
"arch": "linux-arm64",
"hash": "sha256-ztjCyK2378tg9yT9D6ProINlMT5GyUIEH8duHivCQ2E="
"hash": "sha256-A5HmrKZ4WQ6wh5uLBcns2bsYyKIF8eAdZi6v29XUgXU="
},
"x86_64-linux": {
"arch": "linux-amd64",
"hash": "sha256-BD0qE1dEVKVUPwO2fMO0SMXiwG9dD0RMnAzkVZitFKA="
"hash": "sha256-Jq5I78pNNJKYFtk+rBbOt/JqA0I+MMLV75FspqvF8RU="
},
"x86_64-darwin": {
"arch": "darwin-amd64",
"hash": "sha256-9imHOPW8OkFczuNxXGn3bXFI49BIdUJ5GGh1mrvcMgE="
"hash": "sha256-hSSPkPcqwqdb/V9vRvTLYwSzAdk0e94hVgCpQUNZcfo="
},
"aarch64-darwin": {
"arch": "darwin-arm64",
"hash": "sha256-yAOR/bGYBQGp8Mllhh0yKyqmItd2+IfLib3W+lIHwr0="
"hash": "sha256-BH6h27FU9rrGqRPgN22kfOf3a1yQ4InNVY+ms0WXkpk="
}
}
}

View File

@@ -1,29 +1,18 @@
From 9f0024ae3a0377d15788256c72af7a692d250afc Mon Sep 17 00:00:00 2001
From: dotlambda <github@dotlambda.de>
Date: Thu, 23 Oct 2025 13:40:33 -0700
Subject: [PATCH] test(metrics): some metrics only exists on Linux
---
tests/metrics_test.py | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/tests/metrics_test.py b/tests/metrics_test.py
index 1e1ea47..fecf3c0 100644
index 01bb9fa..8555b52 100644
--- a/tests/metrics_test.py
+++ b/tests/metrics_test.py
@@ -2,6 +2,8 @@
from __future__ import annotations
@@ -4,18 +4,22 @@ from __future__ import annotations
from typesense.metrics import Metrics
+import platform
+
from typesense.metrics import Metrics
@@ -9,13 +11,15 @@ def test_actual_retrieve(actual_metrics: Metrics) -> None:
def test_actual_retrieve(actual_metrics: Metrics) -> None:
"""Test that the Debug object can retrieve a debug on Typesense server and verify response structure."""
response = actual_metrics.retrieve()
- assert "system_cpu_active_percentage" in response
+ if platform.system() == "Linux":
+ assert "system_cpu_active_percentage" in response
@@ -39,10 +28,3 @@ index 1e1ea47..fecf3c0 100644
assert "typesense_memory_active_bytes" in response
assert "typesense_memory_allocated_bytes" in response
assert "typesense_memory_fragmentation_ratio" in response
@@ -23,4 +27,4 @@ def test_actual_retrieve(actual_metrics: Metrics) -> None:
assert "typesense_memory_mapped_bytes" in response
assert "typesense_memory_metadata_bytes" in response
assert "typesense_memory_resident_bytes" in response
- assert "typesense_memory_retained_bytes" in response
\ No newline at end of file
+ assert "typesense_memory_retained_bytes" in response

View File

@@ -0,0 +1,13 @@
diff --git a/tests/analytics_rules_v1_test.py b/tests/analytics_rules_v1_test.py
index d222d99..d1021d8 100644
--- a/tests/analytics_rules_v1_test.py
+++ b/tests/analytics_rules_v1_test.py
@@ -45,7 +45,7 @@ def test_get_missing_analytics_rule(fake_analytics_rules: AnalyticsRulesV1) -> N
"""Test that the AnalyticsRulesV1 object can get a missing analytics_rule."""
analytics_rule = fake_analytics_rules["company_analytics_rule"]
- assert analytics_rule.rule_id == "company_analytics_rule"
+ assert analytics_rule.rule_name == "company_analytics_rule"
assert_match_object(analytics_rule.api_call, fake_analytics_rules.api_call)
assert_object_lists_match(
analytics_rule.api_call.node_manager.nodes,

View File

@@ -0,0 +1,256 @@
diff --git a/tests/collection_test.py b/tests/collection_test.py
index 56c4429..1f795d2 100644
--- a/tests/collection_test.py
+++ b/tests/collection_test.py
@@ -11,12 +11,24 @@ from tests.utils.object_assertions import (
assert_object_lists_match,
assert_to_contain_object,
)
+from tests.utils.version import is_v30_or_above
from typesense.api_call import ApiCall
+from typesense.client import Client
from typesense.collection import Collection
from typesense.collections import Collections
from typesense.types.collection import CollectionSchema
+is_v30_or_above_server = is_v30_or_above(
+ Client(
+ {
+ "api_key": "xyz",
+ "nodes": [{"host": "localhost", "port": 8108, "protocol": "http"}],
+ }
+ )
+)
+
+
def test_init(fake_api_call: ApiCall) -> None:
"""Test that the Collection object is initialized correctly."""
collection = Collection(fake_api_call, "companies")
@@ -204,7 +216,6 @@ def test_actual_retrieve(
"infix": False,
"stem": False,
"stem_dictionary": "",
- "truncate_len": 100,
"store": True,
},
{
@@ -218,7 +229,6 @@ def test_actual_retrieve(
"infix": False,
"stem": False,
"stem_dictionary": "",
- "truncate_len": 100,
"store": True,
},
],
@@ -226,9 +236,12 @@ def test_actual_retrieve(
"num_documents": 0,
"symbols_to_index": [],
"token_separators": [],
- "synonym_sets": [],
- "curation_sets": [],
}
+ if is_v30_or_above_server:
+ expected["synonym_sets"] = []
+ expected["curation_sets"] = []
+ expected["fields"][0]["truncate_len"] = 100
+ expected["fields"][1]["truncate_len"] = 100
response.pop("created_at")
@@ -245,10 +258,8 @@ def test_actual_update(
{"fields": [{"name": "num_locations", "type": "int32"}]},
)
- expected: CollectionSchema = {
- "fields": [
- {"name": "num_locations", "truncate_len": 100, "type": "int32"},
- ],
- }
+ expected_field = {"name": "num_locations", "type": "int32"}
+ if is_v30_or_above_server:
+ expected_field["truncate_len"] = 100
- assert_to_contain_object(response.get("fields")[0], expected.get("fields")[0])
+ assert_to_contain_object(response.get("fields")[0], expected_field)
diff --git a/tests/collections_test.py b/tests/collections_test.py
index d742652..1021e8e 100644
--- a/tests/collections_test.py
+++ b/tests/collections_test.py
@@ -13,10 +13,66 @@ else:
from tests.utils.object_assertions import assert_match_object, assert_object_lists_match
from typesense.api_call import ApiCall
+from tests.utils.version import is_v30_or_above
from typesense.collections import Collections
+from typesense.client import Client
from typesense.types.collection import CollectionSchema
+IS_V30_OR_ABOVE = is_v30_or_above(
+ Client(
+ {
+ "api_key": "xyz",
+ "nodes": [{"host": "localhost", "port": 8108, "protocol": "http"}],
+ }
+ )
+)
+
+def expected_collection_field(
+ name: str,
+ type_: str,
+ *,
+ sort: bool,
+) -> dict[str, typing.Any]:
+ field: dict[str, typing.Any] = {
+ "name": name,
+ "type": type_,
+ "facet": False,
+ "index": True,
+ "optional": False,
+ "locale": "",
+ "sort": sort,
+ "infix": False,
+ "stem": False,
+ "stem_dictionary": "",
+ "store": True,
+ }
+ if IS_V30_OR_ABOVE:
+ field["truncate_len"] = 100
+ return field
+
+
+def expected_collection_schema(
+ *,
+ default_sorting_field: str,
+ fields: typing.List[dict[str, typing.Any]],
+ name: str,
+) -> CollectionSchema:
+ expected: CollectionSchema = {
+ "default_sorting_field": default_sorting_field,
+ "enable_nested_fields": False,
+ "fields": fields,
+ "name": name,
+ "num_documents": 0,
+ "symbols_to_index": [],
+ "token_separators": [],
+ }
+ if IS_V30_OR_ABOVE:
+ expected["synonym_sets"] = []
+ expected["curation_sets"] = []
+ return expected
+
+
def test_init(fake_api_call: ApiCall) -> None:
"""Test that the Collections object is initialized correctly."""
collections = Collections(fake_api_call)
@@ -188,46 +244,14 @@ def test_create(fake_collections: Collections) -> None:
def test_actual_create(actual_collections: Collections, delete_all: None) -> None:
"""Test that the Collections object can create a collection on Typesense Server."""
- expected: CollectionSchema = {
- "default_sorting_field": "",
- "enable_nested_fields": False,
- "fields": [
- {
- "name": "company_name",
- "type": "string",
- "facet": False,
- "index": True,
- "optional": False,
- "locale": "",
- "sort": False,
- "infix": False,
- "stem": False,
- "stem_dictionary": "",
- "truncate_len": 100,
- "store": True,
- },
- {
- "name": "num_employees",
- "type": "int32",
- "facet": False,
- "index": True,
- "optional": False,
- "locale": "",
- "sort": False,
- "infix": False,
- "stem": False,
- "stem_dictionary": "",
- "truncate_len": 100,
- "store": True,
- },
- ],
- "name": "companies",
- "num_documents": 0,
- "symbols_to_index": [],
- "token_separators": [],
- "synonym_sets": [],
- "curation_sets": [],
- }
+ expected = expected_collection_schema(
+ default_sorting_field="",
+ fields=[
+ expected_collection_field("company_name", "string", sort=False),
+ expected_collection_field("num_employees", "int32", sort=False),
+ ],
+ name="companies",
+ )
response = actual_collections.create(
{
@@ -260,46 +284,14 @@ def test_actual_retrieve(
response = actual_collections.retrieve()
expected: typing.List[CollectionSchema] = [
- {
- "default_sorting_field": "num_employees",
- "enable_nested_fields": False,
- "fields": [
- {
- "name": "company_name",
- "type": "string",
- "facet": False,
- "index": True,
- "optional": False,
- "locale": "",
- "sort": False,
- "infix": False,
- "stem": False,
- "stem_dictionary": "",
- "truncate_len": 100,
- "store": True,
- },
- {
- "name": "num_employees",
- "type": "int32",
- "facet": False,
- "index": True,
- "optional": False,
- "locale": "",
- "sort": True,
- "infix": False,
- "stem": False,
- "stem_dictionary": "",
- "truncate_len": 100,
- "store": True,
- },
- ],
- "name": "companies",
- "num_documents": 0,
- "symbols_to_index": [],
- "token_separators": [],
- "synonym_sets": [],
- "curation_sets": [],
- },
+ expected_collection_schema(
+ default_sorting_field="num_employees",
+ fields=[
+ expected_collection_field("company_name", "string", sort=False),
+ expected_collection_field("num_employees", "int32", sort=True),
+ ],
+ name="companies",
+ ),
]
response[0].pop("created_at")

View File

@@ -14,22 +14,25 @@
isort,
}:
buildPythonPackage rec {
buildPythonPackage (finalAttrs: {
pname = "typesense";
version = "1.1.1";
version = "1.3.0";
pyproject = true;
src = fetchFromGitHub {
owner = "typesense";
repo = "typesense-python";
tag = "v${version}";
hash = "sha256-vo9DW4kinb00zWW4yX8ibyelQxW3eVabn+oMddPEd18=";
tag = "v${finalAttrs.version}";
hash = "sha256-b3t4l02tOiSMrkqZACV6l5f+Kb5Wfcnq9ZZCld1SKBU=";
};
patches = [
# See <https://github.com/typesense/typesense-python/pull/103>.
./linux-only-metrics.patch
./generated-temp-path.patch
# See <https://github.com/typesense/typesense-python/pull/132>.
# See <https://github.com/typesense/typesense-python/pull/133>.
./0001-linux-only-metrics.patch
./0002-generated-temp-path.patch
./0003-tests-fix-rule_id.patch
./0004-test-gate-v30-collection-schema-expectations.patch
];
build-system = [ setuptools ];
@@ -47,24 +50,36 @@ buildPythonPackage rec {
isort
];
disabledTestMarks = [ "open_ai" ];
disabledTests = [ "import_typing_extensions" ];
disabledTests = [
"import_typing_extensions"
# tests/operations_test.py::test_snapshot_async fails when tests are run
# in parallel due to writing to the shared /tmp directory on macOS
"test_snapshot_async"
];
__darwinAllowLocalNetworking = true;
# For darwin, the nix sandbox doesn't isolate loopback interfaces like linux does.
# So nixpkgs-review builds of python3.x will collide on the hardcoded port 8108.
# So for tests patch it to use random port.
preCheck = ''
export TYPESENSE_PORT=$(( 10000 + $$ % 30000 ))
export PEERING_PORT=$(( TYPESENSE_PORT - 1 ))
find tests -type f -exec sed -i "s/8108/$TYPESENSE_PORT/g" {} +
TYPESENSE_API_KEY="xyz" \
TYPESENSE_DATA_DIR="$(mktemp -d)" \
typesense-server &
typesense-server --api-port=$TYPESENSE_PORT --peering-port=$PEERING_PORT &
typesense_pid=$!
# Ensure typesense-server is killed even if tests fail
trap "kill $typesense_pid" EXIT
# Wait for typesense to finish starting.
timeout 20 bash -c '
while ! curl -s --fail localhost:8108/health; do sleep 1; done
' || false
'';
postCheck = ''
kill $typesense_pid
timeout 20 bash -c "
while ! curl -s --fail localhost:$TYPESENSE_PORT/health; do sleep 1; done
" || false
'';
pythonImportsCheck = [ "typesense" ];
@@ -74,5 +89,7 @@ buildPythonPackage rec {
homepage = "https://github.com/typesense/typesense-python";
license = lib.licenses.asl20;
teams = [ lib.teams.ngi ];
# on x86_64-darwin the typesense server doesn't start
badPlatforms = [ "x86_64-darwin" ];
};
}
})