Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5fa2b5a
Events endpoint
c-thiel May 7, 2025
9f9898c
Address comments
c-thiel May 7, 2025
f1e25fe
revert format changes
c-thiel May 7, 2025
4d67051
rename transaction to request-id, Custom Operations, Actors
c-thiel May 7, 2025
1c36850
remove "assumed-by" recursion in favor of "actor-chain"
c-thiel May 27, 2025
5cfce4a
fix indentation
c-thiel May 27, 2025
86a0f5a
fix remove copy
c-thiel May 27, 2025
3de9a7c
address comments
c-thiel May 28, 2025
c54125d
Address comments
c-thiel Jul 1, 2025
0e8ff9b
fix: remove obsolete `metadata` from required
c-thiel Jul 9, 2025
c944d65
Address Comments
c-thiel Jul 15, 2025
d62d6d6
separate `RenameViewOperation` and `RenameTableOperation` for generators
c-thiel Jul 17, 2025
77b774c
introduce CatalogObject, add updates to Create & Register
c-thiel Aug 12, 2025
5e6d200
address comments
c-thiel Dec 3, 2025
df4a4fd
address comments
c-thiel Dec 4, 2025
178ed3e
page-token -> continuation-token
c-thiel Dec 6, 2025
72318fd
Merge branch 'main' into ct/irc-events-endpoint
c-thiel Dec 6, 2025
492d555
make linter happier
c-thiel Dec 6, 2025
c73e200
fix: OperationType enum type
c-thiel Dec 6, 2025
c9fa451
make linter happy
c-thiel Dec 6, 2025
7f17a42
fix: QueryEventsRequest allow JSON values for custom filters
c-thiel Dec 6, 2025
2f9b4db
fix: request-event-count ename, fix duplicate namespace in CreateName…
c-thiel Dec 6, 2025
3eeb95e
make actor type object
c-thiel Dec 6, 2025
58f1dfc
address comments
c-thiel Dec 9, 2025
5f15acf
rename next-page-token to continuation-token
c-thiel May 20, 2026
86c8b89
Merge remote-tracking branch 'origin/main' into ct/irc-events-endpoint
c-thiel May 20, 2026
0d7059d
rename catalog-objects-by-id to catalog-objects-by-uuid
c-thiel May 20, 2026
9ce7b96
fix typo, update generator
c-thiel May 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
266 changes: 266 additions & 0 deletions open-api/rest-catalog-open-api.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,14 @@ class EnableRowLineageUpdate(BaseUpdate):
action: str = Field('enable-row-lineage', const=True)


class CustomOperationType(BaseModel):
__root__: str = Field(
...,
description="Custom operation type for catalog-specific extensions. Must start with 'x-' followed by an implementation-specific identifier.\n",
regex='^x-[a-zA-Z0-9-_.]+$',
)


class TableRequirement(BaseModel):
type: str

Expand Down Expand Up @@ -504,6 +512,40 @@ class PlanStatus(BaseModel):
)


class Actor(BaseModel):
"""
Represents an actor that performed operations in the catalog
"""

type: str = Field(
..., description='The type of actor (e.g., "user", "principal", "role")'
)
actor_id: str = Field(
..., alias='actor-id', description='The identifier of the actor'
)
metadata: Optional[Dict[str, str]] = Field(
None,
description='Additional metadata about the actor that may vary between implementations',
)


class NamespaceReference(BaseModel):
reference_type: str = Field('namespace', alias='reference-type', const=True)
namespace: Namespace


class TableReference(BaseModel):
reference_type: str = Field('table', alias='reference-type', const=True)
identifier: TableIdentifier
table_uuid: UUID = Field(..., alias='table-uuid')


class ViewReference(BaseModel):
reference_type: str = Field('view', alias='reference-type', const=True)
identifier: TableIdentifier
view_uuid: UUID = Field(..., alias='view-uuid')


class RegisterTableRequest(BaseModel):
name: str
metadata_location: str = Field(..., alias='metadata-location')
Expand Down Expand Up @@ -699,6 +741,36 @@ class UpdateNamespacePropertiesResponse(BaseModel):
)


class CustomOperation(BaseModel):
"""
Extension point for catalog-specific operations not defined in the standard.

"""

