DishEmbedClient Reference
Constructor
from dish_embed.client import DishEmbedClient
client = DishEmbedClient(base_url, api_key)
| Parameter | Type | Default | Description |
|---|---|---|---|
base_url | str | required | API base URL (e.g., "https://dish-embed.latimal.com") |
api_key | str | required | Your API key |
timeout | int | 120 | Request timeout in seconds |
Methods
health()
Check API availability.
result = client.health()
# {"status": "healthy", "biencoder": "loaded", ...}
Returns: dict with status and component info.
embed(items, dimension=128)
Generate embeddings for a list of items. Automatically chunks large lists into multiple requests (512 items per chunk).
embeddings = client.embed(["Butter Chicken", "Dal Tadka"], dimension=384)
# embeddings is a list of float lists, one per input item
| Parameter | Type | Default | Description |
|---|---|---|---|
items | list[str] | required | Menu items to embed (up to 512 per chunk) |
dimension | int | 128 | Embedding dimension: 128, 256, or 384 |
Returns: list[list[float]] - one embedding vector per input item.
Auto-chunking: Lists longer than 512 items are transparently split into multiple HTTP requests. Results are concatenated in order.
embed_batch(items, dimension=128)
Embed up to 5,000 items in a single HTTP request. No chunking. Use this for bulk operations where you want one network round-trip.
result = client.embed_batch(large_menu, dimension=128)
| Parameter | Type | Default | Description |
|---|---|---|---|
items | list[str] | required | Menu items (up to 5,000) |
dimension | int | 128 | Embedding dimension: 128, 256, or 384 |
Returns: Same as embed().
match(pairs, cosine_threshold=0.85)
Check if pairs of items are duplicates.
result = client.match(
pairs=[("Butter Chicken", "Murgh Makhani"), ("Pizza", "Pasta")],
cosine_threshold=0.85
)
for r in result["results"]:
print(f"{r['text_a']} vs {r['text_b']}: {r['match']} (cosine: {r['cosine']:.3f})")
| Parameter | Type | Default | Description |
|---|---|---|---|
pairs | list[tuple] | required | Pairs of (text_a, text_b) tuples to compare. The SDK converts these to {text_a, text_b} objects for the API. |
cosine_threshold | float | 0.85 | Minimum similarity to consider a match |
Returns: dict with results (list of match results including text_a, text_b, cosine, reranker_score, match, dietary_conflict, protein_conflict).
dedup(items, cosine_threshold=0.85)
Find and cluster duplicate items in a menu.
result = client.dedup(menu_items, cosine_threshold=0.85)
for cluster in result["clusters"]:
print(f"Canonical: {cluster['canonical']}, Members: {cluster['members']}")
| Parameter | Type | Default | Description |
|---|---|---|---|
items | list[str] | required | Menu items (up to 2,000) |
cosine_threshold | float | 0.85 | Similarity threshold for clustering |
Returns: dict with clusters, singletons (items with no duplicates), total_items, duplicate_items (excess count), and processing_time_ms.
classify(items)
Classify items by cuisine.
results = client.classify(["Sushi Roll", "Butter Chicken", "Tacos"])
for c in results:
print(f"{c['text']}: {c['cuisine']} ({c['confidence']:.2f})")
| Parameter | Type | Default | Description |
|---|---|---|---|
items | list[str] | required | Menu items (up to 512) |
Returns: list of dicts, each with text, cuisine, confidence.
search(query, corpus, top_k=10)
Semantic search over a corpus of menu items.
result = client.search("spicy noodles", corpus=menu_items, top_k=5)
for r in result["results"]:
print(f"{r['text']}: {r['score']:.3f}")
| Parameter | Type | Default | Description |
|---|---|---|---|
query | str | required | Search query |
corpus | list[str] | required | Items to search over |
top_k | int | 10 | Number of results to return |
Returns: dict with results (list with text, score, reranker_score, is_fallback) and query_preprocessed.
Note: The SDK's search() does not support the corpus_embeddings parameter. For pre-computed embedding search, use the raw HTTP API directly.
report(items, restaurant_name="")
Generate a menu health report.
result = client.report(menu_items, restaurant_name="My Restaurant")
print(f"Quality score: {result['quality_score']}/100")
| Parameter | Type | Default | Description |
|---|---|---|---|
items | list[str] | required | Full menu (up to 2,000 items) |
restaurant_name | str | "" | Restaurant name for the report |
Returns: dict with quality_score, noise_analysis, dedup_summary, non_food_items, cuisine_breakdown.
suggest(cart, menu, top_k=5)
Get upsell suggestions based on cart contents.
result = client.suggest(
cart=["Chicken Biryani"],
menu=restaurant_menu,
top_k=3
)
for s in result["suggestions"]:
print(f"{s['item']} - {s['reason']}")
| Parameter | Type | Default | Description |
|---|---|---|---|
cart | list[str] | required | Current cart items (up to 50) |
menu | list[str] | required | Full restaurant menu (up to 500) |
top_k | int | 5 | Number of suggestions |
Returns: dict with suggestions (list with item, category, reason, score, cuisine_match).
balance()
Check your API credit balance.
result = client.balance()
print(f"Credits remaining: {result['credits_remaining']}")
Returns: dict with credits_remaining and usage info.
Error handling
from dish_embed.client import DishEmbedError
try:
result = client.dedup(items)
except DishEmbedError as e:
print(e.status_code) # HTTP status code (401, 422, 429, 500, etc.)
print(e.detail) # Error message from the API
Common errors:
| Status | Meaning |
|---|---|
| 401 | Invalid or missing API key |
| 422 | Validation error (items too long, empty list, etc.) |
| 429 | Concurrent request limit exceeded (not a per-second rate limit) |
| 500 | Server error |