From 25011a80ac5deb44791f4f648c82eda2b43a0154 Mon Sep 17 00:00:00 2001 From: Nathan Thorpe Date: Fri, 22 May 2026 16:51:50 -0700 Subject: [PATCH 1/4] sync api client --- cirro_api_client/.gitignore | 23 ++ cirro_api_client/README.md | 124 +++++++++ cirro_api_client/pyproject.toml | 26 ++ .../list_app_registration_templates.py | 140 ++++++++++ .../v1/api/execution/get_task_files.py | 194 ++++++++++++++ .../v1/api/execution/get_task_logs.py | 20 ++ .../v1/api/sheets/create_sheet.py | 27 +- .../v1/api/sheets/delete_sheet_data.py | 206 ++++++++++++++ cirro_api_client/v1/api/sheets/get_jobs.py | 8 +- .../v1/api/sheets/insert_sheet_data.py | 202 ++++++++++++++ .../v1/api/sheets/query_namespace_data.py | 188 +++++++++++++ .../v1/api/sheets/query_sheet_data.py | 210 +++++++++++++++ .../v1/api/sheets/refresh_view.py | 2 +- .../v1/api/sheets/trigger_ingest.py | 105 +------- .../v1/api/sheets/update_sheet.py | 144 ++++++++-- .../v1/api/sheets/update_sheet_data.py | 103 ++++++- .../v1/api/workspaces/delete_workspace.py | 23 +- cirro_api_client/v1/models/__init__.py | 58 +++- .../v1/models/app_publisher_type.py | 15 ++ .../v1/models/app_registration.py | 49 ++++ .../v1/models/app_registration_detail.py | 69 +++++ .../v1/models/app_registration_input.py | 101 +++++++ .../v1/models/app_registration_template.py | 128 +++++++++ cirro_api_client/v1/models/column_def.py | 145 +++++++++- .../v1/models/create_sheet_request.py | 252 ------------------ cirro_api_client/v1/models/dataset.py | 36 +-- cirro_api_client/v1/models/dataset_detail.py | 35 +-- cirro_api_client/v1/models/dataset_viz.py | 21 +- ...filter_values.py => dataset_viz_config.py} | 10 +- .../v1/models/delete_rows_request.py | 61 +++++ cirro_api_client/v1/models/entity_type.py | 1 + cirro_api_client/v1/models/feature_flags.py | 16 ++ cirro_api_client/v1/models/file_def.py | 13 +- .../v1/models/{view_filter.py => filter_.py} | 53 ++-- cirro_api_client/v1/models/filter_operator.py | 1 + .../v1/models/get_task_files_response.py | 91 +++++++ .../v1/models/insert_rows_request.py | 75 ++++++ cirro_api_client/v1/models/permission.py | 3 + cirro_api_client/v1/models/query_column.py | 2 +- .../v1/models/raw_view_query_request.py | 72 +++++ ...rigger_ingest_request.py => row_insert.py} | 27 +- .../v1/models/row_insert_values.py | 64 +++++ .../row_insert_values_additional_property.py | 46 ++++ .../v1/models/run_analysis_request.py | 41 +++ .../v1/models/semantic_column_type.py | 22 ++ cirro_api_client/v1/models/sheet.py | 40 ++- .../v1/models/sheet_data_request.py | 165 ++++++++++++ .../v1/models/sheet_data_update_response.py | 62 +++++ cirro_api_client/v1/models/sheet_detail.py | 72 ++++- .../v1/models/sheet_ingest_request.py | 111 ++++++++ cirro_api_client/v1/models/sheet_job_type.py | 1 + .../v1/models/sheet_query_request.py | 111 ++++++++ .../v1/models/sheet_query_response.py | 16 +- cirro_api_client/v1/models/sheet_sort.py | 105 ++++++++ .../v1/models/sheet_update_response.py | 98 +++++++ cirro_api_client/v1/models/source_column.py | 103 +++++++ ...st.py => structured_view_query_request.py} | 40 +-- .../v1/models/table_sheet_input.py | 196 ++++++++++++++ cirro_api_client/v1/models/task.py | 40 +++ cirro_api_client/v1/models/task_log_source.py | 16 ++ .../v1/models/update_sheet_request.py | 109 -------- cirro_api_client/v1/models/user_detail.py | 132 ++++++--- cirro_api_client/v1/models/view_join.py | 8 - .../v1/models/view_sheet_input.py | 179 +++++++++++++ pyproject.toml | 2 +- 65 files changed, 4179 insertions(+), 679 deletions(-) create mode 100644 cirro_api_client/.gitignore create mode 100644 cirro_api_client/README.md create mode 100644 cirro_api_client/pyproject.toml create mode 100644 cirro_api_client/v1/api/app_registrations/list_app_registration_templates.py create mode 100644 cirro_api_client/v1/api/execution/get_task_files.py create mode 100644 cirro_api_client/v1/api/sheets/delete_sheet_data.py create mode 100644 cirro_api_client/v1/api/sheets/insert_sheet_data.py create mode 100644 cirro_api_client/v1/api/sheets/query_namespace_data.py create mode 100644 cirro_api_client/v1/api/sheets/query_sheet_data.py create mode 100644 cirro_api_client/v1/models/app_publisher_type.py create mode 100644 cirro_api_client/v1/models/app_registration_template.py delete mode 100644 cirro_api_client/v1/models/create_sheet_request.py rename cirro_api_client/v1/models/{view_filter_values.py => dataset_viz_config.py} (85%) create mode 100644 cirro_api_client/v1/models/delete_rows_request.py rename cirro_api_client/v1/models/{view_filter.py => filter_.py} (79%) create mode 100644 cirro_api_client/v1/models/get_task_files_response.py create mode 100644 cirro_api_client/v1/models/insert_rows_request.py create mode 100644 cirro_api_client/v1/models/raw_view_query_request.py rename cirro_api_client/v1/models/{trigger_ingest_request.py => row_insert.py} (65%) create mode 100644 cirro_api_client/v1/models/row_insert_values.py create mode 100644 cirro_api_client/v1/models/row_insert_values_additional_property.py create mode 100644 cirro_api_client/v1/models/semantic_column_type.py create mode 100644 cirro_api_client/v1/models/sheet_data_request.py create mode 100644 cirro_api_client/v1/models/sheet_data_update_response.py create mode 100644 cirro_api_client/v1/models/sheet_ingest_request.py create mode 100644 cirro_api_client/v1/models/sheet_query_request.py create mode 100644 cirro_api_client/v1/models/sheet_sort.py create mode 100644 cirro_api_client/v1/models/sheet_update_response.py create mode 100644 cirro_api_client/v1/models/source_column.py rename cirro_api_client/v1/models/{view_query_request.py => structured_view_query_request.py} (82%) create mode 100644 cirro_api_client/v1/models/table_sheet_input.py create mode 100644 cirro_api_client/v1/models/task_log_source.py delete mode 100644 cirro_api_client/v1/models/update_sheet_request.py create mode 100644 cirro_api_client/v1/models/view_sheet_input.py diff --git a/cirro_api_client/.gitignore b/cirro_api_client/.gitignore new file mode 100644 index 0000000..79a2c3d --- /dev/null +++ b/cirro_api_client/.gitignore @@ -0,0 +1,23 @@ +__pycache__/ +build/ +dist/ +*.egg-info/ +.pytest_cache/ + +# pyenv +.python-version + +# Environments +.env +.venv + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# JetBrains +.idea/ + +/coverage.xml +/.coverage diff --git a/cirro_api_client/README.md b/cirro_api_client/README.md new file mode 100644 index 0000000..431cd47 --- /dev/null +++ b/cirro_api_client/README.md @@ -0,0 +1,124 @@ +# cirro_api_client +A client library for accessing Cirro Data + +## Usage +First, create a client: + +```python +from v1 import Client + +client = Client(base_url="https://api.example.com") +``` + +If the endpoints you're going to hit require authentication, use `AuthenticatedClient` instead: + +```python +from v1 import AuthenticatedClient + +client = AuthenticatedClient(base_url="https://api.example.com", token="SuperSecretToken") +``` + +Now call your endpoint and use your models: + +```python +from v1.models import MyDataModel +from v1.api.my_tag import get_my_data_model +from v1.types import Response + +with client as client: + my_data: MyDataModel = get_my_data_model.sync(client=client) + # or if you need more info (e.g. status_code) + response: Response[MyDataModel] = get_my_data_model.sync_detailed(client=client) +``` + +Or do the same thing with an async version: + +```python +from v1.models import MyDataModel +from v1.api.my_tag import get_my_data_model +from v1.types import Response + +async with client as client: + my_data: MyDataModel = await get_my_data_model.asyncio(client=client) + response: Response[MyDataModel] = await get_my_data_model.asyncio_detailed(client=client) +``` + +By default, when you're calling an HTTPS API it will attempt to verify that SSL is working correctly. Using certificate verification is highly recommended most of the time, but sometimes you may need to authenticate to a server (especially an internal server) using a custom certificate bundle. + +```python +client = AuthenticatedClient( + base_url="https://internal_api.example.com", + token="SuperSecretToken", + verify_ssl="/path/to/certificate_bundle.pem", +) +``` + +You can also disable certificate validation altogether, but beware that **this is a security risk**. + +```python +client = AuthenticatedClient( + base_url="https://internal_api.example.com", + token="SuperSecretToken", + verify_ssl=False +) +``` + +Things to know: +1. Every path/method combo becomes a Python module with four functions: + 1. `sync`: Blocking request that returns parsed data (if successful) or `None` + 1. `sync_detailed`: Blocking request that always returns a `Request`, optionally with `parsed` set if the request was successful. + 1. `asyncio`: Like `sync` but async instead of blocking + 1. `asyncio_detailed`: Like `sync_detailed` but async instead of blocking + +1. All path/query params, and bodies become method arguments. +1. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above) +1. Any endpoint which did not have a tag will be in `v1.api.default` + +## Advanced customizations + +There are more settings on the generated `Client` class which let you control more runtime behavior, check out the docstring on that class for more info. You can also customize the underlying `httpx.Client` or `httpx.AsyncClient` (depending on your use-case): + +```python +from v1 import Client + +def log_request(request): + print(f"Request event hook: {request.method} {request.url} - Waiting for response") + +def log_response(response): + request = response.request + print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}") + +client = Client( + base_url="https://api.example.com", + httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}}, +) + +# Or get the underlying httpx client to modify directly with client.get_httpx_client() or client.get_async_httpx_client() +``` + +You can even set the httpx client directly, but beware that this will override any existing settings (e.g., base_url): + +```python +import httpx +from v1 import Client + +client = Client( + base_url="https://api.example.com", +) +# Note that base_url needs to be re-set, as would any shared cookies, headers, etc. +client.set_httpx_client(httpx.Client(base_url="https://api.example.com", proxies="http://localhost:8030")) +``` + +## Building / publishing this package +This project uses [Poetry](https://python-poetry.org/) to manage dependencies and packaging. Here are the basics: +1. Update the metadata in pyproject.toml (e.g. authors, version) +1. If you're using a private repository, configure it with Poetry + 1. `poetry config repositories. ` + 1. `poetry config http-basic. ` +1. Publish the client with `poetry publish --build -r ` or, if for public PyPI, just `poetry publish --build` + +If you want to install this client into another project without publishing it (e.g. for development) then: +1. If that project **is using Poetry**, you can simply do `poetry add ` from that project +1. If that project is not using Poetry: + 1. Build a wheel with `poetry build -f wheel` + 1. Install that wheel from the other project `pip install ` diff --git a/cirro_api_client/pyproject.toml b/cirro_api_client/pyproject.toml new file mode 100644 index 0000000..7195d9b --- /dev/null +++ b/cirro_api_client/pyproject.toml @@ -0,0 +1,26 @@ +[tool.poetry] +name = "cirro_api_client" +version = "1.3.0" +description = "A client library for accessing Cirro Data" +authors = [] +readme = "README.md" +packages = [ + { include = "v1" }, +] +include = ["v1/py.typed"] + +[tool.poetry.dependencies] +python = "^3.10" +httpx = ">=0.23.0,<0.29.0" +attrs = ">=22.2.0" +python-dateutil = "^2.8.0" + +[build-system] +requires = ["poetry-core>=2.0.0,<3.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.ruff] +line-length = 120 + +[tool.ruff.lint] +select = ["F", "I", "UP"] diff --git a/cirro_api_client/v1/api/app_registrations/list_app_registration_templates.py b/cirro_api_client/v1/api/app_registrations/list_app_registration_templates.py new file mode 100644 index 0000000..b3f02ce --- /dev/null +++ b/cirro_api_client/v1/api/app_registrations/list_app_registration_templates.py @@ -0,0 +1,140 @@ +from http import HTTPStatus +from typing import Any + +import httpx + +from ... import errors +from ...client import Client +from ...models.app_registration_template import AppRegistrationTemplate +from ...types import Response + + +def _get_kwargs() -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/app-registration-templates", + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> list[AppRegistrationTemplate] | None: + if response.status_code == 200: + response_200 = [] + _response_200 = response.json() + for response_200_item_data in _response_200: + response_200_item = AppRegistrationTemplate.from_dict(response_200_item_data) + + response_200.append(response_200_item) + + return response_200 + + errors.handle_error_response(response, client.raise_on_unexpected_status) + + +def _build_response(*, client: Client, response: httpx.Response) -> Response[list[AppRegistrationTemplate]]: + 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[list[AppRegistrationTemplate]]: + """List app registration templates + + Lists pre-defined application templates to register. + + 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[list[AppRegistrationTemplate]] + """ + + 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, +) -> list[AppRegistrationTemplate] | None: + """List app registration templates + + Lists pre-defined application templates to register. + + 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: + list[AppRegistrationTemplate] + """ + + try: + return sync_detailed( + client=client, + ).parsed + except errors.NotFoundException: + return None + + +async def asyncio_detailed( + *, + client: Client, +) -> Response[list[AppRegistrationTemplate]]: + """List app registration templates + + Lists pre-defined application templates to register. + + 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[list[AppRegistrationTemplate]] + """ + + 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, +) -> list[AppRegistrationTemplate] | None: + """List app registration templates + + Lists pre-defined application templates to register. + + 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: + list[AppRegistrationTemplate] + """ + + try: + return ( + await asyncio_detailed( + client=client, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/execution/get_task_files.py b/cirro_api_client/v1/api/execution/get_task_files.py new file mode 100644 index 0000000..6e32e50 --- /dev/null +++ b/cirro_api_client/v1/api/execution/get_task_files.py @@ -0,0 +1,194 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import Client +from ...models.get_task_files_response import GetTaskFilesResponse +from ...types import Response + + +def _get_kwargs( + project_id: str, + dataset_id: str, + task_id: str, +) -> dict[str, Any]: + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/projects/{project_id}/execution/{dataset_id}/tasks/{task_id}/files".format( + project_id=quote(str(project_id), safe=""), + dataset_id=quote(str(dataset_id), safe=""), + task_id=quote(str(task_id), safe=""), + ), + } + + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> GetTaskFilesResponse | None: + if response.status_code == 200: + response_200 = GetTaskFilesResponse.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[GetTaskFilesResponse]: + 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, + task_id: str, + *, + client: Client, +) -> Response[GetTaskFilesResponse]: + """Get task files + + Gets the input and output files for an individual Nextflow task + + Args: + project_id (str): + dataset_id (str): + task_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[GetTaskFilesResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + dataset_id=dataset_id, + task_id=task_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, + task_id: str, + *, + client: Client, +) -> GetTaskFilesResponse | None: + """Get task files + + Gets the input and output files for an individual Nextflow task + + Args: + project_id (str): + dataset_id (str): + task_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: + GetTaskFilesResponse + """ + + try: + return sync_detailed( + project_id=project_id, + dataset_id=dataset_id, + task_id=task_id, + client=client, + ).parsed + except errors.NotFoundException: + return None + + +async def asyncio_detailed( + project_id: str, + dataset_id: str, + task_id: str, + *, + client: Client, +) -> Response[GetTaskFilesResponse]: + """Get task files + + Gets the input and output files for an individual Nextflow task + + Args: + project_id (str): + dataset_id (str): + task_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[GetTaskFilesResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + dataset_id=dataset_id, + task_id=task_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, + task_id: str, + *, + client: Client, +) -> GetTaskFilesResponse | None: + """Get task files + + Gets the input and output files for an individual Nextflow task + + Args: + project_id (str): + dataset_id (str): + task_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: + GetTaskFilesResponse + """ + + try: + return ( + await asyncio_detailed( + project_id=project_id, + dataset_id=dataset_id, + task_id=task_id, + client=client, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/execution/get_task_logs.py b/cirro_api_client/v1/api/execution/get_task_logs.py index 713f841..79c95ec 100644 --- a/cirro_api_client/v1/api/execution/get_task_logs.py +++ b/cirro_api_client/v1/api/execution/get_task_logs.py @@ -7,6 +7,7 @@ from ... import errors from ...client import Client from ...models.get_execution_logs_response import GetExecutionLogsResponse +from ...models.task_log_source import TaskLogSource from ...types import UNSET, Response, Unset @@ -16,11 +17,18 @@ def _get_kwargs( task_id: str, *, force_live: bool | Unset = False, + source: TaskLogSource | Unset = UNSET, ) -> dict[str, Any]: params: dict[str, Any] = {} params["forceLive"] = force_live + json_source: str | Unset = UNSET + if not isinstance(source, Unset): + json_source = source.value + + params["source"] = json_source + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} _kwargs: dict[str, Any] = { @@ -61,6 +69,7 @@ def sync_detailed( *, client: Client, force_live: bool | Unset = False, + source: TaskLogSource | Unset = UNSET, ) -> Response[GetExecutionLogsResponse]: """Get task logs @@ -71,6 +80,7 @@ def sync_detailed( dataset_id (str): task_id (str): force_live (bool | Unset): Default: False. + source (TaskLogSource | Unset): client (Client): instance of the API client Raises: @@ -86,6 +96,7 @@ def sync_detailed( dataset_id=dataset_id, task_id=task_id, force_live=force_live, + source=source, ) response = client.get_httpx_client().request( @@ -103,6 +114,7 @@ def sync( *, client: Client, force_live: bool | Unset = False, + source: TaskLogSource | Unset = UNSET, ) -> GetExecutionLogsResponse | None: """Get task logs @@ -113,6 +125,7 @@ def sync( dataset_id (str): task_id (str): force_live (bool | Unset): Default: False. + source (TaskLogSource | Unset): client (Client): instance of the API client Raises: @@ -130,6 +143,7 @@ def sync( task_id=task_id, client=client, force_live=force_live, + source=source, ).parsed except errors.NotFoundException: return None @@ -142,6 +156,7 @@ async def asyncio_detailed( *, client: Client, force_live: bool | Unset = False, + source: TaskLogSource | Unset = UNSET, ) -> Response[GetExecutionLogsResponse]: """Get task logs @@ -152,6 +167,7 @@ async def asyncio_detailed( dataset_id (str): task_id (str): force_live (bool | Unset): Default: False. + source (TaskLogSource | Unset): client (Client): instance of the API client Raises: @@ -167,6 +183,7 @@ async def asyncio_detailed( dataset_id=dataset_id, task_id=task_id, force_live=force_live, + source=source, ) response = await client.get_async_httpx_client().request(auth=client.get_auth(), **kwargs) @@ -181,6 +198,7 @@ async def asyncio( *, client: Client, force_live: bool | Unset = False, + source: TaskLogSource | Unset = UNSET, ) -> GetExecutionLogsResponse | None: """Get task logs @@ -191,6 +209,7 @@ async def asyncio( dataset_id (str): task_id (str): force_live (bool | Unset): Default: False. + source (TaskLogSource | Unset): client (Client): instance of the API client Raises: @@ -209,6 +228,7 @@ async def asyncio( task_id=task_id, client=client, force_live=force_live, + source=source, ) ).parsed except errors.NotFoundException: diff --git a/cirro_api_client/v1/api/sheets/create_sheet.py b/cirro_api_client/v1/api/sheets/create_sheet.py index 527dcd3..a5da041 100644 --- a/cirro_api_client/v1/api/sheets/create_sheet.py +++ b/cirro_api_client/v1/api/sheets/create_sheet.py @@ -7,14 +7,15 @@ from ... import errors from ...client import Client from ...models.create_response import CreateResponse -from ...models.create_sheet_request import CreateSheetRequest +from ...models.table_sheet_input import TableSheetInput +from ...models.view_sheet_input import ViewSheetInput from ...types import Response def _get_kwargs( project_id: str, *, - body: CreateSheetRequest, + body: TableSheetInput | ViewSheetInput, ) -> dict[str, Any]: headers: dict[str, Any] = {} @@ -25,7 +26,11 @@ def _get_kwargs( ), } - _kwargs["json"] = body.to_dict() + _kwargs["json"]: dict[str, Any] + if isinstance(body, TableSheetInput): + _kwargs["json"] = body.to_dict() + else: + _kwargs["json"] = body.to_dict() headers["Content-Type"] = "application/json" @@ -55,7 +60,7 @@ def sync_detailed( project_id: str, *, client: Client, - body: CreateSheetRequest, + body: TableSheetInput | ViewSheetInput, ) -> Response[CreateResponse]: """Create sheet @@ -63,7 +68,7 @@ def sync_detailed( Args: project_id (str): - body (CreateSheetRequest): + body (TableSheetInput | ViewSheetInput): client (Client): instance of the API client Raises: @@ -91,7 +96,7 @@ def sync( project_id: str, *, client: Client, - body: CreateSheetRequest, + body: TableSheetInput | ViewSheetInput, ) -> CreateResponse | None: """Create sheet @@ -99,7 +104,7 @@ def sync( Args: project_id (str): - body (CreateSheetRequest): + body (TableSheetInput | ViewSheetInput): client (Client): instance of the API client Raises: @@ -124,7 +129,7 @@ async def asyncio_detailed( project_id: str, *, client: Client, - body: CreateSheetRequest, + body: TableSheetInput | ViewSheetInput, ) -> Response[CreateResponse]: """Create sheet @@ -132,7 +137,7 @@ async def asyncio_detailed( Args: project_id (str): - body (CreateSheetRequest): + body (TableSheetInput | ViewSheetInput): client (Client): instance of the API client Raises: @@ -157,7 +162,7 @@ async def asyncio( project_id: str, *, client: Client, - body: CreateSheetRequest, + body: TableSheetInput | ViewSheetInput, ) -> CreateResponse | None: """Create sheet @@ -165,7 +170,7 @@ async def asyncio( Args: project_id (str): - body (CreateSheetRequest): + body (TableSheetInput | ViewSheetInput): client (Client): instance of the API client Raises: diff --git a/cirro_api_client/v1/api/sheets/delete_sheet_data.py b/cirro_api_client/v1/api/sheets/delete_sheet_data.py new file mode 100644 index 0000000..e6f8aba --- /dev/null +++ b/cirro_api_client/v1/api/sheets/delete_sheet_data.py @@ -0,0 +1,206 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import Client +from ...models.delete_rows_request import DeleteRowsRequest +from ...models.sheet_data_update_response import SheetDataUpdateResponse +from ...types import Response + + +def _get_kwargs( + project_id: str, + sheet_id: str, + *, + body: DeleteRowsRequest, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "delete", + "url": "/projects/{project_id}/sheets/{sheet_id}/data".format( + project_id=quote(str(project_id), safe=""), + sheet_id=quote(str(sheet_id), safe=""), + ), + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> SheetDataUpdateResponse | None: + if response.status_code == 200: + response_200 = SheetDataUpdateResponse.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[SheetDataUpdateResponse]: + 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, + sheet_id: str, + *, + client: Client, + body: DeleteRowsRequest, +) -> Response[SheetDataUpdateResponse]: + """Delete sheet rows + + Returns number of rows deleted. Deletes specific rows from a sheet by _row_id. The request body + lists the rowIds to delete. + + Args: + project_id (str): + sheet_id (str): + body (DeleteRowsRequest): + 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[SheetDataUpdateResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + sheet_id=sheet_id, + body=body, + ) + + response = client.get_httpx_client().request( + auth=client.get_auth(), + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + project_id: str, + sheet_id: str, + *, + client: Client, + body: DeleteRowsRequest, +) -> SheetDataUpdateResponse | None: + """Delete sheet rows + + Returns number of rows deleted. Deletes specific rows from a sheet by _row_id. The request body + lists the rowIds to delete. + + Args: + project_id (str): + sheet_id (str): + body (DeleteRowsRequest): + 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: + SheetDataUpdateResponse + """ + + try: + return sync_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + ).parsed + except errors.NotFoundException: + return None + + +async def asyncio_detailed( + project_id: str, + sheet_id: str, + *, + client: Client, + body: DeleteRowsRequest, +) -> Response[SheetDataUpdateResponse]: + """Delete sheet rows + + Returns number of rows deleted. Deletes specific rows from a sheet by _row_id. The request body + lists the rowIds to delete. + + Args: + project_id (str): + sheet_id (str): + body (DeleteRowsRequest): + 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[SheetDataUpdateResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + sheet_id=sheet_id, + body=body, + ) + + 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, + sheet_id: str, + *, + client: Client, + body: DeleteRowsRequest, +) -> SheetDataUpdateResponse | None: + """Delete sheet rows + + Returns number of rows deleted. Deletes specific rows from a sheet by _row_id. The request body + lists the rowIds to delete. + + Args: + project_id (str): + sheet_id (str): + body (DeleteRowsRequest): + 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: + SheetDataUpdateResponse + """ + + try: + return ( + await asyncio_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/sheets/get_jobs.py b/cirro_api_client/v1/api/sheets/get_jobs.py index 10d47c7..b6f1438 100644 --- a/cirro_api_client/v1/api/sheets/get_jobs.py +++ b/cirro_api_client/v1/api/sheets/get_jobs.py @@ -56,7 +56,7 @@ def sync_detailed( ) -> Response[list[SheetJob]]: """List jobs - Retrieves ingest jobs for a sheet + Retrieves jobs for a sheet Args: project_id (str): @@ -92,7 +92,7 @@ def sync( ) -> list[SheetJob] | None: """List jobs - Retrieves ingest jobs for a sheet + Retrieves jobs for a sheet Args: project_id (str): @@ -125,7 +125,7 @@ async def asyncio_detailed( ) -> Response[list[SheetJob]]: """List jobs - Retrieves ingest jobs for a sheet + Retrieves jobs for a sheet Args: project_id (str): @@ -158,7 +158,7 @@ async def asyncio( ) -> list[SheetJob] | None: """List jobs - Retrieves ingest jobs for a sheet + Retrieves jobs for a sheet Args: project_id (str): diff --git a/cirro_api_client/v1/api/sheets/insert_sheet_data.py b/cirro_api_client/v1/api/sheets/insert_sheet_data.py new file mode 100644 index 0000000..10d5e30 --- /dev/null +++ b/cirro_api_client/v1/api/sheets/insert_sheet_data.py @@ -0,0 +1,202 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import Client +from ...models.insert_rows_request import InsertRowsRequest +from ...models.sheet_data_update_response import SheetDataUpdateResponse +from ...types import Response + + +def _get_kwargs( + project_id: str, + sheet_id: str, + *, + body: InsertRowsRequest, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "post", + "url": "/projects/{project_id}/sheets/{sheet_id}/data".format( + project_id=quote(str(project_id), safe=""), + sheet_id=quote(str(sheet_id), safe=""), + ), + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> SheetDataUpdateResponse | None: + if response.status_code == 200: + response_200 = SheetDataUpdateResponse.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[SheetDataUpdateResponse]: + 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, + sheet_id: str, + *, + client: Client, + body: InsertRowsRequest, +) -> Response[SheetDataUpdateResponse]: + """Insert sheet rows + + Returns number of rows inserted. + + Args: + project_id (str): + sheet_id (str): + body (InsertRowsRequest): + 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[SheetDataUpdateResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + sheet_id=sheet_id, + body=body, + ) + + response = client.get_httpx_client().request( + auth=client.get_auth(), + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + project_id: str, + sheet_id: str, + *, + client: Client, + body: InsertRowsRequest, +) -> SheetDataUpdateResponse | None: + """Insert sheet rows + + Returns number of rows inserted. + + Args: + project_id (str): + sheet_id (str): + body (InsertRowsRequest): + 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: + SheetDataUpdateResponse + """ + + try: + return sync_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + ).parsed + except errors.NotFoundException: + return None + + +async def asyncio_detailed( + project_id: str, + sheet_id: str, + *, + client: Client, + body: InsertRowsRequest, +) -> Response[SheetDataUpdateResponse]: + """Insert sheet rows + + Returns number of rows inserted. + + Args: + project_id (str): + sheet_id (str): + body (InsertRowsRequest): + 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[SheetDataUpdateResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + sheet_id=sheet_id, + body=body, + ) + + 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, + sheet_id: str, + *, + client: Client, + body: InsertRowsRequest, +) -> SheetDataUpdateResponse | None: + """Insert sheet rows + + Returns number of rows inserted. + + Args: + project_id (str): + sheet_id (str): + body (InsertRowsRequest): + 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: + SheetDataUpdateResponse + """ + + try: + return ( + await asyncio_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/sheets/query_namespace_data.py b/cirro_api_client/v1/api/sheets/query_namespace_data.py new file mode 100644 index 0000000..f5fe0a4 --- /dev/null +++ b/cirro_api_client/v1/api/sheets/query_namespace_data.py @@ -0,0 +1,188 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import Client +from ...models.sheet_query_request import SheetQueryRequest +from ...models.sheet_query_response import SheetQueryResponse +from ...types import Response + + +def _get_kwargs( + project_id: str, + *, + body: SheetQueryRequest, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "post", + "url": "/projects/{project_id}/sheets/raw-query".format( + project_id=quote(str(project_id), safe=""), + ), + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> SheetQueryResponse | None: + if response.status_code == 200: + response_200 = SheetQueryResponse.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[SheetQueryResponse]: + 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, + body: SheetQueryRequest, +) -> Response[SheetQueryResponse]: + """Run raw SQL against the project's sheets. + + Returns executed SQL results. + + Args: + project_id (str): + body (SheetQueryRequest): + 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[SheetQueryResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + body=body, + ) + + 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, + body: SheetQueryRequest, +) -> SheetQueryResponse | None: + """Run raw SQL against the project's sheets. + + Returns executed SQL results. + + Args: + project_id (str): + body (SheetQueryRequest): + 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: + SheetQueryResponse + """ + + try: + return sync_detailed( + project_id=project_id, + client=client, + body=body, + ).parsed + except errors.NotFoundException: + return None + + +async def asyncio_detailed( + project_id: str, + *, + client: Client, + body: SheetQueryRequest, +) -> Response[SheetQueryResponse]: + """Run raw SQL against the project's sheets. + + Returns executed SQL results. + + Args: + project_id (str): + body (SheetQueryRequest): + 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[SheetQueryResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + body=body, + ) + + 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, + body: SheetQueryRequest, +) -> SheetQueryResponse | None: + """Run raw SQL against the project's sheets. + + Returns executed SQL results. + + Args: + project_id (str): + body (SheetQueryRequest): + 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: + SheetQueryResponse + """ + + try: + return ( + await asyncio_detailed( + project_id=project_id, + client=client, + body=body, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/sheets/query_sheet_data.py b/cirro_api_client/v1/api/sheets/query_sheet_data.py new file mode 100644 index 0000000..493881f --- /dev/null +++ b/cirro_api_client/v1/api/sheets/query_sheet_data.py @@ -0,0 +1,210 @@ +from http import HTTPStatus +from typing import Any +from urllib.parse import quote + +import httpx + +from ... import errors +from ...client import Client +from ...models.sheet_data_request import SheetDataRequest +from ...models.sheet_query_response import SheetQueryResponse +from ...types import Response + + +def _get_kwargs( + project_id: str, + sheet_id: str, + *, + body: SheetDataRequest, +) -> dict[str, Any]: + headers: dict[str, Any] = {} + + _kwargs: dict[str, Any] = { + "method": "post", + "url": "/projects/{project_id}/sheets/{sheet_id}/data/query".format( + project_id=quote(str(project_id), safe=""), + sheet_id=quote(str(sheet_id), safe=""), + ), + } + + _kwargs["json"] = body.to_dict() + + headers["Content-Type"] = "application/json" + + _kwargs["headers"] = headers + return _kwargs + + +def _parse_response(*, client: Client, response: httpx.Response) -> SheetQueryResponse | None: + if response.status_code == 200: + response_200 = SheetQueryResponse.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[SheetQueryResponse]: + 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, + sheet_id: str, + *, + client: Client, + body: SheetDataRequest, +) -> Response[SheetQueryResponse]: + """Query sheet data + + Returns paginated rows from a sheet. The first column is always _row_id, which uniquely identifies + each row and is required for row updates via PUT. This is essentially a GET request disguised as a + POST so we can pass in a body. + + Args: + project_id (str): + sheet_id (str): + body (SheetDataRequest): Paginated sheet data query with optional sort and filter + 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[SheetQueryResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + sheet_id=sheet_id, + body=body, + ) + + response = client.get_httpx_client().request( + auth=client.get_auth(), + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + project_id: str, + sheet_id: str, + *, + client: Client, + body: SheetDataRequest, +) -> SheetQueryResponse | None: + """Query sheet data + + Returns paginated rows from a sheet. The first column is always _row_id, which uniquely identifies + each row and is required for row updates via PUT. This is essentially a GET request disguised as a + POST so we can pass in a body. + + Args: + project_id (str): + sheet_id (str): + body (SheetDataRequest): Paginated sheet data query with optional sort and filter + 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: + SheetQueryResponse + """ + + try: + return sync_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + ).parsed + except errors.NotFoundException: + return None + + +async def asyncio_detailed( + project_id: str, + sheet_id: str, + *, + client: Client, + body: SheetDataRequest, +) -> Response[SheetQueryResponse]: + """Query sheet data + + Returns paginated rows from a sheet. The first column is always _row_id, which uniquely identifies + each row and is required for row updates via PUT. This is essentially a GET request disguised as a + POST so we can pass in a body. + + Args: + project_id (str): + sheet_id (str): + body (SheetDataRequest): Paginated sheet data query with optional sort and filter + 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[SheetQueryResponse] + """ + + kwargs = _get_kwargs( + project_id=project_id, + sheet_id=sheet_id, + body=body, + ) + + 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, + sheet_id: str, + *, + client: Client, + body: SheetDataRequest, +) -> SheetQueryResponse | None: + """Query sheet data + + Returns paginated rows from a sheet. The first column is always _row_id, which uniquely identifies + each row and is required for row updates via PUT. This is essentially a GET request disguised as a + POST so we can pass in a body. + + Args: + project_id (str): + sheet_id (str): + body (SheetDataRequest): Paginated sheet data query with optional sort and filter + 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: + SheetQueryResponse + """ + + try: + return ( + await asyncio_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/sheets/refresh_view.py b/cirro_api_client/v1/api/sheets/refresh_view.py index 6bd4934..0d4fef7 100644 --- a/cirro_api_client/v1/api/sheets/refresh_view.py +++ b/cirro_api_client/v1/api/sheets/refresh_view.py @@ -14,7 +14,7 @@ def _get_kwargs( sheet_id: str, ) -> dict[str, Any]: _kwargs: dict[str, Any] = { - "method": "post", + "method": "put", "url": "/projects/{project_id}/sheets/{sheet_id}:refresh".format( project_id=quote(str(project_id), safe=""), sheet_id=quote(str(sheet_id), safe=""), diff --git a/cirro_api_client/v1/api/sheets/trigger_ingest.py b/cirro_api_client/v1/api/sheets/trigger_ingest.py index 2490b66..582a0ec 100644 --- a/cirro_api_client/v1/api/sheets/trigger_ingest.py +++ b/cirro_api_client/v1/api/sheets/trigger_ingest.py @@ -6,8 +6,7 @@ from ... import errors from ...client import Client -from ...models.create_response import CreateResponse -from ...models.trigger_ingest_request import TriggerIngestRequest +from ...models.sheet_ingest_request import SheetIngestRequest from ...types import Response @@ -15,7 +14,7 @@ def _get_kwargs( project_id: str, sheet_id: str, *, - body: TriggerIngestRequest, + body: SheetIngestRequest, ) -> dict[str, Any]: headers: dict[str, Any] = {} @@ -35,16 +34,14 @@ def _get_kwargs( return _kwargs -def _parse_response(*, client: Client, response: httpx.Response) -> CreateResponse | None: - if response.status_code == 201: - response_201 = CreateResponse.from_dict(response.json()) - - return response_201 +def _parse_response(*, client: Client, response: httpx.Response) -> Any | None: + if response.status_code == 202: + return None errors.handle_error_response(response, client.raise_on_unexpected_status) -def _build_response(*, client: Client, response: httpx.Response) -> Response[CreateResponse]: +def _build_response(*, client: Client, response: httpx.Response) -> Response[Any]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -58,8 +55,8 @@ def sync_detailed( sheet_id: str, *, client: Client, - body: TriggerIngestRequest, -) -> Response[CreateResponse]: + body: SheetIngestRequest, +) -> Response[Any]: """Trigger ingest Triggers an async file ingest into the sheet @@ -67,7 +64,7 @@ def sync_detailed( Args: project_id (str): sheet_id (str): - body (TriggerIngestRequest): + body (SheetIngestRequest): client (Client): instance of the API client Raises: @@ -75,7 +72,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CreateResponse] + Response[Any] """ kwargs = _get_kwargs( @@ -92,49 +89,13 @@ def sync_detailed( return _build_response(client=client, response=response) -def sync( - project_id: str, - sheet_id: str, - *, - client: Client, - body: TriggerIngestRequest, -) -> CreateResponse | None: - """Trigger ingest - - Triggers an async file ingest into the sheet - - Args: - project_id (str): - sheet_id (str): - body (TriggerIngestRequest): - 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: - CreateResponse - """ - - try: - return sync_detailed( - project_id=project_id, - sheet_id=sheet_id, - client=client, - body=body, - ).parsed - except errors.NotFoundException: - return None - - async def asyncio_detailed( project_id: str, sheet_id: str, *, client: Client, - body: TriggerIngestRequest, -) -> Response[CreateResponse]: + body: SheetIngestRequest, +) -> Response[Any]: """Trigger ingest Triggers an async file ingest into the sheet @@ -142,7 +103,7 @@ async def asyncio_detailed( Args: project_id (str): sheet_id (str): - body (TriggerIngestRequest): + body (SheetIngestRequest): client (Client): instance of the API client Raises: @@ -150,7 +111,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[CreateResponse] + Response[Any] """ kwargs = _get_kwargs( @@ -162,41 +123,3 @@ async def asyncio_detailed( 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, - sheet_id: str, - *, - client: Client, - body: TriggerIngestRequest, -) -> CreateResponse | None: - """Trigger ingest - - Triggers an async file ingest into the sheet - - Args: - project_id (str): - sheet_id (str): - body (TriggerIngestRequest): - 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: - CreateResponse - """ - - try: - return ( - await asyncio_detailed( - project_id=project_id, - sheet_id=sheet_id, - client=client, - body=body, - ) - ).parsed - except errors.NotFoundException: - return None diff --git a/cirro_api_client/v1/api/sheets/update_sheet.py b/cirro_api_client/v1/api/sheets/update_sheet.py index 7652461..0d83e07 100644 --- a/cirro_api_client/v1/api/sheets/update_sheet.py +++ b/cirro_api_client/v1/api/sheets/update_sheet.py @@ -6,27 +6,41 @@ from ... import errors from ...client import Client -from ...models.update_sheet_request import UpdateSheetRequest -from ...types import Response +from ...models.sheet_update_response import SheetUpdateResponse +from ...models.table_sheet_input import TableSheetInput +from ...models.view_sheet_input import ViewSheetInput +from ...types import UNSET, Response, Unset def _get_kwargs( project_id: str, sheet_id: str, *, - body: UpdateSheetRequest, + body: TableSheetInput | ViewSheetInput, + dry_run: bool | Unset = False, ) -> dict[str, Any]: headers: dict[str, Any] = {} + params: dict[str, Any] = {} + + params["dryRun"] = dry_run + + 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": "/projects/{project_id}/sheets/{sheet_id}".format( project_id=quote(str(project_id), safe=""), sheet_id=quote(str(sheet_id), safe=""), ), + "params": params, } - _kwargs["json"] = body.to_dict() + _kwargs["json"]: dict[str, Any] + if isinstance(body, TableSheetInput): + _kwargs["json"] = body.to_dict() + else: + _kwargs["json"] = body.to_dict() headers["Content-Type"] = "application/json" @@ -34,14 +48,16 @@ def _get_kwargs( return _kwargs -def _parse_response(*, client: Client, response: httpx.Response) -> Any | None: +def _parse_response(*, client: Client, response: httpx.Response) -> SheetUpdateResponse | None: if response.status_code == 200: - return None + response_200 = SheetUpdateResponse.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[Any]: +def _build_response(*, client: Client, response: httpx.Response) -> Response[SheetUpdateResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -55,16 +71,20 @@ def sync_detailed( sheet_id: str, *, client: Client, - body: UpdateSheetRequest, -) -> Response[Any]: + body: TableSheetInput | ViewSheetInput, + dry_run: bool | Unset = False, +) -> Response[SheetUpdateResponse]: """Update sheet - Updates a sheet (table or view) + Idempotent update: send the full target state. Server validates immutable fields match and applies + the diff of mutable fields (rename, columns, view definition). For TABLE dryRun, returns the ALTER + statements that would run. Args: project_id (str): sheet_id (str): - body (UpdateSheetRequest): + dry_run (bool | Unset): Default: False. + body (TableSheetInput | ViewSheetInput): client (Client): instance of the API client Raises: @@ -72,13 +92,14 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[SheetUpdateResponse] """ kwargs = _get_kwargs( project_id=project_id, sheet_id=sheet_id, body=body, + dry_run=dry_run, ) response = client.get_httpx_client().request( @@ -89,21 +110,66 @@ def sync_detailed( return _build_response(client=client, response=response) +def sync( + project_id: str, + sheet_id: str, + *, + client: Client, + body: TableSheetInput | ViewSheetInput, + dry_run: bool | Unset = False, +) -> SheetUpdateResponse | None: + """Update sheet + + Idempotent update: send the full target state. Server validates immutable fields match and applies + the diff of mutable fields (rename, columns, view definition). For TABLE dryRun, returns the ALTER + statements that would run. + + Args: + project_id (str): + sheet_id (str): + dry_run (bool | Unset): Default: False. + body (TableSheetInput | ViewSheetInput): + 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: + SheetUpdateResponse + """ + + try: + return sync_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + dry_run=dry_run, + ).parsed + except errors.NotFoundException: + return None + + async def asyncio_detailed( project_id: str, sheet_id: str, *, client: Client, - body: UpdateSheetRequest, -) -> Response[Any]: + body: TableSheetInput | ViewSheetInput, + dry_run: bool | Unset = False, +) -> Response[SheetUpdateResponse]: """Update sheet - Updates a sheet (table or view) + Idempotent update: send the full target state. Server validates immutable fields match and applies + the diff of mutable fields (rename, columns, view definition). For TABLE dryRun, returns the ALTER + statements that would run. Args: project_id (str): sheet_id (str): - body (UpdateSheetRequest): + dry_run (bool | Unset): Default: False. + body (TableSheetInput | ViewSheetInput): client (Client): instance of the API client Raises: @@ -111,15 +177,59 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[SheetUpdateResponse] """ kwargs = _get_kwargs( project_id=project_id, sheet_id=sheet_id, body=body, + dry_run=dry_run, ) 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, + sheet_id: str, + *, + client: Client, + body: TableSheetInput | ViewSheetInput, + dry_run: bool | Unset = False, +) -> SheetUpdateResponse | None: + """Update sheet + + Idempotent update: send the full target state. Server validates immutable fields match and applies + the diff of mutable fields (rename, columns, view definition). For TABLE dryRun, returns the ALTER + statements that would run. + + Args: + project_id (str): + sheet_id (str): + dry_run (bool | Unset): Default: False. + body (TableSheetInput | ViewSheetInput): + 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: + SheetUpdateResponse + """ + + try: + return ( + await asyncio_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + dry_run=dry_run, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/sheets/update_sheet_data.py b/cirro_api_client/v1/api/sheets/update_sheet_data.py index 1b400b4..fdc5ab2 100644 --- a/cirro_api_client/v1/api/sheets/update_sheet_data.py +++ b/cirro_api_client/v1/api/sheets/update_sheet_data.py @@ -6,6 +6,7 @@ from ... import errors from ...client import Client +from ...models.sheet_data_update_response import SheetDataUpdateResponse from ...models.update_rows_request import UpdateRowsRequest from ...types import Response @@ -19,7 +20,7 @@ def _get_kwargs( headers: dict[str, Any] = {} _kwargs: dict[str, Any] = { - "method": "put", + "method": "patch", "url": "/projects/{project_id}/sheets/{sheet_id}/data".format( project_id=quote(str(project_id), safe=""), sheet_id=quote(str(sheet_id), safe=""), @@ -34,14 +35,16 @@ def _get_kwargs( return _kwargs -def _parse_response(*, client: Client, response: httpx.Response) -> Any | None: +def _parse_response(*, client: Client, response: httpx.Response) -> SheetDataUpdateResponse | None: if response.status_code == 200: - return None + response_200 = SheetDataUpdateResponse.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[Any]: +def _build_response(*, client: Client, response: httpx.Response) -> Response[SheetDataUpdateResponse]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -56,11 +59,11 @@ def sync_detailed( *, client: Client, body: UpdateRowsRequest, -) -> Response[Any]: +) -> Response[SheetDataUpdateResponse]: """Update sheet rows - Updates specific rows in a TABLE sheet by _row_id. This is a partial update: only the columns - included in each entry are modified, all other columns are left unchanged. + Returns number of rows updated. Updates specific rows in a TABLE sheet by _row_id. This is a partial + update: only the columns included in each entry are modified, all other columns are left unchanged. Args: project_id (str): @@ -73,7 +76,7 @@ def sync_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[SheetDataUpdateResponse] """ kwargs = _get_kwargs( @@ -90,17 +93,54 @@ def sync_detailed( return _build_response(client=client, response=response) +def sync( + project_id: str, + sheet_id: str, + *, + client: Client, + body: UpdateRowsRequest, +) -> SheetDataUpdateResponse | None: + """Update sheet rows + + Returns number of rows updated. Updates specific rows in a TABLE sheet by _row_id. This is a partial + update: only the columns included in each entry are modified, all other columns are left unchanged. + + Args: + project_id (str): + sheet_id (str): + body (UpdateRowsRequest): + 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: + SheetDataUpdateResponse + """ + + try: + return sync_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + ).parsed + except errors.NotFoundException: + return None + + async def asyncio_detailed( project_id: str, sheet_id: str, *, client: Client, body: UpdateRowsRequest, -) -> Response[Any]: +) -> Response[SheetDataUpdateResponse]: """Update sheet rows - Updates specific rows in a TABLE sheet by _row_id. This is a partial update: only the columns - included in each entry are modified, all other columns are left unchanged. + Returns number of rows updated. Updates specific rows in a TABLE sheet by _row_id. This is a partial + update: only the columns included in each entry are modified, all other columns are left unchanged. Args: project_id (str): @@ -113,7 +153,7 @@ async def asyncio_detailed( httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Any] + Response[SheetDataUpdateResponse] """ kwargs = _get_kwargs( @@ -125,3 +165,42 @@ async def asyncio_detailed( 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, + sheet_id: str, + *, + client: Client, + body: UpdateRowsRequest, +) -> SheetDataUpdateResponse | None: + """Update sheet rows + + Returns number of rows updated. Updates specific rows in a TABLE sheet by _row_id. This is a partial + update: only the columns included in each entry are modified, all other columns are left unchanged. + + Args: + project_id (str): + sheet_id (str): + body (UpdateRowsRequest): + 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: + SheetDataUpdateResponse + """ + + try: + return ( + await asyncio_detailed( + project_id=project_id, + sheet_id=sheet_id, + client=client, + body=body, + ) + ).parsed + except errors.NotFoundException: + return None diff --git a/cirro_api_client/v1/api/workspaces/delete_workspace.py b/cirro_api_client/v1/api/workspaces/delete_workspace.py index 591bfb2..1ae68d0 100644 --- a/cirro_api_client/v1/api/workspaces/delete_workspace.py +++ b/cirro_api_client/v1/api/workspaces/delete_workspace.py @@ -6,19 +6,28 @@ from ... import errors from ...client import Client -from ...types import Response +from ...types import UNSET, Response, Unset def _get_kwargs( project_id: str, workspace_id: str, + *, + force: bool | Unset = False, ) -> dict[str, Any]: + params: dict[str, Any] = {} + + params["force"] = force + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} + _kwargs: dict[str, Any] = { "method": "delete", "url": "/projects/{project_id}/workspaces/{workspace_id}".format( project_id=quote(str(project_id), safe=""), workspace_id=quote(str(workspace_id), safe=""), ), + "params": params, } return _kwargs @@ -45,14 +54,17 @@ def sync_detailed( workspace_id: str, *, client: Client, + force: bool | Unset = False, ) -> Response[Any]: """Delete workspace - Deletes a workspace within a project + Deletes a workspace within a project. Pass force=true (global admin only) to skip the FAILED-on- + cleanup-error guard and end the workspace in DELETED regardless of partial cleanup failures. Args: project_id (str): workspace_id (str): + force (bool | Unset): Default: False. client (Client): instance of the API client Raises: @@ -66,6 +78,7 @@ def sync_detailed( kwargs = _get_kwargs( project_id=project_id, workspace_id=workspace_id, + force=force, ) response = client.get_httpx_client().request( @@ -81,14 +94,17 @@ async def asyncio_detailed( workspace_id: str, *, client: Client, + force: bool | Unset = False, ) -> Response[Any]: """Delete workspace - Deletes a workspace within a project + Deletes a workspace within a project. Pass force=true (global admin only) to skip the FAILED-on- + cleanup-error guard and end the workspace in DELETED regardless of partial cleanup failures. Args: project_id (str): workspace_id (str): + force (bool | Unset): Default: False. client (Client): instance of the API client Raises: @@ -102,6 +118,7 @@ async def asyncio_detailed( kwargs = _get_kwargs( project_id=project_id, workspace_id=workspace_id, + force=force, ) response = await client.get_async_httpx_client().request(auth=client.get_auth(), **kwargs) diff --git a/cirro_api_client/v1/models/__init__.py b/cirro_api_client/v1/models/__init__.py index 8e010a6..3232e72 100644 --- a/cirro_api_client/v1/models/__init__.py +++ b/cirro_api_client/v1/models/__init__.py @@ -13,10 +13,12 @@ from .agent_tags import AgentTags from .allowed_data_type import AllowedDataType from .app_client_type import AppClientType +from .app_publisher_type import AppPublisherType from .app_registration import AppRegistration from .app_registration_detail import AppRegistrationDetail from .app_registration_input import AppRegistrationInput from .app_registration_secret_response import AppRegistrationSecretResponse +from .app_registration_template import AppRegistrationTemplate from .app_type import AppType from .approve_project_access_request import ApproveProjectAccessRequest from .artifact import Artifact @@ -48,7 +50,6 @@ from .create_project_access_request import CreateProjectAccessRequest from .create_reference_request import CreateReferenceRequest from .create_response import CreateResponse -from .create_sheet_request import CreateSheetRequest from .custom_pipeline_settings import CustomPipelineSettings from .custom_process_input import CustomProcessInput from .customer_type import CustomerType @@ -69,6 +70,8 @@ from .dataset_detail_params import DatasetDetailParams from .dataset_detail_source_sample_files_map import DatasetDetailSourceSampleFilesMap from .dataset_viz import DatasetViz +from .dataset_viz_config import DatasetVizConfig +from .delete_rows_request import DeleteRowsRequest from .discussion import Discussion from .discussion_input import DiscussionInput from .discussion_type import DiscussionType @@ -86,6 +89,7 @@ from .file_name_pattern import FileNamePattern from .file_requirements import FileRequirements from .file_type import FileType +from .filter_ import Filter from .filter_operator import FilterOperator from .foreign_key_ref import ForeignKeyRef from .form_schema import FormSchema @@ -96,6 +100,7 @@ from .generate_sftp_credentials_request import GenerateSftpCredentialsRequest from .get_execution_logs_response import GetExecutionLogsResponse from .get_project_summary_response_200 import GetProjectSummaryResponse200 +from .get_task_files_response import GetTaskFilesResponse from .governance_access_type import GovernanceAccessType from .governance_classification import GovernanceClassification from .governance_contact import GovernanceContact @@ -113,6 +118,7 @@ from .group_cost import GroupCost from .import_data_request import ImportDataRequest from .import_data_request_download_method import ImportDataRequestDownloadMethod +from .insert_rows_request import InsertRowsRequest from .invite_user_request import InviteUserRequest from .invite_user_response import InviteUserResponse from .join_condition import JoinCondition @@ -160,6 +166,7 @@ from .project_settings import ProjectSettings from .project_user import ProjectUser from .query_column import QueryColumn +from .raw_view_query_request import RawViewQueryRequest from .reference import Reference from .reference_type import ReferenceType from .reference_type_validation_item import ReferenceTypeValidationItem @@ -170,6 +177,9 @@ 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 @@ -181,6 +191,7 @@ from .sample_request import SampleRequest from .sample_request_metadata import SampleRequestMetadata from .sample_sheets import SampleSheets +from .semantic_column_type import SemanticColumnType from .service_connection import ServiceConnection from .set_user_project_role_request import SetUserProjectRoleRequest from .sftp_credentials import SftpCredentials @@ -193,27 +204,35 @@ from .sharing_type import SharingType from .sheet import Sheet from .sheet_creation_mode import SheetCreationMode +from .sheet_data_request import SheetDataRequest +from .sheet_data_update_response import SheetDataUpdateResponse from .sheet_detail import SheetDetail +from .sheet_ingest_request import SheetIngestRequest from .sheet_job import SheetJob from .sheet_job_type import SheetJobType +from .sheet_query_request import SheetQueryRequest from .sheet_query_response import SheetQueryResponse from .sheet_query_response_rows_item import SheetQueryResponseRowsItem +from .sheet_sort import SheetSort from .sheet_type import SheetType +from .sheet_update_response import SheetUpdateResponse from .sort_order import SortOrder +from .source_column import SourceColumn from .sql_sort_order import SqlSortOrder from .status import Status from .stop_execution_response import StopExecutionResponse +from .structured_view_query_request import StructuredViewQueryRequest from .sync_status import SyncStatus from .system_info_response import SystemInfoResponse from .table import Table +from .table_sheet_input import TableSheetInput from .tag import Tag from .task import Task from .task_cost import TaskCost +from .task_log_source import TaskLogSource from .tenant_info import TenantInfo -from .trigger_ingest_request import TriggerIngestRequest from .update_dataset_request import UpdateDatasetRequest from .update_rows_request import UpdateRowsRequest -from .update_sheet_request import UpdateSheetRequest from .update_user_request import UpdateUserRequest from .upload_dataset_create_response import UploadDatasetCreateResponse from .upload_dataset_request import UploadDatasetRequest @@ -224,10 +243,8 @@ from .validate_file_name_patterns_request import ValidateFileNamePatternsRequest from .validate_file_requirements_request import ValidateFileRequirementsRequest from .version_specification import VersionSpecification -from .view_filter import ViewFilter -from .view_filter_values import ViewFilterValues from .view_join import ViewJoin -from .view_query_request import ViewQueryRequest +from .view_sheet_input import ViewSheetInput from .view_sheet_ref import ViewSheetRef from .workspace import Workspace from .workspace_compute_config import WorkspaceComputeConfig @@ -251,10 +268,12 @@ "AgentTags", "AllowedDataType", "AppClientType", + "AppPublisherType", "AppRegistration", "AppRegistrationDetail", "AppRegistrationInput", "AppRegistrationSecretResponse", + "AppRegistrationTemplate", "ApproveProjectAccessRequest", "AppType", "Artifact", @@ -286,7 +305,6 @@ "CreateProjectAccessRequest", "CreateReferenceRequest", "CreateResponse", - "CreateSheetRequest", "CustomerType", "CustomPipelineSettings", "CustomProcessInput", @@ -307,6 +325,8 @@ "DatasetDetailParams", "DatasetDetailSourceSampleFilesMap", "DatasetViz", + "DatasetVizConfig", + "DeleteRowsRequest", "Discussion", "DiscussionInput", "DiscussionType", @@ -324,6 +344,7 @@ "FileNamePattern", "FileRequirements", "FileType", + "Filter", "FilterOperator", "ForeignKeyRef", "FormSchema", @@ -334,6 +355,7 @@ "GenerateSftpCredentialsRequest", "GetExecutionLogsResponse", "GetProjectSummaryResponse200", + "GetTaskFilesResponse", "GovernanceAccessType", "GovernanceClassification", "GovernanceContact", @@ -351,6 +373,7 @@ "GroupCost", "ImportDataRequest", "ImportDataRequestDownloadMethod", + "InsertRowsRequest", "InviteUserRequest", "InviteUserResponse", "JoinCondition", @@ -398,6 +421,7 @@ "ProjectSettings", "ProjectUser", "QueryColumn", + "RawViewQueryRequest", "Reference", "ReferenceType", "ReferenceTypeValidationItem", @@ -408,6 +432,9 @@ "RequirementFulfillmentInput", "RequirementInput", "ResourcesInfo", + "RowInsert", + "RowInsertValues", + "RowInsertValuesAdditionalProperty", "RowUpdate", "RowUpdateValues", "RowUpdateValuesAdditionalProperty", @@ -419,6 +446,7 @@ "SampleRequest", "SampleRequestMetadata", "SampleSheets", + "SemanticColumnType", "ServiceConnection", "SetUserProjectRoleRequest", "SftpCredentials", @@ -431,27 +459,35 @@ "SharingType", "Sheet", "SheetCreationMode", + "SheetDataRequest", + "SheetDataUpdateResponse", "SheetDetail", + "SheetIngestRequest", "SheetJob", "SheetJobType", + "SheetQueryRequest", "SheetQueryResponse", "SheetQueryResponseRowsItem", + "SheetSort", "SheetType", + "SheetUpdateResponse", "SortOrder", + "SourceColumn", "SqlSortOrder", "Status", "StopExecutionResponse", + "StructuredViewQueryRequest", "SyncStatus", "SystemInfoResponse", "Table", + "TableSheetInput", "Tag", "Task", "TaskCost", + "TaskLogSource", "TenantInfo", - "TriggerIngestRequest", "UpdateDatasetRequest", "UpdateRowsRequest", - "UpdateSheetRequest", "UpdateUserRequest", "UploadDatasetCreateResponse", "UploadDatasetRequest", @@ -462,10 +498,8 @@ "ValidateFileNamePatternsRequest", "ValidateFileRequirementsRequest", "VersionSpecification", - "ViewFilter", - "ViewFilterValues", "ViewJoin", - "ViewQueryRequest", + "ViewSheetInput", "ViewSheetRef", "Workspace", "WorkspaceComputeConfig", diff --git a/cirro_api_client/v1/models/app_publisher_type.py b/cirro_api_client/v1/models/app_publisher_type.py new file mode 100644 index 0000000..b7b1c32 --- /dev/null +++ b/cirro_api_client/v1/models/app_publisher_type.py @@ -0,0 +1,15 @@ +from enum import Enum + + +class AppPublisherType(str, Enum): + OFFICIAL = "OFFICIAL" + THIRD_PARTY = "THIRD_PARTY" + 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/app_registration.py b/cirro_api_client/v1/models/app_registration.py index 3eefeed..030d7c5 100644 --- a/cirro_api_client/v1/models/app_registration.py +++ b/cirro_api_client/v1/models/app_registration.py @@ -9,6 +9,7 @@ from dateutil.parser import isoparse from ..models.app_client_type import AppClientType +from ..models.app_publisher_type import AppPublisherType from ..models.app_type import AppType from ..models.principal_type import PrincipalType from ..types import UNSET, Unset @@ -24,11 +25,17 @@ class AppRegistration: client_id (str): name (str): description (str): + logo_url (str): + app_url (str): + publisher (str): + publisher_type (AppPublisherType): principal_type (PrincipalType): type_ (AppType): client_type (AppClientType): is_archived (bool): requires_admin_consent (bool): + discovery_enabled (bool): + created_from_template (bool): updated_at (datetime.datetime): created_at (datetime.datetime): created_by (str): @@ -39,11 +46,17 @@ class AppRegistration: client_id: str name: str description: str + logo_url: str + app_url: str + publisher: str + publisher_type: AppPublisherType principal_type: PrincipalType type_: AppType client_type: AppClientType is_archived: bool requires_admin_consent: bool + discovery_enabled: bool + created_from_template: bool updated_at: datetime.datetime created_at: datetime.datetime created_by: str @@ -59,6 +72,14 @@ def to_dict(self) -> dict[str, Any]: description = self.description + logo_url = self.logo_url + + app_url = self.app_url + + publisher = self.publisher + + publisher_type = self.publisher_type.value + principal_type = self.principal_type.value type_ = self.type_.value @@ -69,6 +90,10 @@ def to_dict(self) -> dict[str, Any]: requires_admin_consent = self.requires_admin_consent + discovery_enabled = self.discovery_enabled + + created_from_template = self.created_from_template + updated_at = self.updated_at.isoformat() created_at = self.created_at.isoformat() @@ -91,11 +116,17 @@ def to_dict(self) -> dict[str, Any]: "clientId": client_id, "name": name, "description": description, + "logoUrl": logo_url, + "appUrl": app_url, + "publisher": publisher, + "publisherType": publisher_type, "principalType": principal_type, "type": type_, "clientType": client_type, "isArchived": is_archived, "requiresAdminConsent": requires_admin_consent, + "discoveryEnabled": discovery_enabled, + "createdFromTemplate": created_from_template, "updatedAt": updated_at, "createdAt": created_at, "createdBy": created_by, @@ -117,6 +148,14 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: description = d.pop("description") + logo_url = d.pop("logoUrl") + + app_url = d.pop("appUrl") + + publisher = d.pop("publisher") + + publisher_type = AppPublisherType(d.pop("publisherType")) + principal_type = PrincipalType(d.pop("principalType")) type_ = AppType(d.pop("type")) @@ -127,6 +166,10 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: requires_admin_consent = d.pop("requiresAdminConsent") + discovery_enabled = d.pop("discoveryEnabled") + + created_from_template = d.pop("createdFromTemplate") + updated_at = isoparse(d.pop("updatedAt")) created_at = isoparse(d.pop("createdAt")) @@ -155,11 +198,17 @@ def _parse_secret_expires_at(data: object) -> datetime.datetime | None | Unset: client_id=client_id, name=name, description=description, + logo_url=logo_url, + app_url=app_url, + publisher=publisher, + publisher_type=publisher_type, principal_type=principal_type, type_=type_, client_type=client_type, is_archived=is_archived, requires_admin_consent=requires_admin_consent, + discovery_enabled=discovery_enabled, + created_from_template=created_from_template, updated_at=updated_at, created_at=created_at, created_by=created_by, diff --git a/cirro_api_client/v1/models/app_registration_detail.py b/cirro_api_client/v1/models/app_registration_detail.py index aa979f4..dac9ac7 100644 --- a/cirro_api_client/v1/models/app_registration_detail.py +++ b/cirro_api_client/v1/models/app_registration_detail.py @@ -9,6 +9,7 @@ from dateutil.parser import isoparse from ..models.app_client_type import AppClientType +from ..models.app_publisher_type import AppPublisherType from ..models.app_type import AppType from ..models.permission import Permission from ..models.principal_type import PrincipalType @@ -29,6 +30,10 @@ class AppRegistrationDetail: client_id (str): name (str): description (str): + logo_url (str): + app_url (str): + publisher (str): + publisher_type (AppPublisherType): principal_type (PrincipalType): type_ (AppType): client_type (AppClientType): @@ -36,6 +41,8 @@ class AppRegistrationDetail: global_permissions (list[Permission]): is_archived (bool): requires_admin_consent (bool): + discovery_enabled (bool): + created_from_template (bool): created_at (datetime.datetime): updated_at (datetime.datetime): created_by (str): @@ -44,6 +51,7 @@ class AppRegistrationDetail: secret_expires_at (datetime.datetime | None | Unset): secret_generated_at (datetime.datetime | None | Unset): secret_generated_by (None | str | Unset): + template_id (None | str | Unset): approved_at (datetime.datetime | None | Unset): approved_by (None | str | Unset): """ @@ -52,6 +60,10 @@ class AppRegistrationDetail: client_id: str name: str description: str + logo_url: str + app_url: str + publisher: str + publisher_type: AppPublisherType principal_type: PrincipalType type_: AppType client_type: AppClientType @@ -59,6 +71,8 @@ class AppRegistrationDetail: global_permissions: list[Permission] is_archived: bool requires_admin_consent: bool + discovery_enabled: bool + created_from_template: bool created_at: datetime.datetime updated_at: datetime.datetime created_by: str @@ -67,6 +81,7 @@ class AppRegistrationDetail: secret_expires_at: datetime.datetime | None | Unset = UNSET secret_generated_at: datetime.datetime | None | Unset = UNSET secret_generated_by: None | str | Unset = UNSET + template_id: None | str | Unset = UNSET approved_at: datetime.datetime | None | Unset = UNSET approved_by: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -80,6 +95,14 @@ def to_dict(self) -> dict[str, Any]: description = self.description + logo_url = self.logo_url + + app_url = self.app_url + + publisher = self.publisher + + publisher_type = self.publisher_type.value + principal_type = self.principal_type.value type_ = self.type_.value @@ -100,6 +123,10 @@ def to_dict(self) -> dict[str, Any]: requires_admin_consent = self.requires_admin_consent + discovery_enabled = self.discovery_enabled + + created_from_template = self.created_from_template + created_at = self.created_at.isoformat() updated_at = self.updated_at.isoformat() @@ -146,6 +173,12 @@ def to_dict(self) -> dict[str, Any]: else: secret_generated_by = self.secret_generated_by + template_id: None | str | Unset + if isinstance(self.template_id, Unset): + template_id = UNSET + else: + template_id = self.template_id + approved_at: None | str | Unset if isinstance(self.approved_at, Unset): approved_at = UNSET @@ -168,6 +201,10 @@ def to_dict(self) -> dict[str, Any]: "clientId": client_id, "name": name, "description": description, + "logoUrl": logo_url, + "appUrl": app_url, + "publisher": publisher, + "publisherType": publisher_type, "principalType": principal_type, "type": type_, "clientType": client_type, @@ -175,6 +212,8 @@ def to_dict(self) -> dict[str, Any]: "globalPermissions": global_permissions, "isArchived": is_archived, "requiresAdminConsent": requires_admin_consent, + "discoveryEnabled": discovery_enabled, + "createdFromTemplate": created_from_template, "createdAt": created_at, "updatedAt": updated_at, "createdBy": created_by, @@ -190,6 +229,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["secretGeneratedAt"] = secret_generated_at if secret_generated_by is not UNSET: field_dict["secretGeneratedBy"] = secret_generated_by + if template_id is not UNSET: + field_dict["templateId"] = template_id if approved_at is not UNSET: field_dict["approvedAt"] = approved_at if approved_by is not UNSET: @@ -210,6 +251,14 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: description = d.pop("description") + logo_url = d.pop("logoUrl") + + app_url = d.pop("appUrl") + + publisher = d.pop("publisher") + + publisher_type = AppPublisherType(d.pop("publisherType")) + principal_type = PrincipalType(d.pop("principalType")) type_ = AppType(d.pop("type")) @@ -234,6 +283,10 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: requires_admin_consent = d.pop("requiresAdminConsent") + discovery_enabled = d.pop("discoveryEnabled") + + created_from_template = d.pop("createdFromTemplate") + created_at = isoparse(d.pop("createdAt")) updated_at = isoparse(d.pop("updatedAt")) @@ -317,6 +370,15 @@ def _parse_secret_generated_by(data: object) -> None | str | Unset: secret_generated_by = _parse_secret_generated_by(d.pop("secretGeneratedBy", UNSET)) + def _parse_template_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + template_id = _parse_template_id(d.pop("templateId", UNSET)) + def _parse_approved_at(data: object) -> datetime.datetime | None | Unset: if data is None: return data @@ -348,6 +410,10 @@ def _parse_approved_by(data: object) -> None | str | Unset: client_id=client_id, name=name, description=description, + logo_url=logo_url, + app_url=app_url, + publisher=publisher, + publisher_type=publisher_type, principal_type=principal_type, type_=type_, client_type=client_type, @@ -355,6 +421,8 @@ def _parse_approved_by(data: object) -> None | str | Unset: global_permissions=global_permissions, is_archived=is_archived, requires_admin_consent=requires_admin_consent, + discovery_enabled=discovery_enabled, + created_from_template=created_from_template, created_at=created_at, updated_at=updated_at, created_by=created_by, @@ -363,6 +431,7 @@ def _parse_approved_by(data: object) -> None | str | Unset: secret_expires_at=secret_expires_at, secret_generated_at=secret_generated_at, secret_generated_by=secret_generated_by, + template_id=template_id, approved_at=approved_at, approved_by=approved_by, ) diff --git a/cirro_api_client/v1/models/app_registration_input.py b/cirro_api_client/v1/models/app_registration_input.py index f544e19..444e831 100644 --- a/cirro_api_client/v1/models/app_registration_input.py +++ b/cirro_api_client/v1/models/app_registration_input.py @@ -33,7 +33,13 @@ class AppRegistrationInput: localhost and app callback URLs are supported project_permissions (list[ProjectPermissionSet]): Permissions that this app has on the project global_permissions (list[Permission]): Permissions that this app has globally + logo_url (None | str | Unset): Set a logo for the app, only available for administrators + app_url (None | str | Unset): Set a link for more information on the app + publisher (None | str | Unset): Set a publisher display name, only available for administrators secret_expires_at (datetime.datetime | None | Unset): Optional expiry date of secret + discovery_enabled (bool | None | Unset): Enables dynamic client registration to discover this app (useful for + MCPs), only available for administrators + template_id (None | str | Unset): ID of the app registration template """ name: str @@ -44,7 +50,12 @@ class AppRegistrationInput: redirect_uris: list[str] project_permissions: list[ProjectPermissionSet] global_permissions: list[Permission] + logo_url: None | str | Unset = UNSET + app_url: None | str | Unset = UNSET + publisher: None | str | Unset = UNSET secret_expires_at: datetime.datetime | None | Unset = UNSET + discovery_enabled: bool | None | Unset = UNSET + template_id: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -70,6 +81,24 @@ def to_dict(self) -> dict[str, Any]: global_permissions_item = global_permissions_item_data.value global_permissions.append(global_permissions_item) + logo_url: None | str | Unset + if isinstance(self.logo_url, Unset): + logo_url = UNSET + else: + logo_url = self.logo_url + + app_url: None | str | Unset + if isinstance(self.app_url, Unset): + app_url = UNSET + else: + app_url = self.app_url + + publisher: None | str | Unset + if isinstance(self.publisher, Unset): + publisher = UNSET + else: + publisher = self.publisher + secret_expires_at: None | str | Unset if isinstance(self.secret_expires_at, Unset): secret_expires_at = UNSET @@ -78,6 +107,18 @@ def to_dict(self) -> dict[str, Any]: else: secret_expires_at = self.secret_expires_at + discovery_enabled: bool | None | Unset + if isinstance(self.discovery_enabled, Unset): + discovery_enabled = UNSET + else: + discovery_enabled = self.discovery_enabled + + template_id: None | str | Unset + if isinstance(self.template_id, Unset): + template_id = UNSET + else: + template_id = self.template_id + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -92,8 +133,18 @@ def to_dict(self) -> dict[str, Any]: "globalPermissions": global_permissions, } ) + if logo_url is not UNSET: + field_dict["logoUrl"] = logo_url + if app_url is not UNSET: + field_dict["appUrl"] = app_url + if publisher is not UNSET: + field_dict["publisher"] = publisher if secret_expires_at is not UNSET: field_dict["secretExpiresAt"] = secret_expires_at + if discovery_enabled is not UNSET: + field_dict["discoveryEnabled"] = discovery_enabled + if template_id is not UNSET: + field_dict["templateId"] = template_id return field_dict @@ -128,6 +179,33 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: global_permissions.append(global_permissions_item) + def _parse_logo_url(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + logo_url = _parse_logo_url(d.pop("logoUrl", UNSET)) + + def _parse_app_url(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + app_url = _parse_app_url(d.pop("appUrl", UNSET)) + + def _parse_publisher(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + publisher = _parse_publisher(d.pop("publisher", UNSET)) + def _parse_secret_expires_at(data: object) -> datetime.datetime | None | Unset: if data is None: return data @@ -145,6 +223,24 @@ def _parse_secret_expires_at(data: object) -> datetime.datetime | None | Unset: secret_expires_at = _parse_secret_expires_at(d.pop("secretExpiresAt", UNSET)) + def _parse_discovery_enabled(data: object) -> bool | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(bool | None | Unset, data) + + discovery_enabled = _parse_discovery_enabled(d.pop("discoveryEnabled", UNSET)) + + def _parse_template_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + template_id = _parse_template_id(d.pop("templateId", UNSET)) + app_registration_input = cls( name=name, description=description, @@ -154,7 +250,12 @@ def _parse_secret_expires_at(data: object) -> datetime.datetime | None | Unset: redirect_uris=redirect_uris, project_permissions=project_permissions, global_permissions=global_permissions, + logo_url=logo_url, + app_url=app_url, + publisher=publisher, secret_expires_at=secret_expires_at, + discovery_enabled=discovery_enabled, + template_id=template_id, ) app_registration_input.additional_properties = d diff --git a/cirro_api_client/v1/models/app_registration_template.py b/cirro_api_client/v1/models/app_registration_template.py new file mode 100644 index 0000000..a19f0c7 --- /dev/null +++ b/cirro_api_client/v1/models/app_registration_template.py @@ -0,0 +1,128 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..models.app_client_type import AppClientType +from ..models.principal_type import PrincipalType + +T = TypeVar("T", bound="AppRegistrationTemplate") + + +@_attrs_define +class AppRegistrationTemplate: + """ + Attributes: + id (str): + name (str): + publisher (str): + app_url (str): + logo_url (str): + redirect_uris (list[str]): + principal_type (PrincipalType): + client_type (AppClientType): + discovery_enabled (bool): + """ + + id: str + name: str + publisher: str + app_url: str + logo_url: str + redirect_uris: list[str] + principal_type: PrincipalType + client_type: AppClientType + discovery_enabled: bool + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + id = self.id + + name = self.name + + publisher = self.publisher + + app_url = self.app_url + + logo_url = self.logo_url + + redirect_uris = self.redirect_uris + + principal_type = self.principal_type.value + + client_type = self.client_type.value + + discovery_enabled = self.discovery_enabled + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "id": id, + "name": name, + "publisher": publisher, + "appUrl": app_url, + "logoUrl": logo_url, + "redirectUris": redirect_uris, + "principalType": principal_type, + "clientType": client_type, + "discoveryEnabled": discovery_enabled, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + id = d.pop("id") + + name = d.pop("name") + + publisher = d.pop("publisher") + + app_url = d.pop("appUrl") + + logo_url = d.pop("logoUrl") + + redirect_uris = cast(list[str], d.pop("redirectUris")) + + principal_type = PrincipalType(d.pop("principalType")) + + client_type = AppClientType(d.pop("clientType")) + + discovery_enabled = d.pop("discoveryEnabled") + + app_registration_template = cls( + id=id, + name=name, + publisher=publisher, + app_url=app_url, + logo_url=logo_url, + redirect_uris=redirect_uris, + principal_type=principal_type, + client_type=client_type, + discovery_enabled=discovery_enabled, + ) + + app_registration_template.additional_properties = d + return app_registration_template + + @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/column_def.py b/cirro_api_client/v1/models/column_def.py index 3fa698b..573f81f 100644 --- a/cirro_api_client/v1/models/column_def.py +++ b/cirro_api_client/v1/models/column_def.py @@ -7,6 +7,7 @@ from attrs import field as _attrs_field from ..models.column_data_type import ColumnDataType +from ..models.semantic_column_type import SemanticColumnType from ..types import UNSET, Unset if TYPE_CHECKING: @@ -21,15 +22,28 @@ class ColumnDef: """ Attributes: name (str): - data_type (ColumnDataType): - description (str): + data_type (ColumnDataType): Column data type. + id (None | str | Unset): + display_name (None | str | Unset): Name displayed on UI. + 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. + description (None | str | Unset): foreign_key (ForeignKeyRef | None | Unset): + required (bool | Unset): Whether the column is required to be non-null. Default: False. """ name: str data_type: ColumnDataType - description: str + id: None | str | Unset = UNSET + display_name: None | str | Unset = UNSET + hidden: bool | Unset = False + semantic_type: None | SemanticColumnType | Unset = SemanticColumnType.STANDARD + allowed_values: list[str] | None | Unset = UNSET + description: None | str | Unset = UNSET foreign_key: ForeignKeyRef | None | Unset = UNSET + required: bool | Unset = False additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -39,7 +53,42 @@ def to_dict(self) -> dict[str, Any]: data_type = self.data_type.value - description = self.description + id: None | str | Unset + if isinstance(self.id, Unset): + id = UNSET + else: + id = self.id + + display_name: None | str | Unset + if isinstance(self.display_name, Unset): + display_name = UNSET + else: + display_name = self.display_name + + hidden = self.hidden + + semantic_type: None | str | Unset + if isinstance(self.semantic_type, Unset): + semantic_type = UNSET + elif isinstance(self.semantic_type, SemanticColumnType): + semantic_type = self.semantic_type.value + else: + semantic_type = self.semantic_type + + allowed_values: list[str] | None | Unset + if isinstance(self.allowed_values, Unset): + allowed_values = UNSET + elif isinstance(self.allowed_values, list): + allowed_values = self.allowed_values + + else: + allowed_values = self.allowed_values + + description: None | str | Unset + if isinstance(self.description, Unset): + description = UNSET + else: + description = self.description foreign_key: dict[str, Any] | None | Unset if isinstance(self.foreign_key, Unset): @@ -49,17 +98,32 @@ def to_dict(self) -> dict[str, Any]: else: foreign_key = self.foreign_key + required = self.required + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( { "name": name, "dataType": data_type, - "description": description, } ) + if id is not UNSET: + field_dict["id"] = id + if display_name is not UNSET: + field_dict["displayName"] = display_name + if hidden is not UNSET: + field_dict["hidden"] = hidden + if semantic_type is not UNSET: + field_dict["semanticType"] = semantic_type + if allowed_values is not UNSET: + field_dict["allowedValues"] = allowed_values + if description is not UNSET: + field_dict["description"] = description if foreign_key is not UNSET: field_dict["foreignKey"] = foreign_key + if required is not UNSET: + field_dict["required"] = required return field_dict @@ -72,7 +136,68 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: data_type = ColumnDataType(d.pop("dataType")) - description = d.pop("description") + def _parse_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + id = _parse_id(d.pop("id", UNSET)) + + def _parse_display_name(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + display_name = _parse_display_name(d.pop("displayName", UNSET)) + + hidden = d.pop("hidden", UNSET) + + def _parse_semantic_type(data: object) -> None | SemanticColumnType | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + semantic_type_type_1 = SemanticColumnType(data) + + return semantic_type_type_1 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | SemanticColumnType | Unset, data) + + semantic_type = _parse_semantic_type(d.pop("semanticType", UNSET)) + + def _parse_allowed_values(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() + allowed_values_type_0 = cast(list[str], data) + + return allowed_values_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[str] | None | Unset, data) + + allowed_values = _parse_allowed_values(d.pop("allowedValues", UNSET)) + + def _parse_description(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + description = _parse_description(d.pop("description", UNSET)) def _parse_foreign_key(data: object) -> ForeignKeyRef | None | Unset: if data is None: @@ -91,11 +216,19 @@ def _parse_foreign_key(data: object) -> ForeignKeyRef | None | Unset: foreign_key = _parse_foreign_key(d.pop("foreignKey", UNSET)) + required = d.pop("required", UNSET) + column_def = cls( name=name, data_type=data_type, + id=id, + display_name=display_name, + hidden=hidden, + semantic_type=semantic_type, + allowed_values=allowed_values, description=description, foreign_key=foreign_key, + required=required, ) column_def.additional_properties = d diff --git a/cirro_api_client/v1/models/create_sheet_request.py b/cirro_api_client/v1/models/create_sheet_request.py deleted file mode 100644 index 4c2cc6e..0000000 --- a/cirro_api_client/v1/models/create_sheet_request.py +++ /dev/null @@ -1,252 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..models.sheet_creation_mode import SheetCreationMode -from ..models.sheet_type import SheetType -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.column_def import ColumnDef - from ..models.file_def import FileDef - from ..models.view_query_request import ViewQueryRequest - - -T = TypeVar("T", bound="CreateSheetRequest") - - -@_attrs_define -class CreateSheetRequest: - """ - Attributes: - name (str): Display name for the sheet - namespace_name (str): Namespace for the sheet. This serves as a container to group and manage sheets. - Permissions can be broadly managed at this level too. Example: alz_cohort. - table_name (str): Name of the sheet's underlying table Example: my_table. - sheet_type (SheetType): - description (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. - sheet_creation_mode (None | SheetCreationMode | Unset): How the table should be initialized (required for TABLE) - columns (list[ColumnDef] | None | Unset): Column definitions for the table schema (required for TABLE) - file_def (FileDef | None | Unset): If provided, an ingest job is triggered immediately after table creation - (TABLE only) - view_definition (None | Unset | ViewQueryRequest): View definition specifying sheets, joins, columns, and - filters (required for VIEW) - """ - - name: str - namespace_name: str - table_name: str - sheet_type: SheetType - description: str | Unset = UNSET - audit_read_access: bool | Unset = False - sheet_creation_mode: None | SheetCreationMode | Unset = UNSET - columns: list[ColumnDef] | None | Unset = UNSET - file_def: FileDef | None | Unset = UNSET - view_definition: None | Unset | ViewQueryRequest = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - from ..models.file_def import FileDef - from ..models.view_query_request import ViewQueryRequest - - name = self.name - - namespace_name = self.namespace_name - - table_name = self.table_name - - sheet_type = self.sheet_type.value - - description = self.description - - audit_read_access = self.audit_read_access - - sheet_creation_mode: None | str | Unset - if isinstance(self.sheet_creation_mode, Unset): - sheet_creation_mode = UNSET - elif isinstance(self.sheet_creation_mode, SheetCreationMode): - sheet_creation_mode = self.sheet_creation_mode.value - else: - sheet_creation_mode = self.sheet_creation_mode - - columns: list[dict[str, Any]] | None | Unset - if isinstance(self.columns, Unset): - columns = UNSET - elif isinstance(self.columns, list): - columns = [] - for columns_type_0_item_data in self.columns: - columns_type_0_item = columns_type_0_item_data.to_dict() - columns.append(columns_type_0_item) - - else: - columns = self.columns - - file_def: dict[str, Any] | None | Unset - if isinstance(self.file_def, Unset): - file_def = UNSET - elif isinstance(self.file_def, FileDef): - file_def = self.file_def.to_dict() - else: - file_def = self.file_def - - view_definition: dict[str, Any] | None | Unset - if isinstance(self.view_definition, Unset): - view_definition = UNSET - elif isinstance(self.view_definition, ViewQueryRequest): - view_definition = self.view_definition.to_dict() - else: - view_definition = self.view_definition - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "name": name, - "namespaceName": namespace_name, - "tableName": table_name, - "sheetType": sheet_type, - } - ) - if description is not UNSET: - field_dict["description"] = description - if audit_read_access is not UNSET: - field_dict["auditReadAccess"] = audit_read_access - if sheet_creation_mode is not UNSET: - field_dict["sheetCreationMode"] = sheet_creation_mode - if columns is not UNSET: - field_dict["columns"] = columns - if file_def is not UNSET: - field_dict["fileDef"] = file_def - if view_definition is not UNSET: - field_dict["viewDefinition"] = view_definition - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.column_def import ColumnDef - from ..models.file_def import FileDef - from ..models.view_query_request import ViewQueryRequest - - d = dict(src_dict) - name = d.pop("name") - - namespace_name = d.pop("namespaceName") - - table_name = d.pop("tableName") - - sheet_type = SheetType(d.pop("sheetType")) - - description = d.pop("description", UNSET) - - audit_read_access = d.pop("auditReadAccess", UNSET) - - def _parse_sheet_creation_mode(data: object) -> None | SheetCreationMode | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, str): - raise TypeError() - sheet_creation_mode_type_1 = SheetCreationMode(data) - - return sheet_creation_mode_type_1 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(None | SheetCreationMode | Unset, data) - - sheet_creation_mode = _parse_sheet_creation_mode(d.pop("sheetCreationMode", UNSET)) - - def _parse_columns(data: object) -> list[ColumnDef] | None | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, list): - raise TypeError() - columns_type_0 = [] - _columns_type_0 = data - for columns_type_0_item_data in _columns_type_0: - columns_type_0_item = ColumnDef.from_dict(columns_type_0_item_data) - - columns_type_0.append(columns_type_0_item) - - return columns_type_0 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(list[ColumnDef] | None | Unset, data) - - columns = _parse_columns(d.pop("columns", UNSET)) - - def _parse_file_def(data: object) -> FileDef | None | Unset: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, dict): - raise TypeError() - file_def_type_1 = FileDef.from_dict(data) - - return file_def_type_1 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(FileDef | None | Unset, data) - - file_def = _parse_file_def(d.pop("fileDef", UNSET)) - - def _parse_view_definition(data: object) -> None | Unset | ViewQueryRequest: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, dict): - raise TypeError() - view_definition_type_1 = ViewQueryRequest.from_dict(data) - - return view_definition_type_1 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(None | Unset | ViewQueryRequest, data) - - view_definition = _parse_view_definition(d.pop("viewDefinition", UNSET)) - - create_sheet_request = cls( - name=name, - namespace_name=namespace_name, - table_name=table_name, - sheet_type=sheet_type, - description=description, - audit_read_access=audit_read_access, - sheet_creation_mode=sheet_creation_mode, - columns=columns, - file_def=file_def, - view_definition=view_definition, - ) - - create_sheet_request.additional_properties = d - return create_sheet_request - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/cirro_api_client/v1/models/dataset.py b/cirro_api_client/v1/models/dataset.py index f27abd8..a8334b4 100644 --- a/cirro_api_client/v1/models/dataset.py +++ b/cirro_api_client/v1/models/dataset.py @@ -9,6 +9,7 @@ from dateutil.parser import isoparse from ..models.status import Status +from ..types import UNSET, Unset if TYPE_CHECKING: from ..models.tag import Tag @@ -21,22 +22,21 @@ class Dataset: """ Attributes: - id (str): - name (str): - description (str): - project_id (str): - process_id (str): - source_dataset_ids (list[str]): + id (str): Dataset ID + name (str): Dataset name + project_id (str): Project ID + process_id (str): Process ID + source_dataset_ids (list[str]): Source dataset IDs status (Status): - tags (list[Tag]): - created_by (str): - created_at (datetime.datetime): - updated_at (datetime.datetime): + tags (list[Tag]): Tags + created_by (str): User who created the dataset + created_at (datetime.datetime): Timestamp when the dataset was created + updated_at (datetime.datetime): Timestamp when the dataset was last updated + description (str | Unset): Dataset description """ id: str name: str - description: str project_id: str process_id: str source_dataset_ids: list[str] @@ -45,6 +45,7 @@ class Dataset: created_by: str created_at: datetime.datetime updated_at: datetime.datetime + description: str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -52,8 +53,6 @@ def to_dict(self) -> dict[str, Any]: name = self.name - description = self.description - project_id = self.project_id process_id = self.process_id @@ -73,13 +72,14 @@ def to_dict(self) -> dict[str, Any]: updated_at = self.updated_at.isoformat() + description = self.description + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( { "id": id, "name": name, - "description": description, "projectId": project_id, "processId": process_id, "sourceDatasetIds": source_dataset_ids, @@ -90,6 +90,8 @@ def to_dict(self) -> dict[str, Any]: "updatedAt": updated_at, } ) + if description is not UNSET: + field_dict["description"] = description return field_dict @@ -102,8 +104,6 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: name = d.pop("name") - description = d.pop("description") - project_id = d.pop("projectId") process_id = d.pop("processId") @@ -125,10 +125,11 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: updated_at = isoparse(d.pop("updatedAt")) + description = d.pop("description", UNSET) + dataset = cls( id=id, name=name, - description=description, project_id=project_id, process_id=process_id, source_dataset_ids=source_dataset_ids, @@ -137,6 +138,7 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: created_by=created_by, created_at=created_at, updated_at=updated_at, + description=description, ) dataset.additional_properties = d diff --git a/cirro_api_client/v1/models/dataset_detail.py b/cirro_api_client/v1/models/dataset_detail.py index 55d3c4f..87e9206 100644 --- a/cirro_api_client/v1/models/dataset_detail.py +++ b/cirro_api_client/v1/models/dataset_detail.py @@ -26,26 +26,26 @@ class DatasetDetail: """ Attributes: - id (str): - name (str): - description (str): + id (str): Dataset ID + name (str): Dataset name s3 (str): - process_id (str): - project_id (str): - source_dataset_ids (list[str]): + process_id (str): Process ID + project_id (str): Project ID + source_dataset_ids (list[str]): Source dataset IDs source_datasets (list[NamedItem]): source_sample_ids (list[str]): source_sample_files_map (DatasetDetailSourceSampleFilesMap): Keys are sampleIds, and the lists are file paths to include. status (Status): status_message (str): - tags (list[Tag]): + tags (list[Tag]): Tags params (DatasetDetailParams): info (DatasetDetailInfo): is_view_restricted (bool): - created_by (str): - created_at (datetime.datetime): - updated_at (datetime.datetime): + created_by (str): User who created the dataset + created_at (datetime.datetime): Timestamp when the dataset was created + updated_at (datetime.datetime): Timestamp when the dataset was last updated + description (str | Unset): Dataset description originating_project_id (str | Unset): The originating project ID might be different if the dataset was shared from another project. share (NamedItem | None | Unset): @@ -55,7 +55,6 @@ class DatasetDetail: id: str name: str - description: str s3: str process_id: str project_id: str @@ -72,6 +71,7 @@ class DatasetDetail: created_by: str created_at: datetime.datetime updated_at: datetime.datetime + description: str | Unset = UNSET originating_project_id: str | Unset = UNSET share: NamedItem | None | Unset = UNSET total_size_bytes: int | None | Unset = UNSET @@ -85,8 +85,6 @@ def to_dict(self) -> dict[str, Any]: name = self.name - description = self.description - s3 = self.s3 process_id = self.process_id @@ -125,6 +123,8 @@ def to_dict(self) -> dict[str, Any]: updated_at = self.updated_at.isoformat() + description = self.description + originating_project_id = self.originating_project_id share: dict[str, Any] | None | Unset @@ -153,7 +153,6 @@ def to_dict(self) -> dict[str, Any]: { "id": id, "name": name, - "description": description, "s3": s3, "processId": process_id, "projectId": project_id, @@ -172,6 +171,8 @@ def to_dict(self) -> dict[str, Any]: "updatedAt": updated_at, } ) + if description is not UNSET: + field_dict["description"] = description if originating_project_id is not UNSET: field_dict["originatingProjectId"] = originating_project_id if share is not UNSET: @@ -196,8 +197,6 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: name = d.pop("name") - description = d.pop("description") - s3 = d.pop("s3") process_id = d.pop("processId") @@ -240,6 +239,8 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: updated_at = isoparse(d.pop("updatedAt")) + description = d.pop("description", UNSET) + originating_project_id = d.pop("originatingProjectId", UNSET) def _parse_share(data: object) -> NamedItem | None | Unset: @@ -280,7 +281,6 @@ def _parse_file_count(data: object) -> int | None | Unset: dataset_detail = cls( id=id, name=name, - description=description, s3=s3, process_id=process_id, project_id=project_id, @@ -297,6 +297,7 @@ def _parse_file_count(data: object) -> int | None | Unset: created_by=created_by, created_at=created_at, updated_at=updated_at, + description=description, originating_project_id=originating_project_id, share=share, total_size_bytes=total_size_bytes, diff --git a/cirro_api_client/v1/models/dataset_viz.py b/cirro_api_client/v1/models/dataset_viz.py index 6f8f30c..11aec3c 100644 --- a/cirro_api_client/v1/models/dataset_viz.py +++ b/cirro_api_client/v1/models/dataset_viz.py @@ -1,13 +1,17 @@ from __future__ import annotations 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 from ..types import UNSET, Unset +if TYPE_CHECKING: + from ..models.dataset_viz_config import DatasetVizConfig + + T = TypeVar("T", bound="DatasetViz") @@ -15,12 +19,14 @@ class DatasetViz: """ Attributes: + config (DatasetVizConfig): path (str | Unset): Path to viz configuration, if applicable name (str | Unset): Name of viz desc (str | Unset): Description of viz type_ (str | Unset): Type of viz Example: vitescce. """ + config: DatasetVizConfig path: str | Unset = UNSET name: str | Unset = UNSET desc: str | Unset = UNSET @@ -28,6 +34,8 @@ class DatasetViz: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: + config = self.config.to_dict() + path = self.path name = self.name @@ -38,7 +46,11 @@ def to_dict(self) -> dict[str, Any]: field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) - field_dict.update({}) + field_dict.update( + { + "config": config, + } + ) if path is not UNSET: field_dict["path"] = path if name is not UNSET: @@ -52,7 +64,11 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.dataset_viz_config import DatasetVizConfig + d = dict(src_dict) + config = DatasetVizConfig.from_dict(d.pop("config")) + path = d.pop("path", UNSET) name = d.pop("name", UNSET) @@ -62,6 +78,7 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: type_ = d.pop("type", UNSET) dataset_viz = cls( + config=config, path=path, name=name, desc=desc, diff --git a/cirro_api_client/v1/models/view_filter_values.py b/cirro_api_client/v1/models/dataset_viz_config.py similarity index 85% rename from cirro_api_client/v1/models/view_filter_values.py rename to cirro_api_client/v1/models/dataset_viz_config.py index bc0c65e..27f651e 100644 --- a/cirro_api_client/v1/models/view_filter_values.py +++ b/cirro_api_client/v1/models/dataset_viz_config.py @@ -6,11 +6,11 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field -T = TypeVar("T", bound="ViewFilterValues") +T = TypeVar("T", bound="DatasetVizConfig") @_attrs_define -class ViewFilterValues: +class DatasetVizConfig: """ """ additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -24,10 +24,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) - view_filter_values = cls() + dataset_viz_config = cls() - view_filter_values.additional_properties = d - return view_filter_values + dataset_viz_config.additional_properties = d + return dataset_viz_config @property def additional_keys(self) -> list[str]: diff --git a/cirro_api_client/v1/models/delete_rows_request.py b/cirro_api_client/v1/models/delete_rows_request.py new file mode 100644 index 0000000..573698b --- /dev/null +++ b/cirro_api_client/v1/models/delete_rows_request.py @@ -0,0 +1,61 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="DeleteRowsRequest") + + +@_attrs_define +class DeleteRowsRequest: + """ + Attributes: + row_ids (list[int]): Set of _row_id(s) to delete. Must be non-empty and <= 10000 + """ + + row_ids: list[int] + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + row_ids = self.row_ids + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "rowIds": row_ids, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + row_ids = cast(list[int], d.pop("rowIds")) + + delete_rows_request = cls( + row_ids=row_ids, + ) + + delete_rows_request.additional_properties = d + return delete_rows_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/cirro_api_client/v1/models/entity_type.py b/cirro_api_client/v1/models/entity_type.py index 7b81d3a..07a4272 100644 --- a/cirro_api_client/v1/models/entity_type.py +++ b/cirro_api_client/v1/models/entity_type.py @@ -9,6 +9,7 @@ class EntityType(str, Enum): REFERENCE = "REFERENCE" SAMPLE = "SAMPLE" SHARE = "SHARE" + SHEET = "SHEET" TAG = "TAG" UNKNOWN = "UNKNOWN" USER = "USER" diff --git a/cirro_api_client/v1/models/feature_flags.py b/cirro_api_client/v1/models/feature_flags.py index 736a486..1d733ff 100644 --- a/cirro_api_client/v1/models/feature_flags.py +++ b/cirro_api_client/v1/models/feature_flags.py @@ -19,10 +19,12 @@ class FeatureFlags: workspaces_enabled (bool): drive_enabled (bool): app_registrations_enabled (bool): + machine_auth_enabled (bool): sheets_enabled (bool): ai_enabled (bool): shared_filesystems_enabled (bool): custom_workspace_roles_enabled (bool): + orcid_integration_enabled (bool): """ sftp_enabled: bool @@ -31,10 +33,12 @@ class FeatureFlags: workspaces_enabled: bool drive_enabled: bool app_registrations_enabled: bool + machine_auth_enabled: bool sheets_enabled: bool ai_enabled: bool shared_filesystems_enabled: bool custom_workspace_roles_enabled: bool + orcid_integration_enabled: bool additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -50,6 +54,8 @@ def to_dict(self) -> dict[str, Any]: app_registrations_enabled = self.app_registrations_enabled + machine_auth_enabled = self.machine_auth_enabled + sheets_enabled = self.sheets_enabled ai_enabled = self.ai_enabled @@ -58,6 +64,8 @@ def to_dict(self) -> dict[str, Any]: custom_workspace_roles_enabled = self.custom_workspace_roles_enabled + orcid_integration_enabled = self.orcid_integration_enabled + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -68,10 +76,12 @@ def to_dict(self) -> dict[str, Any]: "workspacesEnabled": workspaces_enabled, "driveEnabled": drive_enabled, "appRegistrationsEnabled": app_registrations_enabled, + "machineAuthEnabled": machine_auth_enabled, "sheetsEnabled": sheets_enabled, "aiEnabled": ai_enabled, "sharedFilesystemsEnabled": shared_filesystems_enabled, "customWorkspaceRolesEnabled": custom_workspace_roles_enabled, + "orcidIntegrationEnabled": orcid_integration_enabled, } ) @@ -92,6 +102,8 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: app_registrations_enabled = d.pop("appRegistrationsEnabled") + machine_auth_enabled = d.pop("machineAuthEnabled") + sheets_enabled = d.pop("sheetsEnabled") ai_enabled = d.pop("aiEnabled") @@ -100,6 +112,8 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: custom_workspace_roles_enabled = d.pop("customWorkspaceRolesEnabled") + orcid_integration_enabled = d.pop("orcidIntegrationEnabled") + feature_flags = cls( sftp_enabled=sftp_enabled, governance_enabled=governance_enabled, @@ -107,10 +121,12 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: workspaces_enabled=workspaces_enabled, drive_enabled=drive_enabled, app_registrations_enabled=app_registrations_enabled, + machine_auth_enabled=machine_auth_enabled, sheets_enabled=sheets_enabled, ai_enabled=ai_enabled, shared_filesystems_enabled=shared_filesystems_enabled, custom_workspace_roles_enabled=custom_workspace_roles_enabled, + orcid_integration_enabled=orcid_integration_enabled, ) feature_flags.additional_properties = d diff --git a/cirro_api_client/v1/models/file_def.py b/cirro_api_client/v1/models/file_def.py index 1dc3c8e..260fe5a 100644 --- a/cirro_api_client/v1/models/file_def.py +++ b/cirro_api_client/v1/models/file_def.py @@ -7,22 +7,20 @@ from attrs import field as _attrs_field from ..models.file_type import FileType -from ..types import UNSET, Unset T = TypeVar("T", bound="FileDef") @_attrs_define class FileDef: - """If provided, an ingest job is triggered immediately after table creation (TABLE only) - + """ Attributes: file_type (FileType): - storage_uri (str | Unset): Full S3 URI to the source file. + storage_uri (str): Full S3 URI to the source file. """ file_type: FileType - storage_uri: str | Unset = UNSET + storage_uri: str additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -35,10 +33,9 @@ def to_dict(self) -> dict[str, Any]: field_dict.update( { "fileType": file_type, + "storageUri": storage_uri, } ) - if storage_uri is not UNSET: - field_dict["storageUri"] = storage_uri return field_dict @@ -47,7 +44,7 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: d = dict(src_dict) file_type = FileType(d.pop("fileType")) - storage_uri = d.pop("storageUri", UNSET) + storage_uri = d.pop("storageUri") file_def = cls( file_type=file_type, diff --git a/cirro_api_client/v1/models/view_filter.py b/cirro_api_client/v1/models/filter_.py similarity index 79% rename from cirro_api_client/v1/models/view_filter.py rename to cirro_api_client/v1/models/filter_.py index 6712084..1a78e56 100644 --- a/cirro_api_client/v1/models/view_filter.py +++ b/cirro_api_client/v1/models/filter_.py @@ -1,7 +1,7 @@ from __future__ import annotations from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast +from typing import Any, TypeVar, cast from attrs import define as _attrs_define from attrs import field as _attrs_field @@ -10,32 +10,30 @@ from ..models.logical_operator import LogicalOperator from ..types import UNSET, Unset -if TYPE_CHECKING: - from ..models.view_filter_values import ViewFilterValues - - -T = TypeVar("T", bound="ViewFilter") +T = TypeVar("T", bound="Filter") @_attrs_define -class ViewFilter: +class Filter: """A filter node: either a group (with logicalOperator and conditions) or a leaf condition (with column, operator, and values) Attributes: logical_operator (LogicalOperator | None | Unset): Set for group nodes to combine child conditions - conditions (list[ViewFilter] | None | Unset): Child filter nodes (for group nodes) - column (None | str | Unset): Qualified column reference in alias.column format (for leaf nodes) Example: s1.age. + conditions (list[Filter] | None | Unset): Child filter nodes (for group nodes) + column (None | str | Unset): Column reference (for leaf nodes). For view filters, must be in alias.column format + (e.g., 's1.age'). For sheet data filters, must be a bare column name (e.g., 'age'). Example: age. operator (FilterOperator | None | Unset): Comparison operator (for leaf nodes) - values (list[ViewFilterValues] | None | Unset): Values for the filter. Single-element list for comparison - operators (EQUALS, GREATER_THAN, etc.), multi-element for IN/NOT_IN. Null or empty for IS_NULL/IS_NOT_NULL. + values (list[bool | float | int | str] | None | Unset): Values for the filter. Single-element list for + comparison operators (EQUALS, GREATER_THAN, etc.), multi-element for IN/NOT_IN. Null or empty for + IS_NULL/IS_NOT_NULL. """ logical_operator: LogicalOperator | None | Unset = UNSET - conditions: list[ViewFilter] | None | Unset = UNSET + conditions: list[Filter] | None | Unset = UNSET column: None | str | Unset = UNSET operator: FilterOperator | None | Unset = UNSET - values: list[ViewFilterValues] | None | Unset = UNSET + values: list[bool | float | int | str] | None | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -73,13 +71,14 @@ def to_dict(self) -> dict[str, Any]: else: operator = self.operator - values: list[dict[str, Any]] | None | Unset + values: list[bool | float | int | str] | None | Unset if isinstance(self.values, Unset): values = UNSET elif isinstance(self.values, list): values = [] for values_type_0_item_data in self.values: - values_type_0_item = values_type_0_item_data.to_dict() + values_type_0_item: bool | float | int | str + values_type_0_item = values_type_0_item_data values.append(values_type_0_item) else: @@ -103,8 +102,6 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.view_filter_values import ViewFilterValues - d = dict(src_dict) def _parse_logical_operator(data: object) -> LogicalOperator | None | Unset: @@ -124,7 +121,7 @@ def _parse_logical_operator(data: object) -> LogicalOperator | None | Unset: logical_operator = _parse_logical_operator(d.pop("logicalOperator", UNSET)) - def _parse_conditions(data: object) -> list[ViewFilter] | None | Unset: + def _parse_conditions(data: object) -> list[Filter] | None | Unset: if data is None: return data if isinstance(data, Unset): @@ -135,14 +132,14 @@ def _parse_conditions(data: object) -> list[ViewFilter] | None | Unset: conditions_type_0 = [] _conditions_type_0 = data for conditions_type_0_item_data in _conditions_type_0: - conditions_type_0_item = ViewFilter.from_dict(conditions_type_0_item_data) + conditions_type_0_item = Filter.from_dict(conditions_type_0_item_data) conditions_type_0.append(conditions_type_0_item) return conditions_type_0 except (TypeError, ValueError, AttributeError, KeyError): pass - return cast(list[ViewFilter] | None | Unset, data) + return cast(list[Filter] | None | Unset, data) conditions = _parse_conditions(d.pop("conditions", UNSET)) @@ -172,7 +169,7 @@ def _parse_operator(data: object) -> FilterOperator | None | Unset: operator = _parse_operator(d.pop("operator", UNSET)) - def _parse_values(data: object) -> list[ViewFilterValues] | None | Unset: + def _parse_values(data: object) -> list[bool | float | int | str] | None | Unset: if data is None: return data if isinstance(data, Unset): @@ -183,18 +180,22 @@ def _parse_values(data: object) -> list[ViewFilterValues] | None | Unset: values_type_0 = [] _values_type_0 = data for values_type_0_item_data in _values_type_0: - values_type_0_item = ViewFilterValues.from_dict(values_type_0_item_data) + + def _parse_values_type_0_item(data: object) -> bool | float | int | str: + return cast(bool | float | int | str, data) + + values_type_0_item = _parse_values_type_0_item(values_type_0_item_data) values_type_0.append(values_type_0_item) return values_type_0 except (TypeError, ValueError, AttributeError, KeyError): pass - return cast(list[ViewFilterValues] | None | Unset, data) + return cast(list[bool | float | int | str] | None | Unset, data) values = _parse_values(d.pop("values", UNSET)) - view_filter = cls( + filter_ = cls( logical_operator=logical_operator, conditions=conditions, column=column, @@ -202,8 +203,8 @@ def _parse_values(data: object) -> list[ViewFilterValues] | None | Unset: values=values, ) - view_filter.additional_properties = d - return view_filter + filter_.additional_properties = d + return filter_ @property def additional_keys(self) -> list[str]: diff --git a/cirro_api_client/v1/models/filter_operator.py b/cirro_api_client/v1/models/filter_operator.py index a2e3675..ae9502e 100644 --- a/cirro_api_client/v1/models/filter_operator.py +++ b/cirro_api_client/v1/models/filter_operator.py @@ -13,6 +13,7 @@ class FilterOperator(str, Enum): LIKE = "LIKE" NOT_EQUALS = "NOT_EQUALS" NOT_IN = "NOT_IN" + NOT_LIKE = "NOT_LIKE" 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/get_task_files_response.py b/cirro_api_client/v1/models/get_task_files_response.py new file mode 100644 index 0000000..6153b45 --- /dev/null +++ b/cirro_api_client/v1/models/get_task_files_response.py @@ -0,0 +1,91 @@ +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.file_entry import FileEntry + + +T = TypeVar("T", bound="GetTaskFilesResponse") + + +@_attrs_define +class GetTaskFilesResponse: + """ + Attributes: + input_files (list[FileEntry]): + output_files (list[FileEntry]): + """ + + input_files: list[FileEntry] + output_files: list[FileEntry] + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + input_files = [] + for input_files_item_data in self.input_files: + input_files_item = input_files_item_data.to_dict() + input_files.append(input_files_item) + + output_files = [] + for output_files_item_data in self.output_files: + output_files_item = output_files_item_data.to_dict() + output_files.append(output_files_item) + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "inputFiles": input_files, + "outputFiles": output_files, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.file_entry import FileEntry + + d = dict(src_dict) + input_files = [] + _input_files = d.pop("inputFiles") + for input_files_item_data in _input_files: + input_files_item = FileEntry.from_dict(input_files_item_data) + + input_files.append(input_files_item) + + output_files = [] + _output_files = d.pop("outputFiles") + for output_files_item_data in _output_files: + output_files_item = FileEntry.from_dict(output_files_item_data) + + output_files.append(output_files_item) + + get_task_files_response = cls( + input_files=input_files, + output_files=output_files, + ) + + get_task_files_response.additional_properties = d + return get_task_files_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/insert_rows_request.py b/cirro_api_client/v1/models/insert_rows_request.py new file mode 100644 index 0000000..8fe1f53 --- /dev/null +++ b/cirro_api_client/v1/models/insert_rows_request.py @@ -0,0 +1,75 @@ +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.row_insert import RowInsert + + +T = TypeVar("T", bound="InsertRowsRequest") + + +@_attrs_define +class InsertRowsRequest: + """ + Attributes: + inserts (list[RowInsert]): List of rows to update. + """ + + inserts: list[RowInsert] + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + inserts = [] + for inserts_item_data in self.inserts: + inserts_item = inserts_item_data.to_dict() + inserts.append(inserts_item) + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "inserts": inserts, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.row_insert import RowInsert + + d = dict(src_dict) + inserts = [] + _inserts = d.pop("inserts") + for inserts_item_data in _inserts: + inserts_item = RowInsert.from_dict(inserts_item_data) + + inserts.append(inserts_item) + + insert_rows_request = cls( + inserts=inserts, + ) + + insert_rows_request.additional_properties = d + return insert_rows_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/cirro_api_client/v1/models/permission.py b/cirro_api_client/v1/models/permission.py index bc2b9e4..3e4f056 100644 --- a/cirro_api_client/v1/models/permission.py +++ b/cirro_api_client/v1/models/permission.py @@ -26,6 +26,7 @@ class Permission(str, Enum): EDIT_PROJECT_METADATA = "EDIT_PROJECT_METADATA" EDIT_PROJECT_REFERENCES = "EDIT_PROJECT_REFERENCES" EDIT_SHEET = "EDIT_SHEET" + EDIT_SHEET_DATA = "EDIT_SHEET_DATA" GENERATE_DOWNLOAD_TOKEN = "GENERATE_DOWNLOAD_TOKEN" INVITE_MEMBER = "INVITE_MEMBER" MANAGE_AGENTS = "MANAGE_AGENTS" @@ -42,6 +43,7 @@ class Permission(str, Enum): REQUEST_PROJECT = "REQUEST_PROJECT" RUN_ANALYSIS = "RUN_ANALYSIS" SEARCH_MEMBERS = "SEARCH_MEMBERS" + SHEET_RAW_QUERY = "SHEET_RAW_QUERY" STOP_ANALYSIS = "STOP_ANALYSIS" SYS_ADMIN_OPERATIONS = "SYS_ADMIN_OPERATIONS" VIEW_ALL_DATA = "VIEW_ALL_DATA" @@ -62,6 +64,7 @@ class Permission(str, Enum): VIEW_PROJECT_SHARES = "VIEW_PROJECT_SHARES" VIEW_SERVICE_CONNECTIONS = "VIEW_SERVICE_CONNECTIONS" VIEW_SHEET = "VIEW_SHEET" + VIEW_SHEET_DATA = "VIEW_SHEET_DATA" VIEW_WORKSPACE_ENVIRONMENTS = "VIEW_WORKSPACE_ENVIRONMENTS" 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/query_column.py b/cirro_api_client/v1/models/query_column.py index ebf79db..8bff4c9 100644 --- a/cirro_api_client/v1/models/query_column.py +++ b/cirro_api_client/v1/models/query_column.py @@ -17,7 +17,7 @@ class QueryColumn: Attributes: name (str): Column name. - data_type (ColumnDataType): + data_type (ColumnDataType): Column data type. """ name: str diff --git a/cirro_api_client/v1/models/raw_view_query_request.py b/cirro_api_client/v1/models/raw_view_query_request.py new file mode 100644 index 0000000..afa0b2a --- /dev/null +++ b/cirro_api_client/v1/models/raw_view_query_request.py @@ -0,0 +1,72 @@ +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 + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="RawViewQueryRequest") + + +@_attrs_define +class RawViewQueryRequest: + """ + Attributes: + query (str): + view_type (str | Unset): + """ + + query: str + view_type: str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + query = self.query + + view_type = self.view_type + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "query": query, + } + ) + if view_type is not UNSET: + field_dict["viewType"] = view_type + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + query = d.pop("query") + + view_type = d.pop("viewType", UNSET) + + raw_view_query_request = cls( + query=query, + view_type=view_type, + ) + + raw_view_query_request.additional_properties = d + return raw_view_query_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/cirro_api_client/v1/models/trigger_ingest_request.py b/cirro_api_client/v1/models/row_insert.py similarity index 65% rename from cirro_api_client/v1/models/trigger_ingest_request.py rename to cirro_api_client/v1/models/row_insert.py index 0e9fac2..32bef5e 100644 --- a/cirro_api_client/v1/models/trigger_ingest_request.py +++ b/cirro_api_client/v1/models/row_insert.py @@ -7,30 +7,31 @@ from attrs import field as _attrs_field if TYPE_CHECKING: - from ..models.file_def import FileDef + from ..models.row_insert_values import RowInsertValues -T = TypeVar("T", bound="TriggerIngestRequest") +T = TypeVar("T", bound="RowInsert") @_attrs_define -class TriggerIngestRequest: +class RowInsert: """ Attributes: - file_def (FileDef): If provided, an ingest job is triggered immediately after table creation (TABLE only) + values (RowInsertValues): Column name and value. Any missing columns will have a null value (will error if + column is required). Example: {'icd_code': 'G65'}. """ - file_def: FileDef + values: RowInsertValues additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - file_def = self.file_def.to_dict() + values = self.values.to_dict() field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( { - "fileDef": file_def, + "values": values, } ) @@ -38,17 +39,17 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.file_def import FileDef + from ..models.row_insert_values import RowInsertValues d = dict(src_dict) - file_def = FileDef.from_dict(d.pop("fileDef")) + values = RowInsertValues.from_dict(d.pop("values")) - trigger_ingest_request = cls( - file_def=file_def, + row_insert = cls( + values=values, ) - trigger_ingest_request.additional_properties = d - return trigger_ingest_request + row_insert.additional_properties = d + return row_insert @property def additional_keys(self) -> list[str]: diff --git a/cirro_api_client/v1/models/row_insert_values.py b/cirro_api_client/v1/models/row_insert_values.py new file mode 100644 index 0000000..f435344 --- /dev/null +++ b/cirro_api_client/v1/models/row_insert_values.py @@ -0,0 +1,64 @@ +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.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). + + Example: + {'icd_code': 'G65'} + + """ + + additional_properties: dict[str, RowInsertValuesAdditionalProperty] = _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.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 + return row_insert_values + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> RowInsertValuesAdditionalProperty: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: RowInsertValuesAdditionalProperty) -> 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/row_insert_values_additional_property.py new file mode 100644 index 0000000..0143cb8 --- /dev/null +++ b/cirro_api_client/v1/models/row_insert_values_additional_property.py @@ -0,0 +1,46 @@ +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="RowInsertValuesAdditionalProperty") + + +@_attrs_define +class RowInsertValuesAdditionalProperty: + """ """ + + 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) + row_insert_values_additional_property = cls() + + row_insert_values_additional_property.additional_properties = d + return row_insert_values_additional_property + + @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/run_analysis_request.py b/cirro_api_client/v1/models/run_analysis_request.py index bddf025..4833b3b 100644 --- a/cirro_api_client/v1/models/run_analysis_request.py +++ b/cirro_api_client/v1/models/run_analysis_request.py @@ -11,6 +11,7 @@ if TYPE_CHECKING: from ..models.run_analysis_request_params import RunAnalysisRequestParams from ..models.run_analysis_request_source_sample_files_map import RunAnalysisRequestSourceSampleFilesMap + from ..models.tag import Tag T = TypeVar("T", bound="RunAnalysisRequest") @@ -35,6 +36,7 @@ class RunAnalysisRequest: dataset specified here, it will re-use the output to minimize duplicate work compute_environment_id (None | str | Unset): The compute environment where to run the workflow, if not specified, it will run in AWS + tags (list[Tag] | None | Unset): List of tags to apply to the dataset """ name: str @@ -47,6 +49,7 @@ class RunAnalysisRequest: source_sample_files_map: None | RunAnalysisRequestSourceSampleFilesMap | Unset = UNSET resume_dataset_id: None | str | Unset = UNSET compute_environment_id: None | str | 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]: @@ -97,6 +100,18 @@ def to_dict(self) -> dict[str, Any]: else: compute_environment_id = self.compute_environment_id + tags: list[dict[str, Any]] | None | Unset + if isinstance(self.tags, Unset): + tags = UNSET + elif isinstance(self.tags, list): + tags = [] + for tags_type_0_item_data in self.tags: + tags_type_0_item = tags_type_0_item_data.to_dict() + tags.append(tags_type_0_item) + + else: + tags = self.tags + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -118,6 +133,8 @@ def to_dict(self) -> dict[str, Any]: field_dict["resumeDatasetId"] = resume_dataset_id if compute_environment_id is not UNSET: field_dict["computeEnvironmentId"] = compute_environment_id + if tags is not UNSET: + field_dict["tags"] = tags return field_dict @@ -125,6 +142,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.tag import Tag d = dict(src_dict) name = d.pop("name") @@ -198,6 +216,28 @@ def _parse_compute_environment_id(data: object) -> None | str | Unset: compute_environment_id = _parse_compute_environment_id(d.pop("computeEnvironmentId", UNSET)) + def _parse_tags(data: object) -> list[Tag] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + tags_type_0 = [] + _tags_type_0 = data + for tags_type_0_item_data in _tags_type_0: + tags_type_0_item = Tag.from_dict(tags_type_0_item_data) + + tags_type_0.append(tags_type_0_item) + + return tags_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[Tag] | None | Unset, data) + + tags = _parse_tags(d.pop("tags", UNSET)) + run_analysis_request = cls( name=name, process_id=process_id, @@ -209,6 +249,7 @@ def _parse_compute_environment_id(data: object) -> None | str | Unset: source_sample_files_map=source_sample_files_map, resume_dataset_id=resume_dataset_id, compute_environment_id=compute_environment_id, + tags=tags, ) run_analysis_request.additional_properties = d diff --git a/cirro_api_client/v1/models/semantic_column_type.py b/cirro_api_client/v1/models/semantic_column_type.py new file mode 100644 index 0000000..ca438d2 --- /dev/null +++ b/cirro_api_client/v1/models/semantic_column_type.py @@ -0,0 +1,22 @@ +from enum import Enum + + +class SemanticColumnType(str, Enum): + DATASET_LINK = "DATASET_LINK" + ENTITY_KEY = "ENTITY_KEY" + ENTITY_NAME = "ENTITY_NAME" + ENUM_MULTI = "ENUM_MULTI" + ENUM_SINGLE = "ENUM_SINGLE" + FILE_LINK = "FILE_LINK" + FOREIGN_KEY = "FOREIGN_KEY" + STANDARD = "STANDARD" + URL = "URL" + 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/sheet.py b/cirro_api_client/v1/models/sheet.py index 55352ea..083b6b5 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 Any, TypeVar +from typing import TYPE_CHECKING, Any, TypeVar from attrs import define as _attrs_define from attrs import field as _attrs_field @@ -12,6 +12,10 @@ from ..models.sheet_type import SheetType from ..models.status import Status +if TYPE_CHECKING: + from ..models.tag import Tag + + T = TypeVar("T", bound="Sheet") @@ -21,6 +25,8 @@ class Sheet: Attributes: id (str): name (str): + namespace_name (str): + table_name (str): description (str): project_id (str): sheet_type (SheetType): @@ -30,10 +36,13 @@ class Sheet: created_at (datetime.datetime): updated_at (datetime.datetime): total_row_count (int): + tags (list[Tag]): """ id: str name: str + namespace_name: str + table_name: str description: str project_id: str sheet_type: SheetType @@ -43,6 +52,7 @@ class Sheet: created_at: datetime.datetime updated_at: datetime.datetime total_row_count: int + tags: list[Tag] additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: @@ -50,6 +60,10 @@ def to_dict(self) -> dict[str, Any]: name = self.name + namespace_name = self.namespace_name + + table_name = self.table_name + description = self.description project_id = self.project_id @@ -68,12 +82,19 @@ def to_dict(self) -> dict[str, Any]: 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) + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( { "id": id, "name": name, + "namespaceName": namespace_name, + "tableName": table_name, "description": description, "projectId": project_id, "sheetType": sheet_type, @@ -83,6 +104,7 @@ def to_dict(self) -> dict[str, Any]: "createdAt": created_at, "updatedAt": updated_at, "totalRowCount": total_row_count, + "tags": tags, } ) @@ -90,11 +112,17 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.tag import Tag + d = dict(src_dict) id = d.pop("id") name = d.pop("name") + namespace_name = d.pop("namespaceName") + + table_name = d.pop("tableName") + description = d.pop("description") project_id = d.pop("projectId") @@ -113,9 +141,18 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: total_row_count = d.pop("totalRowCount") + tags = [] + _tags = d.pop("tags") + for tags_item_data in _tags: + tags_item = Tag.from_dict(tags_item_data) + + tags.append(tags_item) + sheet = cls( id=id, name=name, + namespace_name=namespace_name, + table_name=table_name, description=description, project_id=project_id, sheet_type=sheet_type, @@ -125,6 +162,7 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: created_at=created_at, updated_at=updated_at, total_row_count=total_row_count, + tags=tags, ) sheet.additional_properties = d diff --git a/cirro_api_client/v1/models/sheet_data_request.py b/cirro_api_client/v1/models/sheet_data_request.py new file mode 100644 index 0000000..7f8e449 --- /dev/null +++ b/cirro_api_client/v1/models/sheet_data_request.py @@ -0,0 +1,165 @@ +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.filter_ import Filter + from ..models.sheet_sort import SheetSort + + +T = TypeVar("T", bound="SheetDataRequest") + + +@_attrs_define +class SheetDataRequest: + """Paginated sheet data query with optional sort and filter + + Attributes: + limit (int | None | Unset): Maximum rows to return 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. + """ + + limit: int | None | Unset = 1000 + page: int | None | Unset = 1 + sort: None | SheetSort | Unset = UNSET + filter_: Filter | None | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + from ..models.filter_ import Filter + from ..models.sheet_sort import SheetSort + + limit: int | None | Unset + if isinstance(self.limit, Unset): + limit = UNSET + else: + limit = self.limit + + page: int | None | Unset + if isinstance(self.page, Unset): + page = UNSET + else: + page = self.page + + sort: dict[str, Any] | None | Unset + if isinstance(self.sort, Unset): + sort = UNSET + elif isinstance(self.sort, SheetSort): + sort = self.sort.to_dict() + else: + sort = self.sort + + filter_: dict[str, Any] | None | Unset + if isinstance(self.filter_, Unset): + filter_ = UNSET + elif isinstance(self.filter_, Filter): + filter_ = self.filter_.to_dict() + else: + filter_ = self.filter_ + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if limit is not UNSET: + field_dict["limit"] = limit + if page is not UNSET: + field_dict["page"] = page + if sort is not UNSET: + field_dict["sort"] = sort + if filter_ is not UNSET: + field_dict["filter"] = filter_ + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.filter_ import Filter + from ..models.sheet_sort import SheetSort + + d = dict(src_dict) + + def _parse_limit(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + limit = _parse_limit(d.pop("limit", UNSET)) + + def _parse_page(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + page = _parse_page(d.pop("page", UNSET)) + + def _parse_sort(data: object) -> None | SheetSort | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + sort_type_1 = SheetSort.from_dict(data) + + return sort_type_1 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | SheetSort | Unset, data) + + sort = _parse_sort(d.pop("sort", UNSET)) + + def _parse_filter_(data: object) -> Filter | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, dict): + raise TypeError() + filter_type_1 = Filter.from_dict(data) + + return filter_type_1 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(Filter | None | Unset, data) + + filter_ = _parse_filter_(d.pop("filter", UNSET)) + + sheet_data_request = cls( + limit=limit, + page=page, + sort=sort, + filter_=filter_, + ) + + sheet_data_request.additional_properties = d + return sheet_data_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/cirro_api_client/v1/models/sheet_data_update_response.py b/cirro_api_client/v1/models/sheet_data_update_response.py new file mode 100644 index 0000000..60dd20e --- /dev/null +++ b/cirro_api_client/v1/models/sheet_data_update_response.py @@ -0,0 +1,62 @@ +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="SheetDataUpdateResponse") + + +@_attrs_define +class SheetDataUpdateResponse: + """Data update response for inserts (coming soon), deletes, and updates. + + Attributes: + rows_affected (int): Number of sheet rows updated (deleted, inserted, updated). + """ + + rows_affected: int + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + rows_affected = self.rows_affected + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "rowsAffected": rows_affected, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + rows_affected = d.pop("rowsAffected") + + sheet_data_update_response = cls( + rows_affected=rows_affected, + ) + + sheet_data_update_response.additional_properties = d + return sheet_data_update_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/sheet_detail.py b/cirro_api_client/v1/models/sheet_detail.py index 10b031f..a781e52 100644 --- a/cirro_api_client/v1/models/sheet_detail.py +++ b/cirro_api_client/v1/models/sheet_detail.py @@ -15,7 +15,9 @@ if TYPE_CHECKING: from ..models.column_def import ColumnDef - from ..models.view_query_request import ViewQueryRequest + from ..models.raw_view_query_request import RawViewQueryRequest + from ..models.structured_view_query_request import StructuredViewQueryRequest + from ..models.tag import Tag T = TypeVar("T", bound="SheetDetail") @@ -38,11 +40,17 @@ class SheetDetail: 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. - view_definition (None | Unset | ViewQueryRequest): View definition for VIEW sheets. Null for TABLE sheets. + view_definition (None | RawViewQueryRequest | StructuredViewQueryRequest | Unset): View definition for VIEW + sheets. Null for TABLE 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. + 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. """ id: str @@ -58,14 +66,18 @@ class SheetDetail: 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 | Unset | ViewQueryRequest = UNSET + view_definition: None | RawViewQueryRequest | StructuredViewQueryRequest | Unset = UNSET last_refreshed_at: datetime.datetime | None | Unset = UNSET + staging_upload_path: str | Unset = UNSET + schema_version_id: int | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - from ..models.view_query_request import ViewQueryRequest + from ..models.raw_view_query_request import RawViewQueryRequest + from ..models.structured_view_query_request import StructuredViewQueryRequest id = self.id @@ -93,6 +105,11 @@ def to_dict(self) -> dict[str, Any]: 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) + sheet_creation_mode: None | str | Unset if isinstance(self.sheet_creation_mode, Unset): sheet_creation_mode = UNSET @@ -116,7 +133,9 @@ def to_dict(self) -> dict[str, Any]: view_definition: dict[str, Any] | None | Unset if isinstance(self.view_definition, Unset): view_definition = UNSET - elif isinstance(self.view_definition, ViewQueryRequest): + elif isinstance(self.view_definition, RawViewQueryRequest): + view_definition = self.view_definition.to_dict() + elif isinstance(self.view_definition, StructuredViewQueryRequest): view_definition = self.view_definition.to_dict() else: view_definition = self.view_definition @@ -129,6 +148,10 @@ def to_dict(self) -> dict[str, Any]: else: last_refreshed_at = self.last_refreshed_at + staging_upload_path = self.staging_upload_path + + schema_version_id = self.schema_version_id + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -146,6 +169,7 @@ def to_dict(self) -> dict[str, Any]: "createdAt": created_at, "updatedAt": updated_at, "totalRowCount": total_row_count, + "tags": tags, } ) if sheet_creation_mode is not UNSET: @@ -156,13 +180,19 @@ def to_dict(self) -> dict[str, Any]: field_dict["viewDefinition"] = view_definition 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 schema_version_id is not UNSET: + field_dict["schemaVersionId"] = schema_version_id return field_dict @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: from ..models.column_def import ColumnDef - from ..models.view_query_request import ViewQueryRequest + from ..models.raw_view_query_request import RawViewQueryRequest + from ..models.structured_view_query_request import StructuredViewQueryRequest + from ..models.tag import Tag d = dict(src_dict) id = d.pop("id") @@ -191,6 +221,13 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: total_row_count = d.pop("totalRowCount") + tags = [] + _tags = d.pop("tags") + for tags_item_data in _tags: + tags_item = Tag.from_dict(tags_item_data) + + tags.append(tags_item) + def _parse_sheet_creation_mode(data: object) -> None | SheetCreationMode | Unset: if data is None: return data @@ -230,7 +267,7 @@ def _parse_columns(data: object) -> list[ColumnDef] | None | Unset: columns = _parse_columns(d.pop("columns", UNSET)) - def _parse_view_definition(data: object) -> None | Unset | ViewQueryRequest: + def _parse_view_definition(data: object) -> None | RawViewQueryRequest | StructuredViewQueryRequest | Unset: if data is None: return data if isinstance(data, Unset): @@ -238,12 +275,20 @@ def _parse_view_definition(data: object) -> None | Unset | ViewQueryRequest: try: if not isinstance(data, dict): raise TypeError() - view_definition_type_1 = ViewQueryRequest.from_dict(data) + componentsschemas_view_query_request_type_0 = RawViewQueryRequest.from_dict(data) + + return componentsschemas_view_query_request_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_view_query_request_type_1 = StructuredViewQueryRequest.from_dict(data) - return view_definition_type_1 + return componentsschemas_view_query_request_type_1 except (TypeError, ValueError, AttributeError, KeyError): pass - return cast(None | Unset | ViewQueryRequest, data) + return cast(None | RawViewQueryRequest | StructuredViewQueryRequest | Unset, data) view_definition = _parse_view_definition(d.pop("viewDefinition", UNSET)) @@ -264,6 +309,10 @@ def _parse_last_refreshed_at(data: object) -> datetime.datetime | None | Unset: last_refreshed_at = _parse_last_refreshed_at(d.pop("lastRefreshedAt", UNSET)) + staging_upload_path = d.pop("stagingUploadPath", UNSET) + + schema_version_id = d.pop("schemaVersionId", UNSET) + sheet_detail = cls( id=id, name=name, @@ -278,10 +327,13 @@ def _parse_last_refreshed_at(data: object) -> datetime.datetime | None | Unset: 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, last_refreshed_at=last_refreshed_at, + staging_upload_path=staging_upload_path, + schema_version_id=schema_version_id, ) sheet_detail.additional_properties = d diff --git a/cirro_api_client/v1/models/sheet_ingest_request.py b/cirro_api_client/v1/models/sheet_ingest_request.py new file mode 100644 index 0000000..3d82753 --- /dev/null +++ b/cirro_api_client/v1/models/sheet_ingest_request.py @@ -0,0 +1,111 @@ +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.file_def import FileDef + from ..models.source_column import SourceColumn + + +T = TypeVar("T", bound="SheetIngestRequest") + + +@_attrs_define +class SheetIngestRequest: + """ + Attributes: + file_def (FileDef): + source_columns (list[SourceColumn] | None | Unset): List of file column to sheet column mapping. If null, + requires the column headers to match the sheet column names. + """ + + file_def: FileDef + source_columns: list[SourceColumn] | None | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + file_def = self.file_def.to_dict() + + source_columns: list[dict[str, Any]] | None | Unset + if isinstance(self.source_columns, Unset): + source_columns = UNSET + elif isinstance(self.source_columns, list): + source_columns = [] + for source_columns_type_0_item_data in self.source_columns: + source_columns_type_0_item = source_columns_type_0_item_data.to_dict() + source_columns.append(source_columns_type_0_item) + + else: + source_columns = self.source_columns + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "fileDef": file_def, + } + ) + if source_columns is not UNSET: + field_dict["sourceColumns"] = source_columns + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.file_def import FileDef + from ..models.source_column import SourceColumn + + d = dict(src_dict) + file_def = FileDef.from_dict(d.pop("fileDef")) + + def _parse_source_columns(data: object) -> list[SourceColumn] | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, list): + raise TypeError() + source_columns_type_0 = [] + _source_columns_type_0 = data + for source_columns_type_0_item_data in _source_columns_type_0: + source_columns_type_0_item = SourceColumn.from_dict(source_columns_type_0_item_data) + + source_columns_type_0.append(source_columns_type_0_item) + + return source_columns_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(list[SourceColumn] | None | Unset, data) + + source_columns = _parse_source_columns(d.pop("sourceColumns", UNSET)) + + sheet_ingest_request = cls( + file_def=file_def, + source_columns=source_columns, + ) + + sheet_ingest_request.additional_properties = d + return sheet_ingest_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/cirro_api_client/v1/models/sheet_job_type.py b/cirro_api_client/v1/models/sheet_job_type.py index 2cb4a14..410f66e 100644 --- a/cirro_api_client/v1/models/sheet_job_type.py +++ b/cirro_api_client/v1/models/sheet_job_type.py @@ -6,6 +6,7 @@ class SheetJobType(str, Enum): DROP_TABLE = "DROP_TABLE" INGEST = "INGEST" MATERIALIZE_VIEW = "MATERIALIZE_VIEW" + UPDATE_SCHEMA = "UPDATE_SCHEMA" 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_query_request.py b/cirro_api_client/v1/models/sheet_query_request.py new file mode 100644 index 0000000..9a2b6ab --- /dev/null +++ b/cirro_api_client/v1/models/sheet_query_request.py @@ -0,0 +1,111 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="SheetQueryRequest") + + +@_attrs_define +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. + page (int | None | Unset): Page to return Default: 1. + """ + + namespace_name: str + query: str + 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 + + limit: int | None | Unset + if isinstance(self.limit, Unset): + limit = UNSET + else: + limit = self.limit + + page: int | None | Unset + if isinstance(self.page, Unset): + page = UNSET + else: + page = self.page + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "namespaceName": namespace_name, + "query": query, + } + ) + if limit is not UNSET: + field_dict["limit"] = limit + if page is not UNSET: + field_dict["page"] = page + + return field_dict + + @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_limit(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + limit = _parse_limit(d.pop("limit", UNSET)) + + def _parse_page(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + page = _parse_page(d.pop("page", UNSET)) + + sheet_query_request = cls( + namespace_name=namespace_name, + query=query, + limit=limit, + page=page, + ) + + sheet_query_request.additional_properties = d + return sheet_query_request + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/cirro_api_client/v1/models/sheet_query_response.py b/cirro_api_client/v1/models/sheet_query_response.py index c874f65..eeb5fb1 100644 --- a/cirro_api_client/v1/models/sheet_query_response.py +++ b/cirro_api_client/v1/models/sheet_query_response.py @@ -16,11 +16,17 @@ @_attrs_define class SheetQueryResponse: - """ - Attributes: - columns (list[QueryColumn]): - rows (list[list[SheetQueryResponseRowsItem]]): - total_row_count (int): + """Paginated query result from a sheet. + + + The first column is always `_row_id`, an Iceberg v3 metadata column that + uniquely identifies each row. Clients should use this value when calling the + update endpoint (`PUT /projects/{projectId}/sheets/{sheetId}/data`). + + Attributes: + columns (list[QueryColumn]): column definitions, starting with `_row_id` + rows (list[list[SheetQueryResponseRowsItem]]): row data, each list aligned with `columns` + total_row_count (int): number of total rows in the result set """ columns: list[QueryColumn] diff --git a/cirro_api_client/v1/models/sheet_sort.py b/cirro_api_client/v1/models/sheet_sort.py new file mode 100644 index 0000000..18fd282 --- /dev/null +++ b/cirro_api_client/v1/models/sheet_sort.py @@ -0,0 +1,105 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..models.sql_sort_order import SqlSortOrder +from ..types import UNSET, Unset + +T = TypeVar("T", bound="SheetSort") + + +@_attrs_define +class SheetSort: + """Column and direction for sorting sheet data results. + + Attributes: + order_by (None | str | Unset): Column to sort by. + order (None | SqlSortOrder | Unset): Sort direction. Default: SqlSortOrder.ASC. + """ + + order_by: None | str | Unset = UNSET + order: None | SqlSortOrder | Unset = SqlSortOrder.ASC + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + order_by: None | str | Unset + if isinstance(self.order_by, Unset): + order_by = UNSET + else: + order_by = self.order_by + + order: None | str | Unset + if isinstance(self.order, Unset): + order = UNSET + elif isinstance(self.order, SqlSortOrder): + order = self.order.value + else: + order = self.order + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if order_by is not UNSET: + field_dict["orderBy"] = order_by + if order is not UNSET: + field_dict["order"] = order + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + + def _parse_order_by(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + order_by = _parse_order_by(d.pop("orderBy", UNSET)) + + def _parse_order(data: object) -> None | SqlSortOrder | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + try: + if not isinstance(data, str): + raise TypeError() + order_type_1 = SqlSortOrder(data) + + return order_type_1 + except (TypeError, ValueError, AttributeError, KeyError): + pass + return cast(None | SqlSortOrder | Unset, data) + + order = _parse_order(d.pop("order", UNSET)) + + sheet_sort = cls( + order_by=order_by, + order=order, + ) + + sheet_sort.additional_properties = d + return sheet_sort + + @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/sheet_update_response.py b/cirro_api_client/v1/models/sheet_update_response.py new file mode 100644 index 0000000..e7ae0a6 --- /dev/null +++ b/cirro_api_client/v1/models/sheet_update_response.py @@ -0,0 +1,98 @@ +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.sheet_detail import SheetDetail + + +T = TypeVar("T", bound="SheetUpdateResponse") + + +@_attrs_define +class SheetUpdateResponse: + """ + Attributes: + sheet (SheetDetail | Unset): + sql_statements (list[str] | Unset): SQL DDL statements applied (TABLE schema changes) or that WOULD be applied + (dryRun). Empty for metadata-only updates and for VIEW updates. + changes (list[str] | Unset): Human-readable summary of the changes applied (or that would be applied for + dryRun). Suitable for showing to users unfamiliar with SQL. Empty for metadata-only and VIEW updates. + """ + + sheet: SheetDetail | Unset = UNSET + sql_statements: list[str] | Unset = UNSET + changes: list[str] | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + sheet: dict[str, Any] | Unset = UNSET + if not isinstance(self.sheet, Unset): + sheet = self.sheet.to_dict() + + sql_statements: list[str] | Unset = UNSET + if not isinstance(self.sql_statements, Unset): + sql_statements = self.sql_statements + + changes: list[str] | Unset = UNSET + if not isinstance(self.changes, Unset): + changes = self.changes + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({}) + if sheet is not UNSET: + field_dict["sheet"] = sheet + if sql_statements is not UNSET: + field_dict["sqlStatements"] = sql_statements + if changes is not UNSET: + field_dict["changes"] = changes + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.sheet_detail import SheetDetail + + d = dict(src_dict) + _sheet = d.pop("sheet", UNSET) + sheet: SheetDetail | Unset + if isinstance(_sheet, Unset): + sheet = UNSET + else: + sheet = SheetDetail.from_dict(_sheet) + + sql_statements = cast(list[str], d.pop("sqlStatements", UNSET)) + + changes = cast(list[str], d.pop("changes", UNSET)) + + sheet_update_response = cls( + sheet=sheet, + sql_statements=sql_statements, + changes=changes, + ) + + sheet_update_response.additional_properties = d + return sheet_update_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/source_column.py b/cirro_api_client/v1/models/source_column.py new file mode 100644 index 0000000..a5aabbe --- /dev/null +++ b/cirro_api_client/v1/models/source_column.py @@ -0,0 +1,103 @@ +from __future__ import annotations + +from collections.abc import Mapping +from typing import Any, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import UNSET, Unset + +T = TypeVar("T", bound="SourceColumn") + + +@_attrs_define +class SourceColumn: + """ + Attributes: + 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. + """ + + sheet_column: str + file_column: None | str | Unset = UNSET + index: int | None | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + sheet_column = self.sheet_column + + file_column: None | str | Unset + if isinstance(self.file_column, Unset): + file_column = UNSET + else: + file_column = self.file_column + + index: int | None | Unset + if isinstance(self.index, Unset): + index = UNSET + else: + index = self.index + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "sheetColumn": sheet_column, + } + ) + if file_column is not UNSET: + field_dict["fileColumn"] = file_column + if index is not UNSET: + field_dict["index"] = index + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + d = dict(src_dict) + sheet_column = d.pop("sheetColumn") + + def _parse_file_column(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + file_column = _parse_file_column(d.pop("fileColumn", UNSET)) + + def _parse_index(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + index = _parse_index(d.pop("index", UNSET)) + + source_column = cls( + sheet_column=sheet_column, + file_column=file_column, + index=index, + ) + + source_column.additional_properties = d + return source_column + + @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_query_request.py b/cirro_api_client/v1/models/structured_view_query_request.py similarity index 82% rename from cirro_api_client/v1/models/view_query_request.py rename to cirro_api_client/v1/models/structured_view_query_request.py index 52114e4..5bd7faa 100644 --- a/cirro_api_client/v1/models/view_query_request.py +++ b/cirro_api_client/v1/models/structured_view_query_request.py @@ -9,33 +9,36 @@ from ..types import UNSET, Unset if TYPE_CHECKING: - from ..models.view_filter import ViewFilter + from ..models.filter_ import Filter from ..models.view_join import ViewJoin from ..models.view_sheet_ref import ViewSheetRef -T = TypeVar("T", bound="ViewQueryRequest") +T = TypeVar("T", bound="StructuredViewQueryRequest") @_attrs_define -class ViewQueryRequest: +class StructuredViewQueryRequest: """Request for a view joining one or more sheets with optional column selection and filtering Attributes: - sheets (list[ViewSheetRef]): Sheets to include in the view + sheets (list[ViewSheetRef]): Sheets to include in the view. The first entry (sheets[0]) is the primary sheet — + it becomes the FROM clause of the generated SQL. Subsequent entries are brought in via joins. joins (list[ViewJoin] | None | Unset): Join definitions between sheets columns (list[str] | None | Unset): Columns to select in alias.column format. If null, selects all columns. - filter_ (None | Unset | ViewFilter): Filter conditions to apply + filter_ (Filter | None | Unset): Filter conditions to apply + view_type (str | Unset): """ sheets: list[ViewSheetRef] joins: list[ViewJoin] | None | Unset = UNSET columns: list[str] | None | Unset = UNSET - filter_: None | Unset | ViewFilter = UNSET + filter_: Filter | None | Unset = UNSET + view_type: str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - from ..models.view_filter import ViewFilter + from ..models.filter_ import Filter sheets = [] for sheets_item_data in self.sheets: @@ -66,11 +69,13 @@ def to_dict(self) -> dict[str, Any]: filter_: dict[str, Any] | None | Unset if isinstance(self.filter_, Unset): filter_ = UNSET - elif isinstance(self.filter_, ViewFilter): + elif isinstance(self.filter_, Filter): filter_ = self.filter_.to_dict() else: filter_ = self.filter_ + view_type = self.view_type + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) field_dict.update( @@ -84,12 +89,14 @@ def to_dict(self) -> dict[str, Any]: field_dict["columns"] = columns if filter_ is not UNSET: field_dict["filter"] = filter_ + if view_type is not UNSET: + field_dict["viewType"] = view_type return field_dict @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.view_filter import ViewFilter + from ..models.filter_ import Filter from ..models.view_join import ViewJoin from ..models.view_sheet_ref import ViewSheetRef @@ -140,7 +147,7 @@ def _parse_columns(data: object) -> list[str] | None | Unset: columns = _parse_columns(d.pop("columns", UNSET)) - def _parse_filter_(data: object) -> None | Unset | ViewFilter: + def _parse_filter_(data: object) -> Filter | None | Unset: if data is None: return data if isinstance(data, Unset): @@ -148,24 +155,27 @@ def _parse_filter_(data: object) -> None | Unset | ViewFilter: try: if not isinstance(data, dict): raise TypeError() - filter_type_1 = ViewFilter.from_dict(data) + filter_type_1 = Filter.from_dict(data) return filter_type_1 except (TypeError, ValueError, AttributeError, KeyError): pass - return cast(None | Unset | ViewFilter, data) + return cast(Filter | None | Unset, data) filter_ = _parse_filter_(d.pop("filter", UNSET)) - view_query_request = cls( + view_type = d.pop("viewType", UNSET) + + structured_view_query_request = cls( sheets=sheets, joins=joins, columns=columns, filter_=filter_, + view_type=view_type, ) - view_query_request.additional_properties = d - return view_query_request + structured_view_query_request.additional_properties = d + return structured_view_query_request @property def additional_keys(self) -> list[str]: diff --git a/cirro_api_client/v1/models/table_sheet_input.py b/cirro_api_client/v1/models/table_sheet_input.py new file mode 100644 index 0000000..d4a361a --- /dev/null +++ b/cirro_api_client/v1/models/table_sheet_input.py @@ -0,0 +1,196 @@ +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.sheet_creation_mode import SheetCreationMode +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.column_def import ColumnDef + from ..models.tag import Tag + + +T = TypeVar("T", bound="TableSheetInput") + + +@_attrs_define +class TableSheetInput: + """ + Attributes: + name (str): Display name for the sheet + namespace_name (str): Namespace containing the sheet's underlying table. Immutable after create. Example: + alz_cohort. + table_name (str): Name of the sheet's underlying table. Mutable via update. Example: my_table. + sheet_creation_mode (SheetCreationMode): + columns (list[ColumnDef]): Target column list for the sheet. On update, the server computes the diff against + existing columns (matched by column id) and applies the resulting ADD/DROP/RENAME/TYPE changes as a single + transactional ALTER sequence. Existing columns include their id; new columns omit it. + 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. + schema_version_id (int | None | 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. + tags (list[Tag] | Unset): Tags for the sheet + sheet_type (str | Unset): + """ + + name: str + namespace_name: str + table_name: str + sheet_creation_mode: SheetCreationMode + columns: list[ColumnDef] + description: None | str | Unset = UNSET + audit_read_access: bool | Unset = False + schema_version_id: int | None | Unset = UNSET + tags: list[Tag] | Unset = UNSET + sheet_type: str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + name = self.name + + namespace_name = self.namespace_name + + table_name = self.table_name + + sheet_creation_mode = self.sheet_creation_mode.value + + columns = [] + for columns_item_data in self.columns: + columns_item = columns_item_data.to_dict() + columns.append(columns_item) + + description: None | str | Unset + if isinstance(self.description, Unset): + description = UNSET + else: + description = self.description + + audit_read_access = self.audit_read_access + + schema_version_id: int | None | Unset + if isinstance(self.schema_version_id, Unset): + schema_version_id = UNSET + else: + schema_version_id = self.schema_version_id + + tags: list[dict[str, Any]] | Unset = UNSET + if not isinstance(self.tags, Unset): + tags = [] + for tags_item_data in self.tags: + tags_item = tags_item_data.to_dict() + tags.append(tags_item) + + sheet_type = self.sheet_type + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "name": name, + "namespaceName": namespace_name, + "tableName": table_name, + "sheetCreationMode": sheet_creation_mode, + "columns": columns, + } + ) + if description is not UNSET: + field_dict["description"] = description + if audit_read_access is not UNSET: + field_dict["auditReadAccess"] = audit_read_access + if schema_version_id is not UNSET: + field_dict["schemaVersionId"] = schema_version_id + if tags is not UNSET: + field_dict["tags"] = tags + if sheet_type is not UNSET: + field_dict["sheetType"] = sheet_type + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.column_def import ColumnDef + from ..models.tag import Tag + + d = dict(src_dict) + name = d.pop("name") + + namespace_name = d.pop("namespaceName") + + table_name = d.pop("tableName") + + sheet_creation_mode = SheetCreationMode(d.pop("sheetCreationMode")) + + columns = [] + _columns = d.pop("columns") + for columns_item_data in _columns: + columns_item = ColumnDef.from_dict(columns_item_data) + + columns.append(columns_item) + + def _parse_description(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + description = _parse_description(d.pop("description", UNSET)) + + audit_read_access = d.pop("auditReadAccess", UNSET) + + def _parse_schema_version_id(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + schema_version_id = _parse_schema_version_id(d.pop("schemaVersionId", UNSET)) + + _tags = d.pop("tags", UNSET) + tags: list[Tag] | Unset = UNSET + if _tags is not UNSET: + tags = [] + for tags_item_data in _tags: + tags_item = Tag.from_dict(tags_item_data) + + tags.append(tags_item) + + sheet_type = d.pop("sheetType", UNSET) + + table_sheet_input = cls( + name=name, + namespace_name=namespace_name, + table_name=table_name, + sheet_creation_mode=sheet_creation_mode, + columns=columns, + description=description, + audit_read_access=audit_read_access, + schema_version_id=schema_version_id, + tags=tags, + sheet_type=sheet_type, + ) + + table_sheet_input.additional_properties = d + return table_sheet_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/task.py b/cirro_api_client/v1/models/task.py index 2399324..c4b0519 100644 --- a/cirro_api_client/v1/models/task.py +++ b/cirro_api_client/v1/models/task.py @@ -25,6 +25,8 @@ class Task: started_at (datetime.datetime | None | Unset): stopped_at (datetime.datetime | None | Unset): container_image (None | str | Unset): + work_dir (None | str | Unset): + exit_code (int | None | Unset): command_line (None | str | Unset): log_location (None | str | Unset): """ @@ -37,6 +39,8 @@ class Task: started_at: datetime.datetime | None | Unset = UNSET stopped_at: datetime.datetime | None | Unset = UNSET container_image: None | str | Unset = UNSET + work_dir: None | str | Unset = UNSET + exit_code: int | None | Unset = UNSET command_line: None | str | Unset = UNSET log_location: None | str | Unset = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -88,6 +92,18 @@ def to_dict(self) -> dict[str, Any]: else: container_image = self.container_image + work_dir: None | str | Unset + if isinstance(self.work_dir, Unset): + work_dir = UNSET + else: + work_dir = self.work_dir + + exit_code: int | None | Unset + if isinstance(self.exit_code, Unset): + exit_code = UNSET + else: + exit_code = self.exit_code + command_line: None | str | Unset if isinstance(self.command_line, Unset): command_line = UNSET @@ -120,6 +136,10 @@ def to_dict(self) -> dict[str, Any]: field_dict["stoppedAt"] = stopped_at if container_image is not UNSET: field_dict["containerImage"] = container_image + if work_dir is not UNSET: + field_dict["workDir"] = work_dir + if exit_code is not UNSET: + field_dict["exitCode"] = exit_code if command_line is not UNSET: field_dict["commandLine"] = command_line if log_location is not UNSET: @@ -212,6 +232,24 @@ def _parse_container_image(data: object) -> None | str | Unset: container_image = _parse_container_image(d.pop("containerImage", UNSET)) + def _parse_work_dir(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + work_dir = _parse_work_dir(d.pop("workDir", UNSET)) + + def _parse_exit_code(data: object) -> int | None | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(int | None | Unset, data) + + exit_code = _parse_exit_code(d.pop("exitCode", UNSET)) + def _parse_command_line(data: object) -> None | str | Unset: if data is None: return data @@ -239,6 +277,8 @@ def _parse_log_location(data: object) -> None | str | Unset: started_at=started_at, stopped_at=stopped_at, container_image=container_image, + work_dir=work_dir, + exit_code=exit_code, command_line=command_line, log_location=log_location, ) diff --git a/cirro_api_client/v1/models/task_log_source.py b/cirro_api_client/v1/models/task_log_source.py new file mode 100644 index 0000000..7ef6954 --- /dev/null +++ b/cirro_api_client/v1/models/task_log_source.py @@ -0,0 +1,16 @@ +from enum import Enum + + +class TaskLogSource(str, Enum): + LOG = "LOG" + STDERR = "STDERR" + STDOUT = "STDOUT" + 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/update_sheet_request.py b/cirro_api_client/v1/models/update_sheet_request.py deleted file mode 100644 index ed10921..0000000 --- a/cirro_api_client/v1/models/update_sheet_request.py +++ /dev/null @@ -1,109 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import TYPE_CHECKING, Any, TypeVar, cast - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -from ..types import UNSET, Unset - -if TYPE_CHECKING: - from ..models.view_query_request import ViewQueryRequest - - -T = TypeVar("T", bound="UpdateSheetRequest") - - -@_attrs_define -class UpdateSheetRequest: - """ - Attributes: - name (str): Display name - description (str): - view_definition (None | Unset | ViewQueryRequest): Updated view definition (VIEW sheets only) - """ - - name: str - description: str - view_definition: None | Unset | ViewQueryRequest = UNSET - additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) - - def to_dict(self) -> dict[str, Any]: - from ..models.view_query_request import ViewQueryRequest - - name = self.name - - description = self.description - - view_definition: dict[str, Any] | None | Unset - if isinstance(self.view_definition, Unset): - view_definition = UNSET - elif isinstance(self.view_definition, ViewQueryRequest): - view_definition = self.view_definition.to_dict() - else: - view_definition = self.view_definition - - field_dict: dict[str, Any] = {} - field_dict.update(self.additional_properties) - field_dict.update( - { - "name": name, - "description": description, - } - ) - if view_definition is not UNSET: - field_dict["viewDefinition"] = view_definition - - return field_dict - - @classmethod - def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.view_query_request import ViewQueryRequest - - d = dict(src_dict) - name = d.pop("name") - - description = d.pop("description") - - def _parse_view_definition(data: object) -> None | Unset | ViewQueryRequest: - if data is None: - return data - if isinstance(data, Unset): - return data - try: - if not isinstance(data, dict): - raise TypeError() - view_definition_type_1 = ViewQueryRequest.from_dict(data) - - return view_definition_type_1 - except (TypeError, ValueError, AttributeError, KeyError): - pass - return cast(None | Unset | ViewQueryRequest, data) - - view_definition = _parse_view_definition(d.pop("viewDefinition", UNSET)) - - update_sheet_request = cls( - name=name, - description=description, - view_definition=view_definition, - ) - - update_sheet_request.additional_properties = d - return update_sheet_request - - @property - def additional_keys(self) -> list[str]: - return list(self.additional_properties.keys()) - - def __getitem__(self, key: str) -> Any: - return self.additional_properties[key] - - def __setitem__(self, key: str, value: Any) -> None: - self.additional_properties[key] = value - - def __delitem__(self, key: str) -> None: - del self.additional_properties[key] - - def __contains__(self, key: str) -> bool: - return key in self.additional_properties diff --git a/cirro_api_client/v1/models/user_detail.py b/cirro_api_client/v1/models/user_detail.py index 1a7f095..889e9a7 100644 --- a/cirro_api_client/v1/models/user_detail.py +++ b/cirro_api_client/v1/models/user_detail.py @@ -24,15 +24,16 @@ class UserDetail: Attributes: username (str): name (str): - phone (str): email (str): organization (str): - job_title (str): - department (str): - invited_by (str): project_assignments (list[UserProjectAssignment]): global_roles (list[str]): settings (UserSettings): Additional settings for the user + phone (None | str | Unset): + orcid_id (None | str | Unset): + job_title (None | str | Unset): + department (None | str | Unset): + invited_by (None | str | Unset): sign_up_time (datetime.datetime | None | Unset): last_signed_in (datetime.datetime | None | Unset): groups (list[str] | None | Unset): Replaced by globalRoles. @@ -40,15 +41,16 @@ class UserDetail: username: str name: str - phone: str email: str organization: str - job_title: str - department: str - invited_by: str project_assignments: list[UserProjectAssignment] global_roles: list[str] settings: UserSettings + phone: None | str | Unset = UNSET + orcid_id: None | str | Unset = UNSET + job_title: None | str | Unset = UNSET + department: None | str | Unset = UNSET + invited_by: None | str | Unset = UNSET sign_up_time: datetime.datetime | None | Unset = UNSET last_signed_in: datetime.datetime | None | Unset = UNSET groups: list[str] | None | Unset = UNSET @@ -59,18 +61,10 @@ def to_dict(self) -> dict[str, Any]: name = self.name - phone = self.phone - email = self.email organization = self.organization - job_title = self.job_title - - department = self.department - - invited_by = self.invited_by - project_assignments = [] for project_assignments_item_data in self.project_assignments: project_assignments_item = project_assignments_item_data.to_dict() @@ -80,6 +74,36 @@ def to_dict(self) -> dict[str, Any]: settings = self.settings.to_dict() + phone: None | str | Unset + if isinstance(self.phone, Unset): + phone = UNSET + else: + phone = self.phone + + orcid_id: None | str | Unset + if isinstance(self.orcid_id, Unset): + orcid_id = UNSET + else: + orcid_id = self.orcid_id + + job_title: None | str | Unset + if isinstance(self.job_title, Unset): + job_title = UNSET + else: + job_title = self.job_title + + department: None | str | Unset + if isinstance(self.department, Unset): + department = UNSET + else: + department = self.department + + invited_by: None | str | Unset + if isinstance(self.invited_by, Unset): + invited_by = UNSET + else: + invited_by = self.invited_by + sign_up_time: None | str | Unset if isinstance(self.sign_up_time, Unset): sign_up_time = UNSET @@ -111,17 +135,23 @@ def to_dict(self) -> dict[str, Any]: { "username": username, "name": name, - "phone": phone, "email": email, "organization": organization, - "jobTitle": job_title, - "department": department, - "invitedBy": invited_by, "projectAssignments": project_assignments, "globalRoles": global_roles, "settings": settings, } ) + if phone is not UNSET: + field_dict["phone"] = phone + if orcid_id is not UNSET: + field_dict["orcidId"] = orcid_id + if job_title is not UNSET: + field_dict["jobTitle"] = job_title + if department is not UNSET: + field_dict["department"] = department + if invited_by is not UNSET: + field_dict["invitedBy"] = invited_by if sign_up_time is not UNSET: field_dict["signUpTime"] = sign_up_time if last_signed_in is not UNSET: @@ -141,18 +171,10 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: name = d.pop("name") - phone = d.pop("phone") - email = d.pop("email") organization = d.pop("organization") - job_title = d.pop("jobTitle") - - department = d.pop("department") - - invited_by = d.pop("invitedBy") - project_assignments = [] _project_assignments = d.pop("projectAssignments") for project_assignments_item_data in _project_assignments: @@ -164,6 +186,51 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: settings = UserSettings.from_dict(d.pop("settings")) + def _parse_phone(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + phone = _parse_phone(d.pop("phone", UNSET)) + + def _parse_orcid_id(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + orcid_id = _parse_orcid_id(d.pop("orcidId", UNSET)) + + def _parse_job_title(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + job_title = _parse_job_title(d.pop("jobTitle", UNSET)) + + def _parse_department(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + department = _parse_department(d.pop("department", UNSET)) + + def _parse_invited_by(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + invited_by = _parse_invited_by(d.pop("invitedBy", UNSET)) + def _parse_sign_up_time(data: object) -> datetime.datetime | None | Unset: if data is None: return data @@ -218,15 +285,16 @@ def _parse_groups(data: object) -> list[str] | None | Unset: user_detail = cls( username=username, name=name, - phone=phone, email=email, organization=organization, - job_title=job_title, - department=department, - invited_by=invited_by, project_assignments=project_assignments, global_roles=global_roles, settings=settings, + phone=phone, + orcid_id=orcid_id, + job_title=job_title, + department=department, + invited_by=invited_by, sign_up_time=sign_up_time, last_signed_in=last_signed_in, groups=groups, diff --git a/cirro_api_client/v1/models/view_join.py b/cirro_api_client/v1/models/view_join.py index 4d9f441..99d2ef6 100644 --- a/cirro_api_client/v1/models/view_join.py +++ b/cirro_api_client/v1/models/view_join.py @@ -19,19 +19,15 @@ class ViewJoin: """ Attributes: - sheet_alias (str): Alias of the sheet to join join_type (JoinType): conditions (list[JoinCondition]): """ - sheet_alias: str join_type: JoinType conditions: list[JoinCondition] additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - sheet_alias = self.sheet_alias - join_type = self.join_type.value conditions = [] @@ -43,7 +39,6 @@ def to_dict(self) -> dict[str, Any]: field_dict.update(self.additional_properties) field_dict.update( { - "sheetAlias": sheet_alias, "joinType": join_type, "conditions": conditions, } @@ -56,8 +51,6 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: from ..models.join_condition import JoinCondition d = dict(src_dict) - sheet_alias = d.pop("sheetAlias") - join_type = JoinType(d.pop("joinType")) conditions = [] @@ -68,7 +61,6 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: conditions.append(conditions_item) view_join = cls( - sheet_alias=sheet_alias, join_type=join_type, conditions=conditions, ) diff --git a/cirro_api_client/v1/models/view_sheet_input.py b/cirro_api_client/v1/models/view_sheet_input.py new file mode 100644 index 0000000..024b21f --- /dev/null +++ b/cirro_api_client/v1/models/view_sheet_input.py @@ -0,0 +1,179 @@ +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.raw_view_query_request import RawViewQueryRequest + from ..models.structured_view_query_request import StructuredViewQueryRequest + from ..models.tag import Tag + + +T = TypeVar("T", bound="ViewSheetInput") + + +@_attrs_define +class ViewSheetInput: + """ + Attributes: + name (str): Display name for the sheet + namespace_name (str): Namespace containing the sheet's underlying table. Immutable after create. Example: + alz_cohort. + table_name (str): Name of the sheet's underlying table. Mutable via update. Example: my_table. + view_definition (RawViewQueryRequest | StructuredViewQueryRequest): View definition. viewType=STRUCTURED for + 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. + tags (list[Tag] | Unset): Tags for the sheet + sheet_type (str | Unset): + """ + + name: str + namespace_name: str + table_name: str + view_definition: RawViewQueryRequest | StructuredViewQueryRequest + description: None | str | Unset = UNSET + audit_read_access: bool | Unset = False + tags: list[Tag] | Unset = UNSET + sheet_type: str | Unset = UNSET + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> dict[str, Any]: + from ..models.raw_view_query_request import RawViewQueryRequest + + name = self.name + + namespace_name = self.namespace_name + + table_name = self.table_name + + view_definition: dict[str, Any] + if isinstance(self.view_definition, RawViewQueryRequest): + view_definition = self.view_definition.to_dict() + else: + view_definition = self.view_definition.to_dict() + + description: None | str | Unset + if isinstance(self.description, Unset): + description = UNSET + else: + description = self.description + + audit_read_access = self.audit_read_access + + tags: list[dict[str, Any]] | Unset = UNSET + if not isinstance(self.tags, Unset): + tags = [] + for tags_item_data in self.tags: + tags_item = tags_item_data.to_dict() + tags.append(tags_item) + + sheet_type = self.sheet_type + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "name": name, + "namespaceName": namespace_name, + "tableName": table_name, + "viewDefinition": view_definition, + } + ) + if description is not UNSET: + field_dict["description"] = description + if audit_read_access is not UNSET: + field_dict["auditReadAccess"] = audit_read_access + if tags is not UNSET: + field_dict["tags"] = tags + if sheet_type is not UNSET: + field_dict["sheetType"] = sheet_type + + return field_dict + + @classmethod + def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: + from ..models.raw_view_query_request import RawViewQueryRequest + from ..models.structured_view_query_request import StructuredViewQueryRequest + from ..models.tag import Tag + + d = dict(src_dict) + name = d.pop("name") + + namespace_name = d.pop("namespaceName") + + table_name = d.pop("tableName") + + def _parse_view_definition(data: object) -> RawViewQueryRequest | StructuredViewQueryRequest: + try: + if not isinstance(data, dict): + raise TypeError() + componentsschemas_view_query_request_type_0 = RawViewQueryRequest.from_dict(data) + + return componentsschemas_view_query_request_type_0 + except (TypeError, ValueError, AttributeError, KeyError): + pass + if not isinstance(data, dict): + raise TypeError() + componentsschemas_view_query_request_type_1 = StructuredViewQueryRequest.from_dict(data) + + return componentsschemas_view_query_request_type_1 + + view_definition = _parse_view_definition(d.pop("viewDefinition")) + + def _parse_description(data: object) -> None | str | Unset: + if data is None: + return data + if isinstance(data, Unset): + return data + return cast(None | str | Unset, data) + + description = _parse_description(d.pop("description", UNSET)) + + audit_read_access = d.pop("auditReadAccess", UNSET) + + _tags = d.pop("tags", UNSET) + tags: list[Tag] | Unset = UNSET + if _tags is not UNSET: + tags = [] + for tags_item_data in _tags: + tags_item = Tag.from_dict(tags_item_data) + + tags.append(tags_item) + + sheet_type = d.pop("sheetType", UNSET) + + view_sheet_input = cls( + name=name, + namespace_name=namespace_name, + table_name=table_name, + view_definition=view_definition, + description=description, + audit_read_access=audit_read_access, + tags=tags, + sheet_type=sheet_type, + ) + + view_sheet_input.additional_properties = d + return view_sheet_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/pyproject.toml b/pyproject.toml index 70016d1..2f9ba5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "cirro_api_client" -version = "1.4.0" +version = "1.5.0" description = "A client library for accessing Cirro" authors = ["Cirro "] license = "MIT" From a5df08ee0a3dc3226a35f6b1899e2e5b4ec20db4 Mon Sep 17 00:00:00 2001 From: Nathan Thorpe Date: Fri, 22 May 2026 16:52:40 -0700 Subject: [PATCH 2/4] no --- cirro_api_client/.gitignore | 23 ------ cirro_api_client/README.md | 124 -------------------------------- cirro_api_client/pyproject.toml | 26 ------- 3 files changed, 173 deletions(-) delete mode 100644 cirro_api_client/.gitignore delete mode 100644 cirro_api_client/README.md delete mode 100644 cirro_api_client/pyproject.toml diff --git a/cirro_api_client/.gitignore b/cirro_api_client/.gitignore deleted file mode 100644 index 79a2c3d..0000000 --- a/cirro_api_client/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -__pycache__/ -build/ -dist/ -*.egg-info/ -.pytest_cache/ - -# pyenv -.python-version - -# Environments -.env -.venv - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# JetBrains -.idea/ - -/coverage.xml -/.coverage diff --git a/cirro_api_client/README.md b/cirro_api_client/README.md deleted file mode 100644 index 431cd47..0000000 --- a/cirro_api_client/README.md +++ /dev/null @@ -1,124 +0,0 @@ -# cirro_api_client -A client library for accessing Cirro Data - -## Usage -First, create a client: - -```python -from v1 import Client - -client = Client(base_url="https://api.example.com") -``` - -If the endpoints you're going to hit require authentication, use `AuthenticatedClient` instead: - -```python -from v1 import AuthenticatedClient - -client = AuthenticatedClient(base_url="https://api.example.com", token="SuperSecretToken") -``` - -Now call your endpoint and use your models: - -```python -from v1.models import MyDataModel -from v1.api.my_tag import get_my_data_model -from v1.types import Response - -with client as client: - my_data: MyDataModel = get_my_data_model.sync(client=client) - # or if you need more info (e.g. status_code) - response: Response[MyDataModel] = get_my_data_model.sync_detailed(client=client) -``` - -Or do the same thing with an async version: - -```python -from v1.models import MyDataModel -from v1.api.my_tag import get_my_data_model -from v1.types import Response - -async with client as client: - my_data: MyDataModel = await get_my_data_model.asyncio(client=client) - response: Response[MyDataModel] = await get_my_data_model.asyncio_detailed(client=client) -``` - -By default, when you're calling an HTTPS API it will attempt to verify that SSL is working correctly. Using certificate verification is highly recommended most of the time, but sometimes you may need to authenticate to a server (especially an internal server) using a custom certificate bundle. - -```python -client = AuthenticatedClient( - base_url="https://internal_api.example.com", - token="SuperSecretToken", - verify_ssl="/path/to/certificate_bundle.pem", -) -``` - -You can also disable certificate validation altogether, but beware that **this is a security risk**. - -```python -client = AuthenticatedClient( - base_url="https://internal_api.example.com", - token="SuperSecretToken", - verify_ssl=False -) -``` - -Things to know: -1. Every path/method combo becomes a Python module with four functions: - 1. `sync`: Blocking request that returns parsed data (if successful) or `None` - 1. `sync_detailed`: Blocking request that always returns a `Request`, optionally with `parsed` set if the request was successful. - 1. `asyncio`: Like `sync` but async instead of blocking - 1. `asyncio_detailed`: Like `sync_detailed` but async instead of blocking - -1. All path/query params, and bodies become method arguments. -1. If your endpoint had any tags on it, the first tag will be used as a module name for the function (my_tag above) -1. Any endpoint which did not have a tag will be in `v1.api.default` - -## Advanced customizations - -There are more settings on the generated `Client` class which let you control more runtime behavior, check out the docstring on that class for more info. You can also customize the underlying `httpx.Client` or `httpx.AsyncClient` (depending on your use-case): - -```python -from v1 import Client - -def log_request(request): - print(f"Request event hook: {request.method} {request.url} - Waiting for response") - -def log_response(response): - request = response.request - print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}") - -client = Client( - base_url="https://api.example.com", - httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}}, -) - -# Or get the underlying httpx client to modify directly with client.get_httpx_client() or client.get_async_httpx_client() -``` - -You can even set the httpx client directly, but beware that this will override any existing settings (e.g., base_url): - -```python -import httpx -from v1 import Client - -client = Client( - base_url="https://api.example.com", -) -# Note that base_url needs to be re-set, as would any shared cookies, headers, etc. -client.set_httpx_client(httpx.Client(base_url="https://api.example.com", proxies="http://localhost:8030")) -``` - -## Building / publishing this package -This project uses [Poetry](https://python-poetry.org/) to manage dependencies and packaging. Here are the basics: -1. Update the metadata in pyproject.toml (e.g. authors, version) -1. If you're using a private repository, configure it with Poetry - 1. `poetry config repositories. ` - 1. `poetry config http-basic. ` -1. Publish the client with `poetry publish --build -r ` or, if for public PyPI, just `poetry publish --build` - -If you want to install this client into another project without publishing it (e.g. for development) then: -1. If that project **is using Poetry**, you can simply do `poetry add ` from that project -1. If that project is not using Poetry: - 1. Build a wheel with `poetry build -f wheel` - 1. Install that wheel from the other project `pip install ` diff --git a/cirro_api_client/pyproject.toml b/cirro_api_client/pyproject.toml deleted file mode 100644 index 7195d9b..0000000 --- a/cirro_api_client/pyproject.toml +++ /dev/null @@ -1,26 +0,0 @@ -[tool.poetry] -name = "cirro_api_client" -version = "1.3.0" -description = "A client library for accessing Cirro Data" -authors = [] -readme = "README.md" -packages = [ - { include = "v1" }, -] -include = ["v1/py.typed"] - -[tool.poetry.dependencies] -python = "^3.10" -httpx = ">=0.23.0,<0.29.0" -attrs = ">=22.2.0" -python-dateutil = "^2.8.0" - -[build-system] -requires = ["poetry-core>=2.0.0,<3.0.0"] -build-backend = "poetry.core.masonry.api" - -[tool.ruff] -line-length = 120 - -[tool.ruff.lint] -select = ["F", "I", "UP"] From 58451e77df65539653761cae1d70ce155325a41c Mon Sep 17 00:00:00 2001 From: Nathan Thorpe Date: Fri, 22 May 2026 17:07:32 -0700 Subject: [PATCH 3/4] remove misc error code --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2f9ba5b..497466c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,4 +30,4 @@ lint.select = ["F", "I", "UP"] line-length = 120 [tool.mypy] -disable_error_code = ["return", "import-untyped", "var-annotated"] +disable_error_code = ["return", "import-untyped", "var-annotated", "misc"] From a63c59a11d49a43de385d18a6d763ae693985f8d Mon Sep 17 00:00:00 2001 From: Nathan Thorpe Date: Fri, 22 May 2026 17:08:00 -0700 Subject: [PATCH 4/4] remove dataset viz config --- cirro_api_client/v1/models/__init__.py | 2 - cirro_api_client/v1/models/dataset_viz.py | 21 +-------- .../v1/models/dataset_viz_config.py | 46 ------------------- 3 files changed, 2 insertions(+), 67 deletions(-) delete mode 100644 cirro_api_client/v1/models/dataset_viz_config.py diff --git a/cirro_api_client/v1/models/__init__.py b/cirro_api_client/v1/models/__init__.py index 3232e72..309268d 100644 --- a/cirro_api_client/v1/models/__init__.py +++ b/cirro_api_client/v1/models/__init__.py @@ -70,7 +70,6 @@ from .dataset_detail_params import DatasetDetailParams from .dataset_detail_source_sample_files_map import DatasetDetailSourceSampleFilesMap from .dataset_viz import DatasetViz -from .dataset_viz_config import DatasetVizConfig from .delete_rows_request import DeleteRowsRequest from .discussion import Discussion from .discussion_input import DiscussionInput @@ -325,7 +324,6 @@ "DatasetDetailParams", "DatasetDetailSourceSampleFilesMap", "DatasetViz", - "DatasetVizConfig", "DeleteRowsRequest", "Discussion", "DiscussionInput", diff --git a/cirro_api_client/v1/models/dataset_viz.py b/cirro_api_client/v1/models/dataset_viz.py index 11aec3c..6f8f30c 100644 --- a/cirro_api_client/v1/models/dataset_viz.py +++ b/cirro_api_client/v1/models/dataset_viz.py @@ -1,17 +1,13 @@ 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 from ..types import UNSET, Unset -if TYPE_CHECKING: - from ..models.dataset_viz_config import DatasetVizConfig - - T = TypeVar("T", bound="DatasetViz") @@ -19,14 +15,12 @@ class DatasetViz: """ Attributes: - config (DatasetVizConfig): path (str | Unset): Path to viz configuration, if applicable name (str | Unset): Name of viz desc (str | Unset): Description of viz type_ (str | Unset): Type of viz Example: vitescce. """ - config: DatasetVizConfig path: str | Unset = UNSET name: str | Unset = UNSET desc: str | Unset = UNSET @@ -34,8 +28,6 @@ class DatasetViz: additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> dict[str, Any]: - config = self.config.to_dict() - path = self.path name = self.name @@ -46,11 +38,7 @@ def to_dict(self) -> dict[str, Any]: field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) - field_dict.update( - { - "config": config, - } - ) + field_dict.update({}) if path is not UNSET: field_dict["path"] = path if name is not UNSET: @@ -64,11 +52,7 @@ def to_dict(self) -> dict[str, Any]: @classmethod def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: - from ..models.dataset_viz_config import DatasetVizConfig - d = dict(src_dict) - config = DatasetVizConfig.from_dict(d.pop("config")) - path = d.pop("path", UNSET) name = d.pop("name", UNSET) @@ -78,7 +62,6 @@ def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T: type_ = d.pop("type", UNSET) dataset_viz = cls( - config=config, path=path, name=name, desc=desc, diff --git a/cirro_api_client/v1/models/dataset_viz_config.py b/cirro_api_client/v1/models/dataset_viz_config.py deleted file mode 100644 index 27f651e..0000000 --- a/cirro_api_client/v1/models/dataset_viz_config.py +++ /dev/null @@ -1,46 +0,0 @@ -from __future__ import annotations - -from collections.abc import Mapping -from typing import Any, TypeVar - -from attrs import define as _attrs_define -from attrs import field as _attrs_field - -T = TypeVar("T", bound="DatasetVizConfig") - - -@_attrs_define -class DatasetVizConfig: - """ """ - - 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) - dataset_viz_config = cls() - - dataset_viz_config.additional_properties = d - return dataset_viz_config - - @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