class Config:
extra = Extra.allow

operation_type: Literal['custom'] = Field(..., alias='operation-type', const=True)
custom_type: CustomOperationType = Field(..., alias='custom-type')
identifier: Optional[TableIdentifier] = Field(
None,
description='Table or view identifier this operation applies to, if applicable',
)
namespace: Optional[Namespace] = Field(
None, description='Namespace this operation applies to, if applicable'
)
table_uuid: Optional[UUID] = Field(
None,
alias='table-uuid',
description='UUID of table this operation applies to, if applicable',
)
view_uuid: Optional[UUID] = Field(
None,
alias='view-uuid',
description='UUID of view this operation applies to, if applicable',
)


class BlobMetadata(BaseModel):
type: str
snapshot_id: int = Field(..., alias='snapshot-id')
Expand Down Expand Up @@ -941,6 +1013,29 @@ class SetPartitionStatisticsUpdate(BaseUpdate):
)


class OperationType(BaseModel):
__root__: Union[
Literal[
'create-table',
'register-table',
'drop-table',
'update-table',
'rename-table',
'create-view',
'drop-view',
'replace-view',
'rename-view',
'create-namespace',
'update-namespace-properties',
'drop-namespace',
],
CustomOperationType,
] = Field(
...,
description='Defines the type of operation, either a standard operation defined by the Iceberg REST API specification or a custom operation specific to an implementation.\n',
)


class ViewRequirement(BaseModel):
__root__: AssertViewUUID = Field(..., discriminator='type')

Expand Down Expand Up @@ -968,10 +1063,84 @@ class EmptyPlanningResult(BaseModel):
status: Literal['cancelled']


class GetEventsRequest(BaseModel):
next_page_token: Optional[PageToken] = Field(None, alias='next-page-token')
page_size: Optional[int] = Field(
None,
alias='page-size',
description='The maximum number of events to return in a single response. If not provided, the server may choose a default page size.\n',
)
after_timestamp_ms: Optional[int] = Field(
None,
alias='after-timestamp-ms',
description='The (server) timestamp in milliseconds to start consuming events from (inclusive). If not provided, the first available timestamp is used.\n',
)
operation_types: Optional[List[OperationType]] = Field(
None,
alias='operation-types',
description='Filter events by the type of operation. If not provided, all types are returned.\n',
)
actors: Optional[List[Actor]] = Field(
None, description='Filter events by actors who performed them.\n'
)
catalog_objects: Optional[
List[Union[NamespaceReference, TableReference, ViewReference]]
] = Field(
None,
alias='catalog-objects',
description='List of catalog objects (namespaces, tables, views) to get events for. If not provided, events for all objects will be returned subject to other filters. For specified namespaces, events for the namespaces and all containing objects (namespaces, tables, views) will be returned.\n',
discriminator='reference_type',
)


class ReportMetricsRequest2(CommitReport):
report_type: str = Field(..., alias='report-type')


class DropTableOperation(BaseModel):
operation_type: Literal['drop-table'] = Field(
..., alias='operation-type', const=True
)
identifier: TableIdentifier
table_uuid: UUID = Field(..., alias='table-uuid')
purge: Optional[bool] = Field(None, description='Whether purge flag was set')


class RenameTableOperation(RenameTableRequest):
operation_type: Literal['rename-table', 'rename-view'] = Field(
..., alias='operation-type', const=True
)
table_uuid: UUID = Field(..., alias='table-uuid')


class DropViewOperation(BaseModel):
operation_type: Literal['drop-view'] = Field(
..., alias='operation-type', const=True
)
identifier: TableIdentifier
view_uuid: UUID = Field(..., alias='view-uuid')


class CreateNamespaceOperation(CreateNamespaceResponse):
operation_type: Literal['create-namespace'] = Field(
..., alias='operation-type', const=True
)


class UpdateNamespacePropertiesOperation(UpdateNamespacePropertiesResponse):
operation_type: Literal['update-namespace-properties'] = Field(
..., alias='operation-type', const=True
)
namespace: Namespace


class DropNamespaceOperation(BaseModel):
operation_type: Literal['drop-namespace'] = Field(
..., alias='operation-type', const=True
)
namespace: Namespace


