diff --git a/doc/changes/changelog.md b/doc/changes/changelog.md index bcbf41a..208d42b 100644 --- a/doc/changes/changelog.md +++ b/doc/changes/changelog.md @@ -1,6 +1,7 @@ # Changes * [unreleased](unreleased.md) +* [1.1.0](changes_1.1.0.md) * [1.0.0](changes_1.0.0.md) * [0.10.0](changes_0.10.0.md) * [0.9.0](changes_0.9.0.md) @@ -19,6 +20,7 @@ hidden: --- unreleased +changes_1.1.0 changes_1.0.0 changes_0.10.0 changes_0.9.0 diff --git a/doc/changes/changes_1.1.0.md b/doc/changes/changes_1.1.0.md new file mode 100644 index 0000000..df2c8c4 --- /dev/null +++ b/doc/changes/changes_1.1.0.md @@ -0,0 +1,29 @@ +# 1.1.0 - 2025-04-07 + +## Summary + +This release updates the Python API generated from file `openapi.json`. + +Changes to `open-api.json` in detail: + +Endpoint was renamed +* from `/api/v1/accounts/{accountId}/databases/{databaseId}/database_settings` +* to `/api/v1/accounts/{accountId}/databases/{databaseId}/settings` + +Method `GET` was added for endpoint +* `/api/v1/accounts/{accountId}/databases/{databaseId}/upgrade` + +Changes to models below `components` / `schemas`: + +Attribute `streamType` was added to +* `CreateDatabase` / `properties` +* `Database` / `properties` / `settings` / `required` +* `Database` / `properties` / `settings` / `properties` +* `DatabaseSettings` / `required` +* `DatabaseSettings` / `properties` + +Model `DatabaseUpgradeInfo` was added. + +* Refactorings + +* #88: Updated `openapi.json` diff --git a/exasol/saas/client/openapi/api/databases/get_database_settings.py b/exasol/saas/client/openapi/api/databases/get_database_settings.py index 5a6d27d..08ccc0b 100644 --- a/exasol/saas/client/openapi/api/databases/get_database_settings.py +++ b/exasol/saas/client/openapi/api/databases/get_database_settings.py @@ -33,7 +33,7 @@ def _get_kwargs( _kwargs: dict[str, Any] = { "method": "get", - "url": "/api/v1/accounts/{account_id}/databases/{database_id}/database_settings".format(account_id=account_id,database_id=database_id,), + "url": "/api/v1/accounts/{account_id}/databases/{database_id}/settings".format(account_id=account_id,database_id=database_id,), } diff --git a/exasol/saas/client/openapi/api/databases/get_database_upgrade_info.py b/exasol/saas/client/openapi/api/databases/get_database_upgrade_info.py new file mode 100644 index 0000000..3e97bd5 --- /dev/null +++ b/exasol/saas/client/openapi/api/databases/get_database_upgrade_info.py @@ -0,0 +1,185 @@ +from http import HTTPStatus +from typing import ( + Any, + Optional, + Union, + cast, +) + +import httpx + +from ... import errors +from ...client import ( + AuthenticatedClient, + Client, +) +from ...models.database_upgrade_info import DatabaseUpgradeInfo +from ...types import ( + UNSET, + Response, +) + + +def _get_kwargs( + account_id: str, + database_id: str, + +) -> dict[str, Any]: + + + + + + + _kwargs: dict[str, Any] = { + "method": "get", + "url": "/api/v1/accounts/{account_id}/databases/{database_id}/upgrade".format(account_id=account_id,database_id=database_id,), + } + + + return _kwargs + + +def _parse_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Optional[DatabaseUpgradeInfo]: + if response.status_code == 200: + response_200 = DatabaseUpgradeInfo.from_dict(response.json()) + + + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response(*, client: Union[AuthenticatedClient, Client], response: httpx.Response) -> Response[DatabaseUpgradeInfo]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + account_id: str, + database_id: str, + *, + client: AuthenticatedClient, + +) -> Response[DatabaseUpgradeInfo]: + """ + Args: + account_id (str): + database_id (str): + + 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[DatabaseUpgradeInfo] + """ + + + kwargs = _get_kwargs( + account_id=account_id, +database_id=database_id, + + ) + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + +def sync( + account_id: str, + database_id: str, + *, + client: AuthenticatedClient, + +) -> Optional[DatabaseUpgradeInfo]: + """ + Args: + account_id (str): + database_id (str): + + 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: + DatabaseUpgradeInfo + """ + + + return sync_detailed( + account_id=account_id, +database_id=database_id, +client=client, + + ).parsed + +async def asyncio_detailed( + account_id: str, + database_id: str, + *, + client: AuthenticatedClient, + +) -> Response[DatabaseUpgradeInfo]: + """ + Args: + account_id (str): + database_id (str): + + 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[DatabaseUpgradeInfo] + """ + + + kwargs = _get_kwargs( + account_id=account_id, +database_id=database_id, + + ) + + response = await client.get_async_httpx_client().request( + **kwargs + ) + + return _build_response(client=client, response=response) + +async def asyncio( + account_id: str, + database_id: str, + *, + client: AuthenticatedClient, + +) -> Optional[DatabaseUpgradeInfo]: + """ + Args: + account_id (str): + database_id (str): + + 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: + DatabaseUpgradeInfo + """ + + + return (await asyncio_detailed( + account_id=account_id, +database_id=database_id, +client=client, + + )).parsed diff --git a/exasol/saas/client/openapi/api/databases/set_auto_updates_database.py b/exasol/saas/client/openapi/api/databases/set_auto_updates_database.py index 0219714..ec2607b 100644 --- a/exasol/saas/client/openapi/api/databases/set_auto_updates_database.py +++ b/exasol/saas/client/openapi/api/databases/set_auto_updates_database.py @@ -36,7 +36,7 @@ def _get_kwargs( _kwargs: dict[str, Any] = { "method": "patch", - "url": "/api/v1/accounts/{account_id}/databases/{database_id}/database_settings".format(account_id=account_id,database_id=database_id,), + "url": "/api/v1/accounts/{account_id}/databases/{database_id}/settings".format(account_id=account_id,database_id=database_id,), } _body = body.to_dict() diff --git a/exasol/saas/client/openapi/models/__init__.py b/exasol/saas/client/openapi/models/__init__.py index de1f449..acf1a38 100644 --- a/exasol/saas/client/openapi/models/__init__.py +++ b/exasol/saas/client/openapi/models/__init__.py @@ -17,6 +17,7 @@ from .create_database_initial_cluster import CreateDatabaseInitialCluster from .create_extension_instance import CreateExtensionInstance from .database_settings import DatabaseSettings +from .database_upgrade_info import DatabaseUpgradeInfo from .download_file import DownloadFile from .exasol_database import ExasolDatabase from .exasol_database_clusters import ExasolDatabaseClusters @@ -70,6 +71,7 @@ "CreateDatabaseInitialCluster", "CreateExtensionInstance", "DatabaseSettings", + "DatabaseUpgradeInfo", "DownloadFile", "ExasolDatabase", "ExasolDatabaseClusters", diff --git a/exasol/saas/client/openapi/models/create_database.py b/exasol/saas/client/openapi/models/create_database.py index a9bc71f..7e39339 100644 --- a/exasol/saas/client/openapi/models/create_database.py +++ b/exasol/saas/client/openapi/models/create_database.py @@ -36,6 +36,7 @@ class CreateDatabase: provider (str): region (str): num_nodes (Union[Unset, int]): + stream_type (Union[Unset, str]): """ name: str @@ -43,6 +44,7 @@ class CreateDatabase: provider: str region: str num_nodes: Union[Unset, int] = UNSET + stream_type: Union[Unset, str] = UNSET additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) @@ -60,6 +62,8 @@ def to_dict(self) -> dict[str, Any]: num_nodes = self.num_nodes + stream_type = self.stream_type + field_dict: dict[str, Any] = {} field_dict.update(self.additional_properties) @@ -71,6 +75,8 @@ def to_dict(self) -> dict[str, Any]: }) if num_nodes is not UNSET: field_dict["numNodes"] = num_nodes + if stream_type is not UNSET: + field_dict["streamType"] = stream_type return field_dict @@ -95,12 +101,15 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: num_nodes = d.pop("numNodes", UNSET) + stream_type = d.pop("streamType", UNSET) + create_database = cls( name=name, initial_cluster=initial_cluster, provider=provider, region=region, num_nodes=num_nodes, + stream_type=stream_type, ) diff --git a/exasol/saas/client/openapi/models/database_settings.py b/exasol/saas/client/openapi/models/database_settings.py index 0996c19..827a953 100644 --- a/exasol/saas/client/openapi/models/database_settings.py +++ b/exasol/saas/client/openapi/models/database_settings.py @@ -26,12 +26,14 @@ class DatabaseSettings: auto_updates_enabled (bool): auto_updates_hard_disabled (bool): num_nodes (int): + stream_type (str): """ offload_enabled: bool auto_updates_enabled: bool auto_updates_hard_disabled: bool num_nodes: int + stream_type: str def to_dict(self) -> dict[str, Any]: @@ -43,6 +45,8 @@ def to_dict(self) -> dict[str, Any]: num_nodes = self.num_nodes + stream_type = self.stream_type + field_dict: dict[str, Any] = {} field_dict.update({ @@ -50,6 +54,7 @@ def to_dict(self) -> dict[str, Any]: "autoUpdatesEnabled": auto_updates_enabled, "autoUpdatesHardDisabled": auto_updates_hard_disabled, "numNodes": num_nodes, + "streamType": stream_type, }) return field_dict @@ -67,11 +72,14 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: num_nodes = d.pop("numNodes") + stream_type = d.pop("streamType") + database_settings = cls( offload_enabled=offload_enabled, auto_updates_enabled=auto_updates_enabled, auto_updates_hard_disabled=auto_updates_hard_disabled, num_nodes=num_nodes, + stream_type=stream_type, ) return database_settings diff --git a/exasol/saas/client/openapi/models/database_upgrade_info.py b/exasol/saas/client/openapi/models/database_upgrade_info.py new file mode 100644 index 0000000..bc331da --- /dev/null +++ b/exasol/saas/client/openapi/models/database_upgrade_info.py @@ -0,0 +1,89 @@ +from typing import ( + TYPE_CHECKING, + Any, + BinaryIO, + Optional, + TextIO, + TypeVar, +) + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +from ..types import ( + UNSET, + Unset, +) + +T = TypeVar("T", bound="DatabaseUpgradeInfo") + + +@_attrs_define +class DatabaseUpgradeInfo: + """ + Attributes: + current_version (str): + update_version (str): + update_possible (bool): + """ + + current_version: str + update_version: str + update_possible: bool + additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict) + + + def to_dict(self) -> dict[str, Any]: + current_version = self.current_version + + update_version = self.update_version + + update_possible = self.update_possible + + + field_dict: dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update({ + "currentVersion": current_version, + "updateVersion": update_version, + "updatePossible": update_possible, + }) + + return field_dict + + + + @classmethod + def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: + d = src_dict.copy() + current_version = d.pop("currentVersion") + + update_version = d.pop("updateVersion") + + update_possible = d.pop("updatePossible") + + database_upgrade_info = cls( + current_version=current_version, + update_version=update_version, + update_possible=update_possible, + ) + + + database_upgrade_info.additional_properties = d + return database_upgrade_info + + @property + def additional_keys(self) -> list[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/exasol/saas/client/openapi/models/exasol_database_settings.py b/exasol/saas/client/openapi/models/exasol_database_settings.py index 70f1c59..2d888c6 100644 --- a/exasol/saas/client/openapi/models/exasol_database_settings.py +++ b/exasol/saas/client/openapi/models/exasol_database_settings.py @@ -26,12 +26,14 @@ class ExasolDatabaseSettings: auto_updates_enabled (bool): auto_updates_hard_disabled (bool): num_nodes (int): + stream_type (str): """ offload_enabled: bool auto_updates_enabled: bool auto_updates_hard_disabled: bool num_nodes: int + stream_type: str def to_dict(self) -> dict[str, Any]: @@ -43,6 +45,8 @@ def to_dict(self) -> dict[str, Any]: num_nodes = self.num_nodes + stream_type = self.stream_type + field_dict: dict[str, Any] = {} field_dict.update({ @@ -50,6 +54,7 @@ def to_dict(self) -> dict[str, Any]: "autoUpdatesEnabled": auto_updates_enabled, "autoUpdatesHardDisabled": auto_updates_hard_disabled, "numNodes": num_nodes, + "streamType": stream_type, }) return field_dict @@ -67,11 +72,14 @@ def from_dict(cls: type[T], src_dict: dict[str, Any]) -> T: num_nodes = d.pop("numNodes") + stream_type = d.pop("streamType") + exasol_database_settings = cls( offload_enabled=offload_enabled, auto_updates_enabled=auto_updates_enabled, auto_updates_hard_disabled=auto_updates_hard_disabled, num_nodes=num_nodes, + stream_type=stream_type, ) return exasol_database_settings diff --git a/openapi.json b/openapi.json index 772cff7..d688fac 100644 --- a/openapi.json +++ b/openapi.json @@ -6,7 +6,7 @@ "version": "1.0", "download": { "source": "https://cloud.exasol.com/openapi.json", - "timestamp": "2025-02-27T08:23:39.416074+00:00" + "timestamp": "2025-04-04T11:27:52.781680+00:00" } }, "servers": [ @@ -1277,7 +1277,7 @@ ] } }, - "/api/v1/accounts/{accountId}/databases/{databaseId}/database_settings": { + "/api/v1/accounts/{accountId}/databases/{databaseId}/settings": { "get": { "operationId": "GetDatabaseSettings", "responses": { @@ -1384,16 +1384,16 @@ } } }, - "/api/v1/accounts/{accountId}/databases": { - "post": { - "operationId": "CreateDatabase", + "/api/v1/accounts/{accountId}/databases/{databaseId}/upgrade": { + "get": { + "operationId": "GetDatabaseUpgradeInfo", "responses": { "200": { - "description": "A database", + "description": "A database upgrade info", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Database" + "$ref": "#/components/schemas/DatabaseUpgradeInfo" } } } @@ -1420,39 +1420,27 @@ "schema": { "type": "string" } + }, + { + "in": "path", + "required": true, + "name": "databaseId", + "schema": { + "type": "string" + } } ], "security": [ { "authorizer": [] } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateDatabase" - } - } - }, - "required": true - } + ] }, - "get": { - "operationId": "ListDatabases", + "put": { + "operationId": "UpgradeDatabase", "responses": { - "200": { - "description": "List of databases the user has access to", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Database" - } - } - } - } + "204": { + "description": "No content" }, "default": { "description": "Default api error", @@ -1476,6 +1464,14 @@ "schema": { "type": "string" } + }, + { + "in": "path", + "required": true, + "name": "databaseId", + "schema": { + "type": "string" + } } ], "security": [ @@ -1485,12 +1481,19 @@ ] } }, - "/api/v1/accounts/{accountId}/databases/{databaseId}/start": { - "put": { - "operationId": "StartDatabase", + "/api/v1/accounts/{accountId}/databases": { + "post": { + "operationId": "CreateDatabase", "responses": { - "204": { - "description": "No content" + "200": { + "description": "A database", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Database" + } + } + } }, "default": { "description": "Default api error", @@ -1514,11 +1517,59 @@ "schema": { "type": "string" } + } + ], + "security": [ + { + "authorizer": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateDatabase" + } + } }, + "required": true + } + }, + "get": { + "operationId": "ListDatabases", + "responses": { + "200": { + "description": "List of databases the user has access to", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Database" + } + } + } + } + }, + "default": { + "description": "Default api error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiError" + } + } + } + } + }, + "tags": [ + "Databases" + ], + "parameters": [ { "in": "path", "required": true, - "name": "databaseId", + "name": "accountId", "schema": { "type": "string" } @@ -1531,9 +1582,9 @@ ] } }, - "/api/v1/accounts/{accountId}/databases/{databaseId}/stop": { + "/api/v1/accounts/{accountId}/databases/{databaseId}/start": { "put": { - "operationId": "StopDatabase", + "operationId": "StartDatabase", "responses": { "204": { "description": "No content" @@ -1577,9 +1628,9 @@ ] } }, - "/api/v1/accounts/{accountId}/databases/{databaseId}/upgrade": { + "/api/v1/accounts/{accountId}/databases/{databaseId}/stop": { "put": { - "operationId": "UpgradeDatabase", + "operationId": "StopDatabase", "responses": { "204": { "description": "No content" @@ -3134,6 +3185,9 @@ }, "numNodes": { "type": "integer" + }, + "streamType": { + "type": "string" } }, "additionalProperties": true, @@ -3223,7 +3277,8 @@ "offloadEnabled", "autoUpdatesEnabled", "autoUpdatesHardDisabled", - "numNodes" + "numNodes", + "streamType" ], "properties": { "offloadEnabled": { @@ -3237,6 +3292,9 @@ }, "numNodes": { "type": "integer" + }, + "streamType": { + "type": "string" } }, "additionalProperties": false, @@ -3250,7 +3308,8 @@ "offloadEnabled", "autoUpdatesEnabled", "autoUpdatesHardDisabled", - "numNodes" + "numNodes", + "streamType" ], "properties": { "offloadEnabled": { @@ -3264,11 +3323,33 @@ }, "numNodes": { "type": "integer" + }, + "streamType": { + "type": "string" } }, "additionalProperties": false, "type": "object" }, + "DatabaseUpgradeInfo": { + "required": [ + "currentVersion", + "updateVersion", + "updatePossible" + ], + "properties": { + "currentVersion": { + "type": "string" + }, + "updateVersion": { + "type": "string" + }, + "updatePossible": { + "type": "boolean" + } + }, + "type": "object" + }, "DownloadFile": { "required": [ "url" diff --git a/poetry.lock b/poetry.lock index 0d568d0..086e4f3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -79,21 +79,21 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} [[package]] name = "attrs" -version = "25.1.0" +version = "25.3.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.8" groups = ["main", "dev"] files = [ - {file = "attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a"}, - {file = "attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e"}, + {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, + {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, ] [package.extras] benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"] cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit-uv", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] -docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"] diff --git a/pyproject.toml b/pyproject.toml index 0af48b2..d7c8486 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "exasol-saas-api" -version = "1.0.0" +version = "1.1.0" description = "API enabling Python applications connecting to Exasol database SaaS instances and using their SaaS services" packages = [ {include = "exasol"}, ] authors = [ "Christoph Kuhnke " ] diff --git a/version.py b/version.py index 5ee60e1..84b9409 100644 --- a/version.py +++ b/version.py @@ -5,7 +5,7 @@ # Do not edit this file manually! # If you need to change the version, do so in the project.toml, e.g. by using `poetry version X.Y.Z`. MAJOR = 1 -MINOR = 0 +MINOR = 1 PATCH = 0 VERSION = f"{MAJOR}.{MINOR}.{PATCH}" __version__ = VERSION