diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES
index d8d632e..1681899 100644
--- a/.openapi-generator/FILES
+++ b/.openapi-generator/FILES
@@ -313,14 +313,4 @@ requirements.txt
setup.cfg
test-requirements.txt
test/__init__.py
-test/test_attach_database_catalog_request.py
-test/test_create_database_request.py
-test/test_create_database_response.py
-test/test_database_attachment_info.py
-test/test_database_default_schema_decl.py
-test/test_database_default_table_decl.py
-test/test_database_detail_response.py
-test/test_database_summary.py
-test/test_databases_api.py
-test/test_list_databases_response.py
tox.ini
diff --git a/docs/ConnectionTypeDetail.md b/docs/ConnectionTypeDetail.md
index b98ce11..de627ec 100644
--- a/docs/ConnectionTypeDetail.md
+++ b/docs/ConnectionTypeDetail.md
@@ -1,5 +1,6 @@
# ConnectionTypeDetail
+Detailed configuration and authentication schema for a single connection type.
## Properties
diff --git a/docs/ConnectionTypeSummary.md b/docs/ConnectionTypeSummary.md
index 5d15589..ba7dab9 100644
--- a/docs/ConnectionTypeSummary.md
+++ b/docs/ConnectionTypeSummary.md
@@ -1,5 +1,6 @@
# ConnectionTypeSummary
+Summary entry for the connection-type list endpoint.
## Properties
diff --git a/docs/ConnectionsApi.md b/docs/ConnectionsApi.md
index a633983..0f98f18 100644
--- a/docs/ConnectionsApi.md
+++ b/docs/ConnectionsApi.md
@@ -270,7 +270,7 @@ void (empty response body)
|-------------|-------------|------------------|
**204** | Connection deleted | - |
**404** | Connection not found | - |
-**409** | Connection backs a database's default catalog and cannot be deleted directly | - |
+**409** | Connection backs a database's default catalog, or is attached to one or more databases as a non-default catalog; detach via DELETE /v1/databases/{database_id}/catalogs/{connection_id} first | - |
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
diff --git a/docs/CreateDatabaseRequest.md b/docs/CreateDatabaseRequest.md
index 460707d..4bbcb75 100644
--- a/docs/CreateDatabaseRequest.md
+++ b/docs/CreateDatabaseRequest.md
@@ -7,6 +7,7 @@ Request body for POST /databases
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**description** | **str** | Optional free-form display label (for UIs/CLIs). Not unique. Not an identifier — databases are always addressed by `id`. | [optional]
+**expires_at** | **str** | When this database expires. Accepts either an RFC 3339 timestamp (e.g. `\"2026-06-01T00:00:00Z\"`) or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days) — for example `\"24h\"`, `\"48h\"`, or `\"7d\"`. Defaults to `\"24h\"` when omitted. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp. | [optional]
**schemas** | [**List[DatabaseDefaultSchemaDecl]**](DatabaseDefaultSchemaDecl.md) | Optional schemas/tables to declare on the database's auto-created `default` catalog. Mirrors the `config.schemas` field of a managed `POST /v1/connections`. Tables declared here can be loaded via the standard managed-table load endpoint targeting `default_connection_id`. Omitted or empty means the default catalog starts empty. | [optional]
## Example
diff --git a/docs/CreateDatabaseResponse.md b/docs/CreateDatabaseResponse.md
index 183ec27..82f03c3 100644
--- a/docs/CreateDatabaseResponse.md
+++ b/docs/CreateDatabaseResponse.md
@@ -8,6 +8,7 @@ Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**default_connection_id** | **str** | Internal id of the connection that backs this database's `default` catalog. Workspace-level connection endpoints (list, get, health, delete, cache purge) refuse to act on this id — it is exposed only for the managed-tables load endpoint (`POST /v1/connections/{id}/schemas/{s}/tables/{t}/loads`) so callers can publish parquet into tables declared at database-create time. Addressing it directly in SQL is not the recommended path — use `default` inside an `X-Database-Id` scope instead. |
**description** | **str** | | [optional]
+**expires_at** | **datetime** | When this database expires. | [optional]
**id** | **str** | |
## Example
diff --git a/docs/DatabaseDetailResponse.md b/docs/DatabaseDetailResponse.md
index 7fb562b..f2699cb 100644
--- a/docs/DatabaseDetailResponse.md
+++ b/docs/DatabaseDetailResponse.md
@@ -9,6 +9,7 @@ Name | Type | Description | Notes
**attachments** | [**List[DatabaseAttachmentInfo]**](DatabaseAttachmentInfo.md) | |
**default_connection_id** | **str** | |
**description** | **str** | | [optional]
+**expires_at** | **datetime** | When this database expires. | [optional]
**id** | **str** | |
## Example
diff --git a/docs/DatabaseSummary.md b/docs/DatabaseSummary.md
index c754a17..83395f0 100644
--- a/docs/DatabaseSummary.md
+++ b/docs/DatabaseSummary.md
@@ -7,6 +7,7 @@ Summary item in GET /databases
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**description** | **str** | | [optional]
+**expires_at** | **datetime** | | [optional]
**id** | **str** | |
## Example
diff --git a/docs/DatabasesApi.md b/docs/DatabasesApi.md
index 1a8ee17..cdb854d 100644
--- a/docs/DatabasesApi.md
+++ b/docs/DatabasesApi.md
@@ -105,7 +105,7 @@ void (empty response body)
Create database
-Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`. The optional `description` is a free-form display label and is not required to be unique. Optional `schemas` declares schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`.
+Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`, with a `main` schema pre-declared so `default.main.
` works out of the box. The optional `description` is a free-form display label and is not required to be unique. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. Defaults to `24h` when omitted. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp.
### Example
diff --git a/docs/ListConnectionTypesResponse.md b/docs/ListConnectionTypesResponse.md
index 30ec854..d841c94 100644
--- a/docs/ListConnectionTypesResponse.md
+++ b/docs/ListConnectionTypesResponse.md
@@ -1,5 +1,6 @@
# ListConnectionTypesResponse
+Envelope for the connection-types list response.
## Properties
diff --git a/hotdata/api/databases_api.py b/hotdata/api/databases_api.py
index 1d25d42..15315bb 100644
--- a/hotdata/api/databases_api.py
+++ b/hotdata/api/databases_api.py
@@ -360,7 +360,7 @@ def create_database(
) -> CreateDatabaseResponse:
"""Create database
- Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`. The optional `description` is a free-form display label and is not required to be unique. Optional `schemas` declares schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`.
+ Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`, with a `main` schema pre-declared so `default.main.` works out of the box. The optional `description` is a free-form display label and is not required to be unique. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. Defaults to `24h` when omitted. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp.
:param create_database_request: (required)
:type create_database_request: CreateDatabaseRequest
@@ -429,7 +429,7 @@ def create_database_with_http_info(
) -> ApiResponse[CreateDatabaseResponse]:
"""Create database
- Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`. The optional `description` is a free-form display label and is not required to be unique. Optional `schemas` declares schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`.
+ Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`, with a `main` schema pre-declared so `default.main.` works out of the box. The optional `description` is a free-form display label and is not required to be unique. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. Defaults to `24h` when omitted. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp.
:param create_database_request: (required)
:type create_database_request: CreateDatabaseRequest
@@ -498,7 +498,7 @@ def create_database_without_preload_content(
) -> RESTResponseType:
"""Create database
- Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`. The optional `description` is a free-form display label and is not required to be unique. Optional `schemas` declares schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`.
+ Create a new database (a metadata-only grouping). A managed default catalog is auto-created and addressable inside the database as `default`, with a `main` schema pre-declared so `default.main.` works out of the box. The optional `description` is a free-form display label and is not required to be unique. Optional `schemas` declares additional schemas/tables on the default catalog at create time; declared tables can be loaded via the standard managed-tables-load endpoint targeting `default_connection_id`. Optional `expires_at` sets when the database expires — accepts either an RFC 3339 timestamp or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days), e.g. `24h`, `48h`, `90m`, `7d`. Defaults to `24h` when omitted. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp.
:param create_database_request: (required)
:type create_database_request: CreateDatabaseRequest
diff --git a/hotdata/models/connection_type_detail.py b/hotdata/models/connection_type_detail.py
index 9c3cdea..78fb178 100644
--- a/hotdata/models/connection_type_detail.py
+++ b/hotdata/models/connection_type_detail.py
@@ -25,7 +25,7 @@
class ConnectionTypeDetail(BaseModel):
"""
- ConnectionTypeDetail
+ Detailed configuration and authentication schema for a single connection type.
""" # noqa: E501
auth: Optional[Any] = None
config_schema: Optional[Any] = None
diff --git a/hotdata/models/connection_type_summary.py b/hotdata/models/connection_type_summary.py
index 67bdb12..e1e5909 100644
--- a/hotdata/models/connection_type_summary.py
+++ b/hotdata/models/connection_type_summary.py
@@ -25,7 +25,7 @@
class ConnectionTypeSummary(BaseModel):
"""
- ConnectionTypeSummary
+ Summary entry for the connection-type list endpoint.
""" # noqa: E501
label: StrictStr
name: StrictStr
diff --git a/hotdata/models/create_database_request.py b/hotdata/models/create_database_request.py
index 65ab961..001c98e 100644
--- a/hotdata/models/create_database_request.py
+++ b/hotdata/models/create_database_request.py
@@ -29,8 +29,9 @@ class CreateDatabaseRequest(BaseModel):
Request body for POST /databases
""" # noqa: E501
description: Optional[StrictStr] = Field(default=None, description="Optional free-form display label (for UIs/CLIs). Not unique. Not an identifier — databases are always addressed by `id`.")
+ expires_at: Optional[StrictStr] = Field(default=None, description="When this database expires. Accepts either an RFC 3339 timestamp (e.g. `\"2026-06-01T00:00:00Z\"`) or a relative duration suffixed with `h` (hours), `m` (minutes), or `d` (days) — for example `\"24h\"`, `\"48h\"`, or `\"7d\"`. Defaults to `\"24h\"` when omitted. Expiry is best-effort: the database will not be deleted before `expires_at`, but cleanup may run later than the exact timestamp.")
schemas: Optional[List[DatabaseDefaultSchemaDecl]] = Field(default=None, description="Optional schemas/tables to declare on the database's auto-created `default` catalog. Mirrors the `config.schemas` field of a managed `POST /v1/connections`. Tables declared here can be loaded via the standard managed-table load endpoint targeting `default_connection_id`. Omitted or empty means the default catalog starts empty.")
- __properties: ClassVar[List[str]] = ["description", "schemas"]
+ __properties: ClassVar[List[str]] = ["description", "expires_at", "schemas"]
model_config = ConfigDict(
populate_by_name=True,
@@ -83,6 +84,11 @@ def to_dict(self) -> Dict[str, Any]:
if self.description is None and "description" in self.model_fields_set:
_dict['description'] = None
+ # set to None if expires_at (nullable) is None
+ # and model_fields_set contains the field
+ if self.expires_at is None and "expires_at" in self.model_fields_set:
+ _dict['expires_at'] = None
+
return _dict
@classmethod
@@ -96,6 +102,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
_obj = cls.model_validate({
"description": obj.get("description"),
+ "expires_at": obj.get("expires_at"),
"schemas": [DatabaseDefaultSchemaDecl.from_dict(_item) for _item in obj["schemas"]] if obj.get("schemas") is not None else None
})
return _obj
diff --git a/hotdata/models/create_database_response.py b/hotdata/models/create_database_response.py
index 5601ad4..62422ee 100644
--- a/hotdata/models/create_database_response.py
+++ b/hotdata/models/create_database_response.py
@@ -18,6 +18,7 @@
import re # noqa: F401
import json
+from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from typing import Optional, Set
@@ -29,8 +30,9 @@ class CreateDatabaseResponse(BaseModel):
""" # noqa: E501
default_connection_id: StrictStr = Field(description="Internal id of the connection that backs this database's `default` catalog. Workspace-level connection endpoints (list, get, health, delete, cache purge) refuse to act on this id — it is exposed only for the managed-tables load endpoint (`POST /v1/connections/{id}/schemas/{s}/tables/{t}/loads`) so callers can publish parquet into tables declared at database-create time. Addressing it directly in SQL is not the recommended path — use `default` inside an `X-Database-Id` scope instead.")
description: Optional[StrictStr] = None
+ expires_at: Optional[datetime] = Field(default=None, description="When this database expires.")
id: StrictStr
- __properties: ClassVar[List[str]] = ["default_connection_id", "description", "id"]
+ __properties: ClassVar[List[str]] = ["default_connection_id", "description", "expires_at", "id"]
model_config = ConfigDict(
populate_by_name=True,
@@ -76,6 +78,11 @@ def to_dict(self) -> Dict[str, Any]:
if self.description is None and "description" in self.model_fields_set:
_dict['description'] = None
+ # set to None if expires_at (nullable) is None
+ # and model_fields_set contains the field
+ if self.expires_at is None and "expires_at" in self.model_fields_set:
+ _dict['expires_at'] = None
+
return _dict
@classmethod
@@ -90,6 +97,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
_obj = cls.model_validate({
"default_connection_id": obj.get("default_connection_id"),
"description": obj.get("description"),
+ "expires_at": obj.get("expires_at"),
"id": obj.get("id")
})
return _obj
diff --git a/hotdata/models/database_detail_response.py b/hotdata/models/database_detail_response.py
index 94a8419..5ad9bf7 100644
--- a/hotdata/models/database_detail_response.py
+++ b/hotdata/models/database_detail_response.py
@@ -18,7 +18,8 @@
import re # noqa: F401
import json
-from pydantic import BaseModel, ConfigDict, StrictStr
+from datetime import datetime
+from pydantic import BaseModel, ConfigDict, Field, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from hotdata.models.database_attachment_info import DatabaseAttachmentInfo
from typing import Optional, Set
@@ -31,8 +32,9 @@ class DatabaseDetailResponse(BaseModel):
attachments: List[DatabaseAttachmentInfo]
default_connection_id: StrictStr
description: Optional[StrictStr] = None
+ expires_at: Optional[datetime] = Field(default=None, description="When this database expires.")
id: StrictStr
- __properties: ClassVar[List[str]] = ["attachments", "default_connection_id", "description", "id"]
+ __properties: ClassVar[List[str]] = ["attachments", "default_connection_id", "description", "expires_at", "id"]
model_config = ConfigDict(
populate_by_name=True,
@@ -85,6 +87,11 @@ def to_dict(self) -> Dict[str, Any]:
if self.description is None and "description" in self.model_fields_set:
_dict['description'] = None
+ # set to None if expires_at (nullable) is None
+ # and model_fields_set contains the field
+ if self.expires_at is None and "expires_at" in self.model_fields_set:
+ _dict['expires_at'] = None
+
return _dict
@classmethod
@@ -100,6 +107,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
"attachments": [DatabaseAttachmentInfo.from_dict(_item) for _item in obj["attachments"]] if obj.get("attachments") is not None else None,
"default_connection_id": obj.get("default_connection_id"),
"description": obj.get("description"),
+ "expires_at": obj.get("expires_at"),
"id": obj.get("id")
})
return _obj
diff --git a/hotdata/models/database_summary.py b/hotdata/models/database_summary.py
index 06b20bf..bc29cde 100644
--- a/hotdata/models/database_summary.py
+++ b/hotdata/models/database_summary.py
@@ -18,6 +18,7 @@
import re # noqa: F401
import json
+from datetime import datetime
from pydantic import BaseModel, ConfigDict, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from typing import Optional, Set
@@ -28,8 +29,9 @@ class DatabaseSummary(BaseModel):
Summary item in GET /databases
""" # noqa: E501
description: Optional[StrictStr] = None
+ expires_at: Optional[datetime] = None
id: StrictStr
- __properties: ClassVar[List[str]] = ["description", "id"]
+ __properties: ClassVar[List[str]] = ["description", "expires_at", "id"]
model_config = ConfigDict(
populate_by_name=True,
@@ -75,6 +77,11 @@ def to_dict(self) -> Dict[str, Any]:
if self.description is None and "description" in self.model_fields_set:
_dict['description'] = None
+ # set to None if expires_at (nullable) is None
+ # and model_fields_set contains the field
+ if self.expires_at is None and "expires_at" in self.model_fields_set:
+ _dict['expires_at'] = None
+
return _dict
@classmethod
@@ -88,6 +95,7 @@ def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
_obj = cls.model_validate({
"description": obj.get("description"),
+ "expires_at": obj.get("expires_at"),
"id": obj.get("id")
})
return _obj
diff --git a/hotdata/models/list_connection_types_response.py b/hotdata/models/list_connection_types_response.py
index cfe67ba..3125356 100644
--- a/hotdata/models/list_connection_types_response.py
+++ b/hotdata/models/list_connection_types_response.py
@@ -26,7 +26,7 @@
class ListConnectionTypesResponse(BaseModel):
"""
- ListConnectionTypesResponse
+ Envelope for the connection-types list response.
""" # noqa: E501
connection_types: List[ConnectionTypeSummary]
__properties: ClassVar[List[str]] = ["connection_types"]