Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions benchmarks/response_time_becnhmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ def run_benchmark(args):
f" {args.dimension})"
)
try:
client.create_namespace(
client.namespaces.create(
namespace_name=args.namespace,
type="vector",
vector_dimension=args.dimension,
Expand Down Expand Up @@ -213,7 +213,7 @@ def run_benchmark(args):
f" ({len(batch_vectors)} vectors)..."
)
try:
upload_response = client.upload_vectors(
upload_response = client.vectors.upload(
namespace_name=args.namespace, vectors=payload["vectors"]
)
if upload_response.get("status") == "success":
Expand Down Expand Up @@ -254,7 +254,7 @@ def run_benchmark(args):
for i, q_vec in enumerate(query_vectors):
print(f" Running search query {i + 1}/{args.num_queries}...")
try:
search_response = client.search(
search_response = client.similarity_search.query(
namespaces=[args.namespace], query=q_vec, top_k=args.top_k
)
exec_time = search_response.get("execution_time")
Expand Down Expand Up @@ -343,7 +343,7 @@ def run_benchmark(args):
with MoorchehClient(
api_key=api_key, base_url=args.base_url
) as cleanup_client:
cleanup_client.delete_namespace(args.namespace)
cleanup_client.namespaces.delete(args.namespace)
print("Namespace deleted successfully.")
except Exception as e:
print(
Expand Down
4 changes: 2 additions & 2 deletions examples/01_create_namespace.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ def main():
if vector_dimension:
logger.info(f" Dimension: {vector_dimension}")

# 3. Call the create_namespace method
# 3. Call client.namespaces.create
try:
# Use the client's context manager for automatic cleanup
with client:
# SDK method call will produce its own logs (e.g., request details at DEBUG)
response = client.create_namespace(
response = client.namespaces.create(
namespace_name=namespace_to_create,
type=namespace_type,
vector_dimension=vector_dimension,
Expand Down
6 changes: 3 additions & 3 deletions examples/02_list_namespaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ def main():
) # Log full traceback
sys.exit(1)

# 2. Call the list_namespaces method
# 2. Call client.namespaces.list
logger.info("Attempting to list namespaces...")
try:
# Use the client's context manager for automatic cleanup
with client:
# SDK method call will produce its own logs
response = client.list_namespaces() # Call the SDK method
response = client.namespaces.list()

logger.info("--- API Response ---")
# Use json.dumps for pretty printing the response dict in the log
Expand All @@ -66,7 +66,7 @@ def main():
logger.info(f"Successfully retrieved {num_namespaces} namespace(s). ✅")
# Optionally iterate and log names at DEBUG level if needed
# for ns in response['namespaces']:
# logger.debug(f" - {ns.get('namespace_name')} (Type: {ns.get('type')}, Items: {ns.get('itemCount')})") # noqa: E501
# logger.debug(f" - {ns.get('namespace_name')} (Type: {ns.get('type')}, Items: {ns.get('item_count')})") # noqa: E501
else:
# Log a warning if the expected key is missing
logger.warning(
Expand Down
5 changes: 3 additions & 2 deletions examples/03_upload_documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def main():
# 2. Define Target Namespace and Documents to Upload
target_namespace = "sdk-test-text-ns-01" # Use the text namespace created earlier

# Any keys other than id and text are treated as metadata (flat key/value).
documents_to_upload = [
{
"id": "sdk-doc-001", # Unique ID for this chunk
Expand Down Expand Up @@ -80,12 +81,12 @@ def main():
f" '{target_namespace}'"
)

# 3. Call the upload_documents method
# 3. Call client.documents.upload
try:
# Use the client's context manager
with client:
# SDK method call will produce its own logs
response = client.upload_documents(
response = client.documents.upload(
namespace_name=target_namespace, documents=documents_to_upload
)
logger.info("--- API Response (Should be 202 Accepted) ---")
Expand Down
4 changes: 2 additions & 2 deletions examples/04_search_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ def main():
if score_threshold is not None:
logger.info(f" Threshold: {score_threshold}")

# 3. Call the search method
# 3. Call client.similarity_search.query
try:
# Use the client's context manager
with client:
# SDK method call will produce its own logs
response = client.search(
response = client.similarity_search.query(
namespaces=[target_namespace], # Pass namespace(s) as a list
query=search_query, # Pass the text query string
top_k=top_k_results,
Expand Down
11 changes: 7 additions & 4 deletions examples/05_delete_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ def main():
f" '{target_namespace}'"
)

# 3. Call the delete_documents method
# 3. Call client.documents.delete
# Note: The method expects a LIST of IDs, even if deleting only one.
try:
with client:
# SDK method call will produce its own logs
response = client.delete_documents(
response = client.documents.delete(
namespace_name=target_namespace,
ids=[document_id_to_delete], # Pass the ID inside a list
)
Expand All @@ -76,8 +76,11 @@ def main():
logger.info("-----------------------------------------------------------")

if response and response.get("status") == "success":
# Check if the specific ID is in the returned list (optional validation)
if document_id_to_delete in response.get("deleted_ids", []):
# API may return deleted_ids and/or requested_ids
ids_reported = (
response.get("deleted_ids") or response.get("requested_ids") or []
)
if document_id_to_delete in ids_reported:
logger.info(
"Successfully processed deletion request for document ID"
f" '{document_id_to_delete}'. ✅"
Expand Down
4 changes: 2 additions & 2 deletions examples/06_get_gen_ai_answer.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ def main():
logger.info(f" Query: '{query}'")
logger.info(f" Context (top_k): {top_k_context}")

# 3. Call the get_generative_answer method
# 3. Call client.answer.generate
try:
# Use the client's context manager
with client:
# SDK method call will produce its own logs
response = client.get_generative_answer(
response = client.answer.generate(
namespace=target_namespace, query=query, top_k=top_k_context
)
logger.info("--- API Response (Generative Answer) ---")
Expand Down
4 changes: 2 additions & 2 deletions examples/07_upload_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ def main():

if response.get("success"):
logger.info("✅ File uploaded successfully!")
logger.info(f" File: {response.get('fileName')}")
logger.info(f" Size: {response.get('fileSize')} bytes")
logger.info(f" File: {response.get('file_name')}")
logger.info(f" Size: {response.get('file_size')} bytes")
logger.info(f" Namespace: {response.get('namespace')}")
else:
logger.warning(
Expand Down
2 changes: 1 addition & 1 deletion examples/08_delete_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def main():
for result in response.get("results", []):
logger.info(
"File '%s' -> %s (%s)",
result.get("fileName"),
result.get("file_name"),
result.get("status"),
result.get("message"),
)
Expand Down
93 changes: 93 additions & 0 deletions examples/09_fetch_text_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# examples/09_fetch_text_data.py

import json
import logging
import sys

from moorcheh_sdk import (
APIError,
AuthenticationError,
InvalidInputError,
MoorchehClient,
MoorchehError,
NamespaceNotFound,
)

# --- Configure Logging ---
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
logger = logging.getLogger(__name__)
# -------------------------


def main():
"""
Example: list stored text and summary chunks for a text namespace (GET
fetch-text-data). Up to 100 items per response. For retrieving full
documents by ID, use client.documents.get instead.
"""
logger.info("--- Moorcheh SDK: Fetch Text Data Example ---")

try:
client = MoorchehClient()
logger.info("Client initialized successfully.")
except AuthenticationError as e:
logger.error(f"Authentication Error: {e}")
logger.error(
"Please ensure the MOORCHEH_API_KEY environment variable is set correctly."
)
sys.exit(1)
except MoorchehError as e:
logger.error(f"Error initializing client: {e}", exc_info=True)
sys.exit(1)

target_namespace = "sdk-test-text-ns-01"

logger.info(f"Target namespace (must be type=text): {target_namespace}")

try:
with client:
logger.info(f"Fetching text chunks from namespace '{target_namespace}'...")
response = client.documents.fetch_text_data(
namespace_name=target_namespace,
)

logger.info("--- API Response (200 OK) ---")
logger.info(json.dumps(response, indent=2))
logger.info("-------------------------------")

if response.get("status") == "success":
items = response.get("items") or []
stats = response.get("statistics") or {}
logger.info(
f"✅ Fetched {len(items)} item(s). "
f"statistics.total_items={stats.get('total_items')}"
)
else:
logger.warning(
f"Unexpected status in response: {response.get('status')!r}"
)

except NamespaceNotFound:
logger.error(f"Namespace '{target_namespace}' was not found.")
logger.info(
"Create a text namespace first (see examples/01_create_namespace.py) "
"and upload data (examples/03_upload_documents.py)."
)
except InvalidInputError as e:
logger.error(f"Invalid input: {e}")
except AuthenticationError as e:
logger.error(f"Authentication failed: {e}")
except APIError:
logger.exception("An API error occurred.")
except MoorchehError:
logger.exception("An SDK or network error occurred.")
except Exception:
logger.exception("An unexpected error occurred.")


if __name__ == "__main__":
main()
30 changes: 19 additions & 11 deletions examples/quickstart.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def run_quickstart():
# --- 1. Create Namespaces ---
try:
logger.info(f"[Step 1a] Creating text namespace: '{text_ns_name}'")
creation_response_text = client.create_namespace(
creation_response_text = client.namespaces.create(
namespace_name=text_ns_name, type="text"
)
logger.info(
Expand All @@ -79,7 +79,7 @@ def run_quickstart():
f"[Step 1b] Creating vector namespace: '{vector_ns_name}' (Dim:"
f" {vector_dim})"
)
creation_response_vector = client.create_namespace(
creation_response_vector = client.namespaces.create(
namespace_name=vector_ns_name,
type="vector",
vector_dimension=vector_dim,
Expand All @@ -97,7 +97,7 @@ def run_quickstart():
# --- 2. List Namespaces ---
logger.info("[Step 2] Listing namespaces...")
try:
namespaces_response = client.list_namespaces()
namespaces_response = client.namespaces.list()
logger.info("Current Namespaces:")
logger.info(
json.dumps(namespaces_response.get("namespaces", []), indent=2)
Expand All @@ -107,6 +107,7 @@ def run_quickstart():

# --- 3. Upload Documents (to text namespace) ---
logger.info(f"[Step 3] Uploading documents to '{text_ns_name}'...")
# Any keys other than id and text are treated as metadata (flat key/value).
docs_to_upload = [
{
"id": "qs-doc-1",
Expand All @@ -128,13 +129,19 @@ def run_quickstart():
},
]
try:
upload_doc_res = client.upload_documents(
upload_doc_res = client.documents.upload(
namespace_name=text_ns_name, documents=docs_to_upload
)
logger.info(
"Upload documents response (queued):"
f" {json.dumps(upload_doc_res, indent=2)}"
)
if not upload_doc_res.get("submitted_ids"):
logger.info(
"Note: submitted_ids can be empty when these document IDs were"
" already ingested (re-runs). Search may still return existing"
" chunks."
)
except (NamespaceNotFound, InvalidInputError) as e:
logger.error(f"Could not upload documents to '{text_ns_name}': {e}")
except Exception as e:
Expand All @@ -152,6 +159,7 @@ def run_quickstart():
random_vector = [
random.uniform(-1.0, 1.0) for _ in range(vector_dim)
] # Generate random vector
# Any keys other than id and vector are treated as metadata (flat).
vectors_to_upload.append(
{
"id": vec_id,
Expand All @@ -162,7 +170,7 @@ def run_quickstart():
}
)
try:
upload_vec_res = client.upload_vectors(
upload_vec_res = client.vectors.upload(
namespace_name=vector_ns_name, vectors=vectors_to_upload
)
logger.info(
Expand Down Expand Up @@ -191,7 +199,7 @@ def run_quickstart():
" interaction'"
)
try:
text_search_res = client.search(
text_search_res = client.similarity_search.query(
namespaces=[text_ns_name],
query="API interaction", # Text query
top_k=2,
Expand All @@ -214,7 +222,7 @@ def run_quickstart():
try:
# Generate a new random query vector
query_vector = [random.uniform(-1.0, 1.0) for _ in range(vector_dim)]
vector_search_res = client.search(
vector_search_res = client.similarity_search.query(
namespaces=[vector_ns_name],
query=query_vector, # Vector query
top_k=2,
Expand All @@ -238,7 +246,7 @@ def run_quickstart():
f" '{text_ns_name}'..."
)
try:
del_doc_res = client.delete_documents(
del_doc_res = client.documents.delete(
namespace_name=text_ns_name, ids=[doc_id_to_delete]
)
logger.info(
Expand All @@ -258,7 +266,7 @@ def run_quickstart():
f" '{vector_ns_name}'..."
)
try:
del_vec_res = client.delete_vectors(
del_vec_res = client.vectors.delete(
namespace_name=vector_ns_name, ids=[vec_id_to_delete]
)
logger.info(
Expand All @@ -275,15 +283,15 @@ def run_quickstart():
# --- 8. Cleanup: Delete Namespaces (Optional - uncomment to run) ---
# logger.info(f"[Step 8 - Cleanup] Deleting namespace: {text_ns_name}")
# try:
# client.delete_namespace(text_ns_name)
# client.namespaces.delete(namespace_name=text_ns_name)
# except NamespaceNotFound:
# logger.warning(f"Namespace '{text_ns_name}' likely already deleted or never created.") # noqa: E501
# except Exception as e:
# logger.error(f"Error deleting '{text_ns_name}': {e}", exc_info=True)

# logger.info(f"[Step 8 - Cleanup] Deleting namespace: {vector_ns_name}")
# try:
# client.delete_namespace(vector_ns_name)
# client.namespaces.delete(namespace_name=vector_ns_name)
# except NamespaceNotFound:
# logger.warning(f"Namespace '{vector_ns_name}' likely already deleted or never created.") # noqa: E501
# except Exception as e:
Expand Down
Loading
Loading