From 9fcd939d6d8754c5dbf5a385ad1e28bd1c660238 Mon Sep 17 00:00:00 2001 From: "Joseph T. French" Date: Sun, 19 Apr 2026 22:06:26 -0500 Subject: [PATCH 1/4] Refactor API response handling to improve error management This update enhances the error handling across multiple API modules by replacing the `ErrorResponse` model with `OperationError` for various HTTP status codes (400, 404, 409). The changes ensure that error responses are consistently parsed and returned, improving the robustness of the API client. Key Changes: - Updated `_parse_response` methods in several modules to utilize `OperationError` for better error management. - Refactored response handling to include additional status codes, providing clearer feedback for API consumers. This enhancement aims to improve the user experience by delivering more informative error messages and maintaining consistency across the API client. --- bin/generate-sdk.sh | 10 +- .../api/documents/upload_documents_bulk.py | 225 --------------- .../op_create_portfolio.py | 54 ++-- .../op_create_position.py | 58 ++-- .../op_create_security.py | 58 ++-- .../op_delete_portfolio.py | 62 ++-- .../op_delete_position.py | 62 ++-- .../op_delete_security.py | 62 ++-- .../op_update_portfolio.py | 74 +++-- .../op_update_position.py | 62 ++-- .../op_update_security.py | 62 ++-- .../op_create_closing_entry.py | 82 ++++-- .../op_create_manual_closing_entry.py | 58 ++-- .../op_create_mapping_association.py | 78 +++-- .../op_create_schedule.py | 54 ++-- .../op_financial_statement_analysis.py | 271 ++++++++++++++++++ .../op_live_financial_statement.py | 269 +++++++++++++++++ .../op_truncate_schedule.py | 90 ++++-- .../api/query/execute_cypher_query.py | 6 + robosystems_client/clients/document_client.py | 39 --- robosystems_client/models/__init__.py | 12 +- .../models/bulk_document_upload_request.py | 76 ----- .../models/bulk_document_upload_response.py | 143 --------- ...ment_upload_response_errors_type_0_item.py | 47 --- .../models/create_closing_entry_operation.py | 18 +- .../create_element_request_classification.py | 5 +- .../models/create_element_request_source.py | 2 + .../create_mapping_association_operation.py | 26 +- .../models/delete_portfolio_operation.py | 5 +- .../models/delete_position_operation.py | 5 +- .../models/delete_security_operation.py | 5 +- .../financial_statement_analysis_request.py | 154 ++++++++++ .../live_financial_statement_request.py | 175 +++++++++++ .../models/truncate_schedule_operation.py | 18 +- ...e_element_request_classification_type_0.py | 5 +- .../models/update_portfolio_operation.py | 20 +- .../models/update_position_operation.py | 5 +- .../models/update_security_operation.py | 5 +- tests/test_document_client.py | 36 --- 39 files changed, 1461 insertions(+), 1037 deletions(-) delete mode 100644 robosystems_client/api/documents/upload_documents_bulk.py create mode 100644 robosystems_client/api/extensions_robo_ledger/op_financial_statement_analysis.py create mode 100644 robosystems_client/api/extensions_robo_ledger/op_live_financial_statement.py delete mode 100644 robosystems_client/models/bulk_document_upload_request.py delete mode 100644 robosystems_client/models/bulk_document_upload_response.py delete mode 100644 robosystems_client/models/bulk_document_upload_response_errors_type_0_item.py create mode 100644 robosystems_client/models/financial_statement_analysis_request.py create mode 100644 robosystems_client/models/live_financial_statement_request.py diff --git a/bin/generate-sdk.sh b/bin/generate-sdk.sh index 9e3dab1..73dfc58 100755 --- a/bin/generate-sdk.sh +++ b/bin/generate-sdk.sh @@ -54,8 +54,12 @@ def patch_ndjson_handling() -> bool: return None """ - # Find the location to insert the patch (raw generated code uses 4 spaces) - search_pattern = " if response.status_code == 200:\n response_200 = ExecuteCypherQueryResponse200.from_dict(response.json())\n\n return response_200" + # Find the location to insert the patch (raw generated code uses 4 spaces). + # The /v1/graphs/{graph_id}/query endpoint declares `response_model=None` + # (it returns JSONResponse | StreamingResponse | EventSourceResponse depending + # on mode), so the generator emits `response.json()` directly with no typed + # Response200 model. + search_pattern = " if response.status_code == 200:\n response_200 = response.json()\n return response_200" if search_pattern not in content: print(f"❌ Could not find expected pattern in {file_path}") @@ -63,7 +67,7 @@ def patch_ndjson_handling() -> bool: return False # Replace the pattern with the patched version - replacement = f" if response.status_code == 200:\n{ndjson_check} response_200 = ExecuteCypherQueryResponse200.from_dict(response.json())\n\n return response_200" + replacement = f" if response.status_code == 200:\n{ndjson_check} response_200 = response.json()\n return response_200" patched_content = content.replace(search_pattern, replacement) # Write the patched content back diff --git a/robosystems_client/api/documents/upload_documents_bulk.py b/robosystems_client/api/documents/upload_documents_bulk.py deleted file mode 100644 index 8fbea55..0000000 --- a/robosystems_client/api/documents/upload_documents_bulk.py +++ /dev/null @@ -1,225 +0,0 @@ -from http import HTTPStatus -from typing import Any -from urllib.parse import quote - -import httpx - -from ... import errors -from ...client import AuthenticatedClient, Client -from ...models.bulk_document_upload_request import BulkDocumentUploadRequest -from ...models.bulk_document_upload_response import BulkDocumentUploadResponse -from ...models.error_response import ErrorResponse -from ...models.http_validation_error import HTTPValidationError -from ...types import Response - - -def _get_kwargs( - graph_id: str, - *, - body: BulkDocumentUploadRequest, -) -> dict[str, Any]: - headers: dict[str, Any] = {} - - _kwargs: dict[str, Any] = { - "method": "post", - "url": "/v1/graphs/{graph_id}/documents/bulk".format( - graph_id=quote(str(graph_id), safe=""), - ), - } - - _kwargs["json"] = body.to_dict() - - headers["Content-Type"] = "application/json" - - _kwargs["headers"] = headers - return _kwargs - - -def _parse_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError | None: - if response.status_code == 200: - response_200 = BulkDocumentUploadResponse.from_dict(response.json()) - - return response_200 - - if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) - - return response_400 - - if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - - return response_401 - - if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - - return response_403 - - if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) - - return response_404 - - if response.status_code == 422: - response_422 = HTTPValidationError.from_dict(response.json()) - - return response_422 - - if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - - return response_429 - - if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - - return response_500 - - if client.raise_on_unexpected_status: - raise errors.UnexpectedStatus(response.status_code, response.content) - else: - return None - - -def _build_response( - *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError]: - return Response( - status_code=HTTPStatus(response.status_code), - content=response.content, - headers=response.headers, - parsed=_parse_response(client=client, response=response), - ) - - -def sync_detailed( - graph_id: str, - *, - client: AuthenticatedClient, - body: BulkDocumentUploadRequest, -) -> Response[BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError]: - """Bulk Upload Documents - - Upload up to 50 documents at once. Partial success is supported — check the errors array in the - response. - - Args: - graph_id (str): - body (BulkDocumentUploadRequest): Bulk upload multiple markdown documents. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - graph_id=graph_id, - body=body, - ) - - response = client.get_httpx_client().request( - **kwargs, - ) - - return _build_response(client=client, response=response) - - -def sync( - graph_id: str, - *, - client: AuthenticatedClient, - body: BulkDocumentUploadRequest, -) -> BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError | None: - """Bulk Upload Documents - - Upload up to 50 documents at once. Partial success is supported — check the errors array in the - response. - - Args: - graph_id (str): - body (BulkDocumentUploadRequest): Bulk upload multiple markdown documents. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError - """ - - return sync_detailed( - graph_id=graph_id, - client=client, - body=body, - ).parsed - - -async def asyncio_detailed( - graph_id: str, - *, - client: AuthenticatedClient, - body: BulkDocumentUploadRequest, -) -> Response[BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError]: - """Bulk Upload Documents - - Upload up to 50 documents at once. Partial success is supported — check the errors array in the - response. - - Args: - graph_id (str): - body (BulkDocumentUploadRequest): Bulk upload multiple markdown documents. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - Response[BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError] - """ - - kwargs = _get_kwargs( - graph_id=graph_id, - body=body, - ) - - response = await client.get_async_httpx_client().request(**kwargs) - - return _build_response(client=client, response=response) - - -async def asyncio( - graph_id: str, - *, - client: AuthenticatedClient, - body: BulkDocumentUploadRequest, -) -> BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError | None: - """Bulk Upload Documents - - Upload up to 50 documents at once. Partial success is supported — check the errors array in the - response. - - Args: - graph_id (str): - body (BulkDocumentUploadRequest): Bulk upload multiple markdown documents. - - Raises: - errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. - httpx.TimeoutException: If the request takes longer than Client.timeout. - - Returns: - BulkDocumentUploadResponse | ErrorResponse | HTTPValidationError - """ - - return ( - await asyncio_detailed( - graph_id=graph_id, - client=client, - body=body, - ) - ).parsed diff --git a/robosystems_client/api/extensions_robo_investor/op_create_portfolio.py b/robosystems_client/api/extensions_robo_investor/op_create_portfolio.py index eb1ac85..ed2b6a8 100644 --- a/robosystems_client/api/extensions_robo_investor/op_create_portfolio.py +++ b/robosystems_client/api/extensions_robo_investor/op_create_portfolio.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -7,9 +7,9 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.create_portfolio_request import CreatePortfolioRequest -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,11 @@ def sync_detailed( client: AuthenticatedClient, body: CreatePortfolioRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Portfolio - + Create an investment portfolio within this graph. Portfolios are logical groupings of securities + (stocks, notes, warrants) owned by the entity; subsequent positions attach to the portfolio. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -127,7 +124,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +146,11 @@ def sync( client: AuthenticatedClient, body: CreatePortfolioRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Portfolio - + Create an investment portfolio within this graph. Portfolios are logical groupings of securities + (stocks, notes, warrants) owned by the entity; subsequent positions attach to the portfolio. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -167,7 +165,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +182,11 @@ async def asyncio_detailed( client: AuthenticatedClient, body: CreatePortfolioRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Portfolio - + Create an investment portfolio within this graph. Portfolios are logical groupings of securities + (stocks, notes, warrants) owned by the entity; subsequent positions attach to the portfolio. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -202,7 +201,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +221,11 @@ async def asyncio( client: AuthenticatedClient, body: CreatePortfolioRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Portfolio - + Create an investment portfolio within this graph. Portfolios are logical groupings of securities + (stocks, notes, warrants) owned by the entity; subsequent positions attach to the portfolio. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -240,7 +240,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_investor/op_create_position.py b/robosystems_client/api/extensions_robo_investor/op_create_position.py index 7b6fd85..81a8033 100644 --- a/robosystems_client/api/extensions_robo_investor/op_create_position.py +++ b/robosystems_client/api/extensions_robo_investor/op_create_position.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -7,9 +7,9 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.create_position_request import CreatePositionRequest -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,12 @@ def sync_detailed( client: AuthenticatedClient, body: CreatePositionRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Position - Returns 409 if an active position for this security already exists in the portfolio. + Open a position in a security within a portfolio. One active position per (portfolio, security) pair + — creating a second active position returns 409. Dispose an existing position via `delete-position` + before opening a new one. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -127,7 +125,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +147,12 @@ def sync( client: AuthenticatedClient, body: CreatePositionRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Position - Returns 409 if an active position for this security already exists in the portfolio. + Open a position in a security within a portfolio. One active position per (portfolio, security) pair + — creating a second active position returns 409. Dispose an existing position via `delete-position` + before opening a new one. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -167,7 +167,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +184,12 @@ async def asyncio_detailed( client: AuthenticatedClient, body: CreatePositionRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Position - Returns 409 if an active position for this security already exists in the portfolio. + Open a position in a security within a portfolio. One active position per (portfolio, security) pair + — creating a second active position returns 409. Dispose an existing position via `delete-position` + before opening a new one. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -202,7 +204,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +224,12 @@ async def asyncio( client: AuthenticatedClient, body: CreatePositionRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Position - Returns 409 if an active position for this security already exists in the portfolio. + Open a position in a security within a portfolio. One active position per (portfolio, security) pair + — creating a second active position returns 409. Dispose an existing position via `delete-position` + before opening a new one. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -240,7 +244,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_investor/op_create_security.py b/robosystems_client/api/extensions_robo_investor/op_create_security.py index 80b5c66..e315e6c 100644 --- a/robosystems_client/api/extensions_robo_investor/op_create_security.py +++ b/robosystems_client/api/extensions_robo_investor/op_create_security.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -7,9 +7,9 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.create_security_request import CreateSecurityRequest -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,12 @@ def sync_detailed( client: AuthenticatedClient, body: CreateSecurityRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Security - + Register a security (common stock, preferred stock, warrant, convertible note, etc.) owned by this + graph's entity. Optionally cross-links to an issuing entity in another graph via `source_graph_id` + for mutual-handshake attribution. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -127,7 +125,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +147,12 @@ def sync( client: AuthenticatedClient, body: CreateSecurityRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Security - + Register a security (common stock, preferred stock, warrant, convertible note, etc.) owned by this + graph's entity. Optionally cross-links to an issuing entity in another graph via `source_graph_id` + for mutual-handshake attribution. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -167,7 +167,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +184,12 @@ async def asyncio_detailed( client: AuthenticatedClient, body: CreateSecurityRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Security - + Register a security (common stock, preferred stock, warrant, convertible note, etc.) owned by this + graph's entity. Optionally cross-links to an issuing entity in another graph via `source_graph_id` + for mutual-handshake attribution. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -202,7 +204,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +224,12 @@ async def asyncio( client: AuthenticatedClient, body: CreateSecurityRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Security - + Register a security (common stock, preferred stock, warrant, convertible note, etc.) owned by this + graph's entity. Optionally cross-links to an issuing entity in another graph via `source_graph_id` + for mutual-handshake attribution. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -240,7 +244,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_investor/op_delete_portfolio.py b/robosystems_client/api/extensions_robo_investor/op_delete_portfolio.py index 96a327a..8741801 100644 --- a/robosystems_client/api/extensions_robo_investor/op_delete_portfolio.py +++ b/robosystems_client/api/extensions_robo_investor/op_delete_portfolio.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -7,9 +7,9 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.delete_portfolio_operation import DeletePortfolioOperation -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,11 @@ def sync_detailed( client: AuthenticatedClient, body: DeletePortfolioOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Delete Portfolio - Returns 409 if the portfolio has active positions — dispose them first. + Hard-delete a portfolio. Returns 409 if the portfolio has active positions — dispose (soft-delete) + them first. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -120,14 +117,14 @@ def sync_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeletePortfolioOperation): + body (DeletePortfolioOperation): CQRS body for `POST /operations/delete-portfolio`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +146,11 @@ def sync( client: AuthenticatedClient, body: DeletePortfolioOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Delete Portfolio - Returns 409 if the portfolio has active positions — dispose them first. + Hard-delete a portfolio. Returns 409 if the portfolio has active positions — dispose (soft-delete) + them first. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -160,14 +158,14 @@ def sync( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeletePortfolioOperation): + body (DeletePortfolioOperation): CQRS body for `POST /operations/delete-portfolio`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +182,11 @@ async def asyncio_detailed( client: AuthenticatedClient, body: DeletePortfolioOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Delete Portfolio - Returns 409 if the portfolio has active positions — dispose them first. + Hard-delete a portfolio. Returns 409 if the portfolio has active positions — dispose (soft-delete) + them first. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -195,14 +194,14 @@ async def asyncio_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeletePortfolioOperation): + body (DeletePortfolioOperation): CQRS body for `POST /operations/delete-portfolio`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +221,11 @@ async def asyncio( client: AuthenticatedClient, body: DeletePortfolioOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Delete Portfolio - Returns 409 if the portfolio has active positions — dispose them first. + Hard-delete a portfolio. Returns 409 if the portfolio has active positions — dispose (soft-delete) + them first. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -233,14 +233,14 @@ async def asyncio( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeletePortfolioOperation): + body (DeletePortfolioOperation): CQRS body for `POST /operations/delete-portfolio`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_investor/op_delete_position.py b/robosystems_client/api/extensions_robo_investor/op_delete_position.py index fe40d10..4b0d284 100644 --- a/robosystems_client/api/extensions_robo_investor/op_delete_position.py +++ b/robosystems_client/api/extensions_robo_investor/op_delete_position.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -7,9 +7,9 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.delete_position_operation import DeletePositionOperation -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,10 @@ def sync_detailed( client: AuthenticatedClient, body: DeletePositionOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Delete Position - Soft-deletes the position (`is_active=false`). Historical holding records referencing it remain + Soft-delete the position (`status='disposed'`). Historical holding records referencing it remain valid. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours @@ -121,14 +117,15 @@ def sync_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeletePositionOperation): + body (DeletePositionOperation): CQRS body for `POST /operations/delete-position` (soft + delete). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -150,10 +147,10 @@ def sync( client: AuthenticatedClient, body: DeletePositionOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Delete Position - Soft-deletes the position (`is_active=false`). Historical holding records referencing it remain + Soft-delete the position (`status='disposed'`). Historical holding records referencing it remain valid. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours @@ -162,14 +159,15 @@ def sync( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeletePositionOperation): + body (DeletePositionOperation): CQRS body for `POST /operations/delete-position` (soft + delete). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -186,10 +184,10 @@ async def asyncio_detailed( client: AuthenticatedClient, body: DeletePositionOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Delete Position - Soft-deletes the position (`is_active=false`). Historical holding records referencing it remain + Soft-delete the position (`status='disposed'`). Historical holding records referencing it remain valid. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours @@ -198,14 +196,15 @@ async def asyncio_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeletePositionOperation): + body (DeletePositionOperation): CQRS body for `POST /operations/delete-position` (soft + delete). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -225,10 +224,10 @@ async def asyncio( client: AuthenticatedClient, body: DeletePositionOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Delete Position - Soft-deletes the position (`is_active=false`). Historical holding records referencing it remain + Soft-delete the position (`status='disposed'`). Historical holding records referencing it remain valid. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours @@ -237,14 +236,15 @@ async def asyncio( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeletePositionOperation): + body (DeletePositionOperation): CQRS body for `POST /operations/delete-position` (soft + delete). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_investor/op_delete_security.py b/robosystems_client/api/extensions_robo_investor/op_delete_security.py index cddb260..a7e18bc 100644 --- a/robosystems_client/api/extensions_robo_investor/op_delete_security.py +++ b/robosystems_client/api/extensions_robo_investor/op_delete_security.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -7,9 +7,9 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.delete_security_operation import DeleteSecurityOperation -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,10 @@ def sync_detailed( client: AuthenticatedClient, body: DeleteSecurityOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Delete Security - Soft-deletes the security (`is_active=false`). Historical positions referencing it remain valid. + Soft-delete the security (`is_active=false`). Historical positions referencing it remain valid. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -120,14 +116,15 @@ def sync_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeleteSecurityOperation): + body (DeleteSecurityOperation): CQRS body for `POST /operations/delete-security` (soft + delete). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +146,10 @@ def sync( client: AuthenticatedClient, body: DeleteSecurityOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Delete Security - Soft-deletes the security (`is_active=false`). Historical positions referencing it remain valid. + Soft-delete the security (`is_active=false`). Historical positions referencing it remain valid. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -160,14 +157,15 @@ def sync( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeleteSecurityOperation): + body (DeleteSecurityOperation): CQRS body for `POST /operations/delete-security` (soft + delete). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +182,10 @@ async def asyncio_detailed( client: AuthenticatedClient, body: DeleteSecurityOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Delete Security - Soft-deletes the security (`is_active=false`). Historical positions referencing it remain valid. + Soft-delete the security (`is_active=false`). Historical positions referencing it remain valid. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -195,14 +193,15 @@ async def asyncio_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeleteSecurityOperation): + body (DeleteSecurityOperation): CQRS body for `POST /operations/delete-security` (soft + delete). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +221,10 @@ async def asyncio( client: AuthenticatedClient, body: DeleteSecurityOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Delete Security - Soft-deletes the security (`is_active=false`). Historical positions referencing it remain valid. + Soft-delete the security (`is_active=false`). Historical positions referencing it remain valid. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -233,14 +232,15 @@ async def asyncio( Args: graph_id (str): idempotency_key (None | str | Unset): - body (DeleteSecurityOperation): + body (DeleteSecurityOperation): CQRS body for `POST /operations/delete-security` (soft + delete). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_investor/op_update_portfolio.py b/robosystems_client/api/extensions_robo_investor/op_update_portfolio.py index 4efaa2d..b4efa82 100644 --- a/robosystems_client/api/extensions_robo_investor/op_update_portfolio.py +++ b/robosystems_client/api/extensions_robo_investor/op_update_portfolio.py @@ -1,14 +1,14 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx from ... import errors from ...client import AuthenticatedClient, Client -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...models.update_portfolio_operation import UpdatePortfolioOperation from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,11 @@ def sync_detailed( client: AuthenticatedClient, body: UpdatePortfolioOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Update Portfolio - + Update mutable fields on a portfolio (name, description, strategy, inception_date, base_currency). + Unset fields are ignored — partial updates are explicit. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -120,14 +117,17 @@ def sync_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdatePortfolioOperation): + body (UpdatePortfolioOperation): CQRS body for `POST /operations/update-portfolio`. + + Folds `portfolio_id` into the payload so REST + MCP share one body + type via the registrar. Unset fields are ignored (partial update). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +149,11 @@ def sync( client: AuthenticatedClient, body: UpdatePortfolioOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Update Portfolio - + Update mutable fields on a portfolio (name, description, strategy, inception_date, base_currency). + Unset fields are ignored — partial updates are explicit. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -160,14 +161,17 @@ def sync( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdatePortfolioOperation): + body (UpdatePortfolioOperation): CQRS body for `POST /operations/update-portfolio`. + + Folds `portfolio_id` into the payload so REST + MCP share one body + type via the registrar. Unset fields are ignored (partial update). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +188,11 @@ async def asyncio_detailed( client: AuthenticatedClient, body: UpdatePortfolioOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Update Portfolio - + Update mutable fields on a portfolio (name, description, strategy, inception_date, base_currency). + Unset fields are ignored — partial updates are explicit. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -195,14 +200,17 @@ async def asyncio_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdatePortfolioOperation): + body (UpdatePortfolioOperation): CQRS body for `POST /operations/update-portfolio`. + + Folds `portfolio_id` into the payload so REST + MCP share one body + type via the registrar. Unset fields are ignored (partial update). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +230,11 @@ async def asyncio( client: AuthenticatedClient, body: UpdatePortfolioOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Update Portfolio - + Update mutable fields on a portfolio (name, description, strategy, inception_date, base_currency). + Unset fields are ignored — partial updates are explicit. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -233,14 +242,17 @@ async def asyncio( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdatePortfolioOperation): + body (UpdatePortfolioOperation): CQRS body for `POST /operations/update-portfolio`. + + Folds `portfolio_id` into the payload so REST + MCP share one body + type via the registrar. Unset fields are ignored (partial update). Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_investor/op_update_position.py b/robosystems_client/api/extensions_robo_investor/op_update_position.py index b36121e..506b2ae 100644 --- a/robosystems_client/api/extensions_robo_investor/op_update_position.py +++ b/robosystems_client/api/extensions_robo_investor/op_update_position.py @@ -1,14 +1,14 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx from ... import errors from ...client import AuthenticatedClient, Client -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...models.update_position_operation import UpdatePositionOperation from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,11 @@ def sync_detailed( client: AuthenticatedClient, body: UpdatePositionOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Update Position - + Update mutable fields on a position (quantity, cost basis, valuation, notes, status). Use `delete- + position` for soft disposal instead of setting `status` manually. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -120,14 +117,14 @@ def sync_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdatePositionOperation): + body (UpdatePositionOperation): CQRS body for `POST /operations/update-position`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +146,11 @@ def sync( client: AuthenticatedClient, body: UpdatePositionOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Update Position - + Update mutable fields on a position (quantity, cost basis, valuation, notes, status). Use `delete- + position` for soft disposal instead of setting `status` manually. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -160,14 +158,14 @@ def sync( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdatePositionOperation): + body (UpdatePositionOperation): CQRS body for `POST /operations/update-position`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +182,11 @@ async def asyncio_detailed( client: AuthenticatedClient, body: UpdatePositionOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Update Position - + Update mutable fields on a position (quantity, cost basis, valuation, notes, status). Use `delete- + position` for soft disposal instead of setting `status` manually. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -195,14 +194,14 @@ async def asyncio_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdatePositionOperation): + body (UpdatePositionOperation): CQRS body for `POST /operations/update-position`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +221,11 @@ async def asyncio( client: AuthenticatedClient, body: UpdatePositionOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Update Position - + Update mutable fields on a position (quantity, cost basis, valuation, notes, status). Use `delete- + position` for soft disposal instead of setting `status` manually. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -233,14 +233,14 @@ async def asyncio( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdatePositionOperation): + body (UpdatePositionOperation): CQRS body for `POST /operations/update-position`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_investor/op_update_security.py b/robosystems_client/api/extensions_robo_investor/op_update_security.py index 99446d5..60a37ef 100644 --- a/robosystems_client/api/extensions_robo_investor/op_update_security.py +++ b/robosystems_client/api/extensions_robo_investor/op_update_security.py @@ -1,14 +1,14 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx from ... import errors from ...client import AuthenticatedClient, Client -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...models.update_security_operation import UpdateSecurityOperation from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,11 @@ def sync_detailed( client: AuthenticatedClient, body: UpdateSecurityOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Update Security - + Update mutable fields on a security (name, type, subtype, terms, share counts, entity linkage). + Unset fields are ignored. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -120,14 +117,14 @@ def sync_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdateSecurityOperation): + body (UpdateSecurityOperation): CQRS body for `POST /operations/update-security`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +146,11 @@ def sync( client: AuthenticatedClient, body: UpdateSecurityOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Update Security - + Update mutable fields on a security (name, type, subtype, terms, share counts, entity linkage). + Unset fields are ignored. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -160,14 +158,14 @@ def sync( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdateSecurityOperation): + body (UpdateSecurityOperation): CQRS body for `POST /operations/update-security`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +182,11 @@ async def asyncio_detailed( client: AuthenticatedClient, body: UpdateSecurityOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Update Security - + Update mutable fields on a security (name, type, subtype, terms, share counts, entity linkage). + Unset fields are ignored. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -195,14 +194,14 @@ async def asyncio_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdateSecurityOperation): + body (UpdateSecurityOperation): CQRS body for `POST /operations/update-security`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +221,11 @@ async def asyncio( client: AuthenticatedClient, body: UpdateSecurityOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Update Security - + Update mutable fields on a security (name, type, subtype, terms, share counts, entity linkage). + Unset fields are ignored. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -233,14 +233,14 @@ async def asyncio( Args: graph_id (str): idempotency_key (None | str | Unset): - body (UpdateSecurityOperation): + body (UpdateSecurityOperation): CQRS body for `POST /operations/update-security`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_ledger/op_create_closing_entry.py b/robosystems_client/api/extensions_robo_ledger/op_create_closing_entry.py index 7cc9ae4..a67572c 100644 --- a/robosystems_client/api/extensions_robo_ledger/op_create_closing_entry.py +++ b/robosystems_client/api/extensions_robo_ledger/op_create_closing_entry.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -7,9 +7,9 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.create_closing_entry_operation import CreateClosingEntryOperation -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,12 @@ def sync_detailed( client: AuthenticatedClient, body: CreateClosingEntryOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Closing Entry - Creates a draft closing entry pre-populated from a schedule's facts for the given period. + Create a draft closing entry pre-populated from a schedule's facts for the given period. Idempotent + — safe to call repeatedly; the `outcome` field describes what happened (`created`, `unchanged`, + `regenerated`, `removed`, `skipped`). **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -120,14 +118,18 @@ def sync_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (CreateClosingEntryOperation): + body (CreateClosingEntryOperation): CQRS-shaped body for `POST /operations/create-closing- + entry`. + + `structure_id` moves into the body so REST + MCP share a single body + type via the registrar. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +151,12 @@ def sync( client: AuthenticatedClient, body: CreateClosingEntryOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Closing Entry - Creates a draft closing entry pre-populated from a schedule's facts for the given period. + Create a draft closing entry pre-populated from a schedule's facts for the given period. Idempotent + — safe to call repeatedly; the `outcome` field describes what happened (`created`, `unchanged`, + `regenerated`, `removed`, `skipped`). **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -160,14 +164,18 @@ def sync( Args: graph_id (str): idempotency_key (None | str | Unset): - body (CreateClosingEntryOperation): + body (CreateClosingEntryOperation): CQRS-shaped body for `POST /operations/create-closing- + entry`. + + `structure_id` moves into the body so REST + MCP share a single body + type via the registrar. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +192,12 @@ async def asyncio_detailed( client: AuthenticatedClient, body: CreateClosingEntryOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Closing Entry - Creates a draft closing entry pre-populated from a schedule's facts for the given period. + Create a draft closing entry pre-populated from a schedule's facts for the given period. Idempotent + — safe to call repeatedly; the `outcome` field describes what happened (`created`, `unchanged`, + `regenerated`, `removed`, `skipped`). **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -195,14 +205,18 @@ async def asyncio_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (CreateClosingEntryOperation): + body (CreateClosingEntryOperation): CQRS-shaped body for `POST /operations/create-closing- + entry`. + + `structure_id` moves into the body so REST + MCP share a single body + type via the registrar. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +236,12 @@ async def asyncio( client: AuthenticatedClient, body: CreateClosingEntryOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Closing Entry - Creates a draft closing entry pre-populated from a schedule's facts for the given period. + Create a draft closing entry pre-populated from a schedule's facts for the given period. Idempotent + — safe to call repeatedly; the `outcome` field describes what happened (`created`, `unchanged`, + `regenerated`, `removed`, `skipped`). **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -233,14 +249,18 @@ async def asyncio( Args: graph_id (str): idempotency_key (None | str | Unset): - body (CreateClosingEntryOperation): + body (CreateClosingEntryOperation): CQRS-shaped body for `POST /operations/create-closing- + entry`. + + `structure_id` moves into the body so REST + MCP share a single body + type via the registrar. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_ledger/op_create_manual_closing_entry.py b/robosystems_client/api/extensions_robo_ledger/op_create_manual_closing_entry.py index 8f60091..9ad5cc7 100644 --- a/robosystems_client/api/extensions_robo_ledger/op_create_manual_closing_entry.py +++ b/robosystems_client/api/extensions_robo_ledger/op_create_manual_closing_entry.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -9,9 +9,9 @@ from ...models.create_manual_closing_entry_request import ( CreateManualClosingEntryRequest, ) -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -42,34 +42,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -79,13 +77,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -96,7 +92,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -111,10 +107,12 @@ def sync_detailed( client: AuthenticatedClient, body: CreateManualClosingEntryRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Manual Closing Entry - Creates a draft closing entry with manually specified amounts — not tied to a schedule. + Create a draft closing entry with manually specified line items — not tied to a schedule. Use for + one-off business events (asset disposal, correcting entry, impairment). Total debits must equal + total credits. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -129,7 +127,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -151,10 +149,12 @@ def sync( client: AuthenticatedClient, body: CreateManualClosingEntryRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Manual Closing Entry - Creates a draft closing entry with manually specified amounts — not tied to a schedule. + Create a draft closing entry with manually specified line items — not tied to a schedule. Use for + one-off business events (asset disposal, correcting entry, impairment). Total debits must equal + total credits. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -169,7 +169,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -186,10 +186,12 @@ async def asyncio_detailed( client: AuthenticatedClient, body: CreateManualClosingEntryRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Manual Closing Entry - Creates a draft closing entry with manually specified amounts — not tied to a schedule. + Create a draft closing entry with manually specified line items — not tied to a schedule. Use for + one-off business events (asset disposal, correcting entry, impairment). Total debits must equal + total credits. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -204,7 +206,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -224,10 +226,12 @@ async def asyncio( client: AuthenticatedClient, body: CreateManualClosingEntryRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Manual Closing Entry - Creates a draft closing entry with manually specified amounts — not tied to a schedule. + Create a draft closing entry with manually specified line items — not tied to a schedule. Use for + one-off business events (asset disposal, correcting entry, impairment). Total debits must equal + total credits. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -242,7 +246,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_ledger/op_create_mapping_association.py b/robosystems_client/api/extensions_robo_ledger/op_create_mapping_association.py index c81c241..4d37c6d 100644 --- a/robosystems_client/api/extensions_robo_ledger/op_create_mapping_association.py +++ b/robosystems_client/api/extensions_robo_ledger/op_create_mapping_association.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -9,9 +9,9 @@ from ...models.create_mapping_association_operation import ( CreateMappingAssociationOperation, ) -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -42,34 +42,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -79,13 +77,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -96,7 +92,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -111,10 +107,11 @@ def sync_detailed( client: AuthenticatedClient, body: CreateMappingAssociationOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Mapping Association - Links a chart-of-accounts element to a reporting concept (CoA element → US GAAP concept). + Link a chart-of-accounts element to a US GAAP reporting concept. For bulk associations + (presentation/calculation linkbases, 50+ arcs at once) use `create-associations` instead. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -122,14 +119,18 @@ def sync_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (CreateMappingAssociationOperation): + body (CreateMappingAssociationOperation): CQRS-shaped body for `POST /operations/create- + mapping-association`. + + Bundles the target mapping structure's `mapping_id` with the association + payload so REST + MCP share a single body type via the registrar. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -151,10 +152,11 @@ def sync( client: AuthenticatedClient, body: CreateMappingAssociationOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Mapping Association - Links a chart-of-accounts element to a reporting concept (CoA element → US GAAP concept). + Link a chart-of-accounts element to a US GAAP reporting concept. For bulk associations + (presentation/calculation linkbases, 50+ arcs at once) use `create-associations` instead. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -162,14 +164,18 @@ def sync( Args: graph_id (str): idempotency_key (None | str | Unset): - body (CreateMappingAssociationOperation): + body (CreateMappingAssociationOperation): CQRS-shaped body for `POST /operations/create- + mapping-association`. + + Bundles the target mapping structure's `mapping_id` with the association + payload so REST + MCP share a single body type via the registrar. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -186,10 +192,11 @@ async def asyncio_detailed( client: AuthenticatedClient, body: CreateMappingAssociationOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Mapping Association - Links a chart-of-accounts element to a reporting concept (CoA element → US GAAP concept). + Link a chart-of-accounts element to a US GAAP reporting concept. For bulk associations + (presentation/calculation linkbases, 50+ arcs at once) use `create-associations` instead. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -197,14 +204,18 @@ async def asyncio_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (CreateMappingAssociationOperation): + body (CreateMappingAssociationOperation): CQRS-shaped body for `POST /operations/create- + mapping-association`. + + Bundles the target mapping structure's `mapping_id` with the association + payload so REST + MCP share a single body type via the registrar. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -224,10 +235,11 @@ async def asyncio( client: AuthenticatedClient, body: CreateMappingAssociationOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Mapping Association - Links a chart-of-accounts element to a reporting concept (CoA element → US GAAP concept). + Link a chart-of-accounts element to a US GAAP reporting concept. For bulk associations + (presentation/calculation linkbases, 50+ arcs at once) use `create-associations` instead. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -235,14 +247,18 @@ async def asyncio( Args: graph_id (str): idempotency_key (None | str | Unset): - body (CreateMappingAssociationOperation): + body (CreateMappingAssociationOperation): CQRS-shaped body for `POST /operations/create- + mapping-association`. + + Bundles the target mapping structure's `mapping_id` with the association + payload so REST + MCP share a single body type via the registrar. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_ledger/op_create_schedule.py b/robosystems_client/api/extensions_robo_ledger/op_create_schedule.py index 87735e3..b175311 100644 --- a/robosystems_client/api/extensions_robo_ledger/op_create_schedule.py +++ b/robosystems_client/api/extensions_robo_ledger/op_create_schedule.py @@ -1,5 +1,5 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx @@ -7,9 +7,9 @@ from ... import errors from ...client import AuthenticatedClient, Client from ...models.create_schedule_request import CreateScheduleRequest -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,11 @@ def sync_detailed( client: AuthenticatedClient, body: CreateScheduleRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Schedule - Creates a schedule and pre-generates monthly amortization facts spanning the period range. + Create a schedule and pre-generate monthly amortization facts spanning the period range. + `entry_template` defines the debit/credit elements used by `create-closing-entry` each period. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -127,7 +124,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +146,11 @@ def sync( client: AuthenticatedClient, body: CreateScheduleRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Schedule - Creates a schedule and pre-generates monthly amortization facts spanning the period range. + Create a schedule and pre-generate monthly amortization facts spanning the period range. + `entry_template` defines the debit/credit elements used by `create-closing-entry` each period. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -167,7 +165,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +182,11 @@ async def asyncio_detailed( client: AuthenticatedClient, body: CreateScheduleRequest, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Create Schedule - Creates a schedule and pre-generates monthly amortization facts spanning the period range. + Create a schedule and pre-generate monthly amortization facts spanning the period range. + `entry_template` defines the debit/credit elements used by `create-closing-entry` each period. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -202,7 +201,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +221,11 @@ async def asyncio( client: AuthenticatedClient, body: CreateScheduleRequest, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Create Schedule - Creates a schedule and pre-generates monthly amortization facts spanning the period range. + Create a schedule and pre-generate monthly amortization facts spanning the period range. + `entry_template` defines the debit/credit elements used by `create-closing-entry` each period. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -240,7 +240,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/extensions_robo_ledger/op_financial_statement_analysis.py b/robosystems_client/api/extensions_robo_ledger/op_financial_statement_analysis.py new file mode 100644 index 0000000..b3a02f4 --- /dev/null +++ b/robosystems_client/api/extensions_robo_ledger/op_financial_statement_analysis.py @@ -0,0 +1,271 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error_response import ErrorResponse +from ...models.financial_statement_analysis_request import ( + FinancialStatementAnalysisRequest, +) +from ...models.http_validation_error import HTTPValidationError +from ...models.operation_envelope import OperationEnvelope +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + graph_id: str, + *, + body: FinancialStatementAnalysisRequest, + idempotency_key: None | str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(idempotency_key, Unset): + headers["Idempotency-Key"] = idempotency_key + + _kwargs: dict[str, Any] = { + "method": "post", + "url": "/extensions/roboledger/{graph_id}/operations/financial-statement-analysis".format( + graph_id=quote(str(graph_id), safe=""), + ), + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: + if response.status_code == 200: + response_200 = OperationEnvelope.from_dict(response.json()) + + return response_200 + + if response.status_code == 400: + response_400 = ErrorResponse.from_dict(response.json()) + + return response_400 + + if response.status_code == 401: + response_401 = ErrorResponse.from_dict(response.json()) + + return response_401 + + if response.status_code == 403: + response_403 = ErrorResponse.from_dict(response.json()) + + return response_403 + + if response.status_code == 404: + response_404 = ErrorResponse.from_dict(response.json()) + + return response_404 + + if response.status_code == 409: + response_409 = ErrorResponse.from_dict(response.json()) + + return response_409 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 429: + response_429 = ErrorResponse.from_dict(response.json()) + + return response_429 + + if response.status_code == 500: + response_500 = ErrorResponse.from_dict(response.json()) + + return response_500 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + graph_id: str, + *, + client: AuthenticatedClient, + body: FinancialStatementAnalysisRequest, + idempotency_key: None | str | Unset = UNSET, +) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: + """Financial Statement Analysis + + Query a rendered financial statement from the graph-backed XBRL hypercube (Structure → FactSet → + Fact). Works on the SEC shared repository today and on any RoboLedger tenant graph whose ledger has + been materialized to LadybugDB. For shared-repo graphs, provide `ticker` to auto-resolve the latest + filing; for tenant graphs, provide `report_id` explicitly. + + **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours + return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. + + Args: + graph_id (str): + idempotency_key (None | str | Unset): + body (FinancialStatementAnalysisRequest): Request for financial-statement-analysis (graph- + backed Cypher). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + """ + + kwargs = _get_kwargs( + graph_id=graph_id, + body=body, + idempotency_key=idempotency_key, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + graph_id: str, + *, + client: AuthenticatedClient, + body: FinancialStatementAnalysisRequest, + idempotency_key: None | str | Unset = UNSET, +) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: + """Financial Statement Analysis + + Query a rendered financial statement from the graph-backed XBRL hypercube (Structure → FactSet → + Fact). Works on the SEC shared repository today and on any RoboLedger tenant graph whose ledger has + been materialized to LadybugDB. For shared-repo graphs, provide `ticker` to auto-resolve the latest + filing; for tenant graphs, provide `report_id` explicitly. + + **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours + return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. + + Args: + graph_id (str): + idempotency_key (None | str | Unset): + body (FinancialStatementAnalysisRequest): Request for financial-statement-analysis (graph- + backed Cypher). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ErrorResponse | HTTPValidationError | OperationEnvelope + """ + + return sync_detailed( + graph_id=graph_id, + client=client, + body=body, + idempotency_key=idempotency_key, + ).parsed + + +async def asyncio_detailed( + graph_id: str, + *, + client: AuthenticatedClient, + body: FinancialStatementAnalysisRequest, + idempotency_key: None | str | Unset = UNSET, +) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: + """Financial Statement Analysis + + Query a rendered financial statement from the graph-backed XBRL hypercube (Structure → FactSet → + Fact). Works on the SEC shared repository today and on any RoboLedger tenant graph whose ledger has + been materialized to LadybugDB. For shared-repo graphs, provide `ticker` to auto-resolve the latest + filing; for tenant graphs, provide `report_id` explicitly. + + **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours + return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. + + Args: + graph_id (str): + idempotency_key (None | str | Unset): + body (FinancialStatementAnalysisRequest): Request for financial-statement-analysis (graph- + backed Cypher). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + """ + + kwargs = _get_kwargs( + graph_id=graph_id, + body=body, + idempotency_key=idempotency_key, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + graph_id: str, + *, + client: AuthenticatedClient, + body: FinancialStatementAnalysisRequest, + idempotency_key: None | str | Unset = UNSET, +) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: + """Financial Statement Analysis + + Query a rendered financial statement from the graph-backed XBRL hypercube (Structure → FactSet → + Fact). Works on the SEC shared repository today and on any RoboLedger tenant graph whose ledger has + been materialized to LadybugDB. For shared-repo graphs, provide `ticker` to auto-resolve the latest + filing; for tenant graphs, provide `report_id` explicitly. + + **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours + return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. + + Args: + graph_id (str): + idempotency_key (None | str | Unset): + body (FinancialStatementAnalysisRequest): Request for financial-statement-analysis (graph- + backed Cypher). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ErrorResponse | HTTPValidationError | OperationEnvelope + """ + + return ( + await asyncio_detailed( + graph_id=graph_id, + client=client, + body=body, + idempotency_key=idempotency_key, + ) + ).parsed diff --git a/robosystems_client/api/extensions_robo_ledger/op_live_financial_statement.py b/robosystems_client/api/extensions_robo_ledger/op_live_financial_statement.py new file mode 100644 index 0000000..58bb270 --- /dev/null +++ b/robosystems_client/api/extensions_robo_ledger/op_live_financial_statement.py @@ -0,0 +1,269 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.error_response import ErrorResponse +from ...models.http_validation_error import HTTPValidationError +from ...models.live_financial_statement_request import LiveFinancialStatementRequest +from ...models.operation_envelope import OperationEnvelope +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + graph_id: str, + *, + body: LiveFinancialStatementRequest, + idempotency_key: None | str | Unset = UNSET, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + if not isinstance(idempotency_key, Unset): + headers["Idempotency-Key"] = idempotency_key + + _kwargs: dict[str, Any] = { + "method": "post", + "url": "/extensions/roboledger/{graph_id}/operations/live-financial-statement".format( + graph_id=quote(str(graph_id), safe=""), + ), + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: + if response.status_code == 200: + response_200 = OperationEnvelope.from_dict(response.json()) + + return response_200 + + if response.status_code == 400: + response_400 = ErrorResponse.from_dict(response.json()) + + return response_400 + + if response.status_code == 401: + response_401 = ErrorResponse.from_dict(response.json()) + + return response_401 + + if response.status_code == 403: + response_403 = ErrorResponse.from_dict(response.json()) + + return response_403 + + if response.status_code == 404: + response_404 = ErrorResponse.from_dict(response.json()) + + return response_404 + + if response.status_code == 409: + response_409 = ErrorResponse.from_dict(response.json()) + + return response_409 + + if response.status_code == 422: + response_422 = HTTPValidationError.from_dict(response.json()) + + return response_422 + + if response.status_code == 429: + response_429 = ErrorResponse.from_dict(response.json()) + + return response_429 + + if response.status_code == 500: + response_500 = ErrorResponse.from_dict(response.json()) + + return response_500 + + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: AuthenticatedClient | Client, response: httpx.Response +) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + graph_id: str, + *, + client: AuthenticatedClient, + body: LiveFinancialStatementRequest, + idempotency_key: None | str | Unset = UNSET, +) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: + """Live Financial Statement + + Generate an ad-hoc financial statement directly from the tenant's OLTP ledger data using the active + CoA→GAAP mapping. This is the authoritative source for RoboLedger entity graphs — no graph + materialization required. Rejected on shared-repository graphs; those should use `financial- + statement-analysis` instead. + + **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours + return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. + + Args: + graph_id (str): + idempotency_key (None | str | Unset): + body (LiveFinancialStatementRequest): Request for live-financial-statement (OLTP, entity + graphs only). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + """ + + kwargs = _get_kwargs( + graph_id=graph_id, + body=body, + idempotency_key=idempotency_key, + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + graph_id: str, + *, + client: AuthenticatedClient, + body: LiveFinancialStatementRequest, + idempotency_key: None | str | Unset = UNSET, +) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: + """Live Financial Statement + + Generate an ad-hoc financial statement directly from the tenant's OLTP ledger data using the active + CoA→GAAP mapping. This is the authoritative source for RoboLedger entity graphs — no graph + materialization required. Rejected on shared-repository graphs; those should use `financial- + statement-analysis` instead. + + **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours + return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. + + Args: + graph_id (str): + idempotency_key (None | str | Unset): + body (LiveFinancialStatementRequest): Request for live-financial-statement (OLTP, entity + graphs only). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ErrorResponse | HTTPValidationError | OperationEnvelope + """ + + return sync_detailed( + graph_id=graph_id, + client=client, + body=body, + idempotency_key=idempotency_key, + ).parsed + + +async def asyncio_detailed( + graph_id: str, + *, + client: AuthenticatedClient, + body: LiveFinancialStatementRequest, + idempotency_key: None | str | Unset = UNSET, +) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: + """Live Financial Statement + + Generate an ad-hoc financial statement directly from the tenant's OLTP ledger data using the active + CoA→GAAP mapping. This is the authoritative source for RoboLedger entity graphs — no graph + materialization required. Rejected on shared-repository graphs; those should use `financial- + statement-analysis` instead. + + **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours + return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. + + Args: + graph_id (str): + idempotency_key (None | str | Unset): + body (LiveFinancialStatementRequest): Request for live-financial-statement (OLTP, entity + graphs only). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + """ + + kwargs = _get_kwargs( + graph_id=graph_id, + body=body, + idempotency_key=idempotency_key, + ) + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + graph_id: str, + *, + client: AuthenticatedClient, + body: LiveFinancialStatementRequest, + idempotency_key: None | str | Unset = UNSET, +) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: + """Live Financial Statement + + Generate an ad-hoc financial statement directly from the tenant's OLTP ledger data using the active + CoA→GAAP mapping. This is the authoritative source for RoboLedger entity graphs — no graph + materialization required. Rejected on shared-repository graphs; those should use `financial- + statement-analysis` instead. + + **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours + return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. + + Args: + graph_id (str): + idempotency_key (None | str | Unset): + body (LiveFinancialStatementRequest): Request for live-financial-statement (OLTP, entity + graphs only). + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + ErrorResponse | HTTPValidationError | OperationEnvelope + """ + + return ( + await asyncio_detailed( + graph_id=graph_id, + client=client, + body=body, + idempotency_key=idempotency_key, + ) + ).parsed diff --git a/robosystems_client/api/extensions_robo_ledger/op_truncate_schedule.py b/robosystems_client/api/extensions_robo_ledger/op_truncate_schedule.py index af122c5..146abb2 100644 --- a/robosystems_client/api/extensions_robo_ledger/op_truncate_schedule.py +++ b/robosystems_client/api/extensions_robo_ledger/op_truncate_schedule.py @@ -1,14 +1,14 @@ from http import HTTPStatus -from typing import Any +from typing import Any, cast from urllib.parse import quote import httpx from ... import errors from ...client import AuthenticatedClient, Client -from ...models.error_response import ErrorResponse from ...models.http_validation_error import HTTPValidationError from ...models.operation_envelope import OperationEnvelope +from ...models.operation_error import OperationError from ...models.truncate_schedule_operation import TruncateScheduleOperation from ...types import UNSET, Response, Unset @@ -40,34 +40,32 @@ def _get_kwargs( def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: if response.status_code == 200: response_200 = OperationEnvelope.from_dict(response.json()) return response_200 if response.status_code == 400: - response_400 = ErrorResponse.from_dict(response.json()) + response_400 = OperationError.from_dict(response.json()) return response_400 if response.status_code == 401: - response_401 = ErrorResponse.from_dict(response.json()) - + response_401 = cast(Any, None) return response_401 if response.status_code == 403: - response_403 = ErrorResponse.from_dict(response.json()) - + response_403 = cast(Any, None) return response_403 if response.status_code == 404: - response_404 = ErrorResponse.from_dict(response.json()) + response_404 = OperationError.from_dict(response.json()) return response_404 if response.status_code == 409: - response_409 = ErrorResponse.from_dict(response.json()) + response_409 = OperationError.from_dict(response.json()) return response_409 @@ -77,13 +75,11 @@ def _parse_response( return response_422 if response.status_code == 429: - response_429 = ErrorResponse.from_dict(response.json()) - + response_429 = cast(Any, None) return response_429 if response.status_code == 500: - response_500 = ErrorResponse.from_dict(response.json()) - + response_500 = cast(Any, None) return response_500 if client.raise_on_unexpected_status: @@ -94,7 +90,7 @@ def _parse_response( def _build_response( *, client: AuthenticatedClient | Client, response: httpx.Response -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -109,10 +105,12 @@ def sync_detailed( client: AuthenticatedClient, body: TruncateScheduleOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Truncate Schedule (End Early) - Ends a schedule early by deleting forward facts and any stale draft closing entries past the cutoff. + End a schedule early by deleting forward facts and any stale draft closing entries past the cutoff. + Historical facts and posted entries are preserved. Use this when a business event (asset disposal, + contract cancellation) shortens the schedule's lifespan. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -120,14 +118,20 @@ def sync_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (TruncateScheduleOperation): + body (TruncateScheduleOperation): CQRS-shaped body for `POST /operations/truncate- + schedule`. + + Bundles the target schedule's `structure_id` with the update payload so + the single-body signature matches the registrar/MCP contract. The REST + handler, GraphQL resolver, and MCP tool all resolve to the same + `cmd_truncate_schedule(session, body, created_by=...)`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -149,10 +153,12 @@ def sync( client: AuthenticatedClient, body: TruncateScheduleOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Truncate Schedule (End Early) - Ends a schedule early by deleting forward facts and any stale draft closing entries past the cutoff. + End a schedule early by deleting forward facts and any stale draft closing entries past the cutoff. + Historical facts and posted entries are preserved. Use this when a business event (asset disposal, + contract cancellation) shortens the schedule's lifespan. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -160,14 +166,20 @@ def sync( Args: graph_id (str): idempotency_key (None | str | Unset): - body (TruncateScheduleOperation): + body (TruncateScheduleOperation): CQRS-shaped body for `POST /operations/truncate- + schedule`. + + Bundles the target schedule's `structure_id` with the update payload so + the single-body signature matches the registrar/MCP contract. The REST + handler, GraphQL resolver, and MCP tool all resolve to the same + `cmd_truncate_schedule(session, body, created_by=...)`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return sync_detailed( @@ -184,10 +196,12 @@ async def asyncio_detailed( client: AuthenticatedClient, body: TruncateScheduleOperation, idempotency_key: None | str | Unset = UNSET, -) -> Response[ErrorResponse | HTTPValidationError | OperationEnvelope]: +) -> Response[Any | HTTPValidationError | OperationEnvelope | OperationError]: """Truncate Schedule (End Early) - Ends a schedule early by deleting forward facts and any stale draft closing entries past the cutoff. + End a schedule early by deleting forward facts and any stale draft closing entries past the cutoff. + Historical facts and posted entries are preserved. Use this when a business event (asset disposal, + contract cancellation) shortens the schedule's lifespan. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -195,14 +209,20 @@ async def asyncio_detailed( Args: graph_id (str): idempotency_key (None | str | Unset): - body (TruncateScheduleOperation): + body (TruncateScheduleOperation): CQRS-shaped body for `POST /operations/truncate- + schedule`. + + Bundles the target schedule's `structure_id` with the update payload so + the single-body signature matches the registrar/MCP contract. The REST + handler, GraphQL resolver, and MCP tool all resolve to the same + `cmd_truncate_schedule(session, body, created_by=...)`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[ErrorResponse | HTTPValidationError | OperationEnvelope] + Response[Any | HTTPValidationError | OperationEnvelope | OperationError] """ kwargs = _get_kwargs( @@ -222,10 +242,12 @@ async def asyncio( client: AuthenticatedClient, body: TruncateScheduleOperation, idempotency_key: None | str | Unset = UNSET, -) -> ErrorResponse | HTTPValidationError | OperationEnvelope | None: +) -> Any | HTTPValidationError | OperationEnvelope | OperationError | None: """Truncate Schedule (End Early) - Ends a schedule early by deleting forward facts and any stale draft closing entries past the cutoff. + End a schedule early by deleting forward facts and any stale draft closing entries past the cutoff. + Historical facts and posted entries are preserved. Use this when a business event (asset disposal, + contract cancellation) shortens the schedule's lifespan. **Idempotency**: supply an `Idempotency-Key` header to make safe retries; replays within 24 hours return the same envelope. Reusing the key with a different body returns HTTP 409 Conflict. @@ -233,14 +255,20 @@ async def asyncio( Args: graph_id (str): idempotency_key (None | str | Unset): - body (TruncateScheduleOperation): + body (TruncateScheduleOperation): CQRS-shaped body for `POST /operations/truncate- + schedule`. + + Bundles the target schedule's `structure_id` with the update payload so + the single-body signature matches the registrar/MCP contract. The REST + handler, GraphQL resolver, and MCP tool all resolve to the same + `cmd_truncate_schedule(session, body, created_by=...)`. Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - ErrorResponse | HTTPValidationError | OperationEnvelope + Any | HTTPValidationError | OperationEnvelope | OperationError """ return ( diff --git a/robosystems_client/api/query/execute_cypher_query.py b/robosystems_client/api/query/execute_cypher_query.py index 898604c..f535f42 100644 --- a/robosystems_client/api/query/execute_cypher_query.py +++ b/robosystems_client/api/query/execute_cypher_query.py @@ -65,6 +65,12 @@ def _parse_response( *, client: AuthenticatedClient | Client, response: httpx.Response ) -> Any | ErrorResponse | HTTPValidationError | None: if response.status_code == 200: + content_type = response.headers.get("content-type", "") + if ( + "application/x-ndjson" in content_type + or response.headers.get("x-stream-format") == "ndjson" + ): + return None response_200 = response.json() return response_200 diff --git a/robosystems_client/clients/document_client.py b/robosystems_client/clients/document_client.py index 51b85e2..7bd9093 100644 --- a/robosystems_client/clients/document_client.py +++ b/robosystems_client/clients/document_client.py @@ -14,7 +14,6 @@ from ..api.documents.list_documents import sync_detailed as list_documents from ..api.documents.update_document import sync_detailed as update_document from ..api.documents.upload_document import sync_detailed as upload_document -from ..api.documents.upload_documents_bulk import sync_detailed as upload_documents_bulk from ..api.search.get_document_section import sync_detailed as get_document_section from ..api.search.search_documents import sync_detailed as search_documents from ..client import AuthenticatedClient @@ -22,8 +21,6 @@ from ..models.document_list_response import DocumentListResponse from ..models.document_section import DocumentSection from ..models.document_update_request import DocumentUpdateRequest -from ..models.bulk_document_upload_request import BulkDocumentUploadRequest -from ..models.bulk_document_upload_response import BulkDocumentUploadResponse from ..models.document_upload_request import DocumentUploadRequest from ..models.document_upload_response import DocumentUploadResponse from ..models.search_request import SearchRequest @@ -229,42 +226,6 @@ def upload_directory( return results - def upload_bulk( - self, - graph_id: str, - documents: List[Dict[str, Any]], - ) -> BulkDocumentUploadResponse: - """Upload multiple markdown documents (max 50 per request). - - Args: - graph_id: Target graph ID. - documents: List of dicts with keys: title, content, and - optionally tags, folder, external_id. - - Returns: - BulkDocumentUploadResponse with per-document results. - """ - items = [] - for doc in documents: - items.append( - DocumentUploadRequest( - title=doc["title"], - content=doc["content"], - tags=doc.get("tags", UNSET), - folder=doc.get("folder", UNSET), - external_id=doc.get("external_id", UNSET), - ) - ) - - body = BulkDocumentUploadRequest(documents=items) - client = self._get_client() - response = upload_documents_bulk(graph_id=graph_id, client=client, body=body) - if response.status_code != HTTPStatus.OK: - raise Exception( - f"Bulk upload failed ({response.status_code}): {response.content.decode()}" - ) - return response.parsed - def search( self, graph_id: str, diff --git a/robosystems_client/models/__init__.py b/robosystems_client/models/__init__.py index 05a0689..41d4406 100644 --- a/robosystems_client/models/__init__.py +++ b/robosystems_client/models/__init__.py @@ -44,11 +44,6 @@ from .bulk_association_item import BulkAssociationItem from .bulk_association_item_association_type import BulkAssociationItemAssociationType from .bulk_create_associations_request import BulkCreateAssociationsRequest -from .bulk_document_upload_request import BulkDocumentUploadRequest -from .bulk_document_upload_response import BulkDocumentUploadResponse -from .bulk_document_upload_response_errors_type_0_item import ( - BulkDocumentUploadResponseErrorsType0Item, -) from .cancel_operation_response_canceloperation import ( CancelOperationResponseCanceloperation, ) @@ -163,6 +158,7 @@ from .file_status_update import FileStatusUpdate from .file_upload_request import FileUploadRequest from .file_upload_response import FileUploadResponse +from .financial_statement_analysis_request import FinancialStatementAnalysisRequest from .forgot_password_request import ForgotPasswordRequest from .forgot_password_response_forgotpassword import ( ForgotPasswordResponseForgotpassword, @@ -212,6 +208,7 @@ from .list_org_graphs_response_200_item import ListOrgGraphsResponse200Item from .list_subgraphs_response import ListSubgraphsResponse from .list_table_files_response import ListTableFilesResponse +from .live_financial_statement_request import LiveFinancialStatementRequest from .login_request import LoginRequest from .logout_user_response_logoutuser import LogoutUserResponseLogoutuser from .manual_line_item_request import ManualLineItemRequest @@ -413,9 +410,6 @@ "BulkAssociationItem", "BulkAssociationItemAssociationType", "BulkCreateAssociationsRequest", - "BulkDocumentUploadRequest", - "BulkDocumentUploadResponse", - "BulkDocumentUploadResponseErrorsType0Item", "CancelOperationResponseCanceloperation", "ChangeTierOp", "ChangeTierOpNewTier", @@ -518,6 +512,7 @@ "FileStatusUpdate", "FileUploadRequest", "FileUploadResponse", + "FinancialStatementAnalysisRequest", "ForgotPasswordRequest", "ForgotPasswordResponseForgotpassword", "GetCurrentAuthUserResponseGetcurrentauthuser", @@ -559,6 +554,7 @@ "ListOrgGraphsResponse200Item", "ListSubgraphsResponse", "ListTableFilesResponse", + "LiveFinancialStatementRequest", "LoginRequest", "LogoutUserResponseLogoutuser", "ManualLineItemRequest", diff --git a/robosystems_client/models/bulk_document_upload_request.py b/robosystems_client/models/bulk_document_upload_request.py deleted file mode 100644 index 9c4d294..0000000 --- a/robosystems_client/models/bulk_document_upload_request.py +++ /dev/null @@ -1,76 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -if TYPE_CHECKING: - from ..models.document_upload_request import DocumentUploadRequest - - -T = TypeVar("T", bound="BulkDocumentUploadRequest") - - -@_attrs_define -class BulkDocumentUploadRequest: - """Bulk upload multiple markdown documents. - - Attributes: - documents (list[DocumentUploadRequest]): Documents to upload (max 50) - """ - - documents: list[DocumentUploadRequest] - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - documents = [] - for documents_item_data in self.documents: - documents_item = documents_item_data.to_dict() - documents.append(documents_item) - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "documents": documents, - } - ) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.document_upload_request import DocumentUploadRequest - - d = dict(src_dict) - documents = [] - _documents = d.pop("documents") - for documents_item_data in _documents: - documents_item = DocumentUploadRequest.from_dict(documents_item_data) - - documents.append(documents_item) - - bulk_document_upload_request = cls( - documents=documents, - ) - - bulk_document_upload_request.additional_properties = d - return bulk_document_upload_request - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/robosystems_client/models/bulk_document_upload_response.py b/robosystems_client/models/bulk_document_upload_response.py deleted file mode 100644 index f87a95c..0000000 --- a/robosystems_client/models/bulk_document_upload_response.py +++ /dev/null @@ -1,143 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.bulk_document_upload_response_errors_type_0_item import ( - BulkDocumentUploadResponseErrorsType0Item, - ) - from ..models.document_upload_response import DocumentUploadResponse - - -T = TypeVar("T", bound="BulkDocumentUploadResponse") - - -@_attrs_define -class BulkDocumentUploadResponse: - """Response from bulk document upload. - - Attributes: - total_documents (int): - total_sections_indexed (int): - results (list[DocumentUploadResponse]): - errors (list[BulkDocumentUploadResponseErrorsType0Item] | None | Unset): - """ - - total_documents: int - total_sections_indexed: int - results: list[DocumentUploadResponse] - errors: list[BulkDocumentUploadResponseErrorsType0Item] | None | Unset = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - total_documents = self.total_documents - - total_sections_indexed = self.total_sections_indexed - - results = [] - for results_item_data in self.results: - results_item = results_item_data.to_dict() - results.append(results_item) - - errors: list[dict[str, Any]] | None | Unset - if isinstance(self.errors, Unset): - errors = UNSET - elif isinstance(self.errors, list): - errors = [] - for errors_type_0_item_data in self.errors: - errors_type_0_item = errors_type_0_item_data.to_dict() - errors.append(errors_type_0_item) - - else: - errors = self.errors - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "total_documents": total_documents, - "total_sections_indexed": total_sections_indexed, - "results": results, - } - ) - if errors is not UNSET: - field_dict["errors"] = errors - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.bulk_document_upload_response_errors_type_0_item import ( - BulkDocumentUploadResponseErrorsType0Item, - ) - from ..models.document_upload_response import DocumentUploadResponse - - d = dict(src_dict) - total_documents = d.pop("total_documents") - - total_sections_indexed = d.pop("total_sections_indexed") - - results = [] - _results = d.pop("results") - for results_item_data in _results: - results_item = DocumentUploadResponse.from_dict(results_item_data) - - results.append(results_item) - - def _parse_errors( - data: object, - ) -> list[BulkDocumentUploadResponseErrorsType0Item] | None | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, list): - raise TypeError() - errors_type_0 = [] - _errors_type_0 = data - for errors_type_0_item_data in _errors_type_0: - errors_type_0_item = BulkDocumentUploadResponseErrorsType0Item.from_dict( - errors_type_0_item_data - ) - - errors_type_0.append(errors_type_0_item) - - return errors_type_0 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(list[BulkDocumentUploadResponseErrorsType0Item] | None | Unset, data) - - errors = _parse_errors(d.pop("errors", UNSET)) - - bulk_document_upload_response = cls( - total_documents=total_documents, - total_sections_indexed=total_sections_indexed, - results=results, - errors=errors, - ) - - bulk_document_upload_response.additional_properties = d - return bulk_document_upload_response - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/robosystems_client/models/bulk_document_upload_response_errors_type_0_item.py b/robosystems_client/models/bulk_document_upload_response_errors_type_0_item.py deleted file mode 100644 index 5037320..0000000 --- a/robosystems_client/models/bulk_document_upload_response_errors_type_0_item.py +++ /dev/null @@ -1,47 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="BulkDocumentUploadResponseErrorsType0Item") - - -@_attrs_define -class BulkDocumentUploadResponseErrorsType0Item: - """ """ - - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - bulk_document_upload_response_errors_type_0_item = cls() - - bulk_document_upload_response_errors_type_0_item.additional_properties = d - return bulk_document_upload_response_errors_type_0_item - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/robosystems_client/models/create_closing_entry_operation.py b/robosystems_client/models/create_closing_entry_operation.py index 73f24fa..e0d5291 100644 --- a/robosystems_client/models/create_closing_entry_operation.py +++ b/robosystems_client/models/create_closing_entry_operation.py @@ -15,13 +15,17 @@ @_attrs_define class CreateClosingEntryOperation: - """ - Attributes: - posting_date (datetime.date): Posting date for the entry - period_start (datetime.date): Period start - period_end (datetime.date): Period end - structure_id (str): - memo (None | str | Unset): Override memo + """CQRS-shaped body for `POST /operations/create-closing-entry`. + + `structure_id` moves into the body so REST + MCP share a single body + type via the registrar. + + Attributes: + posting_date (datetime.date): Posting date for the entry + period_start (datetime.date): Period start + period_end (datetime.date): Period end + structure_id (str): Schedule structure the closing entry is derived from. + memo (None | str | Unset): Override memo """ posting_date: datetime.date diff --git a/robosystems_client/models/create_element_request_classification.py b/robosystems_client/models/create_element_request_classification.py index 894a6aa..1513fb1 100644 --- a/robosystems_client/models/create_element_request_classification.py +++ b/robosystems_client/models/create_element_request_classification.py @@ -3,10 +3,11 @@ class CreateElementRequestClassification(str, Enum): ASSET = "asset" + CASHFLOW = "cashflow" EQUITY = "equity" - EXPENSE = "expense" + INFLOW = "inflow" LIABILITY = "liability" - REVENUE = "revenue" + OUTFLOW = "outflow" def __str__(self) -> str: return str(self.value) diff --git a/robosystems_client/models/create_element_request_source.py b/robosystems_client/models/create_element_request_source.py index 40faa2e..eae712c 100644 --- a/robosystems_client/models/create_element_request_source.py +++ b/robosystems_client/models/create_element_request_source.py @@ -2,11 +2,13 @@ class CreateElementRequestSource(str, Enum): + FAC = "fac" IFRS = "ifrs" IMPORT = "import" NATIVE = "native" PLAID = "plaid" QUICKBOOKS = "quickbooks" + RS_GAAP = "rs-gaap" SFAC6 = "sfac6" US_GAAP = "us-gaap" XERO = "xero" diff --git a/robosystems_client/models/create_mapping_association_operation.py b/robosystems_client/models/create_mapping_association_operation.py index bd4ca44..96d20f0 100644 --- a/robosystems_client/models/create_mapping_association_operation.py +++ b/robosystems_client/models/create_mapping_association_operation.py @@ -16,17 +16,21 @@ @_attrs_define class CreateMappingAssociationOperation: - """ - Attributes: - from_element_id (str): - to_element_id (str): - mapping_id (str): - association_type (CreateMappingAssociationOperationAssociationType | Unset): Default: - CreateMappingAssociationOperationAssociationType.MAPPING. - order_value (float | None | Unset): - weight (float | None | Unset): - confidence (float | None | Unset): - suggested_by (None | str | Unset): + """CQRS-shaped body for `POST /operations/create-mapping-association`. + + Bundles the target mapping structure's `mapping_id` with the association + payload so REST + MCP share a single body type via the registrar. + + Attributes: + from_element_id (str): + to_element_id (str): + mapping_id (str): Target mapping structure ID. + association_type (CreateMappingAssociationOperationAssociationType | Unset): Default: + CreateMappingAssociationOperationAssociationType.MAPPING. + order_value (float | None | Unset): + weight (float | None | Unset): + confidence (float | None | Unset): + suggested_by (None | str | Unset): """ from_element_id: str diff --git a/robosystems_client/models/delete_portfolio_operation.py b/robosystems_client/models/delete_portfolio_operation.py index 524a2e2..a37cd0d 100644 --- a/robosystems_client/models/delete_portfolio_operation.py +++ b/robosystems_client/models/delete_portfolio_operation.py @@ -11,9 +11,10 @@ @_attrs_define class DeletePortfolioOperation: - """ + """CQRS body for `POST /operations/delete-portfolio`. + Attributes: - portfolio_id (str): + portfolio_id (str): Target portfolio ID. """ portfolio_id: str diff --git a/robosystems_client/models/delete_position_operation.py b/robosystems_client/models/delete_position_operation.py index cf23aa3..3e57137 100644 --- a/robosystems_client/models/delete_position_operation.py +++ b/robosystems_client/models/delete_position_operation.py @@ -11,9 +11,10 @@ @_attrs_define class DeletePositionOperation: - """ + """CQRS body for `POST /operations/delete-position` (soft delete). + Attributes: - position_id (str): + position_id (str): Target position ID. """ position_id: str diff --git a/robosystems_client/models/delete_security_operation.py b/robosystems_client/models/delete_security_operation.py index f5a1038..3c7582a 100644 --- a/robosystems_client/models/delete_security_operation.py +++ b/robosystems_client/models/delete_security_operation.py @@ -11,9 +11,10 @@ @_attrs_define class DeleteSecurityOperation: - """ + """CQRS body for `POST /operations/delete-security` (soft delete). + Attributes: - security_id (str): + security_id (str): Target security ID. """ security_id: str diff --git a/robosystems_client/models/financial_statement_analysis_request.py b/robosystems_client/models/financial_statement_analysis_request.py new file mode 100644 index 0000000..022a66c --- /dev/null +++ b/robosystems_client/models/financial_statement_analysis_request.py @@ -0,0 +1,154 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="FinancialStatementAnalysisRequest") + + +@_attrs_define +class FinancialStatementAnalysisRequest: + """Request for financial-statement-analysis (graph-backed Cypher). + + Attributes: + statement_type (str): income_statement | balance_sheet | cash_flow_statement | equity_statement + ticker (None | str | Unset): Company ticker (required on shared-repo graphs, ignored otherwise) + report_id (None | str | Unset): Specific report identifier. If omitted, auto-resolves latest by ticker + + filters. + fiscal_year (int | None | Unset): Filter by fiscal year focus when auto-resolving the report + period_type (None | str | Unset): annual | quarterly | instant + limit (int | Unset): Default: 50. + """ + + statement_type: str + ticker: None | str | Unset = UNSET + report_id: None | str | Unset = UNSET + fiscal_year: int | None | Unset = UNSET + period_type: None | str | Unset = UNSET + limit: int | Unset = 50 + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + statement_type = self.statement_type + + ticker: None | str | Unset + if isinstance(self.ticker, Unset): + ticker = UNSET + else: + ticker = self.ticker + + report_id: None | str | Unset + if isinstance(self.report_id, Unset): + report_id = UNSET + else: + report_id = self.report_id + + fiscal_year: int | None | Unset + if isinstance(self.fiscal_year, Unset): + fiscal_year = UNSET + else: + fiscal_year = self.fiscal_year + + period_type: None | str | Unset + if isinstance(self.period_type, Unset): + period_type = UNSET + else: + period_type = self.period_type + + limit = self.limit + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "statement_type": statement_type, + } + ) + if ticker is not UNSET: + field_dict["ticker"] = ticker + if report_id is not UNSET: + field_dict["report_id"] = report_id + if fiscal_year is not UNSET: + field_dict["fiscal_year"] = fiscal_year + if period_type is not UNSET: + field_dict["period_type"] = period_type + if limit is not UNSET: + field_dict["limit"] = limit + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + statement_type = d.pop("statement_type") + + def _parse_ticker(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + ticker = _parse_ticker(d.pop("ticker", UNSET)) + + def _parse_report_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + report_id = _parse_report_id(d.pop("report_id", UNSET)) + + def _parse_fiscal_year(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + fiscal_year = _parse_fiscal_year(d.pop("fiscal_year", UNSET)) + + def _parse_period_type(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + period_type = _parse_period_type(d.pop("period_type", UNSET)) + + limit = d.pop("limit", UNSET) + + financial_statement_analysis_request = cls( + statement_type=statement_type, + ticker=ticker, + report_id=report_id, + fiscal_year=fiscal_year, + period_type=period_type, + limit=limit, + ) + + financial_statement_analysis_request.additional_properties = d + return financial_statement_analysis_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/robosystems_client/models/live_financial_statement_request.py b/robosystems_client/models/live_financial_statement_request.py new file mode 100644 index 0000000..c17cf5c --- /dev/null +++ b/robosystems_client/models/live_financial_statement_request.py @@ -0,0 +1,175 @@ +from __future__ import annotations + +import datetime +from collections.abc import Mapping +from typing import Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field +from dateutil.parser import isoparse + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="LiveFinancialStatementRequest") + + +@_attrs_define +class LiveFinancialStatementRequest: + """Request for live-financial-statement (OLTP, entity graphs only). + + Attributes: + statement_type (str): income_statement | balance_sheet | equity_statement + period_start (datetime.date | None | Unset): Explicit window start. Overrides period_type/fiscal_year. + period_end (datetime.date | None | Unset): Explicit window end. Overrides period_type/fiscal_year. + period_type (None | str | Unset): annual | quarterly | instant (ignored when dates supplied) + fiscal_year (int | None | Unset): Fiscal year for annual window (anchored on FiscalCalendar) + limit (int | Unset): Max fact rows returned Default: 50. + """ + + statement_type: str + period_start: datetime.date | None | Unset = UNSET + period_end: datetime.date | None | Unset = UNSET + period_type: None | str | Unset = UNSET + fiscal_year: int | None | Unset = UNSET + limit: int | Unset = 50 + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + statement_type = self.statement_type + + period_start: None | str | Unset + if isinstance(self.period_start, Unset): + period_start = UNSET + elif isinstance(self.period_start, datetime.date): + period_start = self.period_start.isoformat() + else: + period_start = self.period_start + + period_end: None | str | Unset + if isinstance(self.period_end, Unset): + period_end = UNSET + elif isinstance(self.period_end, datetime.date): + period_end = self.period_end.isoformat() + else: + period_end = self.period_end + + period_type: None | str | Unset + if isinstance(self.period_type, Unset): + period_type = UNSET + else: + period_type = self.period_type + + fiscal_year: int | None | Unset + if isinstance(self.fiscal_year, Unset): + fiscal_year = UNSET + else: + fiscal_year = self.fiscal_year + + limit = self.limit + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "statement_type": statement_type, + } + ) + if period_start is not UNSET: + field_dict["period_start"] = period_start + if period_end is not UNSET: + field_dict["period_end"] = period_end + if period_type is not UNSET: + field_dict["period_type"] = period_type + if fiscal_year is not UNSET: + field_dict["fiscal_year"] = fiscal_year + if limit is not UNSET: + field_dict["limit"] = limit + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + statement_type = d.pop("statement_type") + + def _parse_period_start(data: object) -> datetime.date | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + period_start_type_0 = isoparse(data).date() + + return period_start_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(datetime.date | None | Unset, data) + + period_start = _parse_period_start(d.pop("period_start", UNSET)) + + def _parse_period_end(data: object) -> datetime.date | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + period_end_type_0 = isoparse(data).date() + + return period_end_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(datetime.date | None | Unset, data) + + period_end = _parse_period_end(d.pop("period_end", UNSET)) + + def _parse_period_type(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + period_type = _parse_period_type(d.pop("period_type", UNSET)) + + def _parse_fiscal_year(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + fiscal_year = _parse_fiscal_year(d.pop("fiscal_year", UNSET)) + + limit = d.pop("limit", UNSET) + + live_financial_statement_request = cls( + statement_type=statement_type, + period_start=period_start, + period_end=period_end, + period_type=period_type, + fiscal_year=fiscal_year, + limit=limit, + ) + + live_financial_statement_request.additional_properties = d + return live_financial_statement_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/robosystems_client/models/truncate_schedule_operation.py b/robosystems_client/models/truncate_schedule_operation.py index 28049a5..b001e2a 100644 --- a/robosystems_client/models/truncate_schedule_operation.py +++ b/robosystems_client/models/truncate_schedule_operation.py @@ -13,12 +13,18 @@ @_attrs_define class TruncateScheduleOperation: - """ - Attributes: - new_end_date (datetime.date): New last-covered date for the schedule. Facts with period_start > this date are - deleted (along with any stale draft entries they produced). Historical facts (already posted) are preserved. - reason (str): Required reason for the truncation (captured in audit log). - structure_id (str): + """CQRS-shaped body for `POST /operations/truncate-schedule`. + + Bundles the target schedule's `structure_id` with the update payload so + the single-body signature matches the registrar/MCP contract. The REST + handler, GraphQL resolver, and MCP tool all resolve to the same + `cmd_truncate_schedule(session, body, created_by=...)`. + + Attributes: + new_end_date (datetime.date): New last-covered date for the schedule. Facts with period_start > this date are + deleted (along with any stale draft entries they produced). Historical facts (already posted) are preserved. + reason (str): Required reason for the truncation (captured in audit log). + structure_id (str): Target schedule structure ID. """ new_end_date: datetime.date diff --git a/robosystems_client/models/update_element_request_classification_type_0.py b/robosystems_client/models/update_element_request_classification_type_0.py index 588160d..200f782 100644 --- a/robosystems_client/models/update_element_request_classification_type_0.py +++ b/robosystems_client/models/update_element_request_classification_type_0.py @@ -3,10 +3,11 @@ class UpdateElementRequestClassificationType0(str, Enum): ASSET = "asset" + CASHFLOW = "cashflow" EQUITY = "equity" - EXPENSE = "expense" + INFLOW = "inflow" LIABILITY = "liability" - REVENUE = "revenue" + OUTFLOW = "outflow" def __str__(self) -> str: return str(self.value) diff --git a/robosystems_client/models/update_portfolio_operation.py b/robosystems_client/models/update_portfolio_operation.py index f0dc210..fada6a4 100644 --- a/robosystems_client/models/update_portfolio_operation.py +++ b/robosystems_client/models/update_portfolio_operation.py @@ -15,14 +15,18 @@ @_attrs_define class UpdatePortfolioOperation: - """ - Attributes: - portfolio_id (str): - name (None | str | Unset): - description (None | str | Unset): - strategy (None | str | Unset): - inception_date (datetime.date | None | Unset): - base_currency (None | str | Unset): + """CQRS body for `POST /operations/update-portfolio`. + + Folds `portfolio_id` into the payload so REST + MCP share one body + type via the registrar. Unset fields are ignored (partial update). + + Attributes: + portfolio_id (str): Target portfolio ID. + name (None | str | Unset): + description (None | str | Unset): + strategy (None | str | Unset): + inception_date (datetime.date | None | Unset): + base_currency (None | str | Unset): """ portfolio_id: str diff --git a/robosystems_client/models/update_position_operation.py b/robosystems_client/models/update_position_operation.py index 579ce57..ca5824c 100644 --- a/robosystems_client/models/update_position_operation.py +++ b/robosystems_client/models/update_position_operation.py @@ -15,9 +15,10 @@ @_attrs_define class UpdatePositionOperation: - """ + """CQRS body for `POST /operations/update-position`. + Attributes: - position_id (str): + position_id (str): Target position ID. quantity (float | None | Unset): quantity_type (None | str | Unset): cost_basis (int | None | Unset): diff --git a/robosystems_client/models/update_security_operation.py b/robosystems_client/models/update_security_operation.py index e96db29..d01c8ca 100644 --- a/robosystems_client/models/update_security_operation.py +++ b/robosystems_client/models/update_security_operation.py @@ -19,9 +19,10 @@ @_attrs_define class UpdateSecurityOperation: - """ + """CQRS body for `POST /operations/update-security`. + Attributes: - security_id (str): + security_id (str): Target security ID. entity_id (None | str | Unset): source_graph_id (None | str | Unset): name (None | str | Unset): diff --git a/tests/test_document_client.py b/tests/test_document_client.py index 46995fb..3530bee 100644 --- a/tests/test_document_client.py +++ b/tests/test_document_client.py @@ -334,42 +334,6 @@ def test_get_section_not_found(self, mock_get_section, mock_config, graph_id): assert result is None -@pytest.mark.unit -class TestDocumentBulkUpload: - """Test suite for DocumentClient.upload_bulk method.""" - - @patch("robosystems_client.clients.document_client.upload_documents_bulk") - def test_upload_bulk(self, mock_bulk, mock_config, graph_id): - """Test bulk uploading documents.""" - mock_resp = Mock() - mock_resp.status_code = HTTPStatus.OK - mock_resp.parsed = Mock(total=2, succeeded=2, failed=0, results=[Mock(), Mock()]) - mock_bulk.return_value = mock_resp - - client = DocumentClient(mock_config) - docs = [ - {"title": "Doc 1", "content": "Content 1"}, - {"title": "Doc 2", "content": "Content 2", "tags": ["tag1"]}, - ] - result = client.upload_bulk(graph_id=graph_id, documents=docs) - - assert result.total == 2 - assert result.succeeded == 2 - - @patch("robosystems_client.clients.document_client.upload_documents_bulk") - def test_upload_bulk_failure(self, mock_bulk, mock_config, graph_id): - """Test bulk upload failure raises exception.""" - mock_resp = Mock() - mock_resp.status_code = HTTPStatus.BAD_REQUEST - mock_resp.content = b"Bulk upload error" - mock_bulk.return_value = mock_resp - - client = DocumentClient(mock_config) - - with pytest.raises(Exception, match="Bulk upload failed"): - client.upload_bulk(graph_id=graph_id, documents=[{"title": "x", "content": "y"}]) - - @pytest.mark.unit class TestDocumentUploadFile: """Test suite for DocumentClient.upload_file method.""" From 108dc0f910610116912ad118b34f87b7ab62f2ff Mon Sep 17 00:00:00 2001 From: "Joseph T. French" Date: Sun, 19 Apr 2026 23:09:21 -0500 Subject: [PATCH 2/4] Update project metadata and enhance client library integration This commit modifies the `pyproject.toml` file to improve project descriptions and add relevant URLs for the repository, homepage, and bug tracker. Additionally, the `__init__.py` file in the client library is updated to include the `LibraryClient` and its associated `LIBRARY_GRAPH_ID`, enhancing the API's usability and discoverability. Key Changes: - Updated project description for clarity. - Added keywords to reflect the knowledge graph functionality. - Included project URLs for better resource access. - Integrated `LibraryClient` and `LIBRARY_GRAPH_ID` into the public API surface. These changes aim to improve the overall developer experience and project visibility. --- pyproject.toml | 9 +- robosystems_client/clients/__init__.py | 5 +- robosystems_client/clients/library_client.py | 229 +++++++++++++ .../graphql/queries/library/__init__.py | 318 ++++++++++++++++++ 4 files changed, 558 insertions(+), 3 deletions(-) create mode 100644 robosystems_client/clients/library_client.py create mode 100644 robosystems_client/graphql/queries/library/__init__.py diff --git a/pyproject.toml b/pyproject.toml index 121711d..be522d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,14 @@ [project] name = "robosystems-client" version = "0.3.8" -description = "Python Client for RoboSystems financial graph database API" +description = "Python client library for RoboSystems Financial Knowledge Graph API" readme = "README.md" requires-python = ">=3.10" authors = [ {name = "RFS LLC"}, ] license = {text = "MIT"} -keywords = ["client", "robosystems", "financial", "graph", "api", "sdk"] +keywords = ["client", "robosystems", "financial", "graph", "api", "sdk", "knowledge-graph"] classifiers = [ "Development Status :: 4 - Beta", "Framework :: AsyncIO", @@ -51,6 +51,11 @@ dev = [ "twine>=5.0.0", ] +[project.urls] +Repository = "https://github.com/RoboFinSystems/robosystems-python-client" +Homepage = "https://github.com/RoboFinSystems/robosystems-python-client#readme" +"Bug Tracker" = "https://github.com/RoboFinSystems/robosystems-python-client/issues" + [build-system] requires = ["hatchling"] build-backend = "hatchling.build" diff --git a/robosystems_client/clients/__init__.py b/robosystems_client/clients/__init__.py index 8af9891..a05fe33 100644 --- a/robosystems_client/clients/__init__.py +++ b/robosystems_client/clients/__init__.py @@ -49,6 +49,7 @@ ) from .investor_client import InvestorClient from .ledger_client import LedgerClient +from .library_client import LIBRARY_GRAPH_ID, LibraryClient from .facade import ( RoboSystemsClients, RoboSystemsClientConfig, @@ -166,7 +167,9 @@ "LedgerClient", # Investor Client "InvestorClient", - # Report Client + # Library Client + "LibraryClient", + "LIBRARY_GRAPH_ID", # Utilities "QueryBuilder", "ResultProcessor", diff --git a/robosystems_client/clients/library_client.py b/robosystems_client/clients/library_client.py new file mode 100644 index 0000000..7830ea3 --- /dev/null +++ b/robosystems_client/clients/library_client.py @@ -0,0 +1,229 @@ +"""Library Client for RoboSystems API. + +Read-only facade for the taxonomy library — the shared reference material +(sfac6, fac, rs-gaap, …, mapping taxonomies) in the extensions DB public +schema. + +**Two access modes** — picked by the caller's ``graph_id``: + +- ``"library"`` (sentinel, default) → canonical browse of the public + schema. Route: ``POST /extensions/library/graphql``. +- Any tenant ``graph_id`` (``"kg…"``) → tenant schema + public fallback + via search_path. Returns the tenant's library copy plus any tenant + extensions of library tables. Route: ``POST /extensions/{graph_id}/graphql``. + +**Read-only**: the library is immutable at the DB level (triggers block +UPDATE/DELETE on rows whose ``created_by='library-seeder'``), so there is +no write surface here. Tenant-scope writes go through ``LedgerClient``. +""" + +from __future__ import annotations + +from typing import Any + +from ..graphql.client import GraphQLClient, strip_none_vars +from ..graphql.queries.library import ( + GET_LIBRARY_ELEMENT_ARCS_QUERY, + GET_LIBRARY_ELEMENT_EQUIVALENTS_QUERY, + GET_LIBRARY_ELEMENT_QUERY, + GET_LIBRARY_TAXONOMY_QUERY, + LIST_LIBRARY_ELEMENTS_QUERY, + LIST_LIBRARY_TAXONOMIES_QUERY, + LIST_LIBRARY_TAXONOMY_ARCS_QUERY, + SEARCH_LIBRARY_ELEMENTS_QUERY, + parse_library_element, + parse_library_element_arcs, + parse_library_element_equivalents, + parse_library_elements, + parse_library_search_results, + parse_library_taxonomies, + parse_library_taxonomy, + parse_library_taxonomy_arcs, +) + +LIBRARY_GRAPH_ID = "library" +"""Sentinel graph_id for the canonical library read surface. + +Passing this to any LibraryClient method routes the GraphQL request to +``/extensions/library/graphql`` and reads from the public schema only. +""" + + +class LibraryClient: + """Read-only facade for the RoboSystems taxonomy library.""" + + def __init__(self, config: dict[str, Any]): + self.config = config + self.base_url = config["base_url"] + self.headers = config.get("headers", {}) + self.token = config.get("token") + self.timeout = config.get("timeout", 60) + + def _get_graphql_client(self) -> GraphQLClient: + if not self.token: + raise RuntimeError("No API key provided. Set token in config.") + return GraphQLClient( + base_url=self.base_url, + token=self.token, + headers=self.headers, + timeout=self.timeout, + ) + + def _query( + self, + graph_id: str, + query: str, + variables: dict[str, Any] | None = None, + ) -> dict[str, Any]: + cleaned = strip_none_vars(variables) if variables else None + return self._get_graphql_client().execute(graph_id, query, cleaned) + + # ── Taxonomies ────────────────────────────────────────────────────── + + def list_library_taxonomies( + self, + graph_id: str = LIBRARY_GRAPH_ID, + *, + standard: str | None = None, + include_element_count: bool = False, + ) -> list[dict[str, Any]]: + """List every taxonomy visible at this graph_id.""" + data = self._query( + graph_id, + LIST_LIBRARY_TAXONOMIES_QUERY, + {"standard": standard, "includeElementCount": include_element_count}, + ) + return parse_library_taxonomies(data) + + def get_library_taxonomy( + self, + graph_id: str = LIBRARY_GRAPH_ID, + *, + id: str | None = None, + standard: str | None = None, + version: str | None = None, + include_element_count: bool = False, + ) -> dict[str, Any] | None: + """Fetch one taxonomy by id or by (standard, version). Returns None if not found.""" + data = self._query( + graph_id, + GET_LIBRARY_TAXONOMY_QUERY, + { + "id": id, + "standard": standard, + "version": version, + "includeElementCount": include_element_count, + }, + ) + return parse_library_taxonomy(data) + + # ── Elements ──────────────────────────────────────────────────────── + + def list_library_elements( + self, + graph_id: str = LIBRARY_GRAPH_ID, + *, + taxonomy_id: str | None = None, + source: str | None = None, + classification: str | None = None, + statement_context: str | None = None, + derivation_role: str | None = None, + element_type: str | None = None, + is_abstract: bool | None = None, + limit: int = 50, + offset: int = 0, + include_labels: bool = False, + include_references: bool = False, + ) -> list[dict[str, Any]]: + """List library elements with filters and pagination.""" + data = self._query( + graph_id, + LIST_LIBRARY_ELEMENTS_QUERY, + { + "taxonomyId": taxonomy_id, + "source": source, + "classification": classification, + "statementContext": statement_context, + "derivationRole": derivation_role, + "elementType": element_type, + "isAbstract": is_abstract, + "limit": limit, + "offset": offset, + "includeLabels": include_labels, + "includeReferences": include_references, + }, + ) + return parse_library_elements(data) + + def search_library_elements( + self, + query: str, + graph_id: str = LIBRARY_GRAPH_ID, + *, + source: str | None = None, + limit: int = 50, + ) -> list[dict[str, Any]]: + """Substring search across qname, name, and standard label text.""" + data = self._query( + graph_id, + SEARCH_LIBRARY_ELEMENTS_QUERY, + {"query": query, "source": source, "limit": limit}, + ) + return parse_library_search_results(data) + + def get_library_element( + self, + graph_id: str = LIBRARY_GRAPH_ID, + *, + id: str | None = None, + qname: str | None = None, + ) -> dict[str, Any] | None: + """Get a single element by id or qname. Returns None if not found.""" + data = self._query( + graph_id, + GET_LIBRARY_ELEMENT_QUERY, + {"id": id, "qname": qname}, + ) + return parse_library_element(data) + + # ── Arcs / Equivalence ────────────────────────────────────────────── + + def list_library_taxonomy_arcs( + self, + taxonomy_id: str, + graph_id: str = LIBRARY_GRAPH_ID, + *, + association_type: str | None = None, + limit: int = 200, + offset: int = 0, + ) -> dict[str, Any]: + """All arcs contributed by a taxonomy plus their total count.""" + data = self._query( + graph_id, + LIST_LIBRARY_TAXONOMY_ARCS_QUERY, + { + "taxonomyId": taxonomy_id, + "associationType": association_type, + "limit": limit, + "offset": offset, + }, + ) + return parse_library_taxonomy_arcs(data) + + def get_library_element_arcs( + self, + id: str, + graph_id: str = LIBRARY_GRAPH_ID, + ) -> list[dict[str, Any]]: + """All mapping arcs where this element is source or target.""" + data = self._query(graph_id, GET_LIBRARY_ELEMENT_ARCS_QUERY, {"id": id}) + return parse_library_element_arcs(data) + + def get_library_element_equivalents( + self, + id: str, + graph_id: str = LIBRARY_GRAPH_ID, + ) -> dict[str, Any] | None: + """Equivalence fan-out (FAC ↔ us-gaap collapse). Returns None if not found.""" + data = self._query(graph_id, GET_LIBRARY_ELEMENT_EQUIVALENTS_QUERY, {"id": id}) + return parse_library_element_equivalents(data) diff --git a/robosystems_client/graphql/queries/library/__init__.py b/robosystems_client/graphql/queries/library/__init__.py new file mode 100644 index 0000000..8db714c --- /dev/null +++ b/robosystems_client/graphql/queries/library/__init__.py @@ -0,0 +1,318 @@ +"""Library-domain GraphQL queries and parsers. + +Read-only facade for the taxonomy library — the shared reference material +(sfac6, fac, rs-gaap, …, mapping taxonomies) in the extensions DB public +schema. + +Same pattern as the investor queries: one constant + one ``parse_*`` +helper per query, returning camelCase → snake_case dicts. +""" + +from __future__ import annotations + +from typing import Any + +from ...client import keys_to_snake + + +# ── Taxonomies ───────────────────────────────────────────────────────── + +LIST_LIBRARY_TAXONOMIES_QUERY = """ +query ListLibraryTaxonomies($standard: String, $includeElementCount: Boolean! = false) { + libraryTaxonomies(standard: $standard, includeElementCount: $includeElementCount) { + id + name + description + standard + version + namespaceUri + taxonomyType + isShared + isActive + isLocked + elementCount + } +} +""".strip() + + +def parse_library_taxonomies(data: dict[str, Any]) -> list[dict[str, Any]]: + items = data.get("libraryTaxonomies") or [] + return [keys_to_snake(t) for t in items] + + +GET_LIBRARY_TAXONOMY_QUERY = """ +query GetLibraryTaxonomy( + $id: ID + $standard: String + $version: String + $includeElementCount: Boolean! = false +) { + libraryTaxonomy( + id: $id + standard: $standard + version: $version + includeElementCount: $includeElementCount + ) { + id + name + description + standard + version + namespaceUri + taxonomyType + isShared + isActive + isLocked + elementCount + } +} +""".strip() + + +def parse_library_taxonomy(data: dict[str, Any]) -> dict[str, Any] | None: + t = data.get("libraryTaxonomy") + return keys_to_snake(t) if t is not None else None + + +# ── Elements ─────────────────────────────────────────────────────────── + +LIST_LIBRARY_ELEMENTS_QUERY = """ +query ListLibraryElements( + $taxonomyId: ID + $source: String + $classification: String + $statementContext: String + $derivationRole: String + $elementType: String + $isAbstract: Boolean + $limit: Int! = 50 + $offset: Int! = 0 + $includeLabels: Boolean! = false + $includeReferences: Boolean! = false +) { + libraryElements( + taxonomyId: $taxonomyId + source: $source + classification: $classification + statementContext: $statementContext + derivationRole: $derivationRole + elementType: $elementType + isAbstract: $isAbstract + limit: $limit + offset: $offset + includeLabels: $includeLabels + includeReferences: $includeReferences + ) { + id + qname + namespace + name + classification + statementContext + derivationRole + balanceType + periodType + isAbstract + isMonetary + elementType + source + taxonomyId + parentId + labels @include(if: $includeLabels) { + role + language + text + } + references @include(if: $includeReferences) { + refType + citation + uri + } + } +} +""".strip() + + +def parse_library_elements(data: dict[str, Any]) -> list[dict[str, Any]]: + items = data.get("libraryElements") or [] + return [keys_to_snake(e) for e in items] + + +SEARCH_LIBRARY_ELEMENTS_QUERY = """ +query SearchLibraryElements($query: String!, $source: String, $limit: Int! = 50) { + searchLibraryElements(query: $query, source: $source, limit: $limit) { + id + qname + namespace + name + classification + statementContext + derivationRole + balanceType + periodType + isAbstract + isMonetary + elementType + source + taxonomyId + parentId + labels { + role + language + text + } + references { + refType + citation + uri + } + } +} +""".strip() + + +def parse_library_search_results(data: dict[str, Any]) -> list[dict[str, Any]]: + items = data.get("searchLibraryElements") or [] + return [keys_to_snake(e) for e in items] + + +GET_LIBRARY_ELEMENT_QUERY = """ +query GetLibraryElement($id: ID, $qname: String) { + libraryElement(id: $id, qname: $qname) { + id + qname + namespace + name + classification + statementContext + derivationRole + balanceType + periodType + isAbstract + isMonetary + elementType + source + taxonomyId + parentId + labels { + role + language + text + } + references { + refType + citation + uri + } + } +} +""".strip() + + +def parse_library_element(data: dict[str, Any]) -> dict[str, Any] | None: + e = data.get("libraryElement") + return keys_to_snake(e) if e is not None else None + + +# ── Arcs / Equivalence ───────────────────────────────────────────────── + +LIST_LIBRARY_TAXONOMY_ARCS_QUERY = """ +query ListLibraryTaxonomyArcs( + $taxonomyId: ID! + $associationType: String + $limit: Int! = 200 + $offset: Int! = 0 +) { + libraryTaxonomyArcCount(taxonomyId: $taxonomyId) + libraryTaxonomyArcs( + taxonomyId: $taxonomyId + associationType: $associationType + limit: $limit + offset: $offset + ) { + id + structureId + structureName + fromElementId + fromElementQname + fromElementName + toElementId + toElementQname + toElementName + associationType + arcrole + orderValue + weight + } +} +""".strip() + + +def parse_library_taxonomy_arcs(data: dict[str, Any]) -> dict[str, Any]: + return { + "arcs": [keys_to_snake(a) for a in (data.get("libraryTaxonomyArcs") or [])], + "count": data.get("libraryTaxonomyArcCount", 0), + } + + +GET_LIBRARY_ELEMENT_ARCS_QUERY = """ +query GetLibraryElementArcs($id: ID!) { + libraryElementArcs(id: $id) { + id + direction + associationType + arcrole + taxonomyId + taxonomyStandard + taxonomyName + structureId + structureName + peer { + id + qname + name + classification + statementContext + derivationRole + source + } + } +} +""".strip() + + +def parse_library_element_arcs(data: dict[str, Any]) -> list[dict[str, Any]]: + items = data.get("libraryElementArcs") or [] + return [keys_to_snake(a) for a in items] + + +GET_LIBRARY_ELEMENT_EQUIVALENTS_QUERY = """ +query GetLibraryElementEquivalents($id: ID!) { + libraryElementEquivalents(id: $id) { + element { + id + qname + name + classification + statementContext + derivationRole + source + } + equivalents { + id + qname + name + classification + statementContext + derivationRole + source + } + } +} +""".strip() + + +def parse_library_element_equivalents(data: dict[str, Any]) -> dict[str, Any] | None: + eq = data.get("libraryElementEquivalents") + return keys_to_snake(eq) if eq is not None else None From 583a74bdf52208ea85eb44f7f0eb658f3ede436c Mon Sep 17 00:00:00 2001 From: "Joseph T. French" Date: Mon, 20 Apr 2026 18:18:42 -0500 Subject: [PATCH 3/4] Refactor element request models by removing unused classifications and updating related imports --- robosystems_client/models/__init__.py | 4 -- .../models/create_element_request.py | 20 ------- .../create_element_request_classification.py | 15 ++++- .../models/create_element_request_source.py | 1 - .../models/update_element_request.py | 55 ------------------- ...e_element_request_classification_type_0.py | 13 ----- 6 files changed, 12 insertions(+), 96 deletions(-) delete mode 100644 robosystems_client/models/update_element_request_classification_type_0.py diff --git a/robosystems_client/models/__init__.py b/robosystems_client/models/__init__.py index 41d4406..0955ffe 100644 --- a/robosystems_client/models/__init__.py +++ b/robosystems_client/models/__init__.py @@ -337,9 +337,6 @@ from .update_element_request_balance_type_type_0 import ( UpdateElementRequestBalanceTypeType0, ) -from .update_element_request_classification_type_0 import ( - UpdateElementRequestClassificationType0, -) from .update_element_request_period_type_type_0 import ( UpdateElementRequestPeriodTypeType0, ) @@ -667,7 +664,6 @@ "UpdateAssociationRequest", "UpdateElementRequest", "UpdateElementRequestBalanceTypeType0", - "UpdateElementRequestClassificationType0", "UpdateElementRequestPeriodTypeType0", "UpdateEntityRequest", "UpdateFileResponseUpdatefile", diff --git a/robosystems_client/models/create_element_request.py b/robosystems_client/models/create_element_request.py index d9bb6d8..fbb14cb 100644 --- a/robosystems_client/models/create_element_request.py +++ b/robosystems_client/models/create_element_request.py @@ -29,7 +29,6 @@ class CreateElementRequest: classification (CreateElementRequestClassification): code (None | str | Unset): description (None | str | Unset): - sub_classification (None | str | Unset): balance_type (CreateElementRequestBalanceType | Unset): Default: CreateElementRequestBalanceType.DEBIT. period_type (CreateElementRequestPeriodType | Unset): Default: CreateElementRequestPeriodType.DURATION. element_type (CreateElementRequestElementType | Unset): Default: CreateElementRequestElementType.CONCEPT. @@ -49,7 +48,6 @@ class CreateElementRequest: classification: CreateElementRequestClassification code: None | str | Unset = UNSET description: None | str | Unset = UNSET - sub_classification: None | str | Unset = UNSET balance_type: CreateElementRequestBalanceType | Unset = ( CreateElementRequestBalanceType.DEBIT ) @@ -89,12 +87,6 @@ def to_dict(self) -> dict[str, Any]: else: description = self.description - sub_classification: None | str | Unset - if isinstance(self.sub_classification, Unset): - sub_classification = UNSET - else: - sub_classification = self.sub_classification - balance_type: str | Unset = UNSET if not isinstance(self.balance_type, Unset): balance_type = self.balance_type.value @@ -160,8 +152,6 @@ def to_dict(self) -> dict[str, Any]: field_dict["code"] = code if description is not UNSET: field_dict["description"] = description - if sub_classification is not UNSET: - field_dict["sub_classification"] = sub_classification if balance_type is not UNSET: field_dict["balance_type"] = balance_type if period_type is not UNSET: @@ -216,15 +206,6 @@ def _parse_description(data: object) -> None | str | Unset: description = _parse_description(d.pop("description", UNSET)) - def _parse_sub_classification(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - sub_classification = _parse_sub_classification(d.pop("sub_classification", UNSET)) - _balance_type = d.pop("balance_type", UNSET) balance_type: CreateElementRequestBalanceType | Unset if isinstance(_balance_type, Unset): @@ -310,7 +291,6 @@ def _parse_external_source(data: object) -> None | str | Unset: classification=classification, code=code, description=description, - sub_classification=sub_classification, balance_type=balance_type, period_type=period_type, element_type=element_type, diff --git a/robosystems_client/models/create_element_request_classification.py b/robosystems_client/models/create_element_request_classification.py index 1513fb1..fbd51b4 100644 --- a/robosystems_client/models/create_element_request_classification.py +++ b/robosystems_client/models/create_element_request_classification.py @@ -3,11 +3,20 @@ class CreateElementRequestClassification(str, Enum): ASSET = "asset" - CASHFLOW = "cashflow" + COMPREHENSIVEINCOME = "comprehensiveIncome" + CONTRAASSET = "contraAsset" + CONTRAEQUITY = "contraEquity" + CONTRALIABILITY = "contraLiability" + DISTRIBUTIONTOOWNERS = "distributionToOwners" EQUITY = "equity" - INFLOW = "inflow" + EXPENSE = "expense" + EXPENSEREVERSAL = "expenseReversal" + GAIN = "gain" + INVESTMENTBYOWNERS = "investmentByOwners" LIABILITY = "liability" - OUTFLOW = "outflow" + LOSS = "loss" + REVENUE = "revenue" + TEMPORARYEQUITY = "temporaryEquity" def __str__(self) -> str: return str(self.value) diff --git a/robosystems_client/models/create_element_request_source.py b/robosystems_client/models/create_element_request_source.py index eae712c..70c28d1 100644 --- a/robosystems_client/models/create_element_request_source.py +++ b/robosystems_client/models/create_element_request_source.py @@ -9,7 +9,6 @@ class CreateElementRequestSource(str, Enum): PLAID = "plaid" QUICKBOOKS = "quickbooks" RS_GAAP = "rs-gaap" - SFAC6 = "sfac6" US_GAAP = "us-gaap" XERO = "xero" diff --git a/robosystems_client/models/update_element_request.py b/robosystems_client/models/update_element_request.py index 32e443a..9df7196 100644 --- a/robosystems_client/models/update_element_request.py +++ b/robosystems_client/models/update_element_request.py @@ -9,9 +9,6 @@ from ..models.update_element_request_balance_type_type_0 import ( UpdateElementRequestBalanceTypeType0, ) -from ..models.update_element_request_classification_type_0 import ( - UpdateElementRequestClassificationType0, -) from ..models.update_element_request_period_type_type_0 import ( UpdateElementRequestPeriodTypeType0, ) @@ -32,8 +29,6 @@ class UpdateElementRequest: code (None | str | Unset): name (None | str | Unset): description (None | str | Unset): - classification (None | Unset | UpdateElementRequestClassificationType0): - sub_classification (None | str | Unset): balance_type (None | Unset | UpdateElementRequestBalanceTypeType0): period_type (None | Unset | UpdateElementRequestPeriodTypeType0): parent_id (None | str | Unset): @@ -44,8 +39,6 @@ class UpdateElementRequest: code: None | str | Unset = UNSET name: None | str | Unset = UNSET description: None | str | Unset = UNSET - classification: None | Unset | UpdateElementRequestClassificationType0 = UNSET - sub_classification: None | str | Unset = UNSET balance_type: None | Unset | UpdateElementRequestBalanceTypeType0 = UNSET period_type: None | Unset | UpdateElementRequestPeriodTypeType0 = UNSET parent_id: None | str | Unset = UNSET @@ -73,20 +66,6 @@ def to_dict(self) -> dict[str, Any]: else: description = self.description - classification: None | str | Unset - if isinstance(self.classification, Unset): - classification = UNSET - elif isinstance(self.classification, UpdateElementRequestClassificationType0): - classification = self.classification.value - else: - classification = self.classification - - sub_classification: None | str | Unset - if isinstance(self.sub_classification, Unset): - sub_classification = UNSET - else: - sub_classification = self.sub_classification - balance_type: None | str | Unset if isinstance(self.balance_type, Unset): balance_type = UNSET @@ -128,10 +107,6 @@ def to_dict(self) -> dict[str, Any]: field_dict["name"] = name if description is not UNSET: field_dict["description"] = description - if classification is not UNSET: - field_dict["classification"] = classification - if sub_classification is not UNSET: - field_dict["sub_classification"] = sub_classification if balance_type is not UNSET: field_dict["balance_type"] = balance_type if period_type is not UNSET: @@ -175,34 +150,6 @@ def _parse_description(data: object) -> None | str | Unset: description = _parse_description(d.pop("description", UNSET)) - def _parse_classification( - data: object, - ) -> None | Unset | UpdateElementRequestClassificationType0: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, str): - raise TypeError() - classification_type_0 = UpdateElementRequestClassificationType0(data) - - return classification_type_0 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(None | Unset | UpdateElementRequestClassificationType0, data) - - classification = _parse_classification(d.pop("classification", UNSET)) - - def _parse_sub_classification(data: object) -> None | str | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - return cast(None | str | Unset, data) - - sub_classification = _parse_sub_classification(d.pop("sub_classification", UNSET)) - def _parse_balance_type( data: object, ) -> None | Unset | UpdateElementRequestBalanceTypeType0: @@ -264,8 +211,6 @@ def _parse_currency(data: object) -> None | str | Unset: code=code, name=name, description=description, - classification=classification, - sub_classification=sub_classification, balance_type=balance_type, period_type=period_type, parent_id=parent_id, diff --git a/robosystems_client/models/update_element_request_classification_type_0.py b/robosystems_client/models/update_element_request_classification_type_0.py deleted file mode 100644 index 200f782..0000000 --- a/robosystems_client/models/update_element_request_classification_type_0.py +++ /dev/null @@ -1,13 +0,0 @@ -from enum import Enum - - -class UpdateElementRequestClassificationType0(str, Enum): - ASSET = "asset" - CASHFLOW = "cashflow" - EQUITY = "equity" - INFLOW = "inflow" - LIABILITY = "liability" - OUTFLOW = "outflow" - - def __str__(self) -> str: - return str(self.value) From 484985bc54ee1f4ab830bff605f419182bc00cad Mon Sep 17 00:00:00 2001 From: "Joseph T. French" Date: Mon, 20 Apr 2026 23:23:54 -0500 Subject: [PATCH 4/4] Add classification support to UpdateElementRequest and related models --- .../op_update_element.py | 28 +++++++++++++ robosystems_client/models/__init__.py | 4 ++ ..._association_operation_association_type.py | 1 + .../models/update_element_request.py | 42 +++++++++++++++++++ ...e_element_request_classification_type_0.py | 22 ++++++++++ 5 files changed, 97 insertions(+) create mode 100644 robosystems_client/models/update_element_request_classification_type_0.py diff --git a/robosystems_client/api/extensions_robo_ledger/op_update_element.py b/robosystems_client/api/extensions_robo_ledger/op_update_element.py index 05912c0..29a5dbc 100644 --- a/robosystems_client/api/extensions_robo_ledger/op_update_element.py +++ b/robosystems_client/api/extensions_robo_ledger/op_update_element.py @@ -123,6 +123,13 @@ def sync_detailed( omit the field to leave unchanged, pass `null` to clear the parent (make root). + ``classification`` updates the element's primary FASB + elementsOfFinancialStatements assignment (in ``element_classifications``, + not a direct column on ``elements``). Omit to leave unchanged. Passing a + value replaces the current primary EFS assignment; there is no + set-to-null semantics (use the UI/admin path for full classification + teardown — here we only support correction of a misclassified account). + Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. @@ -168,6 +175,13 @@ def sync( omit the field to leave unchanged, pass `null` to clear the parent (make root). + ``classification`` updates the element's primary FASB + elementsOfFinancialStatements assignment (in ``element_classifications``, + not a direct column on ``elements``). Omit to leave unchanged. Passing a + value replaces the current primary EFS assignment; there is no + set-to-null semantics (use the UI/admin path for full classification + teardown — here we only support correction of a misclassified account). + Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. @@ -208,6 +222,13 @@ async def asyncio_detailed( omit the field to leave unchanged, pass `null` to clear the parent (make root). + ``classification`` updates the element's primary FASB + elementsOfFinancialStatements assignment (in ``element_classifications``, + not a direct column on ``elements``). Omit to leave unchanged. Passing a + value replaces the current primary EFS assignment; there is no + set-to-null semantics (use the UI/admin path for full classification + teardown — here we only support correction of a misclassified account). + Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. @@ -251,6 +272,13 @@ async def asyncio( omit the field to leave unchanged, pass `null` to clear the parent (make root). + ``classification`` updates the element's primary FASB + elementsOfFinancialStatements assignment (in ``element_classifications``, + not a direct column on ``elements``). Omit to leave unchanged. Passing a + value replaces the current primary EFS assignment; there is no + set-to-null semantics (use the UI/admin path for full classification + teardown — here we only support correction of a misclassified account). + Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. diff --git a/robosystems_client/models/__init__.py b/robosystems_client/models/__init__.py index 0955ffe..41d4406 100644 --- a/robosystems_client/models/__init__.py +++ b/robosystems_client/models/__init__.py @@ -337,6 +337,9 @@ from .update_element_request_balance_type_type_0 import ( UpdateElementRequestBalanceTypeType0, ) +from .update_element_request_classification_type_0 import ( + UpdateElementRequestClassificationType0, +) from .update_element_request_period_type_type_0 import ( UpdateElementRequestPeriodTypeType0, ) @@ -664,6 +667,7 @@ "UpdateAssociationRequest", "UpdateElementRequest", "UpdateElementRequestBalanceTypeType0", + "UpdateElementRequestClassificationType0", "UpdateElementRequestPeriodTypeType0", "UpdateEntityRequest", "UpdateFileResponseUpdatefile", diff --git a/robosystems_client/models/create_mapping_association_operation_association_type.py b/robosystems_client/models/create_mapping_association_operation_association_type.py index 53dd076..5963cab 100644 --- a/robosystems_client/models/create_mapping_association_operation_association_type.py +++ b/robosystems_client/models/create_mapping_association_operation_association_type.py @@ -3,6 +3,7 @@ class CreateMappingAssociationOperationAssociationType(str, Enum): CALCULATION = "calculation" + EQUIVALENCE = "equivalence" MAPPING = "mapping" PRESENTATION = "presentation" diff --git a/robosystems_client/models/update_element_request.py b/robosystems_client/models/update_element_request.py index 9df7196..c44ec66 100644 --- a/robosystems_client/models/update_element_request.py +++ b/robosystems_client/models/update_element_request.py @@ -9,6 +9,9 @@ from ..models.update_element_request_balance_type_type_0 import ( UpdateElementRequestBalanceTypeType0, ) +from ..models.update_element_request_classification_type_0 import ( + UpdateElementRequestClassificationType0, +) from ..models.update_element_request_period_type_type_0 import ( UpdateElementRequestPeriodTypeType0, ) @@ -24,6 +27,13 @@ class UpdateElementRequest: omit the field to leave unchanged, pass `null` to clear the parent (make root). + ``classification`` updates the element's primary FASB + elementsOfFinancialStatements assignment (in ``element_classifications``, + not a direct column on ``elements``). Omit to leave unchanged. Passing a + value replaces the current primary EFS assignment; there is no + set-to-null semantics (use the UI/admin path for full classification + teardown — here we only support correction of a misclassified account). + Attributes: element_id (str): code (None | str | Unset): @@ -33,6 +43,7 @@ class UpdateElementRequest: period_type (None | Unset | UpdateElementRequestPeriodTypeType0): parent_id (None | str | Unset): currency (None | str | Unset): + classification (None | Unset | UpdateElementRequestClassificationType0): """ element_id: str @@ -43,6 +54,7 @@ class UpdateElementRequest: period_type: None | Unset | UpdateElementRequestPeriodTypeType0 = UNSET parent_id: None | str | Unset = UNSET currency: None | str | Unset = UNSET + classification: None | Unset | UpdateElementRequestClassificationType0 = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -94,6 +106,14 @@ def to_dict(self) -> dict[str, Any]: else: currency = self.currency + classification: None | str | Unset + if isinstance(self.classification, Unset): + classification = UNSET + elif isinstance(self.classification, UpdateElementRequestClassificationType0): + classification = self.classification.value + else: + classification = self.classification + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -115,6 +135,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["parent_id"] = parent_id if currency is not UNSET: field_dict["currency"] = currency + if classification is not UNSET: + field_dict["classification"] = classification return field_dict @@ -206,6 +228,25 @@ def _parse_currency(data: object) -> None | str | Unset: currency = _parse_currency(d.pop("currency", UNSET)) + def _parse_classification( + data: object, + ) -> None | Unset | UpdateElementRequestClassificationType0: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + classification_type_0 = UpdateElementRequestClassificationType0(data) + + return classification_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | Unset | UpdateElementRequestClassificationType0, data) + + classification = _parse_classification(d.pop("classification", UNSET)) + update_element_request = cls( element_id=element_id, code=code, @@ -215,6 +256,7 @@ def _parse_currency(data: object) -> None | str | Unset: period_type=period_type, parent_id=parent_id, currency=currency, + classification=classification, ) update_element_request.additional_properties = d diff --git a/robosystems_client/models/update_element_request_classification_type_0.py b/robosystems_client/models/update_element_request_classification_type_0.py new file mode 100644 index 0000000..fbfd4a7 --- /dev/null +++ b/robosystems_client/models/update_element_request_classification_type_0.py @@ -0,0 +1,22 @@ +from enum import Enum + + +class UpdateElementRequestClassificationType0(str, Enum): + ASSET = "asset" + COMPREHENSIVEINCOME = "comprehensiveIncome" + CONTRAASSET = "contraAsset" + CONTRAEQUITY = "contraEquity" + CONTRALIABILITY = "contraLiability" + DISTRIBUTIONTOOWNERS = "distributionToOwners" + EQUITY = "equity" + EXPENSE = "expense" + EXPENSEREVERSAL = "expenseReversal" + GAIN = "gain" + INVESTMENTBYOWNERS = "investmentByOwners" + LIABILITY = "liability" + LOSS = "loss" + REVENUE = "revenue" + TEMPORARYEQUITY = "temporaryEquity" + + def __str__(self) -> str: + return str(self.value)