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/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/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/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/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/__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/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/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 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.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 894a6aa..fbd51b4 100644 --- a/robosystems_client/models/create_element_request_classification.py +++ b/robosystems_client/models/create_element_request_classification.py @@ -3,10 +3,20 @@ class CreateElementRequestClassification(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) diff --git a/robosystems_client/models/create_element_request_source.py b/robosystems_client/models/create_element_request_source.py index 40faa2e..70c28d1 100644 --- a/robosystems_client/models/create_element_request_source.py +++ b/robosystems_client/models/create_element_request_source.py @@ -2,12 +2,13 @@ class CreateElementRequestSource(str, Enum): + FAC = "fac" IFRS = "ifrs" IMPORT = "import" NATIVE = "native" PLAID = "plaid" QUICKBOOKS = "quickbooks" - SFAC6 = "sfac6" + RS_GAAP = "rs-gaap" 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/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/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.py b/robosystems_client/models/update_element_request.py index 32e443a..c44ec66 100644 --- a/robosystems_client/models/update_element_request.py +++ b/robosystems_client/models/update_element_request.py @@ -27,29 +27,34 @@ 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): 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): currency (None | str | Unset): + classification (None | Unset | UpdateElementRequestClassificationType0): """ element_id: str 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 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]: @@ -73,20 +78,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 @@ -115,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( @@ -128,10 +127,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: @@ -140,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 @@ -175,34 +172,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: @@ -259,17 +228,35 @@ 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, name=name, description=description, - classification=classification, - sub_classification=sub_classification, balance_type=balance_type, 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 index 588160d..fbfd4a7 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,20 @@ 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) 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."""