class StatisticsFile(BaseModel):
snapshot_id: int = Field(..., alias='snapshot-id')
statistics_path: str = Field(..., alias='statistics-path')
Expand Down Expand Up @@ -1389,6 +1558,101 @@ class CommitTableResponse(BaseModel):
metadata: TableMetadata


class EventsResponse(BaseModel):
next_page_token: Optional[PageToken] = Field(None, alias='next-page-token')
highest_processed_timestamp_ms: int = Field(
...,
alias='highest-processed-timestamp-ms',
description='The highest timestamp processed by the server when generating this response. This may not necessarily appear in the returned changes if it was filtered out.\nClients can use this value as the `after-timestamp-ms` parameter in subsequent requests to continue retrieving changes after this point.\n',
)
events: List[Event]


class Event(BaseModel):
event_id: str = Field(
...,
alias='event-id',
description='Unique ID of this event. Clients should perform deduplication based on this ID.',
)
request_id: str = Field(
..., alias='request-id', description='ID of the request this change belongs to.'
)
event_count: int = Field(
...,
alias='event-count',
description='Number of events in the request / batch of events',
)
timestamp_ms: int = Field(
...,
alias='timestamp-ms',
description='Timestamp when this transaction occurred (epoch milliseconds). Timestamps are not guaranteed to be unique. Typically all events in a transaction will have the same timestamp.\n',
)
actor_chain: Optional[List[Actor]] = Field(
None,
alias='actor-chain',
description='An ordered list of actors involved in the operation, with the most direct actor (the one who actually performed the operation) first, followed by delegating actors in order. For example, if a service account (actor[0]) performed an operation on behalf of a role (actor[1]) assumed by a user (actor[2]), the chain represents this delegation path.\n',
)
operation: Union[
CreateTableOperation,
RegisterTableOperation,
DropTableOperation,
UpdateTableOperation,
RenameTableOperation,
CreateViewOperation,
DropViewOperation,
ReplaceViewOperation,
CreateNamespaceOperation,
UpdateNamespacePropertiesOperation,
DropNamespaceOperation,
CustomOperation,
] = Field(..., discriminator='operation_type')


class CreateTableOperation(BaseModel):
operation_type: Literal['create-table'] = Field(
..., alias='operation-type', const=True
)
identifier: TableIdentifier
table_uuid: UUID = Field(..., alias='table-uuid')
metadata: TableMetadata


class RegisterTableOperation(BaseModel):
operation_type: Literal['register-table'] = Field(
..., alias='operation-type', const=True
)
identifier: TableIdentifier
table_uuid: UUID = Field(..., alias='table-uuid')
metadata: TableMetadata
Comment thread
c-thiel marked this conversation as resolved.
Outdated


class UpdateTableOperation(BaseModel):
operation_type: Literal['update-table'] = Field(
..., alias='operation-type', const=True
)
identifier: TableIdentifier
table_uuid: UUID = Field(..., alias='table-uuid')
updates: List[TableUpdate]


class CreateViewOperation(BaseModel):
operation_type: Literal['create-view'] = Field(
..., alias='operation-type', const=True
)
identifier: TableIdentifier
view_uuid: UUID = Field(..., alias='view-uuid')
metadata: ViewMetadata


class ReplaceViewOperation(BaseModel):
operation_type: Literal['replace-view'] = Field(
..., alias='operation-type', const=True
)
identifier: TableIdentifier
view_uuid: UUID = Field(..., alias='view-uuid')
updates: List[ViewUpdate]


class PlanTableScanRequest(BaseModel):
snapshot_id: Optional[int] = Field(
None,
Expand Down Expand Up @@ -1487,6 +1751,8 @@ class CompletedPlanningWithIDResult(CompletedPlanningResult):
CreateTableRequest.update_forward_refs()
CreateViewRequest.update_forward_refs()
ReportMetricsRequest.update_forward_refs()
EventsResponse.update_forward_refs()
Event.update_forward_refs()
CompletedPlanningResult.update_forward_refs()
FetchScanTasksResult.update_forward_refs()
CompletedPlanningWithIDResult.update_forward_refs()
Loading