From 3773632b87773041d5d8acc0624140938b99e0fe Mon Sep 17 00:00:00 2001 From: Sam Minot Date: Wed, 23 Sep 2026 10:14:37 -0700 Subject: [PATCH] Sync api client Bring in changes for: - Structured file inputs on process parameters - Project file query endpoints - Tenant metrics - User activation and status - Paginated audit events - Cost breakdown by source and component - Process execution modes and maintainers - Sheet ingest conflict handling Co-Authored-By: Claude Opus 5 --- cirro_api_client/v1/api/audit/list_events.py | 59 ++- .../v1/api/file/get_project_file.py | 180 +++++++ .../v1/api/file/query_project_files.py | 443 ++++++++++++++++++ .../v1/api/metrics/get_metrics_summary.py | 135 ++++++ .../api/processes/get_process_parameters.py | 24 +- .../v1/api/users/activate_user.py | 101 ++++ .../v1/api/users/deactivate_user.py | 116 +++++ cirro_api_client/v1/models/__init__.py | 54 ++- cirro_api_client/v1/models/audit_event.py | 18 + cirro_api_client/v1/models/column_def.py | 12 +- .../v1/models/column_relationship.py | 78 +++ cirro_api_client/v1/models/cost_component.py | 15 + cirro_api_client/v1/models/cost_response.py | 81 +++- cirro_api_client/v1/models/cost_source.py | 15 + .../v1/models/custom_process_input.py | 71 +++ cirro_api_client/v1/models/dataset_source.py | 15 + cirro_api_client/v1/models/execution_mode.py | 15 + cirro_api_client/v1/models/feature_flags.py | 16 + cirro_api_client/v1/models/file_format.py | 16 + cirro_api_client/v1/models/form_schema.py | 20 +- cirro_api_client/v1/models/form_schema_ui.py | 2 +- .../v1/models/ingest_conflict_mode.py | 16 + .../v1/models/input_file_requirement.py | 126 +++++ ....py => input_file_requirement_examples.py} | 10 +- ...ty.py => input_file_requirement_schema.py} | 12 +- ... => paginated_response_audit_event_dto.py} | 65 ++- cirro_api_client/v1/models/permission.py | 2 + cirro_api_client/v1/models/pipeline_code.py | 3 +- cirro_api_client/v1/models/process.py | 49 ++ cirro_api_client/v1/models/process_detail.py | 49 ++ .../v1/models/process_parameter_schema.py | 115 +++++ .../models/process_parameter_schema_form.py | 47 ++ ...arameter_schema_input_file_requirements.py | 63 +++ .../v1/models/process_parameter_schema_ui.py | 47 ++ .../v1/models/process_resource.py | 1 - cirro_api_client/v1/models/project_detail.py | 20 + cirro_api_client/v1/models/project_file.py | 152 ++++++ .../v1/models/project_file_query_response.py | 117 +++++ cirro_api_client/v1/models/row_insert.py | 5 +- .../v1/models/row_insert_values.py | 34 +- cirro_api_client/v1/models/row_update.py | 5 +- .../v1/models/row_update_values.py | 31 +- .../v1/models/run_analysis_request.py | 66 +++ ...analysis_request_structured_file_inputs.py | 60 +++ .../v1/models/semantic_column_type.py | 7 +- cirro_api_client/v1/models/sheet.py | 58 ++- .../v1/models/sheet_creation_mode.py | 1 + .../v1/models/sheet_data_request.py | 3 +- cirro_api_client/v1/models/sheet_detail.py | 44 +- .../v1/models/sheet_ingest_request.py | 59 ++- .../v1/models/sheet_query_request.py | 32 +- cirro_api_client/v1/models/source_column.py | 22 + .../v1/models/structured_file_input.py | 84 ++++ ....py => structured_file_input_data_item.py} | 12 +- .../v1/models/system_info_response.py | 124 +++-- cirro_api_client/v1/models/tenant_metrics.py | 101 ++++ cirro_api_client/v1/models/user.py | 10 + cirro_api_client/v1/models/user_detail.py | 9 + cirro_api_client/v1/models/user_status.py | 16 + cirro_api_client/v1/models/version_info.py | 102 ++++ .../v1/models/view_sheet_input.py | 10 + .../v1/models/workspace_compute_config.py | 54 +++ config.yml | 4 + pyproject.toml | 2 +- tests/test_client.py | 1 + 65 files changed, 3117 insertions(+), 219 deletions(-) create mode 100644 cirro_api_client/v1/api/file/get_project_file.py create mode 100644 cirro_api_client/v1/api/file/query_project_files.py create mode 100644 cirro_api_client/v1/api/metrics/get_metrics_summary.py create mode 100644 cirro_api_client/v1/api/users/activate_user.py create mode 100644 cirro_api_client/v1/api/users/deactivate_user.py create mode 100644 cirro_api_client/v1/models/column_relationship.py create mode 100644 cirro_api_client/v1/models/cost_component.py create mode 100644 cirro_api_client/v1/models/cost_source.py create mode 100644 cirro_api_client/v1/models/dataset_source.py create mode 100644 cirro_api_client/v1/models/execution_mode.py create mode 100644 cirro_api_client/v1/models/file_format.py create mode 100644 cirro_api_client/v1/models/ingest_conflict_mode.py create mode 100644 cirro_api_client/v1/models/input_file_requirement.py rename cirro_api_client/v1/models/{row_insert_values_additional_property.py => input_file_requirement_examples.py} (79%) rename cirro_api_client/v1/models/{row_update_values_additional_property.py => input_file_requirement_schema.py} (77%) rename cirro_api_client/v1/models/{resources_info.py => paginated_response_audit_event_dto.py} (51%) create mode 100644 cirro_api_client/v1/models/process_parameter_schema.py create mode 100644 cirro_api_client/v1/models/process_parameter_schema_form.py create mode 100644 cirro_api_client/v1/models/process_parameter_schema_input_file_requirements.py create mode 100644 cirro_api_client/v1/models/process_parameter_schema_ui.py create mode 100644 cirro_api_client/v1/models/project_file.py create mode 100644 cirro_api_client/v1/models/project_file_query_response.py create mode 100644 cirro_api_client/v1/models/run_analysis_request_structured_file_inputs.py create mode 100644 cirro_api_client/v1/models/structured_file_input.py rename cirro_api_client/v1/models/{form_schema_metadata_requirements.py => structured_file_input_data_item.py} (76%) create mode 100644 cirro_api_client/v1/models/tenant_metrics.py create mode 100644 cirro_api_client/v1/models/user_status.py create mode 100644 cirro_api_client/v1/models/version_info.py diff --git a/cirro_api_client/v1/api/audit/list_events.py b/cirro_api_client/v1/api/audit/list_events.py index d6d3e87..20d90ec 100644 --- a/cirro_api_client/v1/api/audit/list_events.py +++ b/cirro_api_client/v1/api/audit/list_events.py @@ -5,8 +5,8 @@ from ... import errors from ...client import Client -from ...models.audit_event import AuditEvent from ...models.list_events_entity_type import ListEventsEntityType +from ...models.paginated_response_audit_event_dto import PaginatedResponseAuditEventDto from ...types import UNSET, Response, Unset @@ -15,6 +15,8 @@ def _get_kwargs( username: str | Unset = UNSET, entity_type: ListEventsEntityType | Unset = UNSET, entity_id: str | Unset = UNSET, + limit: int | Unset = 5000, + next_token: str | Unset = UNSET, ) -> dict[str, Any]: params: dict[str, Any] = {} @@ -28,6 +30,10 @@ def _get_kwargs( params["entityId"] = entity_id + params["limit"] = limit + + params["nextToken"] = next_token + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} _kwargs: dict[str, Any] = { @@ -39,21 +45,16 @@ def _get_kwargs( return _kwargs -def _parse_response(*, client: Client, response: httpx.Response) -> list[AuditEvent] | None: +def _parse_response(*, client: Client, response: httpx.Response) -> PaginatedResponseAuditEventDto | None: if response.status_code == 200: - response_200 = [] - _response_200 = response.json() - for response_200_item_data in _response_200: - response_200_item = AuditEvent.from_dict(response_200_item_data) - - response_200.append(response_200_item) + response_200 = PaginatedResponseAuditEventDto.from_dict(response.json()) return response_200 errors.handle_error_response(response, client.raise_on_unexpected_status) -def _build_response(*, client: Client, response: httpx.Response) -> Response[list[AuditEvent]]: +def _build_response(*, client: Client, response: httpx.Response) -> Response[PaginatedResponseAuditEventDto]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -68,7 +69,9 @@ def sync_detailed( username: str | Unset = UNSET, entity_type: ListEventsEntityType | Unset = UNSET, entity_id: str | Unset = UNSET, -) -> Response[list[AuditEvent]]: + limit: int | Unset = 5000, + next_token: str | Unset = UNSET, +) -> Response[PaginatedResponseAuditEventDto]: """List audit events Gets a list of audit events @@ -77,6 +80,8 @@ def sync_detailed( username (str | Unset): entity_type (ListEventsEntityType | Unset): entity_id (str | Unset): + limit (int | Unset): Default: 5000. + next_token (str | Unset): client (Client): instance of the API client Raises: @@ -84,13 +89,15 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[list[AuditEvent]] + Response[PaginatedResponseAuditEventDto] """ kwargs = _get_kwargs( username=username, entity_type=entity_type, entity_id=entity_id, + limit=limit, + next_token=next_token, ) response = client.get_httpx_client().request( @@ -107,7 +114,9 @@ def sync( username: str | Unset = UNSET, entity_type: ListEventsEntityType | Unset = UNSET, entity_id: str | Unset = UNSET, -) -> list[AuditEvent] | None: + limit: int | Unset = 5000, + next_token: str | Unset = UNSET, +) -> PaginatedResponseAuditEventDto | None: """List audit events Gets a list of audit events @@ -116,6 +125,8 @@ def sync( username (str | Unset): entity_type (ListEventsEntityType | Unset): entity_id (str | Unset): + limit (int | Unset): Default: 5000. + next_token (str | Unset): client (Client): instance of the API client Raises: @@ -123,7 +134,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - list[AuditEvent] + PaginatedResponseAuditEventDto """ try: @@ -132,6 +143,8 @@ def sync( username=username, entity_type=entity_type, entity_id=entity_id, + limit=limit, + next_token=next_token, ).parsed except errors.NotFoundException: return None @@ -143,7 +156,9 @@ async def asyncio_detailed( username: str | Unset = UNSET, entity_type: ListEventsEntityType | Unset = UNSET, entity_id: str | Unset = UNSET, -) -> Response[list[AuditEvent]]: + limit: int | Unset = 5000, + next_token: str | Unset = UNSET, +) -> Response[PaginatedResponseAuditEventDto]: """List audit events Gets a list of audit events @@ -152,6 +167,8 @@ async def asyncio_detailed( username (str | Unset): entity_type (ListEventsEntityType | Unset): entity_id (str | Unset): + limit (int | Unset): Default: 5000. + next_token (str | Unset): client (Client): instance of the API client Raises: @@ -159,13 +176,15 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[list[AuditEvent]] + Response[PaginatedResponseAuditEventDto] """ kwargs = _get_kwargs( username=username, entity_type=entity_type, entity_id=entity_id, + limit=limit, + next_token=next_token, ) response = await client.get_async_httpx_client().request(auth=client.get_auth(), **kwargs) @@ -179,7 +198,9 @@ async def asyncio( username: str | Unset = UNSET, entity_type: ListEventsEntityType | Unset = UNSET, entity_id: str | Unset = UNSET, -) -> list[AuditEvent] | None: + limit: int | Unset = 5000, + next_token: str | Unset = UNSET, +) -> PaginatedResponseAuditEventDto | None: """List audit events Gets a list of audit events @@ -188,6 +209,8 @@ async def asyncio( username (str | Unset): entity_type (ListEventsEntityType | Unset): entity_id (str | Unset): + limit (int | Unset): Default: 5000. + next_token (str | Unset): client (Client): instance of the API client Raises: @@ -195,7 +218,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - list[AuditEvent] + PaginatedResponseAuditEventDto """ try: @@ -205,6 +228,8 @@ async def asyncio( username=username, entity_type=entity_type, entity_id=entity_id, + limit=limit, + next_token=next_token, ) ).parsed except errors.NotFoundException: diff --git a/cirro_api_client/v1/api/file/get_project_file.py b/cirro_api_client/v1/api/file/get_project_file.py new file mode 100644 index 0000000..777814f --- /dev/null +++ b/cirro_api_client/v1/api/file/get_project_file.py @@ -0,0 +1,180 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import Client +from ...models.project_file import ProjectFile +from ...types import Response + + +def _get_kwargs( + project_id: str, + dataset_id: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/projects/{project_id}/files/{dataset_id}/path".format( + project_id=quote(str(project_id), safe=""), + dataset_id=quote(str(dataset_id), safe=""), + ), + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> ProjectFile | None: + if response.status_code == 200: + response_200 = ProjectFile.from_dict(response.json()) + + return response_200 + + errors.handle_error_response(response, client.raise_on_unexpected_status) + + +def _build_response(*, client: Client, response: httpx.Response) -> Response[ProjectFile]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + project_id: str, + dataset_id: str, + *, + client: Client, +) -> Response[ProjectFile]: + """Get a project file + + Fetches details on a single file given its dataset ID and relative path. + + Args: + project_id (str): + dataset_id (str): + client (Client): instance of the API client + + 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[ProjectFile] + """ + + kwargs = _get_kwargs( + project_id=project_id, + dataset_id=dataset_id, + ) + + response = client.get_httpx_client().request( + auth=client.get_auth(), + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + project_id: str, + dataset_id: str, + *, + client: Client, +) -> ProjectFile | None: + """Get a project file + + Fetches details on a single file given its dataset ID and relative path. + + Args: + project_id (str): + dataset_id (str): + client (Client): instance of the API client + + 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: + ProjectFile + """ + + try: + return sync_detailed( + project_id=project_id, + dataset_id=dataset_id, + client=client, + ).parsed + except errors.NotFoundException: + return None + + +async def asyncio_detailed( + project_id: str, + dataset_id: str, + *, + client: Client, +) -> Response[ProjectFile]: + """Get a project file + + Fetches details on a single file given its dataset ID and relative path. + + Args: + project_id (str): + dataset_id (str): + client (Client): instance of the API client + + 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[ProjectFile] + """ + + kwargs = _get_kwargs( + project_id=project_id, + dataset_id=dataset_id, + ) + + response = await client.get_async_httpx_client().request(auth=client.get_auth(), **kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + project_id: str, + dataset_id: str, + *, + client: Client, +) -> ProjectFile | None: + """Get a project file + + Fetches details on a single file given its dataset ID and relative path. + + Args: + project_id (str): + dataset_id (str): + client (Client): instance of the API client + + 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: + ProjectFile + """ + + try: + return ( + await asyncio_detailed( + project_id=project_id, + dataset_id=dataset_id, + client=client, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/file/query_project_files.py b/cirro_api_client/v1/api/file/query_project_files.py new file mode 100644 index 0000000..bfc2acb --- /dev/null +++ b/cirro_api_client/v1/api/file/query_project_files.py @@ -0,0 +1,443 @@ +import datetime +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import Client +from ...models.dataset_source import DatasetSource +from ...models.project_file_query_response import ProjectFileQueryResponse +from ...models.sql_sort_order import SqlSortOrder +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + project_id: str, + *, + source: DatasetSource | None | Unset = UNSET, + file_type: None | str | Unset = UNSET, + dataset_id: None | str | Unset = UNSET, + process_id: None | str | Unset = UNSET, + created_by: None | str | Unset = UNSET, + path_contains: None | str | Unset = UNSET, + min_size: int | None | Unset = UNSET, + max_size: int | None | Unset = UNSET, + created_after: datetime.datetime | None | Unset = UNSET, + created_before: datetime.datetime | None | Unset = UNSET, + sort_order: None | SqlSortOrder | Unset = UNSET, + limit: int | None | Unset = UNSET, + next_token: None | str | Unset = UNSET, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + json_source: None | str | Unset + if isinstance(source, Unset): + json_source = UNSET + elif isinstance(source, DatasetSource): + json_source = source.value + else: + json_source = source + params["source"] = json_source + + json_file_type: None | str | Unset + if isinstance(file_type, Unset): + json_file_type = UNSET + else: + json_file_type = file_type + params["fileType"] = json_file_type + + json_dataset_id: None | str | Unset + if isinstance(dataset_id, Unset): + json_dataset_id = UNSET + else: + json_dataset_id = dataset_id + params["datasetId"] = json_dataset_id + + json_process_id: None | str | Unset + if isinstance(process_id, Unset): + json_process_id = UNSET + else: + json_process_id = process_id + params["processId"] = json_process_id + + json_created_by: None | str | Unset + if isinstance(created_by, Unset): + json_created_by = UNSET + else: + json_created_by = created_by + params["createdBy"] = json_created_by + + json_path_contains: None | str | Unset + if isinstance(path_contains, Unset): + json_path_contains = UNSET + else: + json_path_contains = path_contains + params["pathContains"] = json_path_contains + + json_min_size: int | None | Unset + if isinstance(min_size, Unset): + json_min_size = UNSET + else: + json_min_size = min_size + params["minSize"] = json_min_size + + json_max_size: int | None | Unset + if isinstance(max_size, Unset): + json_max_size = UNSET + else: + json_max_size = max_size + params["maxSize"] = json_max_size + + json_created_after: None | str | Unset + if isinstance(created_after, Unset): + json_created_after = UNSET + elif isinstance(created_after, datetime.datetime): + json_created_after = created_after.isoformat() + else: + json_created_after = created_after + params["createdAfter"] = json_created_after + + json_created_before: None | str | Unset + if isinstance(created_before, Unset): + json_created_before = UNSET + elif isinstance(created_before, datetime.datetime): + json_created_before = created_before.isoformat() + else: + json_created_before = created_before + params["createdBefore"] = json_created_before + + json_sort_order: None | str | Unset + if isinstance(sort_order, Unset): + json_sort_order = UNSET + elif isinstance(sort_order, SqlSortOrder): + json_sort_order = sort_order.value + else: + json_sort_order = sort_order + params["sortOrder"] = json_sort_order + + json_limit: int | None | Unset + if isinstance(limit, Unset): + json_limit = UNSET + else: + json_limit = limit + params["limit"] = json_limit + + json_next_token: None | str | Unset + if isinstance(next_token, Unset): + json_next_token = UNSET + else: + json_next_token = next_token + params["nextToken"] = json_next_token + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/projects/{project_id}/files".format( + project_id=quote(str(project_id), safe=""), + ), + "params": params, + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> ProjectFileQueryResponse | None: + if response.status_code == 200: + response_200 = ProjectFileQueryResponse.from_dict(response.json()) + + return response_200 + + errors.handle_error_response(response, client.raise_on_unexpected_status) + + +def _build_response(*, client: Client, response: httpx.Response) -> Response[ProjectFileQueryResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + project_id: str, + *, + client: Client, + source: DatasetSource | None | Unset = UNSET, + file_type: None | str | Unset = UNSET, + dataset_id: None | str | Unset = UNSET, + process_id: None | str | Unset = UNSET, + created_by: None | str | Unset = UNSET, + path_contains: None | str | Unset = UNSET, + min_size: int | None | Unset = UNSET, + max_size: int | None | Unset = UNSET, + created_after: datetime.datetime | None | Unset = UNSET, + created_before: datetime.datetime | None | Unset = UNSET, + sort_order: None | SqlSortOrder | Unset = UNSET, + limit: int | None | Unset = UNSET, + next_token: None | str | Unset = UNSET, +) -> Response[ProjectFileQueryResponse]: + """Search project files + + Queries the project for files, with optional filtering, sorting, and pagination. + + Args: + project_id (str): + source (DatasetSource | None | Unset): + file_type (None | str | Unset): + dataset_id (None | str | Unset): + process_id (None | str | Unset): + created_by (None | str | Unset): + path_contains (None | str | Unset): + min_size (int | None | Unset): + max_size (int | None | Unset): + created_after (datetime.datetime | None | Unset): + created_before (datetime.datetime | None | Unset): + sort_order (None | SqlSortOrder | Unset): + limit (int | None | Unset): + next_token (None | str | Unset): + client (Client): instance of the API client + + 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[ProjectFileQueryResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + source=source, + file_type=file_type, + dataset_id=dataset_id, + process_id=process_id, + created_by=created_by, + path_contains=path_contains, + min_size=min_size, + max_size=max_size, + created_after=created_after, + created_before=created_before, + sort_order=sort_order, + limit=limit, + next_token=next_token, + ) + + response = client.get_httpx_client().request( + auth=client.get_auth(), + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + project_id: str, + *, + client: Client, + source: DatasetSource | None | Unset = UNSET, + file_type: None | str | Unset = UNSET, + dataset_id: None | str | Unset = UNSET, + process_id: None | str | Unset = UNSET, + created_by: None | str | Unset = UNSET, + path_contains: None | str | Unset = UNSET, + min_size: int | None | Unset = UNSET, + max_size: int | None | Unset = UNSET, + created_after: datetime.datetime | None | Unset = UNSET, + created_before: datetime.datetime | None | Unset = UNSET, + sort_order: None | SqlSortOrder | Unset = UNSET, + limit: int | None | Unset = UNSET, + next_token: None | str | Unset = UNSET, +) -> ProjectFileQueryResponse | None: + """Search project files + + Queries the project for files, with optional filtering, sorting, and pagination. + + Args: + project_id (str): + source (DatasetSource | None | Unset): + file_type (None | str | Unset): + dataset_id (None | str | Unset): + process_id (None | str | Unset): + created_by (None | str | Unset): + path_contains (None | str | Unset): + min_size (int | None | Unset): + max_size (int | None | Unset): + created_after (datetime.datetime | None | Unset): + created_before (datetime.datetime | None | Unset): + sort_order (None | SqlSortOrder | Unset): + limit (int | None | Unset): + next_token (None | str | Unset): + client (Client): instance of the API client + + 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: + ProjectFileQueryResponse + """ + + try: + return sync_detailed( + project_id=project_id, + client=client, + source=source, + file_type=file_type, + dataset_id=dataset_id, + process_id=process_id, + created_by=created_by, + path_contains=path_contains, + min_size=min_size, + max_size=max_size, + created_after=created_after, + created_before=created_before, + sort_order=sort_order, + limit=limit, + next_token=next_token, + ).parsed + except errors.NotFoundException: + return None + + +async def asyncio_detailed( + project_id: str, + *, + client: Client, + source: DatasetSource | None | Unset = UNSET, + file_type: None | str | Unset = UNSET, + dataset_id: None | str | Unset = UNSET, + process_id: None | str | Unset = UNSET, + created_by: None | str | Unset = UNSET, + path_contains: None | str | Unset = UNSET, + min_size: int | None | Unset = UNSET, + max_size: int | None | Unset = UNSET, + created_after: datetime.datetime | None | Unset = UNSET, + created_before: datetime.datetime | None | Unset = UNSET, + sort_order: None | SqlSortOrder | Unset = UNSET, + limit: int | None | Unset = UNSET, + next_token: None | str | Unset = UNSET, +) -> Response[ProjectFileQueryResponse]: + """Search project files + + Queries the project for files, with optional filtering, sorting, and pagination. + + Args: + project_id (str): + source (DatasetSource | None | Unset): + file_type (None | str | Unset): + dataset_id (None | str | Unset): + process_id (None | str | Unset): + created_by (None | str | Unset): + path_contains (None | str | Unset): + min_size (int | None | Unset): + max_size (int | None | Unset): + created_after (datetime.datetime | None | Unset): + created_before (datetime.datetime | None | Unset): + sort_order (None | SqlSortOrder | Unset): + limit (int | None | Unset): + next_token (None | str | Unset): + client (Client): instance of the API client + + 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[ProjectFileQueryResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + source=source, + file_type=file_type, + dataset_id=dataset_id, + process_id=process_id, + created_by=created_by, + path_contains=path_contains, + min_size=min_size, + max_size=max_size, + created_after=created_after, + created_before=created_before, + sort_order=sort_order, + limit=limit, + next_token=next_token, + ) + + response = await client.get_async_httpx_client().request(auth=client.get_auth(), **kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + project_id: str, + *, + client: Client, + source: DatasetSource | None | Unset = UNSET, + file_type: None | str | Unset = UNSET, + dataset_id: None | str | Unset = UNSET, + process_id: None | str | Unset = UNSET, + created_by: None | str | Unset = UNSET, + path_contains: None | str | Unset = UNSET, + min_size: int | None | Unset = UNSET, + max_size: int | None | Unset = UNSET, + created_after: datetime.datetime | None | Unset = UNSET, + created_before: datetime.datetime | None | Unset = UNSET, + sort_order: None | SqlSortOrder | Unset = UNSET, + limit: int | None | Unset = UNSET, + next_token: None | str | Unset = UNSET, +) -> ProjectFileQueryResponse | None: + """Search project files + + Queries the project for files, with optional filtering, sorting, and pagination. + + Args: + project_id (str): + source (DatasetSource | None | Unset): + file_type (None | str | Unset): + dataset_id (None | str | Unset): + process_id (None | str | Unset): + created_by (None | str | Unset): + path_contains (None | str | Unset): + min_size (int | None | Unset): + max_size (int | None | Unset): + created_after (datetime.datetime | None | Unset): + created_before (datetime.datetime | None | Unset): + sort_order (None | SqlSortOrder | Unset): + limit (int | None | Unset): + next_token (None | str | Unset): + client (Client): instance of the API client + + 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: + ProjectFileQueryResponse + """ + + try: + return ( + await asyncio_detailed( + project_id=project_id, + client=client, + source=source, + file_type=file_type, + dataset_id=dataset_id, + process_id=process_id, + created_by=created_by, + path_contains=path_contains, + min_size=min_size, + max_size=max_size, + created_after=created_after, + created_before=created_before, + sort_order=sort_order, + limit=limit, + next_token=next_token, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/metrics/get_metrics_summary.py b/cirro_api_client/v1/api/metrics/get_metrics_summary.py new file mode 100644 index 0000000..166d02c --- /dev/null +++ b/cirro_api_client/v1/api/metrics/get_metrics_summary.py @@ -0,0 +1,135 @@ +from http import HTTPStatus +from typing import Any + +import httpx + +from ... import errors +from ...client import Client +from ...models.tenant_metrics import TenantMetrics +from ...types import Response + + +def _get_kwargs() -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/metrics-summary", + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> TenantMetrics | None: + if response.status_code == 200: + response_200 = TenantMetrics.from_dict(response.json()) + + return response_200 + + errors.handle_error_response(response, client.raise_on_unexpected_status) + + +def _build_response(*, client: Client, response: httpx.Response) -> Response[TenantMetrics]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Client, +) -> Response[TenantMetrics]: + """Get tenant metric summary + + Retrieves summary of tenant (item counts) + + 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[TenantMetrics] + """ + + kwargs = _get_kwargs() + + response = client.get_httpx_client().request( + auth=client.get_auth(), + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Client, +) -> TenantMetrics | None: + """Get tenant metric summary + + Retrieves summary of tenant (item counts) + + 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: + TenantMetrics + """ + + try: + return sync_detailed( + client=client, + ).parsed + except errors.NotFoundException: + return None + + +async def asyncio_detailed( + *, + client: Client, +) -> Response[TenantMetrics]: + """Get tenant metric summary + + Retrieves summary of tenant (item counts) + + 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[TenantMetrics] + """ + + kwargs = _get_kwargs() + + response = await client.get_async_httpx_client().request(auth=client.get_auth(), **kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Client, +) -> TenantMetrics | None: + """Get tenant metric summary + + Retrieves summary of tenant (item counts) + + 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: + TenantMetrics + """ + + try: + return ( + await asyncio_detailed( + client=client, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/processes/get_process_parameters.py b/cirro_api_client/v1/api/processes/get_process_parameters.py index 996ee9e..0c37d5f 100644 --- a/cirro_api_client/v1/api/processes/get_process_parameters.py +++ b/cirro_api_client/v1/api/processes/get_process_parameters.py @@ -6,7 +6,7 @@ from ... import errors from ...client import Client -from ...models.form_schema import FormSchema +from ...models.process_parameter_schema import ProcessParameterSchema from ...types import Response @@ -23,16 +23,16 @@ def _get_kwargs( return _kwargs -def _parse_response(*, client: Client, response: httpx.Response) -> FormSchema | None: +def _parse_response(*, client: Client, response: httpx.Response) -> ProcessParameterSchema | None: if response.status_code == 200: - response_200 = FormSchema.from_dict(response.json()) + response_200 = ProcessParameterSchema.from_dict(response.json()) return response_200 errors.handle_error_response(response, client.raise_on_unexpected_status) -def _build_response(*, client: Client, response: httpx.Response) -> Response[FormSchema]: +def _build_response(*, client: Client, response: httpx.Response) -> Response[ProcessParameterSchema]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -45,7 +45,7 @@ def sync_detailed( process_id: str, *, client: Client, -) -> Response[FormSchema]: +) -> Response[ProcessParameterSchema]: """Get process parameters Retrieves the input parameters for a process @@ -59,7 +59,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[FormSchema] + Response[ProcessParameterSchema] """ kwargs = _get_kwargs( @@ -78,7 +78,7 @@ def sync( process_id: str, *, client: Client, -) -> FormSchema | None: +) -> ProcessParameterSchema | None: """Get process parameters Retrieves the input parameters for a process @@ -92,7 +92,7 @@ def sync( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - FormSchema + ProcessParameterSchema """ try: @@ -108,7 +108,7 @@ async def asyncio_detailed( process_id: str, *, client: Client, -) -> Response[FormSchema]: +) -> Response[ProcessParameterSchema]: """Get process parameters Retrieves the input parameters for a process @@ -122,7 +122,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[FormSchema] + Response[ProcessParameterSchema] """ kwargs = _get_kwargs( @@ -138,7 +138,7 @@ async def asyncio( process_id: str, *, client: Client, -) -> FormSchema | None: +) -> ProcessParameterSchema | None: """Get process parameters Retrieves the input parameters for a process @@ -152,7 +152,7 @@ async def asyncio( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - FormSchema + ProcessParameterSchema """ try: diff --git a/cirro_api_client/v1/api/users/activate_user.py b/cirro_api_client/v1/api/users/activate_user.py new file mode 100644 index 0000000..f592aba --- /dev/null +++ b/cirro_api_client/v1/api/users/activate_user.py @@ -0,0 +1,101 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import Client +from ...types import Response + + +def _get_kwargs( + username: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "put", + "url": "/users/{username}:activate".format( + username=quote(str(username), safe=""), + ), + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> Any | None: + if response.status_code == 200: + return None + + errors.handle_error_response(response, client.raise_on_unexpected_status) + + +def _build_response(*, client: Client, response: httpx.Response) -> Response[Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + username: str, + *, + client: Client, +) -> Response[Any]: + """Activate user + + Activate user a previously disabled user + + Args: + username (str): + client (Client): instance of the API client + + 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[Any] + """ + + kwargs = _get_kwargs( + username=username, + ) + + response = client.get_httpx_client().request( + auth=client.get_auth(), + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + username: str, + *, + client: Client, +) -> Response[Any]: + """Activate user + + Activate user a previously disabled user + + Args: + username (str): + client (Client): instance of the API client + + 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[Any] + """ + + kwargs = _get_kwargs( + username=username, + ) + + response = await client.get_async_httpx_client().request(auth=client.get_auth(), **kwargs) + + return _build_response(client=client, response=response) diff --git a/cirro_api_client/v1/api/users/deactivate_user.py b/cirro_api_client/v1/api/users/deactivate_user.py new file mode 100644 index 0000000..63e3aac --- /dev/null +++ b/cirro_api_client/v1/api/users/deactivate_user.py @@ -0,0 +1,116 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import Client +from ...types import UNSET, Response, Unset + + +def _get_kwargs( + username: str, + *, + remove_from_projects: bool | Unset = False, +) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["removeFromProjects"] = remove_from_projects + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + + _kwargs: dict[str, Any] = { + "method": "put", + "url": "/users/{username}:deactivate".format( + username=quote(str(username), safe=""), + ), + "params": params, + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> Any | None: + if response.status_code == 200: + return None + + errors.handle_error_response(response, client.raise_on_unexpected_status) + + +def _build_response(*, client: Client, response: httpx.Response) -> Response[Any]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + username: str, + *, + client: Client, + remove_from_projects: bool | Unset = False, +) -> Response[Any]: + """Deactivate user + + Deactivates a user, blocking sign in and revoking their tokens + + Args: + username (str): + remove_from_projects (bool | Unset): Default: False. + client (Client): instance of the API client + + 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[Any] + """ + + kwargs = _get_kwargs( + username=username, + remove_from_projects=remove_from_projects, + ) + + response = client.get_httpx_client().request( + auth=client.get_auth(), + **kwargs, + ) + + return _build_response(client=client, response=response) + + +async def asyncio_detailed( + username: str, + *, + client: Client, + remove_from_projects: bool | Unset = False, +) -> Response[Any]: + """Deactivate user + + Deactivates a user, blocking sign in and revoking their tokens + + Args: + username (str): + remove_from_projects (bool | Unset): Default: False. + client (Client): instance of the API client + + 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[Any] + """ + + kwargs = _get_kwargs( + username=username, + remove_from_projects=remove_from_projects, + ) + + response = await client.get_async_httpx_client().request(auth=client.get_auth(), **kwargs) + + return _build_response(client=client, response=response) diff --git a/cirro_api_client/v1/models/__init__.py b/cirro_api_client/v1/models/__init__.py index 924a823..c0d4b2a 100644 --- a/cirro_api_client/v1/models/__init__.py +++ b/cirro_api_client/v1/models/__init__.py @@ -40,6 +40,7 @@ from .column_data_type import ColumnDataType from .column_def import ColumnDef from .column_definition import ColumnDefinition +from .column_relationship import ColumnRelationship from .compute_environment_configuration import ComputeEnvironmentConfiguration from .compute_environment_configuration_input import ComputeEnvironmentConfigurationInput from .compute_environment_configuration_input_properties import ComputeEnvironmentConfigurationInputProperties @@ -47,7 +48,9 @@ from .config_source import ConfigSource from .contact import Contact from .contact_input import ContactInput +from .cost_component import CostComponent from .cost_response import CostResponse +from .cost_source import CostSource from .create_project_access_request import CreateProjectAccessRequest from .create_reference_request import CreateReferenceRequest from .create_response import CreateResponse @@ -70,6 +73,7 @@ from .dataset_detail_info import DatasetDetailInfo from .dataset_detail_params import DatasetDetailParams from .dataset_detail_source_sample_files_map import DatasetDetailSourceSampleFilesMap +from .dataset_source import DatasetSource from .dataset_viz import DatasetViz from .delete_rows_request import DeleteRowsRequest from .discussion import Discussion @@ -79,11 +83,13 @@ from .entity_type import EntityType from .environment_type import EnvironmentType from .error_message import ErrorMessage +from .execution_mode import ExecutionMode from .executor import Executor from .feature_flags import FeatureFlags from .file_def import FileDef from .file_entry import FileEntry from .file_entry_metadata import FileEntryMetadata +from .file_format import FileFormat from .file_mapping_rule import FileMappingRule from .file_name_match import FileNameMatch from .file_name_pattern import FileNamePattern @@ -94,7 +100,6 @@ from .foreign_key_ref import ForeignKeyRef from .form_schema import FormSchema from .form_schema_form import FormSchemaForm -from .form_schema_metadata_requirements import FormSchemaMetadataRequirements from .form_schema_ui import FormSchemaUi from .fulfillment_response import FulfillmentResponse from .generate_sftp_credentials_request import GenerateSftpCredentialsRequest @@ -118,6 +123,10 @@ from .group_cost import GroupCost from .import_data_request import ImportDataRequest from .import_data_request_download_method import ImportDataRequestDownloadMethod +from .ingest_conflict_mode import IngestConflictMode +from .input_file_requirement import InputFileRequirement +from .input_file_requirement_examples import InputFileRequirementExamples +from .input_file_requirement_schema import InputFileRequirementSchema from .insert_rows_request import InsertRowsRequest from .invite_user_request import InviteUserRequest from .invite_user_response import InviteUserResponse @@ -137,6 +146,7 @@ from .move_dataset_response import MoveDatasetResponse from .named_item import NamedItem from .paginated_response_app_registration_dto import PaginatedResponseAppRegistrationDto +from .paginated_response_audit_event_dto import PaginatedResponseAuditEventDto from .paginated_response_dataset_list_dto import PaginatedResponseDatasetListDto from .paginated_response_discussion import PaginatedResponseDiscussion from .paginated_response_message import PaginatedResponseMessage @@ -153,6 +163,10 @@ from .process import Process from .process_detail import ProcessDetail from .process_documentation import ProcessDocumentation +from .process_parameter_schema import ProcessParameterSchema +from .process_parameter_schema_form import ProcessParameterSchemaForm +from .process_parameter_schema_input_file_requirements import ProcessParameterSchemaInputFileRequirements +from .process_parameter_schema_ui import ProcessParameterSchemaUi from .process_resource import ProcessResource from .process_resource_content import ProcessResourceContent from .process_revision import ProcessRevision @@ -165,7 +179,9 @@ from .project_access_type import ProjectAccessType from .project_create_options import ProjectCreateOptions from .project_detail import ProjectDetail +from .project_file import ProjectFile from .project_file_access_request import ProjectFileAccessRequest +from .project_file_query_response import ProjectFileQueryResponse from .project_input import ProjectInput from .project_metrics import ProjectMetrics from .project_permission_set import ProjectPermissionSet @@ -185,16 +201,14 @@ from .request_status import RequestStatus from .requirement_fulfillment_input import RequirementFulfillmentInput from .requirement_input import RequirementInput -from .resources_info import ResourcesInfo from .row_insert import RowInsert from .row_insert_values import RowInsertValues -from .row_insert_values_additional_property import RowInsertValuesAdditionalProperty from .row_update import RowUpdate from .row_update_values import RowUpdateValues -from .row_update_values_additional_property import RowUpdateValuesAdditionalProperty from .run_analysis_request import RunAnalysisRequest from .run_analysis_request_params import RunAnalysisRequestParams from .run_analysis_request_source_sample_files_map import RunAnalysisRequestSourceSampleFilesMap +from .run_analysis_request_structured_file_inputs import RunAnalysisRequestStructuredFileInputs from .sample import Sample from .sample_metadata import SampleMetadata from .sample_request import SampleRequest @@ -232,6 +246,8 @@ from .sql_sort_order import SqlSortOrder from .status import Status from .stop_execution_response import StopExecutionResponse +from .structured_file_input import StructuredFileInput +from .structured_file_input_data_item import StructuredFileInputDataItem from .structured_view_query_request import StructuredViewQueryRequest from .sync_status import SyncStatus from .system_info_response import SystemInfoResponse @@ -242,6 +258,7 @@ from .task_cost import TaskCost from .task_log_source import TaskLogSource from .tenant_info import TenantInfo +from .tenant_metrics import TenantMetrics from .update_dataset_request import UpdateDatasetRequest from .update_rows_request import UpdateRowsRequest from .update_user_request import UpdateUserRequest @@ -251,8 +268,10 @@ from .user_detail import UserDetail from .user_project_assignment import UserProjectAssignment from .user_settings import UserSettings +from .user_status import UserStatus from .validate_file_name_patterns_request import ValidateFileNamePatternsRequest from .validate_file_requirements_request import ValidateFileRequirementsRequest +from .version_info import VersionInfo from .version_specification import VersionSpecification from .view_join import ViewJoin from .view_sheet_input import ViewSheetInput @@ -306,6 +325,7 @@ "ColumnDataType", "ColumnDef", "ColumnDefinition", + "ColumnRelationship", "ComputeEnvironmentConfiguration", "ComputeEnvironmentConfigurationInput", "ComputeEnvironmentConfigurationInputProperties", @@ -313,7 +333,9 @@ "ConfigSource", "Contact", "ContactInput", + "CostComponent", "CostResponse", + "CostSource", "CreateProjectAccessRequest", "CreateReferenceRequest", "CreateResponse", @@ -336,6 +358,7 @@ "DatasetDetailInfo", "DatasetDetailParams", "DatasetDetailSourceSampleFilesMap", + "DatasetSource", "DatasetViz", "DeleteRowsRequest", "Discussion", @@ -345,11 +368,13 @@ "EntityType", "EnvironmentType", "ErrorMessage", + "ExecutionMode", "Executor", "FeatureFlags", "FileDef", "FileEntry", "FileEntryMetadata", + "FileFormat", "FileMappingRule", "FileNameMatch", "FileNamePattern", @@ -360,7 +385,6 @@ "ForeignKeyRef", "FormSchema", "FormSchemaForm", - "FormSchemaMetadataRequirements", "FormSchemaUi", "FulfillmentResponse", "GenerateSftpCredentialsRequest", @@ -384,6 +408,10 @@ "GroupCost", "ImportDataRequest", "ImportDataRequestDownloadMethod", + "IngestConflictMode", + "InputFileRequirement", + "InputFileRequirementExamples", + "InputFileRequirementSchema", "InsertRowsRequest", "InviteUserRequest", "InviteUserResponse", @@ -403,6 +431,7 @@ "MoveDatasetResponse", "NamedItem", "PaginatedResponseAppRegistrationDto", + "PaginatedResponseAuditEventDto", "PaginatedResponseDatasetListDto", "PaginatedResponseDiscussion", "PaginatedResponseMessage", @@ -419,6 +448,10 @@ "Process", "ProcessDetail", "ProcessDocumentation", + "ProcessParameterSchema", + "ProcessParameterSchemaForm", + "ProcessParameterSchemaInputFileRequirements", + "ProcessParameterSchemaUi", "ProcessResource", "ProcessResourceContent", "ProcessRevision", @@ -431,7 +464,9 @@ "ProjectAccessType", "ProjectCreateOptions", "ProjectDetail", + "ProjectFile", "ProjectFileAccessRequest", + "ProjectFileQueryResponse", "ProjectInput", "ProjectMetrics", "ProjectPermissionSet", @@ -451,16 +486,14 @@ "RequestStatus", "RequirementFulfillmentInput", "RequirementInput", - "ResourcesInfo", "RowInsert", "RowInsertValues", - "RowInsertValuesAdditionalProperty", "RowUpdate", "RowUpdateValues", - "RowUpdateValuesAdditionalProperty", "RunAnalysisRequest", "RunAnalysisRequestParams", "RunAnalysisRequestSourceSampleFilesMap", + "RunAnalysisRequestStructuredFileInputs", "Sample", "SampleMetadata", "SampleRequest", @@ -498,6 +531,8 @@ "SqlSortOrder", "Status", "StopExecutionResponse", + "StructuredFileInput", + "StructuredFileInputDataItem", "StructuredViewQueryRequest", "SyncStatus", "SystemInfoResponse", @@ -508,6 +543,7 @@ "TaskCost", "TaskLogSource", "TenantInfo", + "TenantMetrics", "UpdateDatasetRequest", "UpdateRowsRequest", "UpdateUserRequest", @@ -517,8 +553,10 @@ "UserDetail", "UserProjectAssignment", "UserSettings", + "UserStatus", "ValidateFileNamePatternsRequest", "ValidateFileRequirementsRequest", + "VersionInfo", "VersionSpecification", "ViewJoin", "ViewSheetInput", diff --git a/cirro_api_client/v1/models/audit_event.py b/cirro_api_client/v1/models/audit_event.py index a40769c..376276e 100644 --- a/cirro_api_client/v1/models/audit_event.py +++ b/cirro_api_client/v1/models/audit_event.py @@ -32,6 +32,8 @@ class AuditEvent: {'.settings.retentionPolicyDays': '1 -> 2'}. username (str | Unset): The username of the user who performed the action Example: admin@cirro.bio. ip_address (str | Unset): The IP address of the user who performed the action Example: 0.0.0.0. + user_agent (str | Unset): The user agent of the user who performed the action + app_id (str | Unset): The ID of the Cirro app that performed the action (if applicable) created_at (datetime.datetime | Unset): The date and time the event was created """ @@ -44,6 +46,8 @@ class AuditEvent: changes: AuditEventChanges | None | Unset = UNSET username: str | Unset = UNSET ip_address: str | Unset = UNSET + user_agent: str | Unset = UNSET + app_id: str | Unset = UNSET created_at: datetime.datetime | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -81,6 +85,10 @@ def to_dict(self) -> dict[str, Any]: ip_address = self.ip_address + user_agent = self.user_agent + + app_id = self.app_id + created_at: str | Unset = UNSET if not isinstance(self.created_at, Unset): created_at = self.created_at.isoformat() @@ -106,6 +114,10 @@ def to_dict(self) -> dict[str, Any]: field_dict["username"] = username if ip_address is not UNSET: field_dict["ipAddress"] = ip_address + if user_agent is not UNSET: + field_dict["userAgent"] = user_agent + if app_id is not UNSET: + field_dict["appId"] = app_id if created_at is not UNSET: field_dict["createdAt"] = created_at @@ -165,6 +177,10 @@ def _parse_changes(data: object) -> AuditEventChanges | None | Unset: ip_address = d.pop("ipAddress", UNSET) + user_agent = d.pop("userAgent", UNSET) + + app_id = d.pop("appId", UNSET) + _created_at = d.pop("createdAt", UNSET) created_at: datetime.datetime | Unset if isinstance(_created_at, Unset): @@ -182,6 +198,8 @@ def _parse_changes(data: object) -> AuditEventChanges | None | Unset: changes=changes, username=username, ip_address=ip_address, + user_agent=user_agent, + app_id=app_id, created_at=created_at, ) diff --git a/cirro_api_client/v1/models/column_def.py b/cirro_api_client/v1/models/column_def.py index 60d447d..d29988f 100644 --- a/cirro_api_client/v1/models/column_def.py +++ b/cirro_api_client/v1/models/column_def.py @@ -28,10 +28,12 @@ class ColumnDef: hidden (bool | Unset): Whether the column is hidden on the UI. Default: False. semantic_type (None | SemanticColumnType | Unset): The semantic type of the column. Default: SemanticColumnType.STANDARD. - allowed_values (list[str] | None | Unset): The allowed values for the column, only used for ENUM* types. + allowed_values (list[str] | None | Unset): The allowed values for an ENUM_SINGLE column. description (None | str | Unset): foreign_key (ForeignKeyRef | None | Unset): required (bool | Unset): Whether the column is required to be non-null. Default: False. + unique (bool | Unset): Whether values in this column must be unique across the sheet (NULLs exempt). Set when + the column is created; enforced at write time by the application. Default: False. """ name: str @@ -44,6 +46,7 @@ class ColumnDef: description: None | str | Unset = UNSET foreign_key: ForeignKeyRef | None | Unset = UNSET required: bool | Unset = False + unique: bool | Unset = False additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -100,6 +103,8 @@ def to_dict(self) -> dict[str, Any]: required = self.required + unique = self.unique + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -124,6 +129,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["foreignKey"] = foreign_key if required is not UNSET: field_dict["required"] = required + if unique is not UNSET: + field_dict["unique"] = unique return field_dict @@ -218,6 +225,8 @@ def _parse_foreign_key(data: object) -> ForeignKeyRef | None | Unset: required = d.pop("required", UNSET) + unique = d.pop("unique", UNSET) + column_def = cls( name=name, data_type=data_type, @@ -229,6 +238,7 @@ def _parse_foreign_key(data: object) -> ForeignKeyRef | None | Unset: description=description, foreign_key=foreign_key, required=required, + unique=unique, ) column_def.additional_properties = d diff --git a/cirro_api_client/v1/models/column_relationship.py b/cirro_api_client/v1/models/column_relationship.py new file mode 100644 index 0000000..161cd5a --- /dev/null +++ b/cirro_api_client/v1/models/column_relationship.py @@ -0,0 +1,78 @@ +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="ColumnRelationship") + + +@_attrs_define +class ColumnRelationship: + """A foreign-key relationship from a column in this sheet to a column in another sheet. + + Attributes: + column_name (str): Name of the foreign-key column on this sheet. + target_sheet_id (str): ID of the sheet this relationship references. + target_column_name (str): Name of the referenced column in the target sheet. + """ + + column_name: str + target_sheet_id: str + target_column_name: str + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + column_name = self.column_name + + target_sheet_id = self.target_sheet_id + + target_column_name = self.target_column_name + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "columnName": column_name, + "targetSheetId": target_sheet_id, + "targetColumnName": target_column_name, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + column_name = d.pop("columnName") + + target_sheet_id = d.pop("targetSheetId") + + target_column_name = d.pop("targetColumnName") + + column_relationship = cls( + column_name=column_name, + target_sheet_id=target_sheet_id, + target_column_name=target_column_name, + ) + + column_relationship.additional_properties = d + return column_relationship + + @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/cirro_api_client/v1/models/cost_component.py b/cirro_api_client/v1/models/cost_component.py new file mode 100644 index 0000000..6a25dd7 --- /dev/null +++ b/cirro_api_client/v1/models/cost_component.py @@ -0,0 +1,15 @@ +from enum import Enum + + +class CostComponent(str, Enum): + EPHEMERAL_STORAGE = "EPHEMERAL_STORAGE" + RUN_STORAGE = "RUN_STORAGE" + UNKNOWN = "UNKNOWN" + """ This is a fallback value for when the value is not known, do not use this value when making requests """ + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, number): + return cls(cls.UNKNOWN) diff --git a/cirro_api_client/v1/models/cost_response.py b/cirro_api_client/v1/models/cost_response.py index b4cd24d..2a34442 100644 --- a/cirro_api_client/v1/models/cost_response.py +++ b/cirro_api_client/v1/models/cost_response.py @@ -1,11 +1,13 @@ from __future__ import annotations from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar, cast from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..models.cost_component import CostComponent +from ..models.cost_source import CostSource from ..types import UNSET, Unset if TYPE_CHECKING: @@ -24,12 +26,20 @@ class CostResponse: groups (list[GroupCost] | Unset): Costs grouped by the task status tasks (list[TaskCost] | Unset): Costs for each workflow task is_estimate (bool | Unset): Whether this is an estimated cost + storage_cost (float | None | Unset): Run storage cost, included in totalCost; null when not reported by the + billing source + cost_source (CostSource | Unset): How a cost was derived + omitted_components (list[CostComponent] | None | Unset): Billed components known to be excluded from totalCost + (e.g. run storage when usage was not reported) """ total_cost: float | Unset = UNSET groups: list[GroupCost] | Unset = UNSET tasks: list[TaskCost] | Unset = UNSET is_estimate: bool | Unset = UNSET + storage_cost: float | None | Unset = UNSET + cost_source: CostSource | Unset = UNSET + omitted_components: list[CostComponent] | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -51,6 +61,28 @@ def to_dict(self) -> dict[str, Any]: is_estimate = self.is_estimate + storage_cost: float | None | Unset + if isinstance(self.storage_cost, Unset): + storage_cost = UNSET + else: + storage_cost = self.storage_cost + + cost_source: str | Unset = UNSET + if not isinstance(self.cost_source, Unset): + cost_source = self.cost_source.value + + omitted_components: list[str] | None | Unset + if isinstance(self.omitted_components, Unset): + omitted_components = UNSET + elif isinstance(self.omitted_components, list): + omitted_components = [] + for omitted_components_type_0_item_data in self.omitted_components: + omitted_components_type_0_item = omitted_components_type_0_item_data.value + omitted_components.append(omitted_components_type_0_item) + + else: + omitted_components = self.omitted_components + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) @@ -62,6 +94,12 @@ def to_dict(self) -> dict[str, Any]: field_dict["tasks"] = tasks if is_estimate is not UNSET: field_dict["isEstimate"] = is_estimate + if storage_cost is not UNSET: + field_dict["storageCost"] = storage_cost + if cost_source is not UNSET: + field_dict["costSource"] = cost_source + if omitted_components is not UNSET: + field_dict["omittedComponents"] = omitted_components return field_dict @@ -93,11 +131,52 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: is_estimate = d.pop("isEstimate", UNSET) + def _parse_storage_cost(data: object) -> float | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(float | None | Unset, data) + + storage_cost = _parse_storage_cost(d.pop("storageCost", UNSET)) + + _cost_source = d.pop("costSource", UNSET) + cost_source: CostSource | Unset + if isinstance(_cost_source, Unset): + cost_source = UNSET + else: + cost_source = CostSource(_cost_source) + + def _parse_omitted_components(data: object) -> list[CostComponent] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + omitted_components_type_0 = [] + _omitted_components_type_0 = data + for omitted_components_type_0_item_data in _omitted_components_type_0: + omitted_components_type_0_item = CostComponent(omitted_components_type_0_item_data) + + omitted_components_type_0.append(omitted_components_type_0_item) + + return omitted_components_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[CostComponent] | None | Unset, data) + + omitted_components = _parse_omitted_components(d.pop("omittedComponents", UNSET)) + cost_response = cls( total_cost=total_cost, groups=groups, tasks=tasks, is_estimate=is_estimate, + storage_cost=storage_cost, + cost_source=cost_source, + omitted_components=omitted_components, ) cost_response.additional_properties = d diff --git a/cirro_api_client/v1/models/cost_source.py b/cirro_api_client/v1/models/cost_source.py new file mode 100644 index 0000000..6a15cd5 --- /dev/null +++ b/cirro_api_client/v1/models/cost_source.py @@ -0,0 +1,15 @@ +from enum import Enum + + +class CostSource(str, Enum): + BATCH_MODEL = "BATCH_MODEL" + OMICS_MANIFEST = "OMICS_MANIFEST" + UNKNOWN = "UNKNOWN" + """ This is a fallback value for when the value is not known, do not use this value when making requests """ + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, number): + return cls(cls.UNKNOWN) diff --git a/cirro_api_client/v1/models/custom_process_input.py b/cirro_api_client/v1/models/custom_process_input.py index 2af206d..e2d35f3 100644 --- a/cirro_api_client/v1/models/custom_process_input.py +++ b/cirro_api_client/v1/models/custom_process_input.py @@ -7,6 +7,7 @@ from attrs import field as _attrs_field from ..models.config_source import ConfigSource +from ..models.execution_mode import ExecutionMode from ..models.executor import Executor from ..types import UNSET, Unset @@ -39,9 +40,11 @@ class CustomProcessInput: https://docs.cirro.bio/pipelines/catalog_targeted_sequencing/#crispr-screen-analysis. file_requirements_message (None | str | Unset): Description of the files to be uploaded (optional) pipeline_code (None | PipelineCode | Unset): + maintainers (list[str] | None | Unset): is_tenant_wide (bool | Unset): Whether the process is shared with the tenant allow_multiple_sources (bool | Unset): Whether the pipeline is allowed to have multiple dataset sources uses_sample_sheet (bool | Unset): Whether the pipeline uses the Cirro-provided sample sheet + execution_modes (list[ExecutionMode] | None | Unset): Execution modes the pipeline supports custom_settings (CustomPipelineSettings | None | Unset): file_mapping_rules (list[FileMappingRule] | None | Unset): tags (list[Tag] | None | Unset): @@ -60,9 +63,11 @@ class CustomProcessInput: documentation_url: None | str | Unset = UNSET file_requirements_message: None | str | Unset = UNSET pipeline_code: None | PipelineCode | Unset = UNSET + maintainers: list[str] | None | Unset = UNSET is_tenant_wide: bool | Unset = UNSET allow_multiple_sources: bool | Unset = UNSET uses_sample_sheet: bool | Unset = UNSET + execution_modes: list[ExecutionMode] | None | Unset = UNSET custom_settings: CustomPipelineSettings | None | Unset = UNSET file_mapping_rules: list[FileMappingRule] | None | Unset = UNSET tags: list[Tag] | None | Unset = UNSET @@ -115,12 +120,33 @@ def to_dict(self) -> dict[str, Any]: else: pipeline_code = self.pipeline_code + maintainers: list[str] | None | Unset + if isinstance(self.maintainers, Unset): + maintainers = UNSET + elif isinstance(self.maintainers, list): + maintainers = self.maintainers + + else: + maintainers = self.maintainers + is_tenant_wide = self.is_tenant_wide allow_multiple_sources = self.allow_multiple_sources uses_sample_sheet = self.uses_sample_sheet + execution_modes: list[str] | None | Unset + if isinstance(self.execution_modes, Unset): + execution_modes = UNSET + elif isinstance(self.execution_modes, list): + execution_modes = [] + for execution_modes_type_0_item_data in self.execution_modes: + execution_modes_type_0_item = execution_modes_type_0_item_data.value + execution_modes.append(execution_modes_type_0_item) + + else: + execution_modes = self.execution_modes + custom_settings: dict[str, Any] | None | Unset if isinstance(self.custom_settings, Unset): custom_settings = UNSET @@ -184,12 +210,16 @@ def to_dict(self) -> dict[str, Any]: field_dict["fileRequirementsMessage"] = file_requirements_message if pipeline_code is not UNSET: field_dict["pipelineCode"] = pipeline_code + if maintainers is not UNSET: + field_dict["maintainers"] = maintainers if is_tenant_wide is not UNSET: field_dict["isTenantWide"] = is_tenant_wide if allow_multiple_sources is not UNSET: field_dict["allowMultipleSources"] = allow_multiple_sources if uses_sample_sheet is not UNSET: field_dict["usesSampleSheet"] = uses_sample_sheet + if execution_modes is not UNSET: + field_dict["executionModes"] = execution_modes if custom_settings is not UNSET: field_dict["customSettings"] = custom_settings if file_mapping_rules is not UNSET: @@ -269,12 +299,51 @@ def _parse_pipeline_code(data: object) -> None | PipelineCode | Unset: pipeline_code = _parse_pipeline_code(d.pop("pipelineCode", UNSET)) + def _parse_maintainers(data: object) -> list[str] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + maintainers_type_0 = cast(list[str], data) + + return maintainers_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + maintainers = _parse_maintainers(d.pop("maintainers", UNSET)) + is_tenant_wide = d.pop("isTenantWide", UNSET) allow_multiple_sources = d.pop("allowMultipleSources", UNSET) uses_sample_sheet = d.pop("usesSampleSheet", UNSET) + def _parse_execution_modes(data: object) -> list[ExecutionMode] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + execution_modes_type_0 = [] + _execution_modes_type_0 = data + for execution_modes_type_0_item_data in _execution_modes_type_0: + execution_modes_type_0_item = ExecutionMode(execution_modes_type_0_item_data) + + execution_modes_type_0.append(execution_modes_type_0_item) + + return execution_modes_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[ExecutionMode] | None | Unset, data) + + execution_modes = _parse_execution_modes(d.pop("executionModes", UNSET)) + def _parse_custom_settings(data: object) -> CustomPipelineSettings | None | Unset: if data is None: return data @@ -366,9 +435,11 @@ def _parse_config_source(data: object) -> ConfigSource | None | Unset: documentation_url=documentation_url, file_requirements_message=file_requirements_message, pipeline_code=pipeline_code, + maintainers=maintainers, is_tenant_wide=is_tenant_wide, allow_multiple_sources=allow_multiple_sources, uses_sample_sheet=uses_sample_sheet, + execution_modes=execution_modes, custom_settings=custom_settings, file_mapping_rules=file_mapping_rules, tags=tags, diff --git a/cirro_api_client/v1/models/dataset_source.py b/cirro_api_client/v1/models/dataset_source.py new file mode 100644 index 0000000..ae6a04d --- /dev/null +++ b/cirro_api_client/v1/models/dataset_source.py @@ -0,0 +1,15 @@ +from enum import Enum + + +class DatasetSource(str, Enum): + DERIVED = "DERIVED" + INGESTED = "INGESTED" + UNKNOWN = "UNKNOWN" + """ This is a fallback value for when the value is not known, do not use this value when making requests """ + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, number): + return cls(cls.UNKNOWN) diff --git a/cirro_api_client/v1/models/execution_mode.py b/cirro_api_client/v1/models/execution_mode.py new file mode 100644 index 0000000..fe45b87 --- /dev/null +++ b/cirro_api_client/v1/models/execution_mode.py @@ -0,0 +1,15 @@ +from enum import Enum + + +class ExecutionMode(str, Enum): + HEALTHOMICS = "HEALTHOMICS" + STANDARD = "STANDARD" + UNKNOWN = "UNKNOWN" + """ This is a fallback value for when the value is not known, do not use this value when making requests """ + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, number): + return cls(cls.UNKNOWN) diff --git a/cirro_api_client/v1/models/feature_flags.py b/cirro_api_client/v1/models/feature_flags.py index 64a4981..406e2fd 100644 --- a/cirro_api_client/v1/models/feature_flags.py +++ b/cirro_api_client/v1/models/feature_flags.py @@ -27,6 +27,8 @@ class FeatureFlags: custom_workspace_roles_enabled (bool): orcid_integration_enabled (bool): cirro_stored_pipeline_config_enabled (bool): + omics_private_workflows_enabled (bool): + dashboards_enabled (bool): """ zip_service_enabled: bool @@ -43,6 +45,8 @@ class FeatureFlags: custom_workspace_roles_enabled: bool orcid_integration_enabled: bool cirro_stored_pipeline_config_enabled: bool + omics_private_workflows_enabled: bool + dashboards_enabled: bool additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -74,6 +78,10 @@ def to_dict(self) -> dict[str, Any]: cirro_stored_pipeline_config_enabled = self.cirro_stored_pipeline_config_enabled + omics_private_workflows_enabled = self.omics_private_workflows_enabled + + dashboards_enabled = self.dashboards_enabled + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -92,6 +100,8 @@ def to_dict(self) -> dict[str, Any]: "customWorkspaceRolesEnabled": custom_workspace_roles_enabled, "orcidIntegrationEnabled": orcid_integration_enabled, "cirroStoredPipelineConfigEnabled": cirro_stored_pipeline_config_enabled, + "omicsPrivateWorkflowsEnabled": omics_private_workflows_enabled, + "dashboardsEnabled": dashboards_enabled, } ) @@ -128,6 +138,10 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: cirro_stored_pipeline_config_enabled = d.pop("cirroStoredPipelineConfigEnabled") + omics_private_workflows_enabled = d.pop("omicsPrivateWorkflowsEnabled") + + dashboards_enabled = d.pop("dashboardsEnabled") + feature_flags = cls( zip_service_enabled=zip_service_enabled, sftp_enabled=sftp_enabled, @@ -143,6 +157,8 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: custom_workspace_roles_enabled=custom_workspace_roles_enabled, orcid_integration_enabled=orcid_integration_enabled, cirro_stored_pipeline_config_enabled=cirro_stored_pipeline_config_enabled, + omics_private_workflows_enabled=omics_private_workflows_enabled, + dashboards_enabled=dashboards_enabled, ) feature_flags.additional_properties = d diff --git a/cirro_api_client/v1/models/file_format.py b/cirro_api_client/v1/models/file_format.py new file mode 100644 index 0000000..4108721 --- /dev/null +++ b/cirro_api_client/v1/models/file_format.py @@ -0,0 +1,16 @@ +from enum import Enum + + +class FileFormat(str, Enum): + CSV = "CSV" + JSON = "JSON" + TSV = "TSV" + UNKNOWN = "UNKNOWN" + """ This is a fallback value for when the value is not known, do not use this value when making requests """ + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, number): + return cls(cls.UNKNOWN) diff --git a/cirro_api_client/v1/models/form_schema.py b/cirro_api_client/v1/models/form_schema.py index caeaf63..ec541cb 100644 --- a/cirro_api_client/v1/models/form_schema.py +++ b/cirro_api_client/v1/models/form_schema.py @@ -10,7 +10,6 @@ if TYPE_CHECKING: from ..models.form_schema_form import FormSchemaForm - from ..models.form_schema_metadata_requirements import FormSchemaMetadataRequirements from ..models.form_schema_ui import FormSchemaUi @@ -22,13 +21,11 @@ class FormSchema: """ Attributes: form (FormSchemaForm | Unset): JSONSchema representation of the parameters - ui (FormSchemaUi | Unset): Describes how the form should be rendered, see rjsf - metadata_requirements (FormSchemaMetadataRequirements | Unset): JSONSchema for validating sample metadata + ui (FormSchemaUi | Unset): Describes how the form should be rendered on the UI, see rjsf """ form: FormSchemaForm | Unset = UNSET ui: FormSchemaUi | Unset = UNSET - metadata_requirements: FormSchemaMetadataRequirements | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -40,10 +37,6 @@ def to_dict(self) -> dict[str, Any]: if not isinstance(self.ui, Unset): ui = self.ui.to_dict() - metadata_requirements: dict[str, Any] | Unset = UNSET - if not isinstance(self.metadata_requirements, Unset): - metadata_requirements = self.metadata_requirements.to_dict() - field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update({}) @@ -51,15 +44,12 @@ def to_dict(self) -> dict[str, Any]: field_dict["form"] = form if ui is not UNSET: field_dict["ui"] = ui - if metadata_requirements is not UNSET: - field_dict["metadataRequirements"] = metadata_requirements return field_dict @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: from ..models.form_schema_form import FormSchemaForm - from ..models.form_schema_metadata_requirements import FormSchemaMetadataRequirements from ..models.form_schema_ui import FormSchemaUi d = dict(src_dict) @@ -77,17 +67,9 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: else: ui = FormSchemaUi.from_dict(_ui) - _metadata_requirements = d.pop("metadataRequirements", UNSET) - metadata_requirements: FormSchemaMetadataRequirements | Unset - if isinstance(_metadata_requirements, Unset): - metadata_requirements = UNSET - else: - metadata_requirements = FormSchemaMetadataRequirements.from_dict(_metadata_requirements) - form_schema = cls( form=form, ui=ui, - metadata_requirements=metadata_requirements, ) form_schema.additional_properties = d diff --git a/cirro_api_client/v1/models/form_schema_ui.py b/cirro_api_client/v1/models/form_schema_ui.py index 780438d..40edf46 100644 --- a/cirro_api_client/v1/models/form_schema_ui.py +++ b/cirro_api_client/v1/models/form_schema_ui.py @@ -11,7 +11,7 @@ @_attrs_define class FormSchemaUi: - """Describes how the form should be rendered, see rjsf""" + """Describes how the form should be rendered on the UI, see rjsf""" additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) diff --git a/cirro_api_client/v1/models/ingest_conflict_mode.py b/cirro_api_client/v1/models/ingest_conflict_mode.py new file mode 100644 index 0000000..9af1f29 --- /dev/null +++ b/cirro_api_client/v1/models/ingest_conflict_mode.py @@ -0,0 +1,16 @@ +from enum import Enum + + +class IngestConflictMode(str, Enum): + ERROR = "ERROR" + OVERWRITE = "OVERWRITE" + SKIP = "SKIP" + UNKNOWN = "UNKNOWN" + """ This is a fallback value for when the value is not known, do not use this value when making requests """ + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, number): + return cls(cls.UNKNOWN) diff --git a/cirro_api_client/v1/models/input_file_requirement.py b/cirro_api_client/v1/models/input_file_requirement.py new file mode 100644 index 0000000..30c373f --- /dev/null +++ b/cirro_api_client/v1/models/input_file_requirement.py @@ -0,0 +1,126 @@ +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 ..models.file_format import FileFormat +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.input_file_requirement_examples import InputFileRequirementExamples + from ..models.input_file_requirement_schema import InputFileRequirementSchema + + +T = TypeVar("T", bound="InputFileRequirement") + + +@_attrs_define +class InputFileRequirement: + """Defines a structured file that a pipeline accepts as an input, and the schema used to validate it + + Attributes: + file_format (FileFormat): Determines the file format used when passing the schema-validated input to the + pipeline. + - CSV: comma-delimited, one row per object, header row taken from the schema's property order. + Nested objects/arrays within a row are JSON-encoded inline as a single cell value (not recommended). + - TSV: same as CSV, but tab-delimited. + - JSON: the row objects are written out unmodified as a JSON array (no flattening). + schema (InputFileRequirementSchema): JSONSchema representation of the input file contents + examples (list[InputFileRequirementExamples] | None | Unset): Example rows of data conforming to the schema, + shown to the user as a starting point + """ + + file_format: FileFormat + schema: InputFileRequirementSchema + examples: list[InputFileRequirementExamples] | None | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + file_format = self.file_format.value + + schema = self.schema.to_dict() + + examples: list[dict[str, Any]] | None | Unset + if isinstance(self.examples, Unset): + examples = UNSET + elif isinstance(self.examples, list): + examples = [] + for examples_type_0_item_data in self.examples: + examples_type_0_item = examples_type_0_item_data.to_dict() + examples.append(examples_type_0_item) + + else: + examples = self.examples + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "fileFormat": file_format, + "schema": schema, + } + ) + if examples is not UNSET: + field_dict["examples"] = examples + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.input_file_requirement_examples import InputFileRequirementExamples + from ..models.input_file_requirement_schema import InputFileRequirementSchema + + d = dict(src_dict) + file_format = FileFormat(d.pop("fileFormat")) + + schema = InputFileRequirementSchema.from_dict(d.pop("schema")) + + def _parse_examples(data: object) -> list[InputFileRequirementExamples] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + examples_type_0 = [] + _examples_type_0 = data + for examples_type_0_item_data in _examples_type_0: + examples_type_0_item = InputFileRequirementExamples.from_dict(examples_type_0_item_data) + + examples_type_0.append(examples_type_0_item) + + return examples_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[InputFileRequirementExamples] | None | Unset, data) + + examples = _parse_examples(d.pop("examples", UNSET)) + + input_file_requirement = cls( + file_format=file_format, + schema=schema, + examples=examples, + ) + + input_file_requirement.additional_properties = d + return input_file_requirement + + @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/cirro_api_client/v1/models/row_insert_values_additional_property.py b/cirro_api_client/v1/models/input_file_requirement_examples.py similarity index 79% rename from cirro_api_client/v1/models/row_insert_values_additional_property.py rename to cirro_api_client/v1/models/input_file_requirement_examples.py index 1d08764..c844f03 100644 --- a/cirro_api_client/v1/models/row_insert_values_additional_property.py +++ b/cirro_api_client/v1/models/input_file_requirement_examples.py @@ -6,11 +6,11 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field -T = TypeVar("T", bound="RowInsertValuesAdditionalProperty") +T = TypeVar("T", bound="InputFileRequirementExamples") @_attrs_define -class RowInsertValuesAdditionalProperty: +class InputFileRequirementExamples: """ """ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -25,10 +25,10 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: d = dict(src_dict) - row_insert_values_additional_property = cls() + input_file_requirement_examples = cls() - row_insert_values_additional_property.additional_properties = d - return row_insert_values_additional_property + input_file_requirement_examples.additional_properties = d + return input_file_requirement_examples @property def additional_keys(self) -> list[str]: diff --git a/cirro_api_client/v1/models/row_update_values_additional_property.py b/cirro_api_client/v1/models/input_file_requirement_schema.py similarity index 77% rename from cirro_api_client/v1/models/row_update_values_additional_property.py rename to cirro_api_client/v1/models/input_file_requirement_schema.py index ad10052..38d2652 100644 --- a/cirro_api_client/v1/models/row_update_values_additional_property.py +++ b/cirro_api_client/v1/models/input_file_requirement_schema.py @@ -6,12 +6,12 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field -T = TypeVar("T", bound="RowUpdateValuesAdditionalProperty") +T = TypeVar("T", bound="InputFileRequirementSchema") @_attrs_define -class RowUpdateValuesAdditionalProperty: - """ """ +class InputFileRequirementSchema: + """JSONSchema representation of the input file contents""" additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -25,10 +25,10 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: d = dict(src_dict) - row_update_values_additional_property = cls() + input_file_requirement_schema = cls() - row_update_values_additional_property.additional_properties = d - return row_update_values_additional_property + input_file_requirement_schema.additional_properties = d + return input_file_requirement_schema @property def additional_keys(self) -> list[str]: diff --git a/cirro_api_client/v1/models/resources_info.py b/cirro_api_client/v1/models/paginated_response_audit_event_dto.py similarity index 51% rename from cirro_api_client/v1/models/resources_info.py rename to cirro_api_client/v1/models/paginated_response_audit_event_dto.py index e5bc051..de29fea 100644 --- a/cirro_api_client/v1/models/resources_info.py +++ b/cirro_api_client/v1/models/paginated_response_audit_event_dto.py @@ -1,48 +1,44 @@ from __future__ import annotations -import datetime from collections.abc import Mapping -from typing import Any, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar from attrs import define as _attrs_define from attrs import field as _attrs_field -T = TypeVar("T", bound="ResourcesInfo") +if TYPE_CHECKING: + from ..models.audit_event import AuditEvent + + +T = TypeVar("T", bound="PaginatedResponseAuditEventDto") @_attrs_define -class ResourcesInfo: +class PaginatedResponseAuditEventDto: """ Attributes: - commit (str): - date (datetime.datetime): - repository (str): - source_version (str): + data (list[AuditEvent]): + next_token (str): """ - commit: str - date: datetime.datetime - repository: str - source_version: str + data: list[AuditEvent] + next_token: str additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - commit = self.commit - - date = self.date.isoformat() + data = [] + for data_item_data in self.data: + data_item = data_item_data.to_dict() + data.append(data_item) - repository = self.repository - - source_version = self.source_version + next_token = self.next_token field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( { - "commit": commit, - "date": date, - "repository": repository, - "sourceVersion": source_version, + "data": data, + "nextToken": next_token, } ) @@ -50,24 +46,25 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - d = dict(src_dict) - commit = d.pop("commit") + from ..models.audit_event import AuditEvent - date = datetime.datetime.fromisoformat(d.pop("date")) + d = dict(src_dict) + data = [] + _data = d.pop("data") + for data_item_data in _data: + data_item = AuditEvent.from_dict(data_item_data) - repository = d.pop("repository") + data.append(data_item) - source_version = d.pop("sourceVersion") + next_token = d.pop("nextToken") - resources_info = cls( - commit=commit, - date=date, - repository=repository, - source_version=source_version, + paginated_response_audit_event_dto = cls( + data=data, + next_token=next_token, ) - resources_info.additional_properties = d - return resources_info + paginated_response_audit_event_dto.additional_properties = d + return paginated_response_audit_event_dto @property def additional_keys(self) -> list[str]: diff --git a/cirro_api_client/v1/models/permission.py b/cirro_api_client/v1/models/permission.py index 0b8925f..c07cea4 100644 --- a/cirro_api_client/v1/models/permission.py +++ b/cirro_api_client/v1/models/permission.py @@ -30,9 +30,11 @@ class Permission(str, Enum): EDIT_SHEET_DATA = "EDIT_SHEET_DATA" GENERATE_DOWNLOAD_TOKEN = "GENERATE_DOWNLOAD_TOKEN" INVITE_MEMBER = "INVITE_MEMBER" + INVOKE_PROMPT_TEMPLATE = "INVOKE_PROMPT_TEMPLATE" MANAGE_AGENTS = "MANAGE_AGENTS" MANAGE_ALL_APP_REGISTRATIONS = "MANAGE_ALL_APP_REGISTRATIONS" MANAGE_BILLING_ACCOUNTS = "MANAGE_BILLING_ACCOUNTS" + MANAGE_CUSTOM_PIPELINES = "MANAGE_CUSTOM_PIPELINES" MANAGE_DISCUSSIONS = "MANAGE_DISCUSSIONS" MANAGE_GOVERNANCE = "MANAGE_GOVERNANCE" MANAGE_MEMBERS = "MANAGE_MEMBERS" diff --git a/cirro_api_client/v1/models/pipeline_code.py b/cirro_api_client/v1/models/pipeline_code.py index 7400ab8..c19d4c9 100644 --- a/cirro_api_client/v1/models/pipeline_code.py +++ b/cirro_api_client/v1/models/pipeline_code.py @@ -21,7 +21,8 @@ class PipelineCode: version (str): Branch, tag, or commit hash of the pipeline code Example: main. repository_type (RepositoryType): Type of repository entry_point (str): Main script for running the pipeline Example: main.nf. - executor_version (None | str | Unset): Version of the executor Example: 24.10.5. + executor_version (None | str | Unset): Nextflow version used to run the pipeline. For pipelines with HealthOmics + support, it must be one of the supported versions Example: 26.04.0. """ repository_path: str diff --git a/cirro_api_client/v1/models/process.py b/cirro_api_client/v1/models/process.py index 4518317..ce31a68 100644 --- a/cirro_api_client/v1/models/process.py +++ b/cirro_api_client/v1/models/process.py @@ -7,6 +7,7 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..models.execution_mode import ExecutionMode from ..models.executor import Executor from ..types import UNSET, Unset @@ -34,6 +35,7 @@ class Process: is_tenant_wide (bool): Whether the process is shared with the tenant allow_multiple_sources (bool): Whether the pipeline is allowed to have multiple dataset sources uses_sample_sheet (bool): Whether the pipeline uses the Cirro-provided sample sheet + execution_modes (list[ExecutionMode]): Execution modes the pipeline supports is_archived (bool): Whether the process is marked as archived tags (list[Tag]): category (str | Unset): Category of the process Example: Microbial Analysis. @@ -42,6 +44,8 @@ class Process: https://docs.cirro.bio/pipelines/catalog_targeted_sequencing/#crispr-screen-analysis. file_requirements_message (str | Unset): Description of the files to be uploaded (optional) owner (None | str | Unset): Username of the pipeline creator (blank if Cirro curated) + maintainers (list[str] | None | Unset): Other users who maintain the pipeline. These users have access to manage + the pipeline (blank if Cirro curated) created_at (datetime.datetime | Unset): When the process was created (does not reflect the pipeline code) updated_at (datetime.datetime | Unset): When the process was updated (does not reflect the pipeline code) """ @@ -57,6 +61,7 @@ class Process: is_tenant_wide: bool allow_multiple_sources: bool uses_sample_sheet: bool + execution_modes: list[ExecutionMode] is_archived: bool tags: list[Tag] category: str | Unset = UNSET @@ -64,6 +69,7 @@ class Process: documentation_url: str | Unset = UNSET file_requirements_message: str | Unset = UNSET owner: None | str | Unset = UNSET + maintainers: list[str] | None | Unset = UNSET created_at: datetime.datetime | Unset = UNSET updated_at: datetime.datetime | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -91,6 +97,11 @@ def to_dict(self) -> dict[str, Any]: uses_sample_sheet = self.uses_sample_sheet + execution_modes = [] + for execution_modes_item_data in self.execution_modes: + execution_modes_item = execution_modes_item_data.value + execution_modes.append(execution_modes_item) + is_archived = self.is_archived tags = [] @@ -112,6 +123,15 @@ def to_dict(self) -> dict[str, Any]: else: owner = self.owner + maintainers: list[str] | None | Unset + if isinstance(self.maintainers, Unset): + maintainers = UNSET + elif isinstance(self.maintainers, list): + maintainers = self.maintainers + + else: + maintainers = self.maintainers + created_at: str | Unset = UNSET if not isinstance(self.created_at, Unset): created_at = self.created_at.isoformat() @@ -135,6 +155,7 @@ def to_dict(self) -> dict[str, Any]: "isTenantWide": is_tenant_wide, "allowMultipleSources": allow_multiple_sources, "usesSampleSheet": uses_sample_sheet, + "executionModes": execution_modes, "isArchived": is_archived, "tags": tags, } @@ -149,6 +170,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["fileRequirementsMessage"] = file_requirements_message if owner is not UNSET: field_dict["owner"] = owner + if maintainers is not UNSET: + field_dict["maintainers"] = maintainers if created_at is not UNSET: field_dict["createdAt"] = created_at if updated_at is not UNSET: @@ -183,6 +206,13 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: uses_sample_sheet = d.pop("usesSampleSheet") + execution_modes = [] + _execution_modes = d.pop("executionModes") + for execution_modes_item_data in _execution_modes: + execution_modes_item = ExecutionMode(execution_modes_item_data) + + execution_modes.append(execution_modes_item) + is_archived = d.pop("isArchived") tags = [] @@ -209,6 +239,23 @@ def _parse_owner(data: object) -> None | str | Unset: owner = _parse_owner(d.pop("owner", UNSET)) + def _parse_maintainers(data: object) -> list[str] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + maintainers_type_0 = cast(list[str], data) + + return maintainers_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + maintainers = _parse_maintainers(d.pop("maintainers", UNSET)) + _created_at = d.pop("createdAt", UNSET) created_at: datetime.datetime | Unset if isinstance(_created_at, Unset): @@ -235,6 +282,7 @@ def _parse_owner(data: object) -> None | str | Unset: is_tenant_wide=is_tenant_wide, allow_multiple_sources=allow_multiple_sources, uses_sample_sheet=uses_sample_sheet, + execution_modes=execution_modes, is_archived=is_archived, tags=tags, category=category, @@ -242,6 +290,7 @@ def _parse_owner(data: object) -> None | str | Unset: documentation_url=documentation_url, file_requirements_message=file_requirements_message, owner=owner, + maintainers=maintainers, created_at=created_at, updated_at=updated_at, ) diff --git a/cirro_api_client/v1/models/process_detail.py b/cirro_api_client/v1/models/process_detail.py index 1f517eb..b36a39d 100644 --- a/cirro_api_client/v1/models/process_detail.py +++ b/cirro_api_client/v1/models/process_detail.py @@ -8,6 +8,7 @@ from attrs import field as _attrs_field from ..models.config_source import ConfigSource +from ..models.execution_mode import ExecutionMode from ..models.executor import Executor from ..types import UNSET, Unset @@ -38,6 +39,7 @@ class ProcessDetail: is_tenant_wide (bool): Whether the process is shared with the tenant allow_multiple_sources (bool): Whether the pipeline is allowed to have multiple dataset sources uses_sample_sheet (bool): Whether the pipeline uses the Cirro-provided sample sheet + execution_modes (list[ExecutionMode]): Execution modes the pipeline supports is_archived (bool): Whether the process is marked as archived tags (list[Tag]): config_source (ConfigSource): Storage backend for the custom pipeline's configuration files @@ -48,6 +50,8 @@ class ProcessDetail: file_requirements_message (str | Unset): Description of the files to be uploaded (optional) pipeline_code (None | PipelineCode | Unset): owner (None | str | Unset): Username of the pipeline creator (blank if Cirro curated) + maintainers (list[str] | None | Unset): Other users who maintain the pipeline. These users have access to manage + the pipeline (blank if Cirro curated) custom_settings (CustomPipelineSettings | None | Unset): file_mapping_rules (list[FileMappingRule] | None | Unset): created_at (datetime.datetime | Unset): When the process was created (does not reflect the pipeline code) @@ -65,6 +69,7 @@ class ProcessDetail: is_tenant_wide: bool allow_multiple_sources: bool uses_sample_sheet: bool + execution_modes: list[ExecutionMode] is_archived: bool tags: list[Tag] config_source: ConfigSource @@ -74,6 +79,7 @@ class ProcessDetail: file_requirements_message: str | Unset = UNSET pipeline_code: None | PipelineCode | Unset = UNSET owner: None | str | Unset = UNSET + maintainers: list[str] | None | Unset = UNSET custom_settings: CustomPipelineSettings | None | Unset = UNSET file_mapping_rules: list[FileMappingRule] | None | Unset = UNSET created_at: datetime.datetime | Unset = UNSET @@ -106,6 +112,11 @@ def to_dict(self) -> dict[str, Any]: uses_sample_sheet = self.uses_sample_sheet + execution_modes = [] + for execution_modes_item_data in self.execution_modes: + execution_modes_item = execution_modes_item_data.value + execution_modes.append(execution_modes_item) + is_archived = self.is_archived tags = [] @@ -137,6 +148,15 @@ def to_dict(self) -> dict[str, Any]: else: owner = self.owner + maintainers: list[str] | None | Unset + if isinstance(self.maintainers, Unset): + maintainers = UNSET + elif isinstance(self.maintainers, list): + maintainers = self.maintainers + + else: + maintainers = self.maintainers + custom_settings: dict[str, Any] | None | Unset if isinstance(self.custom_settings, Unset): custom_settings = UNSET @@ -180,6 +200,7 @@ def to_dict(self) -> dict[str, Any]: "isTenantWide": is_tenant_wide, "allowMultipleSources": allow_multiple_sources, "usesSampleSheet": uses_sample_sheet, + "executionModes": execution_modes, "isArchived": is_archived, "tags": tags, "configSource": config_source, @@ -197,6 +218,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["pipelineCode"] = pipeline_code if owner is not UNSET: field_dict["owner"] = owner + if maintainers is not UNSET: + field_dict["maintainers"] = maintainers if custom_settings is not UNSET: field_dict["customSettings"] = custom_settings if file_mapping_rules is not UNSET: @@ -238,6 +261,13 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: uses_sample_sheet = d.pop("usesSampleSheet") + execution_modes = [] + _execution_modes = d.pop("executionModes") + for execution_modes_item_data in _execution_modes: + execution_modes_item = ExecutionMode(execution_modes_item_data) + + execution_modes.append(execution_modes_item) + is_archived = d.pop("isArchived") tags = [] @@ -283,6 +313,23 @@ def _parse_owner(data: object) -> None | str | Unset: owner = _parse_owner(d.pop("owner", UNSET)) + def _parse_maintainers(data: object) -> list[str] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + maintainers_type_0 = cast(list[str], data) + + return maintainers_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + maintainers = _parse_maintainers(d.pop("maintainers", UNSET)) + def _parse_custom_settings(data: object) -> CustomPipelineSettings | None | Unset: if data is None: return data @@ -348,6 +395,7 @@ def _parse_file_mapping_rules(data: object) -> list[FileMappingRule] | None | Un is_tenant_wide=is_tenant_wide, allow_multiple_sources=allow_multiple_sources, uses_sample_sheet=uses_sample_sheet, + execution_modes=execution_modes, is_archived=is_archived, tags=tags, config_source=config_source, @@ -357,6 +405,7 @@ def _parse_file_mapping_rules(data: object) -> list[FileMappingRule] | None | Un file_requirements_message=file_requirements_message, pipeline_code=pipeline_code, owner=owner, + maintainers=maintainers, custom_settings=custom_settings, file_mapping_rules=file_mapping_rules, created_at=created_at, diff --git a/cirro_api_client/v1/models/process_parameter_schema.py b/cirro_api_client/v1/models/process_parameter_schema.py new file mode 100644 index 0000000..a73a1b7 --- /dev/null +++ b/cirro_api_client/v1/models/process_parameter_schema.py @@ -0,0 +1,115 @@ +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 + +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.process_parameter_schema_form import ProcessParameterSchemaForm + from ..models.process_parameter_schema_input_file_requirements import ProcessParameterSchemaInputFileRequirements + from ..models.process_parameter_schema_ui import ProcessParameterSchemaUi + + +T = TypeVar("T", bound="ProcessParameterSchema") + + +@_attrs_define +class ProcessParameterSchema: + """ + Attributes: + form (ProcessParameterSchemaForm | Unset): JSONSchema representation of the form rendered for the end-user when + executing a pipeline + ui (ProcessParameterSchemaUi | Unset): Describes how the form should be rendered on the UI, see rjsf uiSchema + customizations + input_file_requirements (ProcessParameterSchemaInputFileRequirements | Unset): Structured file inputs required + by this process, keyed by requirement name (referenced elsewhere, e.g. in form, by this same key) + """ + + form: ProcessParameterSchemaForm | Unset = UNSET + ui: ProcessParameterSchemaUi | Unset = UNSET + input_file_requirements: ProcessParameterSchemaInputFileRequirements | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + form: dict[str, Any] | Unset = UNSET + if not isinstance(self.form, Unset): + form = self.form.to_dict() + + ui: dict[str, Any] | Unset = UNSET + if not isinstance(self.ui, Unset): + ui = self.ui.to_dict() + + input_file_requirements: dict[str, Any] | Unset = UNSET + if not isinstance(self.input_file_requirements, Unset): + input_file_requirements = self.input_file_requirements.to_dict() + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if form is not UNSET: + field_dict["form"] = form + if ui is not UNSET: + field_dict["ui"] = ui + if input_file_requirements is not UNSET: + field_dict["inputFileRequirements"] = input_file_requirements + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.process_parameter_schema_form import ProcessParameterSchemaForm + from ..models.process_parameter_schema_input_file_requirements import ( + ProcessParameterSchemaInputFileRequirements, + ) + from ..models.process_parameter_schema_ui import ProcessParameterSchemaUi + + d = dict(src_dict) + _form = d.pop("form", UNSET) + form: ProcessParameterSchemaForm | Unset + if isinstance(_form, Unset): + form = UNSET + else: + form = ProcessParameterSchemaForm.from_dict(_form) + + _ui = d.pop("ui", UNSET) + ui: ProcessParameterSchemaUi | Unset + if isinstance(_ui, Unset): + ui = UNSET + else: + ui = ProcessParameterSchemaUi.from_dict(_ui) + + _input_file_requirements = d.pop("inputFileRequirements", UNSET) + input_file_requirements: ProcessParameterSchemaInputFileRequirements | Unset + if isinstance(_input_file_requirements, Unset): + input_file_requirements = UNSET + else: + input_file_requirements = ProcessParameterSchemaInputFileRequirements.from_dict(_input_file_requirements) + + process_parameter_schema = cls( + form=form, + ui=ui, + input_file_requirements=input_file_requirements, + ) + + process_parameter_schema.additional_properties = d + return process_parameter_schema + + @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/cirro_api_client/v1/models/process_parameter_schema_form.py b/cirro_api_client/v1/models/process_parameter_schema_form.py new file mode 100644 index 0000000..73d5c25 --- /dev/null +++ b/cirro_api_client/v1/models/process_parameter_schema_form.py @@ -0,0 +1,47 @@ +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="ProcessParameterSchemaForm") + + +@_attrs_define +class ProcessParameterSchemaForm: + """JSONSchema representation of the form rendered for the end-user when executing a pipeline""" + + 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) + process_parameter_schema_form = cls() + + process_parameter_schema_form.additional_properties = d + return process_parameter_schema_form + + @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/cirro_api_client/v1/models/process_parameter_schema_input_file_requirements.py b/cirro_api_client/v1/models/process_parameter_schema_input_file_requirements.py new file mode 100644 index 0000000..e9aa62c --- /dev/null +++ b/cirro_api_client/v1/models/process_parameter_schema_input_file_requirements.py @@ -0,0 +1,63 @@ +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.input_file_requirement import InputFileRequirement + + +T = TypeVar("T", bound="ProcessParameterSchemaInputFileRequirements") + + +@_attrs_define +class ProcessParameterSchemaInputFileRequirements: + """Structured file inputs required by this process, keyed by requirement name (referenced elsewhere, e.g. in form, by + this same key) + + """ + + additional_properties: dict[str, InputFileRequirement] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + + field_dict: dict[str, Any] = {} + for prop_name, prop in self.additional_properties.items(): + field_dict[prop_name] = prop.to_dict() + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.input_file_requirement import InputFileRequirement + + d = dict(src_dict) + process_parameter_schema_input_file_requirements = cls() + + additional_properties = {} + for prop_name, prop_dict in d.items(): + additional_property = InputFileRequirement.from_dict(prop_dict) + + additional_properties[prop_name] = additional_property + + process_parameter_schema_input_file_requirements.additional_properties = additional_properties + return process_parameter_schema_input_file_requirements + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> InputFileRequirement: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: InputFileRequirement) -> 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/cirro_api_client/v1/models/process_parameter_schema_ui.py b/cirro_api_client/v1/models/process_parameter_schema_ui.py new file mode 100644 index 0000000..fc24758 --- /dev/null +++ b/cirro_api_client/v1/models/process_parameter_schema_ui.py @@ -0,0 +1,47 @@ +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="ProcessParameterSchemaUi") + + +@_attrs_define +class ProcessParameterSchemaUi: + """Describes how the form should be rendered on the UI, see rjsf uiSchema customizations""" + + 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) + process_parameter_schema_ui = cls() + + process_parameter_schema_ui.additional_properties = d + return process_parameter_schema_ui + + @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/cirro_api_client/v1/models/process_resource.py b/cirro_api_client/v1/models/process_resource.py index 835a0cd..d9cd837 100644 --- a/cirro_api_client/v1/models/process_resource.py +++ b/cirro_api_client/v1/models/process_resource.py @@ -6,7 +6,6 @@ class ProcessResource(str, Enum): DOCUMENTATION = "documentation" FORM = "form" INPUT = "input" - METADATA = "metadata" OUTPUT = "output" PREPROCESS = "preprocess" UNKNOWN = "UNKNOWN" diff --git a/cirro_api_client/v1/models/project_detail.py b/cirro_api_client/v1/models/project_detail.py index 7e6a9c1..0a08406 100644 --- a/cirro_api_client/v1/models/project_detail.py +++ b/cirro_api_client/v1/models/project_detail.py @@ -40,6 +40,7 @@ class ProjectDetail: created_at (datetime.datetime): updated_at (datetime.datetime): deployed_at (datetime.datetime | None | Unset): + deployed_version (None | str | Unset): """ id: str @@ -58,6 +59,7 @@ class ProjectDetail: created_at: datetime.datetime updated_at: datetime.datetime deployed_at: datetime.datetime | None | Unset = UNSET + deployed_version: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -105,6 +107,12 @@ def to_dict(self) -> dict[str, Any]: else: deployed_at = self.deployed_at + deployed_version: None | str | Unset + if isinstance(self.deployed_version, Unset): + deployed_version = UNSET + else: + deployed_version = self.deployed_version + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -128,6 +136,8 @@ def to_dict(self) -> dict[str, Any]: ) if deployed_at is not UNSET: field_dict["deployedAt"] = deployed_at + if deployed_version is not UNSET: + field_dict["deployedVersion"] = deployed_version return field_dict @@ -196,6 +206,15 @@ def _parse_deployed_at(data: object) -> datetime.datetime | None | Unset: deployed_at = _parse_deployed_at(d.pop("deployedAt", UNSET)) + def _parse_deployed_version(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + deployed_version = _parse_deployed_version(d.pop("deployedVersion", UNSET)) + project_detail = cls( id=id, name=name, @@ -213,6 +232,7 @@ def _parse_deployed_at(data: object) -> datetime.datetime | None | Unset: created_at=created_at, updated_at=updated_at, deployed_at=deployed_at, + deployed_version=deployed_version, ) project_detail.additional_properties = d diff --git a/cirro_api_client/v1/models/project_file.py b/cirro_api_client/v1/models/project_file.py new file mode 100644 index 0000000..0b4a0d1 --- /dev/null +++ b/cirro_api_client/v1/models/project_file.py @@ -0,0 +1,152 @@ +from __future__ import annotations + +import datetime +from collections.abc import Mapping +from typing import Any, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..models.dataset_source import DatasetSource +from ..types import UNSET, Unset + +T = TypeVar("T", bound="ProjectFile") + + +@_attrs_define +class ProjectFile: + """ + Attributes: + dataset_id (str | Unset): What dataset ID this file originated from + path (str | Unset): Relative path to file Example: fastq/SRX12875516_SRR16674827_1.fastq.gz. + absolute_path (str | Unset): Absolute path to file Example: + s3://project-1a1a/datasets/2a2a/data/fastq/SRX12875516_SRR16674827_1.fastq.gz. + source (DatasetSource | Unset): How the containing dataset was generated: INGESTED (uploaded) or DERIVED + (produced by a pipeline) + process_id (str | Unset): What process created the containing dataset (pipeline or data type) + file_type (str | Unset): File type derived from the extension, compression suffixes stripped; null when the file + has no extension Example: fastq. + size (int | Unset): File size (in bytes) Example: 1435658507. + created_by (str | Unset): Who created the containing dataset + created_at (datetime.datetime | Unset): When the file was created + """ + + dataset_id: str | Unset = UNSET + path: str | Unset = UNSET + absolute_path: str | Unset = UNSET + source: DatasetSource | Unset = UNSET + process_id: str | Unset = UNSET + file_type: str | Unset = UNSET + size: int | Unset = UNSET + created_by: str | Unset = UNSET + created_at: datetime.datetime | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + dataset_id = self.dataset_id + + path = self.path + + absolute_path = self.absolute_path + + source: str | Unset = UNSET + if not isinstance(self.source, Unset): + source = self.source.value + + process_id = self.process_id + + file_type = self.file_type + + size = self.size + + created_by = self.created_by + + created_at: str | Unset = UNSET + if not isinstance(self.created_at, Unset): + created_at = self.created_at.isoformat() + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if dataset_id is not UNSET: + field_dict["datasetId"] = dataset_id + if path is not UNSET: + field_dict["path"] = path + if absolute_path is not UNSET: + field_dict["absolutePath"] = absolute_path + if source is not UNSET: + field_dict["source"] = source + if process_id is not UNSET: + field_dict["processId"] = process_id + if file_type is not UNSET: + field_dict["fileType"] = file_type + if size is not UNSET: + field_dict["size"] = size + if created_by is not UNSET: + field_dict["createdBy"] = created_by + if created_at is not UNSET: + field_dict["createdAt"] = created_at + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + dataset_id = d.pop("datasetId", UNSET) + + path = d.pop("path", UNSET) + + absolute_path = d.pop("absolutePath", UNSET) + + _source = d.pop("source", UNSET) + source: DatasetSource | Unset + if isinstance(_source, Unset): + source = UNSET + else: + source = DatasetSource(_source) + + process_id = d.pop("processId", UNSET) + + file_type = d.pop("fileType", UNSET) + + size = d.pop("size", UNSET) + + created_by = d.pop("createdBy", UNSET) + + _created_at = d.pop("createdAt", UNSET) + created_at: datetime.datetime | Unset + if isinstance(_created_at, Unset): + created_at = UNSET + else: + created_at = datetime.datetime.fromisoformat(_created_at) + + project_file = cls( + dataset_id=dataset_id, + path=path, + absolute_path=absolute_path, + source=source, + process_id=process_id, + file_type=file_type, + size=size, + created_by=created_by, + created_at=created_at, + ) + + project_file.additional_properties = d + return project_file + + @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/cirro_api_client/v1/models/project_file_query_response.py b/cirro_api_client/v1/models/project_file_query_response.py new file mode 100644 index 0000000..5fe587f --- /dev/null +++ b/cirro_api_client/v1/models/project_file_query_response.py @@ -0,0 +1,117 @@ +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.project_file import ProjectFile + + +T = TypeVar("T", bound="ProjectFileQueryResponse") + + +@_attrs_define +class ProjectFileQueryResponse: + """ + Attributes: + data (list[ProjectFile]): + next_token (None | str | Unset): Token used to fetch the next page; null when there are no more results + total_count (int | None | Unset): Total number of files matching the query; only populated on the first page + """ + + data: list[ProjectFile] + next_token: None | str | Unset = UNSET + total_count: int | None | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data = [] + for data_item_data in self.data: + data_item = data_item_data.to_dict() + data.append(data_item) + + next_token: None | str | Unset + if isinstance(self.next_token, Unset): + next_token = UNSET + else: + next_token = self.next_token + + total_count: int | None | Unset + if isinstance(self.total_count, Unset): + total_count = UNSET + else: + total_count = self.total_count + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "data": data, + } + ) + if next_token is not UNSET: + field_dict["nextToken"] = next_token + if total_count is not UNSET: + field_dict["totalCount"] = total_count + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.project_file import ProjectFile + + d = dict(src_dict) + data = [] + _data = d.pop("data") + for data_item_data in _data: + data_item = ProjectFile.from_dict(data_item_data) + + data.append(data_item) + + def _parse_next_token(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + next_token = _parse_next_token(d.pop("nextToken", UNSET)) + + def _parse_total_count(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + total_count = _parse_total_count(d.pop("totalCount", UNSET)) + + project_file_query_response = cls( + data=data, + next_token=next_token, + total_count=total_count, + ) + + project_file_query_response.additional_properties = d + return project_file_query_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/cirro_api_client/v1/models/row_insert.py b/cirro_api_client/v1/models/row_insert.py index 32bef5e..bdb0cd0 100644 --- a/cirro_api_client/v1/models/row_insert.py +++ b/cirro_api_client/v1/models/row_insert.py @@ -18,7 +18,10 @@ class RowInsert: """ Attributes: values (RowInsertValues): Column name and value. Any missing columns will have a null value (will error if - column is required). Example: {'icd_code': 'G65'}. + column is required). Cirro-typed columns hold Cirro URIs of the form + cirro:::data:/ (scope segments may be empty; path relative to the + dataset's data directory). CIRRO_DATASET cells reference the dataset itself and have no path. Example: + {'icd_code': 'G65', 'sample_file': 'cirro::1a1a...:data:d4f1.../results/sample1.fastq.gz'}. """ values: RowInsertValues diff --git a/cirro_api_client/v1/models/row_insert_values.py b/cirro_api_client/v1/models/row_insert_values.py index 6c668c7..e6eb282 100644 --- a/cirro_api_client/v1/models/row_insert_values.py +++ b/cirro_api_client/v1/models/row_insert_values.py @@ -1,61 +1,51 @@ from __future__ import annotations from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar +from typing import Any, TypeVar from attrs import define as _attrs_define from attrs import field as _attrs_field -if TYPE_CHECKING: - from ..models.row_insert_values_additional_property import RowInsertValuesAdditionalProperty - - T = TypeVar("T", bound="RowInsertValues") @_attrs_define class RowInsertValues: - """Column name and value. Any missing columns will have a null value (will error if column is required). + """Column name and value. Any missing columns will have a null value (will error if column is required). Cirro-typed + columns hold Cirro URIs of the form cirro:::data:/ (scope segments may be + empty; path relative to the dataset's data directory). CIRRO_DATASET cells reference the dataset itself and have no + path. - Example: - {'icd_code': 'G65'} + Example: + {'icd_code': 'G65', 'sample_file': 'cirro::1a1a...:data:d4f1.../results/sample1.fastq.gz'} """ - additional_properties: dict[str, RowInsertValuesAdditionalProperty] = _attrs_field(init=False, factory=dict) + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: field_dict: dict[str, Any] = {} - for prop_name, prop in self.additional_properties.items(): - field_dict[prop_name] = prop.to_dict() + field_dict.update(self.additional_properties) return field_dict @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.row_insert_values_additional_property import RowInsertValuesAdditionalProperty - d = dict(src_dict) row_insert_values = cls() - additional_properties = {} - for prop_name, prop_dict in d.items(): - additional_property = RowInsertValuesAdditionalProperty.from_dict(prop_dict) - - additional_properties[prop_name] = additional_property - - row_insert_values.additional_properties = additional_properties + row_insert_values.additional_properties = d return row_insert_values @property def additional_keys(self) -> list[str]: return list(self.additional_properties.keys()) - def __getitem__(self, key: str) -> RowInsertValuesAdditionalProperty: + def __getitem__(self, key: str) -> Any: return self.additional_properties[key] - def __setitem__(self, key: str, value: RowInsertValuesAdditionalProperty) -> None: + def __setitem__(self, key: str, value: Any) -> None: self.additional_properties[key] = value def __delitem__(self, key: str) -> None: diff --git a/cirro_api_client/v1/models/row_update.py b/cirro_api_client/v1/models/row_update.py index a0024d1..2cd03c0 100644 --- a/cirro_api_client/v1/models/row_update.py +++ b/cirro_api_client/v1/models/row_update.py @@ -19,7 +19,10 @@ class RowUpdate: Attributes: row_id (int): _row_id, which serves as the primary key to identify the row. Example: 42. values (RowUpdateValues): Column name and new value. Only the columns included here are updated; all other - columns on the row are left unchanged. At least one entry is required. Example: {'icd_code': 'G65'}. + columns on the row are left unchanged. At least one entry is required. Cirro-typed columns hold Cirro URIs of + the form cirro:::data:/ (scope segments may be empty; path relative to the + dataset's data directory). CIRRO_DATASET cells reference the dataset itself and have no path. Example: + {'icd_code': 'G65', 'sample_file': 'cirro::1a1a...:data:d4f1.../results/sample1.fastq.gz'}. """ row_id: int diff --git a/cirro_api_client/v1/models/row_update_values.py b/cirro_api_client/v1/models/row_update_values.py index 0819242..8d74acb 100644 --- a/cirro_api_client/v1/models/row_update_values.py +++ b/cirro_api_client/v1/models/row_update_values.py @@ -1,62 +1,51 @@ from __future__ import annotations from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar +from typing import Any, TypeVar from attrs import define as _attrs_define from attrs import field as _attrs_field -if TYPE_CHECKING: - from ..models.row_update_values_additional_property import RowUpdateValuesAdditionalProperty - - T = TypeVar("T", bound="RowUpdateValues") @_attrs_define class RowUpdateValues: """Column name and new value. Only the columns included here are updated; all other columns on the row are left - unchanged. At least one entry is required. + unchanged. At least one entry is required. Cirro-typed columns hold Cirro URIs of the form + cirro:::data:/ (scope segments may be empty; path relative to the dataset's + data directory). CIRRO_DATASET cells reference the dataset itself and have no path. Example: - {'icd_code': 'G65'} + {'icd_code': 'G65', 'sample_file': 'cirro::1a1a...:data:d4f1.../results/sample1.fastq.gz'} """ - additional_properties: dict[str, RowUpdateValuesAdditionalProperty] = _attrs_field(init=False, factory=dict) + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: field_dict: dict[str, Any] = {} - for prop_name, prop in self.additional_properties.items(): - field_dict[prop_name] = prop.to_dict() + field_dict.update(self.additional_properties) return field_dict @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.row_update_values_additional_property import RowUpdateValuesAdditionalProperty - d = dict(src_dict) row_update_values = cls() - additional_properties = {} - for prop_name, prop_dict in d.items(): - additional_property = RowUpdateValuesAdditionalProperty.from_dict(prop_dict) - - additional_properties[prop_name] = additional_property - - row_update_values.additional_properties = additional_properties + row_update_values.additional_properties = d return row_update_values @property def additional_keys(self) -> list[str]: return list(self.additional_properties.keys()) - def __getitem__(self, key: str) -> RowUpdateValuesAdditionalProperty: + def __getitem__(self, key: str) -> Any: return self.additional_properties[key] - def __setitem__(self, key: str, value: RowUpdateValuesAdditionalProperty) -> None: + def __setitem__(self, key: str, value: Any) -> None: self.additional_properties[key] = value def __delitem__(self, key: str) -> None: diff --git a/cirro_api_client/v1/models/run_analysis_request.py b/cirro_api_client/v1/models/run_analysis_request.py index 4833b3b..36366be 100644 --- a/cirro_api_client/v1/models/run_analysis_request.py +++ b/cirro_api_client/v1/models/run_analysis_request.py @@ -6,11 +6,13 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..models.environment_type import EnvironmentType from ..types import UNSET, Unset if TYPE_CHECKING: from ..models.run_analysis_request_params import RunAnalysisRequestParams from ..models.run_analysis_request_source_sample_files_map import RunAnalysisRequestSourceSampleFilesMap + from ..models.run_analysis_request_structured_file_inputs import RunAnalysisRequestStructuredFileInputs from ..models.tag import Tag @@ -34,8 +36,12 @@ class RunAnalysisRequest: the lists are file paths to include. resume_dataset_id (None | str | Unset): Used for caching task execution. If the parameters are the same as the dataset specified here, it will re-use the output to minimize duplicate work + structured_file_inputs (None | RunAnalysisRequestStructuredFileInputs | Unset): Structured file inputs used in + the workflow (can be empty), keyed by the input name on `inputFileRequirements` compute_environment_id (None | str | Unset): The compute environment where to run the workflow, if not specified, it will run in AWS + environment_type (EnvironmentType | None | Unset): The type of execution environment to run the workflow in, if + not specified, the default for the pipeline is used tags (list[Tag] | None | Unset): List of tags to apply to the dataset """ @@ -48,12 +54,15 @@ class RunAnalysisRequest: source_sample_ids: list[str] | None | Unset = UNSET source_sample_files_map: None | RunAnalysisRequestSourceSampleFilesMap | Unset = UNSET resume_dataset_id: None | str | Unset = UNSET + structured_file_inputs: None | RunAnalysisRequestStructuredFileInputs | Unset = UNSET compute_environment_id: None | str | Unset = UNSET + environment_type: EnvironmentType | None | Unset = UNSET tags: list[Tag] | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: from ..models.run_analysis_request_source_sample_files_map import RunAnalysisRequestSourceSampleFilesMap + from ..models.run_analysis_request_structured_file_inputs import RunAnalysisRequestStructuredFileInputs name = self.name @@ -94,12 +103,28 @@ def to_dict(self) -> dict[str, Any]: else: resume_dataset_id = self.resume_dataset_id + structured_file_inputs: dict[str, Any] | None | Unset + if isinstance(self.structured_file_inputs, Unset): + structured_file_inputs = UNSET + elif isinstance(self.structured_file_inputs, RunAnalysisRequestStructuredFileInputs): + structured_file_inputs = self.structured_file_inputs.to_dict() + else: + structured_file_inputs = self.structured_file_inputs + compute_environment_id: None | str | Unset if isinstance(self.compute_environment_id, Unset): compute_environment_id = UNSET else: compute_environment_id = self.compute_environment_id + environment_type: None | str | Unset + if isinstance(self.environment_type, Unset): + environment_type = UNSET + elif isinstance(self.environment_type, EnvironmentType): + environment_type = self.environment_type.value + else: + environment_type = self.environment_type + tags: list[dict[str, Any]] | None | Unset if isinstance(self.tags, Unset): tags = UNSET @@ -131,8 +156,12 @@ def to_dict(self) -> dict[str, Any]: field_dict["sourceSampleFilesMap"] = source_sample_files_map if resume_dataset_id is not UNSET: field_dict["resumeDatasetId"] = resume_dataset_id + if structured_file_inputs is not UNSET: + field_dict["structuredFileInputs"] = structured_file_inputs if compute_environment_id is not UNSET: field_dict["computeEnvironmentId"] = compute_environment_id + if environment_type is not UNSET: + field_dict["environmentType"] = environment_type if tags is not UNSET: field_dict["tags"] = tags @@ -142,6 +171,7 @@ def to_dict(self) -> dict[str, Any]: def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: from ..models.run_analysis_request_params import RunAnalysisRequestParams from ..models.run_analysis_request_source_sample_files_map import RunAnalysisRequestSourceSampleFilesMap + from ..models.run_analysis_request_structured_file_inputs import RunAnalysisRequestStructuredFileInputs from ..models.tag import Tag d = dict(src_dict) @@ -207,6 +237,23 @@ def _parse_resume_dataset_id(data: object) -> None | str | Unset: resume_dataset_id = _parse_resume_dataset_id(d.pop("resumeDatasetId", UNSET)) + def _parse_structured_file_inputs(data: object) -> None | RunAnalysisRequestStructuredFileInputs | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + structured_file_inputs_type_0 = RunAnalysisRequestStructuredFileInputs.from_dict(data) + + return structured_file_inputs_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | RunAnalysisRequestStructuredFileInputs | Unset, data) + + structured_file_inputs = _parse_structured_file_inputs(d.pop("structuredFileInputs", UNSET)) + def _parse_compute_environment_id(data: object) -> None | str | Unset: if data is None: return data @@ -216,6 +263,23 @@ def _parse_compute_environment_id(data: object) -> None | str | Unset: compute_environment_id = _parse_compute_environment_id(d.pop("computeEnvironmentId", UNSET)) + def _parse_environment_type(data: object) -> EnvironmentType | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + environment_type_type_1 = EnvironmentType(data) + + return environment_type_type_1 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(EnvironmentType | None | Unset, data) + + environment_type = _parse_environment_type(d.pop("environmentType", UNSET)) + def _parse_tags(data: object) -> list[Tag] | None | Unset: if data is None: return data @@ -248,7 +312,9 @@ def _parse_tags(data: object) -> list[Tag] | None | Unset: source_sample_ids=source_sample_ids, source_sample_files_map=source_sample_files_map, resume_dataset_id=resume_dataset_id, + structured_file_inputs=structured_file_inputs, compute_environment_id=compute_environment_id, + environment_type=environment_type, tags=tags, ) diff --git a/cirro_api_client/v1/models/run_analysis_request_structured_file_inputs.py b/cirro_api_client/v1/models/run_analysis_request_structured_file_inputs.py new file mode 100644 index 0000000..9552db5 --- /dev/null +++ b/cirro_api_client/v1/models/run_analysis_request_structured_file_inputs.py @@ -0,0 +1,60 @@ +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.structured_file_input import StructuredFileInput + + +T = TypeVar("T", bound="RunAnalysisRequestStructuredFileInputs") + + +@_attrs_define +class RunAnalysisRequestStructuredFileInputs: + """Structured file inputs used in the workflow (can be empty), keyed by the input name on `inputFileRequirements`""" + + additional_properties: dict[str, StructuredFileInput] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + + field_dict: dict[str, Any] = {} + for prop_name, prop in self.additional_properties.items(): + field_dict[prop_name] = prop.to_dict() + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.structured_file_input import StructuredFileInput + + d = dict(src_dict) + run_analysis_request_structured_file_inputs = cls() + + additional_properties = {} + for prop_name, prop_dict in d.items(): + additional_property = StructuredFileInput.from_dict(prop_dict) + + additional_properties[prop_name] = additional_property + + run_analysis_request_structured_file_inputs.additional_properties = additional_properties + return run_analysis_request_structured_file_inputs + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> StructuredFileInput: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: StructuredFileInput) -> 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/cirro_api_client/v1/models/semantic_column_type.py b/cirro_api_client/v1/models/semantic_column_type.py index ca438d2..cfc806f 100644 --- a/cirro_api_client/v1/models/semantic_column_type.py +++ b/cirro_api_client/v1/models/semantic_column_type.py @@ -2,12 +2,11 @@ class SemanticColumnType(str, Enum): - DATASET_LINK = "DATASET_LINK" - ENTITY_KEY = "ENTITY_KEY" - ENTITY_NAME = "ENTITY_NAME" + CIRRO_DATASET = "CIRRO_DATASET" + CIRRO_FILE = "CIRRO_FILE" + CIRRO_FOLDER = "CIRRO_FOLDER" ENUM_MULTI = "ENUM_MULTI" ENUM_SINGLE = "ENUM_SINGLE" - FILE_LINK = "FILE_LINK" FOREIGN_KEY = "FOREIGN_KEY" STANDARD = "STANDARD" URL = "URL" diff --git a/cirro_api_client/v1/models/sheet.py b/cirro_api_client/v1/models/sheet.py index 3c57f1c..a0b40e4 100644 --- a/cirro_api_client/v1/models/sheet.py +++ b/cirro_api_client/v1/models/sheet.py @@ -2,7 +2,7 @@ import datetime from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar, cast from attrs import define as _attrs_define from attrs import field as _attrs_field @@ -10,8 +10,10 @@ from ..models.sheet_creation_mode import SheetCreationMode from ..models.sheet_type import SheetType from ..models.status import Status +from ..types import UNSET, Unset if TYPE_CHECKING: + from ..models.column_relationship import ColumnRelationship from ..models.tag import Tag @@ -30,12 +32,15 @@ class Sheet: project_id (str): sheet_type (SheetType): sheet_creation_mode (SheetCreationMode): + virtual (bool): status (Status): created_by (str): created_at (datetime.datetime): updated_at (datetime.datetime): - total_row_count (int): tags (list[Tag]): + column_relationships (list[ColumnRelationship]): + total_row_count (int | None | Unset): Stored row count, maintained on writes. Null for virtual views, whose rows + are only counted at query time. """ id: str @@ -46,12 +51,14 @@ class Sheet: project_id: str sheet_type: SheetType sheet_creation_mode: SheetCreationMode + virtual: bool status: Status created_by: str created_at: datetime.datetime updated_at: datetime.datetime - total_row_count: int tags: list[Tag] + column_relationships: list[ColumnRelationship] + total_row_count: int | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -71,6 +78,8 @@ def to_dict(self) -> dict[str, Any]: sheet_creation_mode = self.sheet_creation_mode.value + virtual = self.virtual + status = self.status.value created_by = self.created_by @@ -79,13 +88,22 @@ def to_dict(self) -> dict[str, Any]: updated_at = self.updated_at.isoformat() - total_row_count = self.total_row_count - tags = [] for tags_item_data in self.tags: tags_item = tags_item_data.to_dict() tags.append(tags_item) + column_relationships = [] + for column_relationships_item_data in self.column_relationships: + column_relationships_item = column_relationships_item_data.to_dict() + column_relationships.append(column_relationships_item) + + total_row_count: int | None | Unset + if isinstance(self.total_row_count, Unset): + total_row_count = UNSET + else: + total_row_count = self.total_row_count + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -98,19 +116,23 @@ def to_dict(self) -> dict[str, Any]: "projectId": project_id, "sheetType": sheet_type, "sheetCreationMode": sheet_creation_mode, + "virtual": virtual, "status": status, "createdBy": created_by, "createdAt": created_at, "updatedAt": updated_at, - "totalRowCount": total_row_count, "tags": tags, + "columnRelationships": column_relationships, } ) + if total_row_count is not UNSET: + field_dict["totalRowCount"] = total_row_count return field_dict @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.column_relationship import ColumnRelationship from ..models.tag import Tag d = dict(src_dict) @@ -130,6 +152,8 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: sheet_creation_mode = SheetCreationMode(d.pop("sheetCreationMode")) + virtual = d.pop("virtual") + status = Status(d.pop("status")) created_by = d.pop("createdBy") @@ -138,8 +162,6 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: updated_at = datetime.datetime.fromisoformat(d.pop("updatedAt")) - total_row_count = d.pop("totalRowCount") - tags = [] _tags = d.pop("tags") for tags_item_data in _tags: @@ -147,6 +169,22 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: tags.append(tags_item) + column_relationships = [] + _column_relationships = d.pop("columnRelationships") + for column_relationships_item_data in _column_relationships: + column_relationships_item = ColumnRelationship.from_dict(column_relationships_item_data) + + column_relationships.append(column_relationships_item) + + def _parse_total_row_count(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + total_row_count = _parse_total_row_count(d.pop("totalRowCount", UNSET)) + sheet = cls( id=id, name=name, @@ -156,12 +194,14 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: project_id=project_id, sheet_type=sheet_type, sheet_creation_mode=sheet_creation_mode, + virtual=virtual, status=status, created_by=created_by, created_at=created_at, updated_at=updated_at, - total_row_count=total_row_count, tags=tags, + column_relationships=column_relationships, + total_row_count=total_row_count, ) sheet.additional_properties = d diff --git a/cirro_api_client/v1/models/sheet_creation_mode.py b/cirro_api_client/v1/models/sheet_creation_mode.py index 65a3694..7acbf04 100644 --- a/cirro_api_client/v1/models/sheet_creation_mode.py +++ b/cirro_api_client/v1/models/sheet_creation_mode.py @@ -5,6 +5,7 @@ class SheetCreationMode(str, Enum): FILE = "FILE" SCRATCH = "SCRATCH" STANDARD = "STANDARD" + SYSTEM = "SYSTEM" TEMPLATE = "TEMPLATE" UNKNOWN = "UNKNOWN" """ This is a fallback value for when the value is not known, do not use this value when making requests """ diff --git a/cirro_api_client/v1/models/sheet_data_request.py b/cirro_api_client/v1/models/sheet_data_request.py index 7f8e449..8b98758 100644 --- a/cirro_api_client/v1/models/sheet_data_request.py +++ b/cirro_api_client/v1/models/sheet_data_request.py @@ -21,7 +21,8 @@ class SheetDataRequest: """Paginated sheet data query with optional sort and filter Attributes: - limit (int | None | Unset): Maximum rows to return Default: 1000. + limit (int | None | Unset): Maximum rows to return. Responses also have a size limit: with wide rows a large + page can fail with a 502 — lower the limit if so. Default: 1000. page (int | None | Unset): Page to return Default: 1. sort (None | SheetSort | Unset): Sort by column and direction. filter_ (Filter | None | Unset): Filter tree. diff --git a/cirro_api_client/v1/models/sheet_detail.py b/cirro_api_client/v1/models/sheet_detail.py index 9876491..90cdc60 100644 --- a/cirro_api_client/v1/models/sheet_detail.py +++ b/cirro_api_client/v1/models/sheet_detail.py @@ -38,15 +38,19 @@ class SheetDetail: created_by (str): created_at (datetime.datetime): updated_at (datetime.datetime): - total_row_count (int): tags (list[Tag]): - sheet_creation_mode (None | SheetCreationMode | Unset): How the table was initialized. Null for VIEW sheets. - columns (list[ColumnDef] | None | Unset): Column definitions for the table schema. Null for VIEW sheets. + sheet_creation_mode (None | SheetCreationMode | Unset): How the sheet was initialized. SYSTEM for Cirro-managed + sheets, including system views; null for user-created VIEW sheets. + columns (list[ColumnDef] | None | Unset): Column definitions for the sheet's schema. For VIEW sheets, a snapshot + derived from the view definition. view_definition (None | RawViewQueryRequest | StructuredViewQueryRequest | Unset): View definition for VIEW sheets. Null for TABLE sheets. + virtual (bool | Unset): True only for virtual (non-materialized) VIEW sheets. last_refreshed_at (datetime.datetime | None | Unset): When the view was last materialized. Null for TABLE sheets. staging_upload_path (str | Unset): S3 upload path for files to be ingested into this sheet. + total_row_count (int | None | Unset): Stored row count, maintained on writes. Null for virtual views, whose rows + are only counted at query time. schema_version_id (int | Unset): Current table schema version (starts at 0). Used for optimistic concurrency control. New tables can omit this, but updates should include this to prevent overwriting due to stale table schema metadata. @@ -64,13 +68,14 @@ class SheetDetail: created_by: str created_at: datetime.datetime updated_at: datetime.datetime - total_row_count: int tags: list[Tag] sheet_creation_mode: None | SheetCreationMode | Unset = UNSET columns: list[ColumnDef] | None | Unset = UNSET view_definition: None | RawViewQueryRequest | StructuredViewQueryRequest | Unset = UNSET + virtual: bool | Unset = UNSET last_refreshed_at: datetime.datetime | None | Unset = UNSET staging_upload_path: str | Unset = UNSET + total_row_count: int | None | Unset = UNSET schema_version_id: int | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -102,8 +107,6 @@ def to_dict(self) -> dict[str, Any]: updated_at = self.updated_at.isoformat() - total_row_count = self.total_row_count - tags = [] for tags_item_data in self.tags: tags_item = tags_item_data.to_dict() @@ -139,6 +142,8 @@ def to_dict(self) -> dict[str, Any]: else: view_definition = self.view_definition + virtual = self.virtual + last_refreshed_at: None | str | Unset if isinstance(self.last_refreshed_at, Unset): last_refreshed_at = UNSET @@ -149,6 +154,12 @@ def to_dict(self) -> dict[str, Any]: staging_upload_path = self.staging_upload_path + total_row_count: int | None | Unset + if isinstance(self.total_row_count, Unset): + total_row_count = UNSET + else: + total_row_count = self.total_row_count + schema_version_id = self.schema_version_id field_dict: dict[str, Any] = {} @@ -167,7 +178,6 @@ def to_dict(self) -> dict[str, Any]: "createdBy": created_by, "createdAt": created_at, "updatedAt": updated_at, - "totalRowCount": total_row_count, "tags": tags, } ) @@ -177,10 +187,14 @@ def to_dict(self) -> dict[str, Any]: field_dict["columns"] = columns if view_definition is not UNSET: field_dict["viewDefinition"] = view_definition + if virtual is not UNSET: + field_dict["virtual"] = virtual if last_refreshed_at is not UNSET: field_dict["lastRefreshedAt"] = last_refreshed_at if staging_upload_path is not UNSET: field_dict["stagingUploadPath"] = staging_upload_path + if total_row_count is not UNSET: + field_dict["totalRowCount"] = total_row_count if schema_version_id is not UNSET: field_dict["schemaVersionId"] = schema_version_id @@ -218,8 +232,6 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: updated_at = datetime.datetime.fromisoformat(d.pop("updatedAt")) - total_row_count = d.pop("totalRowCount") - tags = [] _tags = d.pop("tags") for tags_item_data in _tags: @@ -291,6 +303,8 @@ def _parse_view_definition(data: object) -> None | RawViewQueryRequest | Structu view_definition = _parse_view_definition(d.pop("viewDefinition", UNSET)) + virtual = d.pop("virtual", UNSET) + def _parse_last_refreshed_at(data: object) -> datetime.datetime | None | Unset: if data is None: return data @@ -310,6 +324,15 @@ def _parse_last_refreshed_at(data: object) -> datetime.datetime | None | Unset: staging_upload_path = d.pop("stagingUploadPath", UNSET) + def _parse_total_row_count(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + total_row_count = _parse_total_row_count(d.pop("totalRowCount", UNSET)) + schema_version_id = d.pop("schemaVersionId", UNSET) sheet_detail = cls( @@ -325,13 +348,14 @@ def _parse_last_refreshed_at(data: object) -> datetime.datetime | None | Unset: created_by=created_by, created_at=created_at, updated_at=updated_at, - total_row_count=total_row_count, tags=tags, sheet_creation_mode=sheet_creation_mode, columns=columns, view_definition=view_definition, + virtual=virtual, last_refreshed_at=last_refreshed_at, staging_upload_path=staging_upload_path, + total_row_count=total_row_count, schema_version_id=schema_version_id, ) diff --git a/cirro_api_client/v1/models/sheet_ingest_request.py b/cirro_api_client/v1/models/sheet_ingest_request.py index 3d82753..17bcf4b 100644 --- a/cirro_api_client/v1/models/sheet_ingest_request.py +++ b/cirro_api_client/v1/models/sheet_ingest_request.py @@ -6,6 +6,7 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..models.ingest_conflict_mode import IngestConflictMode from ..types import UNSET, Unset if TYPE_CHECKING: @@ -21,12 +22,22 @@ class SheetIngestRequest: """ Attributes: file_def (FileDef): - source_columns (list[SourceColumn] | None | Unset): List of file column to sheet column mapping. If null, + source_columns (list[SourceColumn] | None | Unset): List of file column to sheet column mapping. A mapping + targeting a CIRRO_FILE or CIRRO_FOLDER column either sets datasetId (file values are relative paths within that + dataset) or omits it (file values are full Cirro URIs). A CIRRO_DATASET mapping either sets datasetId with no + fileColumn/index (every row gets that dataset's URI) or reads full Cirro URIs from a file column. If null, requires the column headers to match the sheet column names. + on_conflict (IngestConflictMode | None | Unset): How to handle rows colliding with a unique column: fail the job + (default), skip them, or overwrite the stored rows. SKIP and OVERWRITE require the sheet to have a unique + column. Default: IngestConflictMode.ERROR. + conflict_column (None | str | Unset): Unique column OVERWRITE replaces on. Required when the sheet has several + unique columns; inferred when it has one. """ file_def: FileDef source_columns: list[SourceColumn] | None | Unset = UNSET + on_conflict: IngestConflictMode | None | Unset = IngestConflictMode.ERROR + conflict_column: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -44,6 +55,20 @@ def to_dict(self) -> dict[str, Any]: else: source_columns = self.source_columns + on_conflict: None | str | Unset + if isinstance(self.on_conflict, Unset): + on_conflict = UNSET + elif isinstance(self.on_conflict, IngestConflictMode): + on_conflict = self.on_conflict.value + else: + on_conflict = self.on_conflict + + conflict_column: None | str | Unset + if isinstance(self.conflict_column, Unset): + conflict_column = UNSET + else: + conflict_column = self.conflict_column + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -53,6 +78,10 @@ def to_dict(self) -> dict[str, Any]: ) if source_columns is not UNSET: field_dict["sourceColumns"] = source_columns + if on_conflict is not UNSET: + field_dict["onConflict"] = on_conflict + if conflict_column is not UNSET: + field_dict["conflictColumn"] = conflict_column return field_dict @@ -86,9 +115,37 @@ def _parse_source_columns(data: object) -> list[SourceColumn] | None | Unset: source_columns = _parse_source_columns(d.pop("sourceColumns", UNSET)) + def _parse_on_conflict(data: object) -> IngestConflictMode | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + on_conflict_type_1 = IngestConflictMode(data) + + return on_conflict_type_1 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(IngestConflictMode | None | Unset, data) + + on_conflict = _parse_on_conflict(d.pop("onConflict", UNSET)) + + def _parse_conflict_column(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + conflict_column = _parse_conflict_column(d.pop("conflictColumn", UNSET)) + sheet_ingest_request = cls( file_def=file_def, source_columns=source_columns, + on_conflict=on_conflict, + conflict_column=conflict_column, ) sheet_ingest_request.additional_properties = d diff --git a/cirro_api_client/v1/models/sheet_query_request.py b/cirro_api_client/v1/models/sheet_query_request.py index 9a2b6ab..925d61a 100644 --- a/cirro_api_client/v1/models/sheet_query_request.py +++ b/cirro_api_client/v1/models/sheet_query_request.py @@ -15,23 +15,29 @@ class SheetQueryRequest: """ Attributes: - namespace_name (str): Namespace containing the sheets to query. Example: default. query (str): Raw SQL query to run. - limit (int | None | Unset): Maximum rows to return Default: 1000. + namespace_name (None | str | Unset): Deprecated: no longer scopes name resolution — every namespace is on the + engine's search path. Example: default. + limit (int | None | Unset): Maximum rows to return. Responses also have a size limit: with wide rows a large + page can fail with a 502 — lower the limit if so. Default: 1000. page (int | None | Unset): Page to return Default: 1. """ - namespace_name: str query: str + namespace_name: None | str | Unset = UNSET limit: int | None | Unset = 1000 page: int | None | Unset = 1 additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - namespace_name = self.namespace_name - query = self.query + namespace_name: None | str | Unset + if isinstance(self.namespace_name, Unset): + namespace_name = UNSET + else: + namespace_name = self.namespace_name + limit: int | None | Unset if isinstance(self.limit, Unset): limit = UNSET @@ -48,10 +54,11 @@ def to_dict(self) -> dict[str, Any]: field_dict.update(self.additional_properties) field_dict.update( { - "namespaceName": namespace_name, "query": query, } ) + if namespace_name is not UNSET: + field_dict["namespaceName"] = namespace_name if limit is not UNSET: field_dict["limit"] = limit if page is not UNSET: @@ -62,10 +69,17 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: d = dict(src_dict) - namespace_name = d.pop("namespaceName") - query = d.pop("query") + def _parse_namespace_name(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + namespace_name = _parse_namespace_name(d.pop("namespaceName", UNSET)) + def _parse_limit(data: object) -> int | None | Unset: if data is None: return data @@ -85,8 +99,8 @@ def _parse_page(data: object) -> int | None | Unset: page = _parse_page(d.pop("page", UNSET)) sheet_query_request = cls( - namespace_name=namespace_name, query=query, + namespace_name=namespace_name, limit=limit, page=page, ) diff --git a/cirro_api_client/v1/models/source_column.py b/cirro_api_client/v1/models/source_column.py index a5aabbe..411ae91 100644 --- a/cirro_api_client/v1/models/source_column.py +++ b/cirro_api_client/v1/models/source_column.py @@ -18,11 +18,15 @@ class SourceColumn: sheet_column (str): file_column (None | str | Unset): File column header name. Use this OR index, not both. index (int | None | Unset): 0-based file column position. Use this OR fileColumn, not both. + dataset_id (None | str | Unset): Dataset the mapping references. Only allowed on Cirro-typed target columns: on + CIRRO_FILE/CIRRO_FOLDER, source values are bare paths within that dataset; on CIRRO_DATASET, omit + fileColumn/index and every row gets that dataset's URI. When omitted, source values must be full Cirro URIs. """ sheet_column: str file_column: None | str | Unset = UNSET index: int | None | Unset = UNSET + dataset_id: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -40,6 +44,12 @@ def to_dict(self) -> dict[str, Any]: else: index = self.index + dataset_id: None | str | Unset + if isinstance(self.dataset_id, Unset): + dataset_id = UNSET + else: + dataset_id = self.dataset_id + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -51,6 +61,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["fileColumn"] = file_column if index is not UNSET: field_dict["index"] = index + if dataset_id is not UNSET: + field_dict["datasetId"] = dataset_id return field_dict @@ -77,10 +89,20 @@ def _parse_index(data: object) -> int | None | Unset: index = _parse_index(d.pop("index", UNSET)) + def _parse_dataset_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + dataset_id = _parse_dataset_id(d.pop("datasetId", UNSET)) + source_column = cls( sheet_column=sheet_column, file_column=file_column, index=index, + dataset_id=dataset_id, ) source_column.additional_properties = d diff --git a/cirro_api_client/v1/models/structured_file_input.py b/cirro_api_client/v1/models/structured_file_input.py new file mode 100644 index 0000000..00f8ca0 --- /dev/null +++ b/cirro_api_client/v1/models/structured_file_input.py @@ -0,0 +1,84 @@ +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 + +if TYPE_CHECKING: + from ..models.structured_file_input_data_item import StructuredFileInputDataItem + + +T = TypeVar("T", bound="StructuredFileInput") + + +@_attrs_define +class StructuredFileInput: + """Contents for a structured file that a pipeline accepts as an input + + Attributes: + data (list[StructuredFileInputDataItem]): + import_source_uris (list[str]): + """ + + data: list[StructuredFileInputDataItem] + import_source_uris: list[str] + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + data = [] + for data_item_data in self.data: + data_item = data_item_data.to_dict() + data.append(data_item) + + import_source_uris = self.import_source_uris + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "data": data, + "importSourceUris": import_source_uris, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.structured_file_input_data_item import StructuredFileInputDataItem + + d = dict(src_dict) + data = [] + _data = d.pop("data") + for data_item_data in _data: + data_item = StructuredFileInputDataItem.from_dict(data_item_data) + + data.append(data_item) + + import_source_uris = cast(list[str], d.pop("importSourceUris")) + + structured_file_input = cls( + data=data, + import_source_uris=import_source_uris, + ) + + structured_file_input.additional_properties = d + return structured_file_input + + @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/cirro_api_client/v1/models/form_schema_metadata_requirements.py b/cirro_api_client/v1/models/structured_file_input_data_item.py similarity index 76% rename from cirro_api_client/v1/models/form_schema_metadata_requirements.py rename to cirro_api_client/v1/models/structured_file_input_data_item.py index ff7b7a9..b42ddb3 100644 --- a/cirro_api_client/v1/models/form_schema_metadata_requirements.py +++ b/cirro_api_client/v1/models/structured_file_input_data_item.py @@ -6,12 +6,12 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field -T = TypeVar("T", bound="FormSchemaMetadataRequirements") +T = TypeVar("T", bound="StructuredFileInputDataItem") @_attrs_define -class FormSchemaMetadataRequirements: - """JSONSchema for validating sample metadata""" +class StructuredFileInputDataItem: + """Row data serialized to CSV/TSV/JSON per the input file format.""" additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -25,10 +25,10 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: d = dict(src_dict) - form_schema_metadata_requirements = cls() + structured_file_input_data_item = cls() - form_schema_metadata_requirements.additional_properties = d - return form_schema_metadata_requirements + structured_file_input_data_item.additional_properties = d + return structured_file_input_data_item @property def additional_keys(self) -> list[str]: diff --git a/cirro_api_client/v1/models/system_info_response.py b/cirro_api_client/v1/models/system_info_response.py index 6b723f3..02fc396 100644 --- a/cirro_api_client/v1/models/system_info_response.py +++ b/cirro_api_client/v1/models/system_info_response.py @@ -1,15 +1,17 @@ from __future__ import annotations from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar +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.auth_info import AuthInfo - from ..models.resources_info import ResourcesInfo from ..models.tenant_info import TenantInfo + from ..models.version_info import VersionInfo T = TypeVar("T", bound="SystemInfoResponse") @@ -26,11 +28,11 @@ class SystemInfoResponse: region (str): system_message (str): maintenance_mode_enabled (bool): - commit_hash (str): - version (str): - resources_info (ResourcesInfo): tenant_info (TenantInfo): auth (AuthInfo): + backend_version (None | Unset | VersionInfo): + resources_version (None | Unset | VersionInfo): + project_resource_version (None | Unset | VersionInfo): """ resources_bucket: str @@ -40,14 +42,16 @@ class SystemInfoResponse: region: str system_message: str maintenance_mode_enabled: bool - commit_hash: str - version: str - resources_info: ResourcesInfo tenant_info: TenantInfo auth: AuthInfo + backend_version: None | Unset | VersionInfo = UNSET + resources_version: None | Unset | VersionInfo = UNSET + project_resource_version: None | Unset | VersionInfo = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: + from ..models.version_info import VersionInfo + resources_bucket = self.resources_bucket references_bucket = self.references_bucket @@ -62,16 +66,34 @@ def to_dict(self) -> dict[str, Any]: maintenance_mode_enabled = self.maintenance_mode_enabled - commit_hash = self.commit_hash - - version = self.version - - resources_info = self.resources_info.to_dict() - tenant_info = self.tenant_info.to_dict() auth = self.auth.to_dict() + backend_version: dict[str, Any] | None | Unset + if isinstance(self.backend_version, Unset): + backend_version = UNSET + elif isinstance(self.backend_version, VersionInfo): + backend_version = self.backend_version.to_dict() + else: + backend_version = self.backend_version + + resources_version: dict[str, Any] | None | Unset + if isinstance(self.resources_version, Unset): + resources_version = UNSET + elif isinstance(self.resources_version, VersionInfo): + resources_version = self.resources_version.to_dict() + else: + resources_version = self.resources_version + + project_resource_version: dict[str, Any] | None | Unset + if isinstance(self.project_resource_version, Unset): + project_resource_version = UNSET + elif isinstance(self.project_resource_version, VersionInfo): + project_resource_version = self.project_resource_version.to_dict() + else: + project_resource_version = self.project_resource_version + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -83,21 +105,24 @@ def to_dict(self) -> dict[str, Any]: "region": region, "systemMessage": system_message, "maintenanceModeEnabled": maintenance_mode_enabled, - "commitHash": commit_hash, - "version": version, - "resourcesInfo": resources_info, "tenantInfo": tenant_info, "auth": auth, } ) + if backend_version is not UNSET: + field_dict["backendVersion"] = backend_version + if resources_version is not UNSET: + field_dict["resourcesVersion"] = resources_version + if project_resource_version is not UNSET: + field_dict["projectResourceVersion"] = project_resource_version return field_dict @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: from ..models.auth_info import AuthInfo - from ..models.resources_info import ResourcesInfo from ..models.tenant_info import TenantInfo + from ..models.version_info import VersionInfo d = dict(src_dict) resources_bucket = d.pop("resourcesBucket") @@ -114,16 +139,61 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: maintenance_mode_enabled = d.pop("maintenanceModeEnabled") - commit_hash = d.pop("commitHash") - - version = d.pop("version") - - resources_info = ResourcesInfo.from_dict(d.pop("resourcesInfo")) - tenant_info = TenantInfo.from_dict(d.pop("tenantInfo")) auth = AuthInfo.from_dict(d.pop("auth")) + def _parse_backend_version(data: object) -> None | Unset | VersionInfo: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + backend_version_type_1 = VersionInfo.from_dict(data) + + return backend_version_type_1 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | Unset | VersionInfo, data) + + backend_version = _parse_backend_version(d.pop("backendVersion", UNSET)) + + def _parse_resources_version(data: object) -> None | Unset | VersionInfo: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + resources_version_type_1 = VersionInfo.from_dict(data) + + return resources_version_type_1 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | Unset | VersionInfo, data) + + resources_version = _parse_resources_version(d.pop("resourcesVersion", UNSET)) + + def _parse_project_resource_version(data: object) -> None | Unset | VersionInfo: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + project_resource_version_type_1 = VersionInfo.from_dict(data) + + return project_resource_version_type_1 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | Unset | VersionInfo, data) + + project_resource_version = _parse_project_resource_version(d.pop("projectResourceVersion", UNSET)) + system_info_response = cls( resources_bucket=resources_bucket, references_bucket=references_bucket, @@ -132,11 +202,11 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: region=region, system_message=system_message, maintenance_mode_enabled=maintenance_mode_enabled, - commit_hash=commit_hash, - version=version, - resources_info=resources_info, tenant_info=tenant_info, auth=auth, + backend_version=backend_version, + resources_version=resources_version, + project_resource_version=project_resource_version, ) system_info_response.additional_properties = d diff --git a/cirro_api_client/v1/models/tenant_metrics.py b/cirro_api_client/v1/models/tenant_metrics.py new file mode 100644 index 0000000..d38dfa7 --- /dev/null +++ b/cirro_api_client/v1/models/tenant_metrics.py @@ -0,0 +1,101 @@ +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="TenantMetrics") + + +@_attrs_define +class TenantMetrics: + """ + Attributes: + project_count (int): + dataset_count (int): + pipeline_count (int): + workspace_count (int): + user_count (int): + policy_count (int): + """ + + project_count: int + dataset_count: int + pipeline_count: int + workspace_count: int + user_count: int + policy_count: int + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + project_count = self.project_count + + dataset_count = self.dataset_count + + pipeline_count = self.pipeline_count + + workspace_count = self.workspace_count + + user_count = self.user_count + + policy_count = self.policy_count + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "projectCount": project_count, + "datasetCount": dataset_count, + "pipelineCount": pipeline_count, + "workspaceCount": workspace_count, + "userCount": user_count, + "policyCount": policy_count, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + project_count = d.pop("projectCount") + + dataset_count = d.pop("datasetCount") + + pipeline_count = d.pop("pipelineCount") + + workspace_count = d.pop("workspaceCount") + + user_count = d.pop("userCount") + + policy_count = d.pop("policyCount") + + tenant_metrics = cls( + project_count=project_count, + dataset_count=dataset_count, + pipeline_count=pipeline_count, + workspace_count=workspace_count, + user_count=user_count, + policy_count=policy_count, + ) + + tenant_metrics.additional_properties = d + return tenant_metrics + + @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/cirro_api_client/v1/models/user.py b/cirro_api_client/v1/models/user.py index 212900f..d25b5ec 100644 --- a/cirro_api_client/v1/models/user.py +++ b/cirro_api_client/v1/models/user.py @@ -6,6 +6,8 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..models.user_status import UserStatus + T = TypeVar("T", bound="User") @@ -19,6 +21,7 @@ class User: department (str): job_title (str): global_roles (list[str]): + status (UserStatus): """ name: str @@ -27,6 +30,7 @@ class User: department: str job_title: str global_roles: list[str] + status: UserStatus additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -42,6 +46,8 @@ def to_dict(self) -> dict[str, Any]: global_roles = self.global_roles + status = self.status.value + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -52,6 +58,7 @@ def to_dict(self) -> dict[str, Any]: "department": department, "jobTitle": job_title, "globalRoles": global_roles, + "status": status, } ) @@ -72,6 +79,8 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: global_roles = cast(list[str], d.pop("globalRoles")) + status = UserStatus(d.pop("status")) + user = cls( name=name, username=username, @@ -79,6 +88,7 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: department=department, job_title=job_title, global_roles=global_roles, + status=status, ) user.additional_properties = d diff --git a/cirro_api_client/v1/models/user_detail.py b/cirro_api_client/v1/models/user_detail.py index f747cb9..6211d64 100644 --- a/cirro_api_client/v1/models/user_detail.py +++ b/cirro_api_client/v1/models/user_detail.py @@ -7,6 +7,7 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..models.user_status import UserStatus from ..types import UNSET, Unset if TYPE_CHECKING: @@ -28,6 +29,7 @@ class UserDetail: project_assignments (list[UserProjectAssignment]): global_roles (list[str]): settings (UserSettings): Additional settings for the user + status (UserStatus): phone (None | str | Unset): orcid_id (None | str | Unset): job_title (None | str | Unset): @@ -45,6 +47,7 @@ class UserDetail: project_assignments: list[UserProjectAssignment] global_roles: list[str] settings: UserSettings + status: UserStatus phone: None | str | Unset = UNSET orcid_id: None | str | Unset = UNSET job_title: None | str | Unset = UNSET @@ -73,6 +76,8 @@ def to_dict(self) -> dict[str, Any]: settings = self.settings.to_dict() + status = self.status.value + phone: None | str | Unset if isinstance(self.phone, Unset): phone = UNSET @@ -139,6 +144,7 @@ def to_dict(self) -> dict[str, Any]: "projectAssignments": project_assignments, "globalRoles": global_roles, "settings": settings, + "status": status, } ) if phone is not UNSET: @@ -185,6 +191,8 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: settings = UserSettings.from_dict(d.pop("settings")) + status = UserStatus(d.pop("status")) + def _parse_phone(data: object) -> None | str | Unset: if data is None: return data @@ -289,6 +297,7 @@ def _parse_groups(data: object) -> list[str] | None | Unset: project_assignments=project_assignments, global_roles=global_roles, settings=settings, + status=status, phone=phone, orcid_id=orcid_id, job_title=job_title, diff --git a/cirro_api_client/v1/models/user_status.py b/cirro_api_client/v1/models/user_status.py new file mode 100644 index 0000000..b334f4e --- /dev/null +++ b/cirro_api_client/v1/models/user_status.py @@ -0,0 +1,16 @@ +from enum import Enum + + +class UserStatus(str, Enum): + ACTIVE = "ACTIVE" + DEACTIVATED = "DEACTIVATED" + PENDING = "PENDING" + UNKNOWN = "UNKNOWN" + """ This is a fallback value for when the value is not known, do not use this value when making requests """ + + def __str__(self) -> str: + return str(self.value) + + @classmethod + def _missing_(cls, number): + return cls(cls.UNKNOWN) diff --git a/cirro_api_client/v1/models/version_info.py b/cirro_api_client/v1/models/version_info.py new file mode 100644 index 0000000..cc10c27 --- /dev/null +++ b/cirro_api_client/v1/models/version_info.py @@ -0,0 +1,102 @@ +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 ..types import UNSET, Unset + +T = TypeVar("T", bound="VersionInfo") + + +@_attrs_define +class VersionInfo: + """ + Attributes: + commit (str): + version (str): + date (datetime.datetime | None | Unset): + """ + + commit: str + version: str + date: datetime.datetime | None | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + commit = self.commit + + version = self.version + + date: None | str | Unset + if isinstance(self.date, Unset): + date = UNSET + elif isinstance(self.date, datetime.datetime): + date = self.date.isoformat() + else: + date = self.date + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "commit": commit, + "version": version, + } + ) + if date is not UNSET: + field_dict["date"] = date + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + commit = d.pop("commit") + + version = d.pop("version") + + def _parse_date(data: object) -> datetime.datetime | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + date_type_0 = datetime.datetime.fromisoformat(data) + + return date_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(datetime.datetime | None | Unset, data) + + date = _parse_date(d.pop("date", UNSET)) + + version_info = cls( + commit=commit, + version=version, + date=date, + ) + + version_info.additional_properties = d + return version_info + + @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/cirro_api_client/v1/models/view_sheet_input.py b/cirro_api_client/v1/models/view_sheet_input.py index 024b21f..2c2b035 100644 --- a/cirro_api_client/v1/models/view_sheet_input.py +++ b/cirro_api_client/v1/models/view_sheet_input.py @@ -29,6 +29,8 @@ class ViewSheetInput: standard builder; viewType=RAW for a SQL SELECT. description (None | str | Unset): Optional description of the sheet's purpose or contents audit_read_access (bool | Unset): Enable audit logging for read access to this sheet Default: False. + virtual (bool | Unset): True for a view resolved live at query time; false materializes it into a table + (refreshed async). Immutable after create. tags (list[Tag] | Unset): Tags for the sheet sheet_type (str | Unset): """ @@ -39,6 +41,7 @@ class ViewSheetInput: view_definition: RawViewQueryRequest | StructuredViewQueryRequest description: None | str | Unset = UNSET audit_read_access: bool | Unset = False + virtual: bool | Unset = UNSET tags: list[Tag] | Unset = UNSET sheet_type: str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -66,6 +69,8 @@ def to_dict(self) -> dict[str, Any]: audit_read_access = self.audit_read_access + virtual = self.virtual + tags: list[dict[str, Any]] | Unset = UNSET if not isinstance(self.tags, Unset): tags = [] @@ -89,6 +94,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["description"] = description if audit_read_access is not UNSET: field_dict["auditReadAccess"] = audit_read_access + if virtual is not UNSET: + field_dict["virtual"] = virtual if tags is not UNSET: field_dict["tags"] = tags if sheet_type is not UNSET: @@ -137,6 +144,8 @@ def _parse_description(data: object) -> None | str | Unset: audit_read_access = d.pop("auditReadAccess", UNSET) + virtual = d.pop("virtual", UNSET) + _tags = d.pop("tags", UNSET) tags: list[Tag] | Unset = UNSET if _tags is not UNSET: @@ -155,6 +164,7 @@ def _parse_description(data: object) -> None | str | Unset: view_definition=view_definition, description=description, audit_read_access=audit_read_access, + virtual=virtual, tags=tags, sheet_type=sheet_type, ) diff --git a/cirro_api_client/v1/models/workspace_compute_config.py b/cirro_api_client/v1/models/workspace_compute_config.py index 92369a3..f3835a9 100644 --- a/cirro_api_client/v1/models/workspace_compute_config.py +++ b/cirro_api_client/v1/models/workspace_compute_config.py @@ -31,6 +31,11 @@ class WorkspaceComputeConfig: injected into the container at runtime. Keys must be non-blank. Example: {'ENV_MODE': 'production', 'LOG_LEVEL': 'debug'}. local_port (int | Unset): User-facing web server port (http). Example: 8080. + command (list[str] | None | Unset): Command to run in the container, overriding the image's default CMD. + Provided as a list of executable and arguments (exec form). When null, the image's default is used. Example: + ['python', 'app.py']. + user (None | str | Unset): Linux user the container process runs as, as a username or numeric UID (optionally + 'user:group' or 'uid:gid'). When null, the image's default user is used. Example: 1000:1000. custom_task_role_arn (None | str | Unset): Custom IAM task role for the workspace ECS task. Provide either a role name (e.g., 'Cirro-CustomWorkspaceTaskRole-{projectShortCode}-{name}') or a full ARN (e.g., 'arn:aws:iam::{accountId}:role/Cirro-CustomWorkspaceTaskRole-{projectShortCode}-{name}'). Must belong to the @@ -45,6 +50,8 @@ class WorkspaceComputeConfig: gpu_model: None | str | Unset = UNSET environment_variables: None | Unset | WorkspaceComputeConfigEnvironmentVariables = UNSET local_port: int | Unset = UNSET + command: list[str] | None | Unset = UNSET + user: None | str | Unset = UNSET custom_task_role_arn: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -77,6 +84,21 @@ def to_dict(self) -> dict[str, Any]: local_port = self.local_port + command: list[str] | None | Unset + if isinstance(self.command, Unset): + command = UNSET + elif isinstance(self.command, list): + command = self.command + + else: + command = self.command + + user: None | str | Unset + if isinstance(self.user, Unset): + user = UNSET + else: + user = self.user + custom_task_role_arn: None | str | Unset if isinstance(self.custom_task_role_arn, Unset): custom_task_role_arn = UNSET @@ -104,6 +126,10 @@ def to_dict(self) -> dict[str, Any]: field_dict["environmentVariables"] = environment_variables if local_port is not UNSET: field_dict["localPort"] = local_port + if command is not UNSET: + field_dict["command"] = command + if user is not UNSET: + field_dict["user"] = user if custom_task_role_arn is not UNSET: field_dict["customTaskRoleArn"] = custom_task_role_arn @@ -152,6 +178,32 @@ def _parse_environment_variables(data: object) -> None | Unset | WorkspaceComput local_port = d.pop("localPort", UNSET) + def _parse_command(data: object) -> list[str] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + command_type_0 = cast(list[str], data) + + return command_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + command = _parse_command(d.pop("command", UNSET)) + + def _parse_user(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + user = _parse_user(d.pop("user", UNSET)) + def _parse_custom_task_role_arn(data: object) -> None | str | Unset: if data is None: return data @@ -170,6 +222,8 @@ def _parse_custom_task_role_arn(data: object) -> None | str | Unset: gpu_model=gpu_model, environment_variables=environment_variables, local_port=local_port, + command=command, + user=user, custom_task_role_arn=custom_task_role_arn, ) diff --git a/config.yml b/config.yml index 013826b..3db1c17 100644 --- a/config.yml +++ b/config.yml @@ -27,6 +27,10 @@ class_overrides: class_name: GovernanceRequirementProjectFileMap RunAnalysisRequestSourceSampleFilesMapType0: class_name: RunAnalysisRequestSourceSampleFilesMap + RunAnalysisRequestStructuredFileInputsType0: + class_name: RunAnalysisRequestStructuredFileInputs + InputFileRequirementExamplesType0Item: + class_name: InputFileRequirementExamples WorkspaceComputeConfigEnvironmentVariablesType0: class_name: WorkspaceComputeConfigEnvironmentVariables ViewFilterValuesType0Item: diff --git a/pyproject.toml b/pyproject.toml index bf021e3..6cfb528 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "cirro_api_client" -version = "1.6.0" +version = "1.7.0" description = "A client library for accessing Cirro" authors = ["Cirro "] license = "MIT" diff --git a/tests/test_client.py b/tests/test_client.py index 5ed8976..c37d86b 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -45,6 +45,7 @@ def test_import_api_methods(self): "department": "test-dept", "jobTitle": "test-title", "globalRoles": [], + "status": "ACTIVE", } ], "nextToken": None,