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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ csv_data = "name,email,age\nJohn,john@example.com,30\nJane,jane@example.com,25"
db.records.import_csv(
label='USER',
data=csv_data,
options={'returnResult': True, 'suggestTypes': True},
# skipEmptyValues: treat empty cells ("" / []) as unset instead of storing them (0/False are kept)
options={'returnResult': True, 'suggestTypes': True, 'skipEmptyValues': True},
parse_config={'header': True, 'skipEmptyLines': True, 'dynamicTyping': True},
)
```
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "rushdb"
version = "2.3.0"
version = "2.6.0"
description = "RushDB Python SDK — memory layer for AI agents and modern apps"
authors = [
{name = "RushDB Team", email = "hi@rushdb.com"}
Expand Down
24 changes: 12 additions & 12 deletions src/rushdb/api/ai.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""AI API for RushDB Python SDK.

Provides methods for graph ontology exploration, semantic vector search,
Provides methods for graph schema exploration, semantic vector search,
and embedding index management.
"""

Expand Down Expand Up @@ -123,7 +123,7 @@ class AIAPI(BaseAPI):
Example::

>>> db = RushDB(api_key="...")
>>> ontology = db.ai.get_ontology()
>>> schema = db.ai.get_schema()
>>> results = db.ai.search({"query": "fast cars", "propertyName": "description"})
>>> db.ai.indexes.create({"propertyName": "description", "label": "Book"})
"""
Expand All @@ -132,12 +132,12 @@ def __init__(self, client: "RushDB"):
super().__init__(client)
self.indexes = _AIIndexesNamespace(client)

def get_ontology(
def get_schema(
self,
params: Optional[Dict[str, Any]] = None,
transaction: Optional[Union[Transaction, str]] = None,
) -> ApiResponse:
"""Return the full graph ontology as structured JSON.
"""Return the full graph schema as structured JSON.

Each item contains the label name, record count, properties with value
ranges/samples, and cross-label relationships with direction.
Expand All @@ -149,13 +149,13 @@ def get_ontology(

Args:
params: Optional filter. Pass ``{"labels": ["Label1"]}`` to scope
the ontology to specific labels only. Pass ``{"force": True}``
to bypass the 1-hour ontology cache and trigger a full
the schema to specific labels only. Pass ``{"force": True}``
to bypass the 1-hour schema cache and trigger a full
recalculation.
transaction: Optional transaction context.

Returns:
ApiResponse: Response whose ``data`` is a list of ontology items.
ApiResponse: Response whose ``data`` is a list of schema items.
"""
headers: Dict[str, str] = {}
if transaction is not None:
Expand All @@ -165,20 +165,20 @@ def get_ontology(
headers["x-transaction-id"] = tx_id

response = self.client._make_request(
"POST", "/ai/ontology", params or {}, headers=headers or None
"POST", "/ai/schema", params or {}, headers=headers or None
)
return ApiResponse(
data=response.get("data"),
success=response.get("success", True),
total=response.get("total"),
)

def get_ontology_markdown(
def get_schema_markdown(
self,
params: Optional[Dict[str, Any]] = None,
transaction: Optional[Union[Transaction, str]] = None,
) -> ApiResponse:
"""Return the full graph ontology as compact Markdown tables.
"""Return the full graph schema as compact Markdown tables.

Token-efficient representation intended for direct LLM consumption.
Includes labels with counts, properties with types and value
Expand All @@ -191,7 +191,7 @@ def get_ontology_markdown(
Args:
params: Optional filter. Pass ``{"labels": ["Label1"]}`` to scope
the output to specific labels only. Pass ``{"force": True}``
to bypass the 1-hour ontology cache and trigger a full
to bypass the 1-hour schema cache and trigger a full
recalculation.
transaction: Optional transaction context.

Expand All @@ -206,7 +206,7 @@ def get_ontology_markdown(
headers["x-transaction-id"] = tx_id

response = self.client._make_request(
"POST", "/ai/ontology/md", params or {}, headers=headers or None
"POST", "/ai/schema/md", params or {}, headers=headers or None
)
return ApiResponse(
data=response.get("data"),
Expand Down
6 changes: 5 additions & 1 deletion src/rushdb/api/records.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ def create(
Available options:
- returnResult (bool): Whether to return the created record data. Defaults to True.
- suggestTypes (bool): Whether to automatically suggest data types. Defaults to True.
- skipEmptyValues (bool): Treat empty strings ("") and empty arrays ([]) as unset —
no property is created. 0 and False are kept. Defaults to False.
vectors (Optional[List[Dict[str, Any]]]): Optional pre-computed embedding vectors
to write alongside the record. Each entry must contain at least
``propertyName`` and ``vector``; ``similarityFunction`` is required when
Expand Down Expand Up @@ -231,7 +233,9 @@ def create_many(
record. Nested objects/arrays are not supported here — raises
``ValueError`` if any item contains a nested object or list.
options: Optional write options forwarded as-is to the server
(e.g. ``suggestTypes``, ``mergeBy``, ``mergeStrategy``, etc.).
(e.g. ``suggestTypes``, ``skipEmptyValues``, ``mergeBy``,
``mergeStrategy``, etc.). ``skipEmptyValues`` treats empty strings
and empty arrays as unset (``0``/``False`` are kept); defaults to False.
vectors: Optional per-row inline vectors for external embedding indexes.
``vectors[i]`` is applied to ``data[i]``. Each element is a list of
vector entry dicts: ``[{"propertyName": str, "vector": List[float],
Expand Down
6 changes: 3 additions & 3 deletions src/rushdb/api/relationship_patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


class RelationshipPatternsAPI(BaseAPI):
"""Review and manage relationship patterns inferred from project ontology.
"""Review and manage relationship patterns inferred from project schema.

Accessed via ``db.relationships.patterns``.
"""
Expand All @@ -27,12 +27,12 @@ def _wrap(response: Dict[str, Any]) -> ApiResponse:
)

def list(self) -> ApiResponse:
"""List inferred patterns, ontology relationships, and analysis status."""
"""List inferred patterns, schema relationships, and analysis status."""
response = self.client._make_request("GET", "/relationships/patterns")
return self._wrap(response)

def analyze(self) -> ApiResponse:
"""Queue ontology analysis to generate relationship pattern suggestions."""
"""Queue schema analysis to generate relationship pattern suggestions."""
response = self.client._make_request(
"POST", "/relationships/patterns/analyze", {}
)
Expand Down
2 changes: 1 addition & 1 deletion src/rushdb/models/api_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ApiResponse(Generic[T]):
total: Optional total count (e.g. for list endpoints).

Example:
>>> response = db.ai.get_ontology_markdown()
>>> response = db.ai.get_schema_markdown()
>>> schema_md = response.data # str
>>> response = db.ai.indexes.find()
>>> indexes = response.data # list[dict]
Expand Down
5 changes: 3 additions & 2 deletions src/rushdb/models/property.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ class DatetimeObject(TypedDict, total=False):
NumberValue = Union[float, int]
StringValue = str

# Property types
PropertyType = Literal["boolean", "datetime", "null", "number", "string"]
# Property types. A None/null value means the field is unset; `None` is still accepted as an
# input value in `PropertyWithValue.value` below.
PropertyType = Literal["boolean", "datetime", "number", "string"]


class Property(TypedDict):
Expand Down
Loading