Skip to content

Commit 334d1ce

Browse files
committed
Update sdk
1 parent c486789 commit 334d1ce

22 files changed

+275
-263
lines changed

src/rushdb/__init__.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
"""
55

66
from .client import RushDBClient
7-
from .common import RushDBError, RelationOptions, RelationDetachOptions
8-
from .record import Record
9-
from .transaction import Transaction
10-
from .property import Property
7+
from .common import RushDBError
8+
from .models.relationship import RelationshipOptions, RelationshipDetachOptions
9+
from .models.property import Property
10+
from .models.record import Record
11+
from .models.transaction import Transaction
1112

12-
__all__ = ['RushDBClient', 'RushDBError', 'Record', 'RelationOptions', 'RelationDetachOptions', 'Transaction', 'Property']
13+
__all__ = ['RushDBClient', 'RushDBError', 'Record', 'Transaction', 'Property', 'RelationshipOptions', 'RelationshipDetachOptions']

src/rushdb/api/__init__.py

Whitespace-only changes.

src/rushdb/api/base.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from typing import TYPE_CHECKING
2+
3+
if TYPE_CHECKING:
4+
from ..client import RushDBClient
5+
6+
class BaseAPI:
7+
"""Base class for all API endpoints."""
8+
def __init__(self, client: 'RushDBClient'):
9+
self.client = client

src/rushdb/api/labels.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from typing import List, Optional
2+
3+
from .base import BaseAPI
4+
from ..models.search_query import SearchQuery
5+
from ..models.transaction import Transaction
6+
7+
8+
class LabelsAPI(BaseAPI):
9+
"""API for managing labels in RushDB."""
10+
def list(self, query: Optional[SearchQuery] = None, transaction: Optional[Transaction] = None) -> List[str]:
11+
"""List all labels."""
12+
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
13+
14+
return self.client._make_request('POST', '/api/v1/labels', data=query or {}, headers=headers)

src/rushdb/api/properties.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from typing import List, Optional, Literal
2+
3+
from .base import BaseAPI
4+
from ..models.property import Property, PropertyValuesData
5+
from ..models.search_query import SearchQuery
6+
from ..models.transaction import Transaction
7+
8+
9+
class PropertiesAPI(BaseAPI):
10+
"""API for managing properties in RushDB."""
11+
def find(self, query: Optional[SearchQuery] = None, transaction: Optional[Transaction] = None) -> List[Property]:
12+
"""List all properties."""
13+
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
14+
15+
return self.client._make_request('POST', '/api/v1/properties', query or {}, headers)
16+
17+
def find_by_id(self, property_id: str, transaction: Optional[Transaction] = None) -> Property:
18+
"""Get a property by ID."""
19+
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
20+
21+
return self.client._make_request('GET', f'/api/v1/properties/{property_id}', headers=headers)
22+
23+
def delete(self, property_id: str, transaction: Optional[Transaction] = None) -> None:
24+
"""Delete a property."""
25+
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
26+
27+
return self.client._make_request('DELETE', f'/api/v1/properties/{property_id}', headers=headers)
28+
29+
def values(self, property_id: str, sort: Optional[Literal['asc', 'desc']], skip: Optional[int], limit: Optional[int], transaction: Optional[Transaction] = None) -> PropertyValuesData:
30+
"""Get values data for a property."""
31+
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
32+
33+
return self.client._make_request('GET', f'/api/v1/properties/{property_id}/values', headers=headers, params={ "sort": sort, "skip": skip, "limit": limit })

src/rushdb/records_api.py renamed to src/rushdb/api/records.py

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
from typing import Dict, Any, Optional, Union, List
22

3-
from src.rushdb import RushDBClient, RushDBError
4-
from src.rushdb.transaction import Transaction
5-
from src.rushdb.common import RelationOptions, RelationDetachOptions
6-
from src.rushdb.record import Record
3+
from .base import BaseAPI
4+
from ..common import RushDBError
5+
from ..models.relationship import RelationshipOptions, RelationshipDetachOptions
6+
from ..models.search_query import SearchQuery
7+
from ..models.transaction import Transaction
8+
from ..models.record import Record
79

810

9-
class RecordsAPI:
11+
class RecordsAPI(BaseAPI):
1012
"""API for managing records in RushDB."""
11-
def __init__(self, client: 'RushDBClient'):
12-
self.client = client
13-
1413
def set(self, record_id: str, data: Dict[str, Any], transaction: Optional[Transaction] = None) -> Dict[str, str]:
1514
"""Update a record by ID."""
1615
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
@@ -45,7 +44,7 @@ def create(self, label: str, data: Dict[str, Any], options: Optional[Dict[str, b
4544
}
4645
}
4746
response = self.client._make_request('POST', '/api/v1/records', payload, headers)
48-
return Record(self.client, response)
47+
return Record(self.client, response.get('data'))
4948

5049
def create_many(self, label: str, data: Union[Dict[str, Any], List[Dict[str, Any]]], options: Optional[Dict[str, bool]] = None, transaction: Optional[Transaction] = None) -> List[Record]:
5150
"""Create multiple records.
@@ -70,23 +69,19 @@ def create_many(self, label: str, data: Union[Dict[str, Any], List[Dict[str, Any
7069
}
7170
}
7271
response = self.client._make_request('POST', '/api/v1/records/import/json', payload, headers)
72+
return [Record(self.client, record) for record in response.get('data')]
7373

74-
print('r:', response)
75-
76-
return [Record(self.client, {"data": record}) for record in response.get('data')]
77-
78-
def attach(self, source: Union[str, Dict[str, Any]], target: Union[str, List[str], Dict[str, Any], List[Dict[str, Any]]], options: Optional[RelationOptions] = None, transaction: Optional[Transaction] = None) -> Dict[str, str]:
74+
def attach(self, source: Union[str, Dict[str, Any]], target: Union[str, List[str], Dict[str, Any], List[Dict[str, Any]]], options: Optional[RelationshipOptions] = None, transaction: Optional[Transaction] = None) -> Dict[str, str]:
7975
"""Attach records to a source record."""
8076
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
8177
source_id = self._extract_target_ids(source)[0]
8278
target_ids = self._extract_target_ids(target)
8379
payload = {'targetIds': target_ids}
8480
if options:
8581
payload.update(options)
86-
print(payload)
8782
return self.client._make_request('POST', f'/api/v1/records/{source_id}/relations', payload, headers)
8883

89-
def detach(self, source: Union[str, Dict[str, Any]], target: Union[str, List[str], Dict[str, Any], List[Dict[str, Any]]], options: Optional[RelationDetachOptions] = None, transaction: Optional[Transaction] = None) -> Dict[str, str]:
84+
def detach(self, source: Union[str, Dict[str, Any]], target: Union[str, List[str], Dict[str, Any], List[Dict[str, Any]]], options: Optional[RelationshipDetachOptions] = None, transaction: Optional[Transaction] = None) -> Dict[str, str]:
9085
"""Detach records from a source record."""
9186
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
9287
source_id = self._extract_target_ids(source)[0]
@@ -96,7 +91,7 @@ def detach(self, source: Union[str, Dict[str, Any]], target: Union[str, List[str
9691
payload.update(options)
9792
return self.client._make_request('PUT', f'/api/v1/records/{source_id}/relations', payload, headers)
9893

99-
def delete(self, query: Dict[str, Any], transaction: Optional[Transaction] = None) -> Dict[str, str]:
94+
def delete(self, query: SearchQuery, transaction: Optional[Transaction] = None) -> Dict[str, str]:
10095
"""Delete records matching the query."""
10196
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
10297
return self.client._make_request('PUT', '/api/v1/records/delete', query, headers)
@@ -111,35 +106,16 @@ def delete_by_id(self, id_or_ids: Union[str, List[str]], transaction: Optional[T
111106
}, headers)
112107
return self.client._make_request('DELETE', f'/api/v1/records/{id_or_ids}', None, headers)
113108

114-
def find(self, query: Optional[Dict[str, Any]] = None, record_id: Optional[str] = None, transaction: Optional[Transaction] = None) -> List[Record]:
109+
def find(self, query: Optional[SearchQuery] = None, record_id: Optional[str] = None, transaction: Optional[Transaction] = None) -> List[Record]:
115110
"""Find records matching the query."""
116-
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
117-
path = f'/api/v1/records/{record_id}/search' if record_id else '/api/v1/records/search'
118-
response = self.client._make_request('POST', path, data=query, headers=headers)
119-
return [Record(self.client, record) for record in response]
120111

121-
def find_by_id(self, id_or_ids: Union[str, List[str]], transaction: Optional[Transaction] = None) -> Union[Record, List[Record]]:
122-
"""Find records by ID(s)."""
123-
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
124-
if isinstance(id_or_ids, list):
125-
response = self.client._make_request('POST', '/api/v1/records', {'ids': id_or_ids}, headers)
126-
return [Record(self.client, record) for record in response]
127-
response = self.client._make_request('GET', f'/api/v1/records/{id_or_ids}', None, headers)
128-
return Record(self.client, response)
129-
130-
def find_one(self, query: Dict[str, Any], transaction: Optional[Transaction] = None) -> Optional[Record]:
131-
"""Find a single record matching the query."""
132-
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
133-
query = {**query, 'limit': 1, 'skip': 0}
134-
result = self.client._make_request('POST', '/api/v1/records/search', query, headers)
135-
return Record(self.client, result[0]) if result else None
136-
137-
def find_unique(self, query: Dict[str, Any], transaction: Optional[Transaction] = None) -> Record:
138-
"""Find a unique record matching the query."""
139-
result = self.find_one(query, transaction)
140-
if not result:
141-
raise RushDBError("No records found matching the unique query")
142-
return result
112+
try:
113+
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
114+
path = f'/api/v1/records/{record_id}/search' if record_id else '/api/v1/records/search'
115+
response = self.client._make_request('POST', path, data=query or {}, headers=headers)
116+
return [Record(self.client, record) for record in response.get('data')]
117+
except:
118+
return []
143119

144120
def import_csv(self, label: str, csv_data: Union[str, bytes], options: Optional[Dict[str, bool]] = None, transaction: Optional[Transaction] = None) -> List[Dict[str, Any]]:
145121
"""Import data from CSV."""

src/rushdb/api/relationships.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from typing import List, Optional, TypedDict, Union
2+
from urllib.parse import urlencode
3+
4+
from .base import BaseAPI
5+
from ..models.relationship import Relationship
6+
from ..models.search_query import SearchQuery
7+
from ..models.transaction import Transaction
8+
9+
class PaginationParams(TypedDict, total=False):
10+
"""TypedDict for pagination parameters."""
11+
limit: int
12+
skip: int
13+
14+
15+
16+
class RelationsAPI(BaseAPI):
17+
"""API for managing relationships in RushDB."""
18+
19+
async def find(
20+
self,
21+
query: Optional[SearchQuery] = None,
22+
pagination: Optional[PaginationParams] = None,
23+
transaction: Optional[Union[Transaction, str]] = None
24+
) -> List[Relationship]:
25+
"""Find relations matching the search parameters.
26+
27+
Args:
28+
query: Search query parameters
29+
pagination: Optional pagination parameters (limit and skip)
30+
transaction: Optional transaction context or transaction ID
31+
32+
Returns:
33+
List of matching relations
34+
"""
35+
# Build query string for pagination
36+
query_params = {}
37+
if pagination:
38+
if pagination.get('limit') is not None:
39+
query_params['limit'] = str(pagination['limit'])
40+
if pagination.get('skip') is not None:
41+
query_params['skip'] = str(pagination['skip'])
42+
43+
# Construct path with query string
44+
query_string = f"?{urlencode(query_params)}" if query_params else ""
45+
path = f"/records/relations/search{query_string}"
46+
47+
# Build headers with transaction if present
48+
headers = Transaction._build_transaction_header(transaction.id if transaction else None)
49+
50+
# Make request
51+
response = self.client._make_request(
52+
method='POST',
53+
path=path,
54+
data=query or {},
55+
headers=headers
56+
)
57+
58+
return response.data

src/rushdb/transactions_api.py renamed to src/rushdb/api/transactions.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
from typing import Optional
22

3-
from src.rushdb import RushDBClient
4-
from src.rushdb.transaction import Transaction
3+
from .base import BaseAPI
4+
from ..models.transaction import Transaction
55

66

7-
class TransactionsAPI:
7+
class TransactionsAPI(BaseAPI):
88
"""API for managing transactions in RushDB."""
9-
def __init__(self, client: 'RushDBClient'):
10-
self.client = client
11-
129
def begin(self, ttl: Optional[int] = None) -> Transaction:
1310
"""Begin a new transaction.
1411

src/rushdb/client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
import urllib.error
77
from typing import Any, Dict, Optional
88

9-
from src.rushdb.common import RushDBError
10-
from src.rushdb.labels_api import LabelsAPI
11-
from src.rushdb.properties_api import PropertiesAPI
12-
from src.rushdb.records_api import RecordsAPI
13-
from src.rushdb.transactions_api import TransactionsAPI
9+
from .common import RushDBError
10+
from .api.labels import LabelsAPI
11+
from .api.properties import PropertiesAPI
12+
from .api.records import RecordsAPI
13+
from .api.transactions import TransactionsAPI
1414

1515
class RushDBClient:
1616
"""Main client for interacting with RushDB."""

src/rushdb/common.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
1-
from typing import Dict, List, Optional, Union, TypedDict, Literal
1+
from typing import Dict, Optional
22

3-
# Relation types
4-
RelationDirection = Literal['in', 'out']
5-
6-
class RelationOptions(TypedDict, total=False):
7-
"""Options for creating relations."""
8-
direction: Optional[RelationDirection]
9-
type: Optional[str]
10-
11-
class RelationDetachOptions(TypedDict, total=False):
12-
"""Options for detaching relations."""
13-
direction: Optional[RelationDirection]
14-
typeOrTypes: Optional[Union[str, List[str]]]
153

164
class RushDBError(Exception):
175
"""Custom exception for RushDB client errors."""

0 commit comments

Comments
 (0)