Skip to content

Commit 0b73b93

Browse files
committed
Fix #63
1 parent 90a26dd commit 0b73b93

File tree

8 files changed

+67
-10
lines changed

8 files changed

+67
-10
lines changed

docs-src/index.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ The following parameters must be either specified as environment variables, or g
4646
* `PyST_typesense_url` : Typesense host URL
4747
* `PyST_typesense_api_key` : Typesense API key. Must have collection creation rights.
4848
* `PyST_typesense_embedding_model` : [Typesense embedding model](https://typesense.org/docs/28.0/api/vector-search.html#using-built-in-models) for semantic search. Default is "ts/all-MiniLM-L12-v2"
49-
* `PyST_languages` : List of language codes used in the search engine and web UI. Should be a JSON _string_, e.g. `'["en", "de"]'`. Default is `'["en", "de", "es", "fr", "pt", "it", "da"]'`
49+
* `PyST_typesense_prefix` : Optional prefix for Typesense [collection](https://typesense.org/docs/28.0/api/collections.html#create-a-collection) labels.
50+
* `PyST_languages` : List of language codes used in the search engine and web UI. Should be a JSON _string_, e.g. `'["en", "de"]'`. Default is `'["en", "de", "es", "fr", "pt", "it", "da"]'`.
51+
52+
!!! Note
53+
54+
If you are deploying more than one PyST instance, you can set `PyST_typesense_prefix` to a different value for each instance. This will keep the search results for each instance separate. The `PyST_typesense_prefix` should only include letters and numbers, and should start with a letter.
5055

5156
3\. Run the server
5257

docs/index.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,13 @@ <h2 id="quickstart">Quickstart<a class="headerlink" href="#quickstart" title="Pe
513513
<li><code>PyST_typesense_url</code> : Typesense host URL</li>
514514
<li><code>PyST_typesense_api_key</code> : Typesense API key. Must have collection creation rights.</li>
515515
<li><code>PyST_typesense_embedding_model</code> : <a href="https://typesense.org/docs/28.0/api/vector-search.html#using-built-in-models">Typesense embedding model</a> for semantic search. Default is "ts/all-MiniLM-L12-v2"</li>
516-
<li><code>PyST_languages</code> : List of language codes used in the search engine and web UI. Should be a JSON <em>string</em>, e.g. <code>'["en", "de"]'</code>. Default is <code>'["en", "de", "es", "fr", "pt", "it", "da"]'</code></li>
516+
<li><code>PyST_typesense_prefix</code> : Optional prefix for Typesense <a href="https://typesense.org/docs/28.0/api/collections.html#create-a-collection">collection</a> labels.</li>
517+
<li><code>PyST_languages</code> : List of language codes used in the search engine and web UI. Should be a JSON <em>string</em>, e.g. <code>'["en", "de"]'</code>. Default is <code>'["en", "de", "es", "fr", "pt", "it", "da"]'</code>.</li>
517518
</ul>
519+
<div class="admonition note">
520+
<p class="admonition-title">Note</p>
521+
<p>If you are deploying more than one PyST instance, you can set <code>PyST_typesense_prefix</code> to a different value for each instance. This will keep the search results for each instance separate. The <code>PyST_typesense_prefix</code> should only include letters and numbers, and should start with a letter.</p>
522+
</div>
518523
<p>3. Run the server</p>
519524
<p>PyST is a <a href="https://fastapi.tiangolo.com/">FastAPI app</a>; it can be run <a href="https://fastapi.tiangolo.com/deployment/manually/">as any python ASGI app</a>, e.g. with <code>uvicorn</code>:</p>
520525
<div class="highlight"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">uvicorn</span>

docs/search/search_index.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/py_semantic_taxonomy/adapters/persistence/search_engine.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@
99
logger = structlog.get_logger("py-semantic-taxonomy")
1010

1111

12-
def c(language: str) -> str:
13-
return f"pyst-concepts-{language}"
14-
15-
1612
class TypesenseSearchEngine:
1713
def __init__(self, url: str, api_key: str, embedding_model: str):
1814
url = urlparse(url)

src/py_semantic_taxonomy/application/search_service.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,19 @@
1414
logger = structlog.get_logger("py-semantic-taxonomy")
1515

1616

17-
def c(language: str) -> str:
18-
return f"pyst-concepts-{language}"
17+
def c(language: str, prefix: str = "") -> str:
18+
if prefix:
19+
return f"{prefix}-pyst-concepts-{language}"
20+
else:
21+
return f"pyst-concepts-{language}"
1922

2023

2124
class SearchService:
2225
def __init__(self, engine: SearchEngine | None = None):
2326
self.settings = get_settings()
24-
self.languages = {lang: c(lang) for lang in self.settings.languages}
27+
self.languages = {
28+
lang: c(lang, self.settings.typesense_prefix) for lang in self.settings.languages
29+
}
2530

2631
if self.settings.typesense_url == "missing" or not self.settings.typesense_url:
2732
self.configured = False

src/py_semantic_taxonomy/cfg.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Settings(BaseSettings):
1717
typesense_api_key: str = "missing"
1818
typesense_embedding_model: str = "ts/all-MiniLM-L12-v2"
1919
typesense_exclude_if_missing_for_language: bool = True
20+
typesense_prefix: str = ""
2021

2122
languages: list[str] = ["en", "de", "es", "fr", "pt", "it", "da"]
2223

tests/conftest.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,44 @@ async def typesense(typesense_container, entities):
280280
await ts.create_concept(entities[i])
281281

282282

283+
@pytest.fixture
284+
async def typesense_container_with_prefix(monkeypatch, test_password: str = "123abc"):
285+
container = DockerContainer("typesense/typesense:28.0")
286+
container.with_exposed_ports(8108)
287+
# Giving the API key in `with_command` in a pytest fixture doesn't work...
288+
container.with_env("TYPESENSE_API_KEY", test_password)
289+
container.with_command("--data-dir /home --enable-cors")
290+
container.start()
291+
wait_for_logs(container, "Peer refresh succeeded")
292+
293+
ip = container.get_container_host_ip()
294+
port = container.get_exposed_port(8108)
295+
296+
check_response = httpx.get(f"http://{ip}:{port}/health")
297+
if not check_response.status_code == 200:
298+
raise OSError("Typesense container can't start")
299+
300+
monkeypatch.setenv("PyST_typesense_url", f"http://{ip}:{port}")
301+
monkeypatch.setenv("PyST_typesense_api_key", test_password)
302+
monkeypatch.setenv("PyST_languages", '["en", "de"]')
303+
monkeypatch.setenv("PyST_typesense_prefix", "prefixtest")
304+
305+
yield
306+
307+
container.stop()
308+
309+
310+
@pytest.fixture
311+
async def typesense_with_prefix(typesense_container_with_prefix, entities):
312+
from py_semantic_taxonomy.dependencies import get_search_service
313+
314+
ts = get_search_service()
315+
await ts.initialize()
316+
317+
for i in [0, 1, 5, 6]:
318+
await ts.create_concept(entities[i])
319+
320+
283321
@pytest.fixture
284322
async def client() -> TestClient:
285323
from httpx import ASGITransport, AsyncClient

tests/unit/persistence/test_search_engine.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,10 @@ async def test_search_engine(typesense, entities):
5151

5252
results = await engine.search("diesel", "pyst-concepts-en", True, False)
5353
assert not results
54+
55+
56+
@pytest.mark.typesense
57+
async def test_search_engine_collection_prefix(typesense_with_prefix, entities):
58+
engine = get_search_engine()
59+
collections = await engine._collection_labels()
60+
assert collections == ["prefixtest-pyst-concepts-de", "prefixtest-pyst-concepts-en"]

0 commit comments

Comments
 (0)