Skip to content

Commit ce00bcc

Browse files
jfrench9claude
andauthored
Enhance graph limits and materialization features with improved models (#59)
## Summary This PR significantly enhances the robosystems client by expanding graph limits functionality and improving the materialization system. The changes introduce new content and quota management models while refactoring existing structures for better API consistency. ## Key Accomplishments ### New Features - **Content Limits Management**: Added comprehensive content limits tracking and validation - **Download Quota System**: Implemented download quota management with detailed tracking capabilities - **Enhanced Materialization**: Expanded materialization request/response handling with improved limit checking - **Graph Limits API**: Extended graph limits endpoint with additional functionality ### Model Improvements - Added `ContentLimits` model for comprehensive limit management - Introduced `DownloadQuota` model for quota tracking and enforcement - Enhanced `MaterializeResponse` with improved limit validation and type checking - Expanded `ValidationError` with better context handling - Refactored `GraphSubscriptionTier` for improved tier management ### API Enhancements - Updated graph tiers endpoint with improved tier availability logic - Enhanced materialization endpoint with better request/response handling - Improved graph limits endpoint with additional metadata ## Breaking Changes - Removed `CreditLimits` model in favor of more granular limit models - Refactored file structure with model renames: - `storage_info_overage_pricing.py` → `materialize_response_limit_check_type_0.py` - `storage_info_included_per_tier.py` → `validation_error_context.py` - Updated import paths and dependencies in `__init__.py` ## Testing Notes - Verify all graph limits functionality works with new model structure - Test materialization workflows with enhanced request/response handling - Validate quota management and download limit enforcement - Ensure backward compatibility where possible with existing integrations ## Infrastructure Considerations - Models have been restructured to improve maintainability and API consistency - Enhanced error handling and validation throughout the materialization pipeline - Improved type safety with better model definitions and validation contexts --- 🤖 Generated with [Claude Code](https://claude.ai/code) **Branch Info:** - Source: `chore/update-packages` - Target: `main` - Type: feature Co-Authored-By: Claude <noreply@anthropic.com>
2 parents 730cbe3 + 4f0e718 commit ce00bcc

18 files changed

Lines changed: 486 additions & 99 deletions

robosystems_client/api/graph_limits/get_graph_limits.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def sync_detailed(
8282
- **Backup Limits**: Frequency, retention, size limits
8383
- **Rate Limits**: Requests per minute/hour based on tier
8484
- **Credit Limits**: AI operation credits (if applicable)
85+
- **Content Limits**: Node, relationship, and row limits (if applicable)
8586
8687
This unified endpoint provides all limits in one place for easier client integration.
8788
@@ -125,6 +126,7 @@ def sync(
125126
- **Backup Limits**: Frequency, retention, size limits
126127
- **Rate Limits**: Requests per minute/hour based on tier
127128
- **Credit Limits**: AI operation credits (if applicable)
129+
- **Content Limits**: Node, relationship, and row limits (if applicable)
128130
129131
This unified endpoint provides all limits in one place for easier client integration.
130132
@@ -163,6 +165,7 @@ async def asyncio_detailed(
163165
- **Backup Limits**: Frequency, retention, size limits
164166
- **Rate Limits**: Requests per minute/hour based on tier
165167
- **Credit Limits**: AI operation credits (if applicable)
168+
- **Content Limits**: Node, relationship, and row limits (if applicable)
166169
167170
This unified endpoint provides all limits in one place for easier client integration.
168171
@@ -204,6 +207,7 @@ async def asyncio(
204207
- **Backup Limits**: Frequency, retention, size limits
205208
- **Rate Limits**: Requests per minute/hour based on tier
206209
- **Credit Limits**: AI operation credits (if applicable)
210+
- **Content Limits**: Node, relationship, and row limits (if applicable)
207211
208212
This unified endpoint provides all limits in one place for easier client integration.
209213

robosystems_client/api/graphs/get_available_graph_tiers.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,9 @@ def sync_detailed(
8383
- Availability status
8484
8585
**Available Tiers:**
86-
- **ladybug-standard**: Multi-tenant entry-level tier
86+
- **ladybug-standard**: Dedicated entry-level tier
8787
- **ladybug-large**: Dedicated professional tier with subgraph support
8888
- **ladybug-xlarge**: Enterprise tier with maximum resources
89-
- **neo4j-community-large**: Neo4j Community Edition (optional, if enabled)
90-
- **neo4j-enterprise-xlarge**: Neo4j Enterprise Edition (optional, if enabled)
9189
9290
**Use Cases:**
9391
- Display tier options in graph creation UI
@@ -140,11 +138,9 @@ def sync(
140138
- Availability status
141139
142140
**Available Tiers:**
143-
- **ladybug-standard**: Multi-tenant entry-level tier
141+
- **ladybug-standard**: Dedicated entry-level tier
144142
- **ladybug-large**: Dedicated professional tier with subgraph support
145143
- **ladybug-xlarge**: Enterprise tier with maximum resources
146-
- **neo4j-community-large**: Neo4j Community Edition (optional, if enabled)
147-
- **neo4j-enterprise-xlarge**: Neo4j Enterprise Edition (optional, if enabled)
148144
149145
**Use Cases:**
150146
- Display tier options in graph creation UI
@@ -192,11 +188,9 @@ async def asyncio_detailed(
192188
- Availability status
193189
194190
**Available Tiers:**
195-
- **ladybug-standard**: Multi-tenant entry-level tier
191+
- **ladybug-standard**: Dedicated entry-level tier
196192
- **ladybug-large**: Dedicated professional tier with subgraph support
197193
- **ladybug-xlarge**: Enterprise tier with maximum resources
198-
- **neo4j-community-large**: Neo4j Community Edition (optional, if enabled)
199-
- **neo4j-enterprise-xlarge**: Neo4j Enterprise Edition (optional, if enabled)
200194
201195
**Use Cases:**
202196
- Display tier options in graph creation UI
@@ -247,11 +241,9 @@ async def asyncio(
247241
- Availability status
248242
249243
**Available Tiers:**
250-
- **ladybug-standard**: Multi-tenant entry-level tier
244+
- **ladybug-standard**: Dedicated entry-level tier
251245
- **ladybug-large**: Dedicated professional tier with subgraph support
252246
- **ladybug-xlarge**: Enterprise tier with maximum resources
253-
- **neo4j-community-large**: Neo4j Community Edition (optional, if enabled)
254-
- **neo4j-enterprise-xlarge**: Neo4j Enterprise Edition (optional, if enabled)
255247
256248
**Use Cases:**
257249
- Display tier options in graph creation UI

robosystems_client/api/materialize/materialize_graph.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ def _parse_response(
6767

6868
return response_409
6969

70+
if response.status_code == 413:
71+
response_413 = ErrorResponse.from_dict(response.json())
72+
73+
return response_413
74+
7075
if response.status_code == 422:
7176
response_422 = HTTPValidationError.from_dict(response.json())
7277

@@ -150,6 +155,10 @@ def sync_detailed(
150155
Full graph materialization can take minutes for large datasets. Consider running
151156
during off-peak hours for production systems.
152157
158+
**Dry Run:**
159+
Set `dry_run=true` to validate limits without executing. Returns current usage, tier limits,
160+
and any warnings or errors. No lock is acquired, no SSE operation is created.
161+
153162
**Credits:**
154163
Materialization is included - no credit consumption
155164
@@ -234,6 +243,10 @@ def sync(
234243
Full graph materialization can take minutes for large datasets. Consider running
235244
during off-peak hours for production systems.
236245
246+
**Dry Run:**
247+
Set `dry_run=true` to validate limits without executing. Returns current usage, tier limits,
248+
and any warnings or errors. No lock is acquired, no SSE operation is created.
249+
237250
**Credits:**
238251
Materialization is included - no credit consumption
239252
@@ -313,6 +326,10 @@ async def asyncio_detailed(
313326
Full graph materialization can take minutes for large datasets. Consider running
314327
during off-peak hours for production systems.
315328
329+
**Dry Run:**
330+
Set `dry_run=true` to validate limits without executing. Returns current usage, tier limits,
331+
and any warnings or errors. No lock is acquired, no SSE operation is created.
332+
316333
**Credits:**
317334
Materialization is included - no credit consumption
318335
@@ -395,6 +412,10 @@ async def asyncio(
395412
Full graph materialization can take minutes for large datasets. Consider running
396413
during off-peak hours for production systems.
397414
415+
**Dry Run:**
416+
Set `dry_run=true` to validate limits without executing. Returns current usage, tier limits,
417+
and any warnings or errors. No lock is acquired, no SSE operation is created.
418+
398419
**Credits:**
399420
Materialization is included - no credit consumption
400421

robosystems_client/models/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
from .connection_response import ConnectionResponse
5656
from .connection_response_metadata import ConnectionResponseMetadata
5757
from .connection_response_provider import ConnectionResponseProvider
58+
from .content_limits import ContentLimits
5859
from .copy_operation_limits import CopyOperationLimits
5960
from .create_api_key_request import CreateAPIKeyRequest
6061
from .create_api_key_response import CreateAPIKeyResponse
@@ -90,6 +91,7 @@
9091
DetailedTransactionsResponseDateRange,
9192
)
9293
from .detailed_transactions_response_summary import DetailedTransactionsResponseSummary
94+
from .download_quota import DownloadQuota
9395
from .email_verification_request import EmailVerificationRequest
9496
from .enhanced_credit_transaction_response import EnhancedCreditTransactionResponse
9597
from .enhanced_credit_transaction_response_metadata import (
@@ -162,6 +164,7 @@
162164
from .logout_user_response_logoutuser import LogoutUserResponseLogoutuser
163165
from .materialize_request import MaterializeRequest
164166
from .materialize_response import MaterializeResponse
167+
from .materialize_response_limit_check_type_0 import MaterializeResponseLimitCheckType0
165168
from .materialize_status_response import MaterializeStatusResponse
166169
from .mcp_tool_call import MCPToolCall
167170
from .mcp_tool_call_arguments import MCPToolCallArguments
@@ -252,8 +255,6 @@
252255
from .sso_exchange_response import SSOExchangeResponse
253256
from .sso_token_response import SSOTokenResponse
254257
from .storage_info import StorageInfo
255-
from .storage_info_included_per_tier import StorageInfoIncludedPerTier
256-
from .storage_info_overage_pricing import StorageInfoOveragePricing
257258
from .storage_limit_response import StorageLimitResponse
258259
from .storage_limits import StorageLimits
259260
from .storage_summary import StorageSummary
@@ -289,6 +290,7 @@
289290
from .user_graphs_response import UserGraphsResponse
290291
from .user_response import UserResponse
291292
from .validation_error import ValidationError
293+
from .validation_error_context import ValidationErrorContext
292294
from .view_axis_config import ViewAxisConfig
293295
from .view_axis_config_element_labels_type_0 import ViewAxisConfigElementLabelsType0
294296
from .view_axis_config_member_labels_type_0 import ViewAxisConfigMemberLabelsType0
@@ -344,6 +346,7 @@
344346
"ConnectionResponse",
345347
"ConnectionResponseMetadata",
346348
"ConnectionResponseProvider",
349+
"ContentLimits",
347350
"CopyOperationLimits",
348351
"CreateAPIKeyRequest",
349352
"CreateAPIKeyResponse",
@@ -375,6 +378,7 @@
375378
"DetailedTransactionsResponse",
376379
"DetailedTransactionsResponseDateRange",
377380
"DetailedTransactionsResponseSummary",
381+
"DownloadQuota",
378382
"EmailVerificationRequest",
379383
"EnhancedCreditTransactionResponse",
380384
"EnhancedCreditTransactionResponseMetadata",
@@ -433,6 +437,7 @@
433437
"LogoutUserResponseLogoutuser",
434438
"MaterializeRequest",
435439
"MaterializeResponse",
440+
"MaterializeResponseLimitCheckType0",
436441
"MaterializeStatusResponse",
437442
"MCPToolCall",
438443
"MCPToolCallArguments",
@@ -507,8 +512,6 @@
507512
"SSOExchangeResponse",
508513
"SSOTokenResponse",
509514
"StorageInfo",
510-
"StorageInfoIncludedPerTier",
511-
"StorageInfoOveragePricing",
512515
"StorageLimitResponse",
513516
"StorageLimits",
514517
"StorageSummary",
@@ -540,6 +543,7 @@
540543
"UserGraphsResponse",
541544
"UserResponse",
542545
"ValidationError",
546+
"ValidationErrorContext",
543547
"ViewAxisConfig",
544548
"ViewAxisConfigElementLabelsType0",
545549
"ViewAxisConfigMemberLabelsType0",

robosystems_client/models/backup_list_response.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
from __future__ import annotations
22

33
from collections.abc import Mapping
4-
from typing import TYPE_CHECKING, Any, TypeVar
4+
from typing import TYPE_CHECKING, Any, TypeVar, cast
55

66
from attrs import define as _attrs_define
77
from attrs import field as _attrs_field
88

9+
from ..types import UNSET, Unset
10+
911
if TYPE_CHECKING:
1012
from ..models.backup_response import BackupResponse
13+
from ..models.download_quota import DownloadQuota
1114

1215

1316
T = TypeVar("T", bound="BackupListResponse")
@@ -21,14 +24,20 @@ class BackupListResponse:
2124
backups (list[BackupResponse]):
2225
total_count (int):
2326
graph_id (str):
27+
is_shared_repository (bool | Unset): Whether this is a shared repository (limits apply) Default: False.
28+
download_quota (DownloadQuota | None | Unset): Download quota for shared repositories
2429
"""
2530

2631
backups: list[BackupResponse]
2732
total_count: int
2833
graph_id: str
34+
is_shared_repository: bool | Unset = False
35+
download_quota: DownloadQuota | None | Unset = UNSET
2936
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
3037

3138
def to_dict(self) -> dict[str, Any]:
39+
from ..models.download_quota import DownloadQuota
40+
3241
backups = []
3342
for backups_item_data in self.backups:
3443
backups_item = backups_item_data.to_dict()
@@ -38,6 +47,16 @@ def to_dict(self) -> dict[str, Any]:
3847

3948
graph_id = self.graph_id
4049

50+
is_shared_repository = self.is_shared_repository
51+
52+
download_quota: dict[str, Any] | None | Unset
53+
if isinstance(self.download_quota, Unset):
54+
download_quota = UNSET
55+
elif isinstance(self.download_quota, DownloadQuota):
56+
download_quota = self.download_quota.to_dict()
57+
else:
58+
download_quota = self.download_quota
59+
4160
field_dict: dict[str, Any] = {}
4261
field_dict.update(self.additional_properties)
4362
field_dict.update(
@@ -47,12 +66,17 @@ def to_dict(self) -> dict[str, Any]:
4766
"graph_id": graph_id,
4867
}
4968
)
69+
if is_shared_repository is not UNSET:
70+
field_dict["is_shared_repository"] = is_shared_repository
71+
if download_quota is not UNSET:
72+
field_dict["download_quota"] = download_quota
5073

5174
return field_dict
5275

5376
@classmethod
5477
def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
5578
from ..models.backup_response import BackupResponse
79+
from ..models.download_quota import DownloadQuota
5680

5781
d = dict(src_dict)
5882
backups = []
@@ -66,10 +90,31 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
6690

6791
graph_id = d.pop("graph_id")
6892

93+
is_shared_repository = d.pop("is_shared_repository", UNSET)
94+
95+
def _parse_download_quota(data: object) -> DownloadQuota | None | Unset:
96+
if data is None:
97+
return data
98+
if isinstance(data, Unset):
99+
return data
100+
try:
101+
if not isinstance(data, dict):
102+
raise TypeError()
103+
download_quota_type_0 = DownloadQuota.from_dict(data)
104+
105+
return download_quota_type_0
106+
except (TypeError, ValueError, AttributeError, KeyError):
107+
pass
108+
return cast(DownloadQuota | None | Unset, data)
109+
110+
download_quota = _parse_download_quota(d.pop("download_quota", UNSET))
111+
69112
backup_list_response = cls(
70113
backups=backups,
71114
total_count=total_count,
72115
graph_id=graph_id,
116+
is_shared_repository=is_shared_repository,
117+
download_quota=download_quota,
73118
)
74119

75120
backup_list_response.additional_properties = d

0 commit comments

Comments
 (0)