diff --git a/.stats.yml b/.stats.yml
index d2bb80362..dde18a709 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 1993
+configured_endpoints: 1995
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/cloudflare%2Fcloudflare-28b84a5db03b38290dfe7ef1de2c68feb68762d7a8f207bdbea4d39a7aeef1ea.yml
openapi_spec_hash: ba6bd61621e4be20b581f4f3bf0978d3
-config_hash: 316e765ff117ffcf8ecf5a3187c184b1
+config_hash: 605c16e61b71b1e41175315ae4fcc6c0
diff --git a/api.md b/api.md
index 0c76d5b8d..77df8ee7a 100644
--- a/api.md
+++ b/api.md
@@ -5064,16 +5064,29 @@ from cloudflare.types.d1 import (
Methods:
-- client.d1.database.create(\*, account_id, \*\*params) -> D1
-- client.d1.database.update(database_id, \*, account_id, \*\*params) -> D1
-- client.d1.database.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[DatabaseListResponse]
-- client.d1.database.delete(database_id, \*, account_id) -> object
-- client.d1.database.edit(database_id, \*, account_id, \*\*params) -> D1
-- client.d1.database.export(database_id, \*, account_id, \*\*params) -> DatabaseExportResponse
-- client.d1.database.get(database_id, \*, account_id) -> D1
-- client.d1.database.import\_(database_id, \*, account_id, \*\*params) -> DatabaseImportResponse
-- client.d1.database.query(database_id, \*, account_id, \*\*params) -> SyncSinglePage[QueryResult]
-- client.d1.database.raw(database_id, \*, account_id, \*\*params) -> SyncSinglePage[DatabaseRawResponse]
+- client.d1.database.create(\*, account_id, \*\*params) -> D1
+- client.d1.database.update(database_id, \*, account_id, \*\*params) -> D1
+- client.d1.database.list(\*, account_id, \*\*params) -> SyncV4PagePaginationArray[DatabaseListResponse]
+- client.d1.database.delete(database_id, \*, account_id) -> object
+- client.d1.database.edit(database_id, \*, account_id, \*\*params) -> D1
+- client.d1.database.export(database_id, \*, account_id, \*\*params) -> DatabaseExportResponse
+- client.d1.database.get(database_id, \*, account_id) -> D1
+- client.d1.database.import\_(database_id, \*, account_id, \*\*params) -> DatabaseImportResponse
+- client.d1.database.query(database_id, \*, account_id, \*\*params) -> SyncSinglePage[QueryResult]
+- client.d1.database.raw(database_id, \*, account_id, \*\*params) -> SyncSinglePage[DatabaseRawResponse]
+
+### TimeTravel
+
+Types:
+
+```python
+from cloudflare.types.d1.database import TimeTravelGetBookmarkResponse, TimeTravelRestoreResponse
+```
+
+Methods:
+
+- client.d1.database.time_travel.get_bookmark(database_id, \*, account_id, \*\*params) -> TimeTravelGetBookmarkResponse
+- client.d1.database.time_travel.restore(database_id, \*, account_id, \*\*params) -> TimeTravelRestoreResponse
# R2
diff --git a/src/cloudflare/resources/d1/d1.py b/src/cloudflare/resources/d1/d1.py
index 514b18eff..5ced774c4 100644
--- a/src/cloudflare/resources/d1/d1.py
+++ b/src/cloudflare/resources/d1/d1.py
@@ -2,7 +2,9 @@
from __future__ import annotations
-from .database import (
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from .database.database import (
DatabaseResource,
AsyncDatabaseResource,
DatabaseResourceWithRawResponse,
@@ -10,8 +12,6 @@ from .database import (
DatabaseResourceWithStreamingResponse,
AsyncDatabaseResourceWithStreamingResponse,
)
-from ..._compat import cached_property
-from ..._resource import SyncAPIResource, AsyncAPIResource
__all__ = ["D1Resource", "AsyncD1Resource"]
diff --git a/src/cloudflare/resources/d1/database/__init__.py b/src/cloudflare/resources/d1/database/__init__.py
new file mode 100644
index 000000000..5834ebb6a
--- /dev/null
+++ b/src/cloudflare/resources/d1/database/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .database import (
+ DatabaseResource,
+ AsyncDatabaseResource,
+ DatabaseResourceWithRawResponse,
+ AsyncDatabaseResourceWithRawResponse,
+ DatabaseResourceWithStreamingResponse,
+ AsyncDatabaseResourceWithStreamingResponse,
+)
+from .time_travel import (
+ TimeTravelResource,
+ AsyncTimeTravelResource,
+ TimeTravelResourceWithRawResponse,
+ AsyncTimeTravelResourceWithRawResponse,
+ TimeTravelResourceWithStreamingResponse,
+ AsyncTimeTravelResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "TimeTravelResource",
+ "AsyncTimeTravelResource",
+ "TimeTravelResourceWithRawResponse",
+ "AsyncTimeTravelResourceWithRawResponse",
+ "TimeTravelResourceWithStreamingResponse",
+ "AsyncTimeTravelResourceWithStreamingResponse",
+ "DatabaseResource",
+ "AsyncDatabaseResource",
+ "DatabaseResourceWithRawResponse",
+ "AsyncDatabaseResourceWithRawResponse",
+ "DatabaseResourceWithStreamingResponse",
+ "AsyncDatabaseResourceWithStreamingResponse",
+]
diff --git a/src/cloudflare/resources/d1/database.py b/src/cloudflare/resources/d1/database/database.py
similarity index 96%
rename from src/cloudflare/resources/d1/database.py
rename to src/cloudflare/resources/d1/database/database.py
index c844fa90a..200815a56 100644
--- a/src/cloudflare/resources/d1/database.py
+++ b/src/cloudflare/resources/d1/database/database.py
@@ -7,10 +7,10 @@ from typing_extensions import Literal, overload
import httpx
-from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
-from ..._utils import required_args, maybe_transform, async_maybe_transform
-from ..._compat import cached_property
-from ...types.d1 import (
+from ...._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given
+from ...._utils import required_args, maybe_transform, async_maybe_transform
+from ...._compat import cached_property
+from ....types.d1 import (
database_raw_params,
database_edit_params,
database_list_params,
@@ -20,27 +20,39 @@ from ...types.d1 import (
database_import_params,
database_update_params,
)
-from ..._resource import SyncAPIResource, AsyncAPIResource
-from ..._response import (
+from .time_travel import (
+ TimeTravelResource,
+ AsyncTimeTravelResource,
+ TimeTravelResourceWithRawResponse,
+ AsyncTimeTravelResourceWithRawResponse,
+ TimeTravelResourceWithStreamingResponse,
+ AsyncTimeTravelResourceWithStreamingResponse,
+)
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
to_raw_response_wrapper,
to_streamed_response_wrapper,
async_to_raw_response_wrapper,
async_to_streamed_response_wrapper,
)
-from ..._wrappers import ResultWrapper
-from ...pagination import SyncSinglePage, AsyncSinglePage, SyncV4PagePaginationArray, AsyncV4PagePaginationArray
-from ...types.d1.d1 import D1
-from ..._base_client import AsyncPaginator, make_request_options
-from ...types.d1.query_result import QueryResult
-from ...types.d1.database_raw_response import DatabaseRawResponse
-from ...types.d1.database_list_response import DatabaseListResponse
-from ...types.d1.database_export_response import DatabaseExportResponse
-from ...types.d1.database_import_response import DatabaseImportResponse
+from ...._wrappers import ResultWrapper
+from ....pagination import SyncSinglePage, AsyncSinglePage, SyncV4PagePaginationArray, AsyncV4PagePaginationArray
+from ....types.d1.d1 import D1
+from ...._base_client import AsyncPaginator, make_request_options
+from ....types.d1.query_result import QueryResult
+from ....types.d1.database_raw_response import DatabaseRawResponse
+from ....types.d1.database_list_response import DatabaseListResponse
+from ....types.d1.database_export_response import DatabaseExportResponse
+from ....types.d1.database_import_response import DatabaseImportResponse
__all__ = ["DatabaseResource", "AsyncDatabaseResource"]
class DatabaseResource(SyncAPIResource):
+ @cached_property
+ def time_travel(self) -> TimeTravelResource:
+ return TimeTravelResource(self._client)
+
@cached_property
def with_raw_response(self) -> DatabaseResourceWithRawResponse:
"""
@@ -809,6 +821,10 @@ class DatabaseResource(SyncAPIResource):
class AsyncDatabaseResource(AsyncAPIResource):
+ @cached_property
+ def time_travel(self) -> AsyncTimeTravelResource:
+ return AsyncTimeTravelResource(self._client)
+
@cached_property
def with_raw_response(self) -> AsyncDatabaseResourceWithRawResponse:
"""
@@ -1615,6 +1631,10 @@ class DatabaseResourceWithRawResponse:
database.raw,
)
+ @cached_property
+ def time_travel(self) -> TimeTravelResourceWithRawResponse:
+ return TimeTravelResourceWithRawResponse(self._database.time_travel)
+
class AsyncDatabaseResourceWithRawResponse:
def __init__(self, database: AsyncDatabaseResource) -> None:
@@ -1651,6 +1671,10 @@ class AsyncDatabaseResourceWithRawResponse:
database.raw,
)
+ @cached_property
+ def time_travel(self) -> AsyncTimeTravelResourceWithRawResponse:
+ return AsyncTimeTravelResourceWithRawResponse(self._database.time_travel)
+
class DatabaseResourceWithStreamingResponse:
def __init__(self, database: DatabaseResource) -> None:
@@ -1687,6 +1711,10 @@ class DatabaseResourceWithStreamingResponse:
database.raw,
)
+ @cached_property
+ def time_travel(self) -> TimeTravelResourceWithStreamingResponse:
+ return TimeTravelResourceWithStreamingResponse(self._database.time_travel)
+
class AsyncDatabaseResourceWithStreamingResponse:
def __init__(self, database: AsyncDatabaseResource) -> None:
@@ -1722,3 +1750,7 @@ class AsyncDatabaseResourceWithStreamingResponse:
self.raw = async_to_streamed_response_wrapper(
database.raw,
)
+
+ @cached_property
+ def time_travel(self) -> AsyncTimeTravelResourceWithStreamingResponse:
+ return AsyncTimeTravelResourceWithStreamingResponse(self._database.time_travel)
diff --git a/src/cloudflare/resources/d1/database/time_travel.py b/src/cloudflare/resources/d1/database/time_travel.py
new file mode 100644
index 000000000..a3f6c6844
--- /dev/null
+++ b/src/cloudflare/resources/d1/database/time_travel.py
@@ -0,0 +1,340 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Type, Union, cast
+from datetime import datetime
+
+import httpx
+
+from ...._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ...._utils import maybe_transform, async_maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ...._wrappers import ResultWrapper
+from ...._base_client import make_request_options
+from ....types.d1.database import time_travel_restore_params, time_travel_get_bookmark_params
+from ....types.d1.database.time_travel_restore_response import TimeTravelRestoreResponse
+from ....types.d1.database.time_travel_get_bookmark_response import TimeTravelGetBookmarkResponse
+
+__all__ = ["TimeTravelResource", "AsyncTimeTravelResource"]
+
+
+class TimeTravelResource(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> TimeTravelResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return TimeTravelResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> TimeTravelResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return TimeTravelResourceWithStreamingResponse(self)
+
+ def get_bookmark(
+ self,
+ database_id: str,
+ *,
+ account_id: str,
+ timestamp: Union[str, datetime] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TimeTravelGetBookmarkResponse:
+ """
+ Retrieves the current bookmark, or the nearest bookmark at or before a provided
+ timestamp. Bookmarks can be used with the restore endpoint to revert the
+ database to a previous point in time.
+
+ Args:
+ account_id: Account identifier tag.
+
+ database_id: D1 database identifier (UUID).
+
+ timestamp: An optional ISO 8601 timestamp. If provided, returns the nearest available
+ bookmark at or before this timestamp. If omitted, returns the current bookmark.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not database_id:
+ raise ValueError(f"Expected a non-empty value for `database_id` but received {database_id!r}")
+ return self._get(
+ f"/accounts/{account_id}/d1/database/{database_id}/time_travel/bookmark",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {"timestamp": timestamp}, time_travel_get_bookmark_params.TimeTravelGetBookmarkParams
+ ),
+ post_parser=ResultWrapper[TimeTravelGetBookmarkResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TimeTravelGetBookmarkResponse], ResultWrapper[TimeTravelGetBookmarkResponse]),
+ )
+
+ def restore(
+ self,
+ database_id: str,
+ *,
+ account_id: str,
+ bookmark: str | Omit = omit,
+ timestamp: Union[str, datetime] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TimeTravelRestoreResponse:
+ """
+ Restores a D1 database to a previous point in time either via a bookmark or a
+ timestamp.
+
+ Args:
+ account_id: Account identifier tag.
+
+ database_id: D1 database identifier (UUID).
+
+ bookmark: A bookmark to restore the database to. Required if `timestamp` is not provided.
+
+ timestamp: An ISO 8601 timestamp to restore the database to. Required if `bookmark` is not
+ provided.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not database_id:
+ raise ValueError(f"Expected a non-empty value for `database_id` but received {database_id!r}")
+ return self._post(
+ f"/accounts/{account_id}/d1/database/{database_id}/time_travel/restore",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=maybe_transform(
+ {
+ "bookmark": bookmark,
+ "timestamp": timestamp,
+ },
+ time_travel_restore_params.TimeTravelRestoreParams,
+ ),
+ post_parser=ResultWrapper[TimeTravelRestoreResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TimeTravelRestoreResponse], ResultWrapper[TimeTravelRestoreResponse]),
+ )
+
+
+class AsyncTimeTravelResource(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncTimeTravelResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#accessing-raw-response-data-eg-headers
+ """
+ return AsyncTimeTravelResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncTimeTravelResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/cloudflare/cloudflare-python#with_streaming_response
+ """
+ return AsyncTimeTravelResourceWithStreamingResponse(self)
+
+ async def get_bookmark(
+ self,
+ database_id: str,
+ *,
+ account_id: str,
+ timestamp: Union[str, datetime] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TimeTravelGetBookmarkResponse:
+ """
+ Retrieves the current bookmark, or the nearest bookmark at or before a provided
+ timestamp. Bookmarks can be used with the restore endpoint to revert the
+ database to a previous point in time.
+
+ Args:
+ account_id: Account identifier tag.
+
+ database_id: D1 database identifier (UUID).
+
+ timestamp: An optional ISO 8601 timestamp. If provided, returns the nearest available
+ bookmark at or before this timestamp. If omitted, returns the current bookmark.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not database_id:
+ raise ValueError(f"Expected a non-empty value for `database_id` but received {database_id!r}")
+ return await self._get(
+ f"/accounts/{account_id}/d1/database/{database_id}/time_travel/bookmark",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {"timestamp": timestamp}, time_travel_get_bookmark_params.TimeTravelGetBookmarkParams
+ ),
+ post_parser=ResultWrapper[TimeTravelGetBookmarkResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TimeTravelGetBookmarkResponse], ResultWrapper[TimeTravelGetBookmarkResponse]),
+ )
+
+ async def restore(
+ self,
+ database_id: str,
+ *,
+ account_id: str,
+ bookmark: str | Omit = omit,
+ timestamp: Union[str, datetime] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> TimeTravelRestoreResponse:
+ """
+ Restores a D1 database to a previous point in time either via a bookmark or a
+ timestamp.
+
+ Args:
+ account_id: Account identifier tag.
+
+ database_id: D1 database identifier (UUID).
+
+ bookmark: A bookmark to restore the database to. Required if `timestamp` is not provided.
+
+ timestamp: An ISO 8601 timestamp to restore the database to. Required if `bookmark` is not
+ provided.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ if not account_id:
+ raise ValueError(f"Expected a non-empty value for `account_id` but received {account_id!r}")
+ if not database_id:
+ raise ValueError(f"Expected a non-empty value for `database_id` but received {database_id!r}")
+ return await self._post(
+ f"/accounts/{account_id}/d1/database/{database_id}/time_travel/restore",
+ options=make_request_options(
+ extra_headers=extra_headers,
+ extra_query=extra_query,
+ extra_body=extra_body,
+ timeout=timeout,
+ query=await async_maybe_transform(
+ {
+ "bookmark": bookmark,
+ "timestamp": timestamp,
+ },
+ time_travel_restore_params.TimeTravelRestoreParams,
+ ),
+ post_parser=ResultWrapper[TimeTravelRestoreResponse]._unwrapper,
+ ),
+ cast_to=cast(Type[TimeTravelRestoreResponse], ResultWrapper[TimeTravelRestoreResponse]),
+ )
+
+
+class TimeTravelResourceWithRawResponse:
+ def __init__(self, time_travel: TimeTravelResource) -> None:
+ self._time_travel = time_travel
+
+ self.get_bookmark = to_raw_response_wrapper(
+ time_travel.get_bookmark,
+ )
+ self.restore = to_raw_response_wrapper(
+ time_travel.restore,
+ )
+
+
+class AsyncTimeTravelResourceWithRawResponse:
+ def __init__(self, time_travel: AsyncTimeTravelResource) -> None:
+ self._time_travel = time_travel
+
+ self.get_bookmark = async_to_raw_response_wrapper(
+ time_travel.get_bookmark,
+ )
+ self.restore = async_to_raw_response_wrapper(
+ time_travel.restore,
+ )
+
+
+class TimeTravelResourceWithStreamingResponse:
+ def __init__(self, time_travel: TimeTravelResource) -> None:
+ self._time_travel = time_travel
+
+ self.get_bookmark = to_streamed_response_wrapper(
+ time_travel.get_bookmark,
+ )
+ self.restore = to_streamed_response_wrapper(
+ time_travel.restore,
+ )
+
+
+class AsyncTimeTravelResourceWithStreamingResponse:
+ def __init__(self, time_travel: AsyncTimeTravelResource) -> None:
+ self._time_travel = time_travel
+
+ self.get_bookmark = async_to_streamed_response_wrapper(
+ time_travel.get_bookmark,
+ )
+ self.restore = async_to_streamed_response_wrapper(
+ time_travel.restore,
+ )
diff --git a/src/cloudflare/types/d1/database/__init__.py b/src/cloudflare/types/d1/database/__init__.py
new file mode 100644
index 000000000..d01a1918c
--- /dev/null
+++ b/src/cloudflare/types/d1/database/__init__.py
@@ -0,0 +1,8 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .time_travel_restore_params import TimeTravelRestoreParams as TimeTravelRestoreParams
+from .time_travel_restore_response import TimeTravelRestoreResponse as TimeTravelRestoreResponse
+from .time_travel_get_bookmark_params import TimeTravelGetBookmarkParams as TimeTravelGetBookmarkParams
+from .time_travel_get_bookmark_response import TimeTravelGetBookmarkResponse as TimeTravelGetBookmarkResponse
diff --git a/src/cloudflare/types/d1/database/time_travel_get_bookmark_params.py b/src/cloudflare/types/d1/database/time_travel_get_bookmark_params.py
new file mode 100644
index 000000000..690290b66
--- /dev/null
+++ b/src/cloudflare/types/d1/database/time_travel_get_bookmark_params.py
@@ -0,0 +1,23 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Required, Annotated, TypedDict
+
+from ...._utils import PropertyInfo
+
+__all__ = ["TimeTravelGetBookmarkParams"]
+
+
+class TimeTravelGetBookmarkParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Account identifier tag."""
+
+ timestamp: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+ """An optional ISO 8601 timestamp.
+
+ If provided, returns the nearest available bookmark at or before this timestamp.
+ If omitted, returns the current bookmark.
+ """
diff --git a/src/cloudflare/types/d1/database/time_travel_get_bookmark_response.py b/src/cloudflare/types/d1/database/time_travel_get_bookmark_response.py
new file mode 100644
index 000000000..48ce81fdb
--- /dev/null
+++ b/src/cloudflare/types/d1/database/time_travel_get_bookmark_response.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["TimeTravelGetBookmarkResponse"]
+
+
+class TimeTravelGetBookmarkResponse(BaseModel):
+ bookmark: Optional[str] = None
+ """
+ A bookmark representing a specific state of the database at a specific point in
+ time.
+ """
diff --git a/src/cloudflare/types/d1/database/time_travel_restore_params.py b/src/cloudflare/types/d1/database/time_travel_restore_params.py
new file mode 100644
index 000000000..ef86ba6d9
--- /dev/null
+++ b/src/cloudflare/types/d1/database/time_travel_restore_params.py
@@ -0,0 +1,25 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Union
+from datetime import datetime
+from typing_extensions import Required, Annotated, TypedDict
+
+from ...._utils import PropertyInfo
+
+__all__ = ["TimeTravelRestoreParams"]
+
+
+class TimeTravelRestoreParams(TypedDict, total=False):
+ account_id: Required[str]
+ """Account identifier tag."""
+
+ bookmark: str
+ """A bookmark to restore the database to. Required if `timestamp` is not provided."""
+
+ timestamp: Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]
+ """An ISO 8601 timestamp to restore the database to.
+
+ Required if `bookmark` is not provided.
+ """
diff --git a/src/cloudflare/types/d1/database/time_travel_restore_response.py b/src/cloudflare/types/d1/database/time_travel_restore_response.py
new file mode 100644
index 000000000..671d5922a
--- /dev/null
+++ b/src/cloudflare/types/d1/database/time_travel_restore_response.py
@@ -0,0 +1,27 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ...._models import BaseModel
+
+__all__ = ["TimeTravelRestoreResponse"]
+
+
+class TimeTravelRestoreResponse(BaseModel):
+ """Response from a time travel restore operation."""
+
+ bookmark: Optional[str] = None
+ """
+ The new bookmark representing the state of the database after the restore
+ operation.
+ """
+
+ message: Optional[str] = None
+ """A message describing the result of the restore operation."""
+
+ previous_bookmark: Optional[str] = None
+ """The bookmark representing the state of the database before the restore
+ operation.
+
+ Can be used to undo the restore if needed.
+ """
diff --git a/tests/api_resources/d1/database/__init__.py b/tests/api_resources/d1/database/__init__.py
new file mode 100644
index 000000000..fd8019a9a
--- /dev/null
+++ b/tests/api_resources/d1/database/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/d1/database/test_time_travel.py b/tests/api_resources/d1/database/test_time_travel.py
new file mode 100644
index 000000000..7c3d59295
--- /dev/null
+++ b/tests/api_resources/d1/database/test_time_travel.py
@@ -0,0 +1,258 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from cloudflare import Cloudflare, AsyncCloudflare
+from tests.utils import assert_matches_type
+from cloudflare._utils import parse_datetime
+from cloudflare.types.d1.database import (
+ TimeTravelRestoreResponse,
+ TimeTravelGetBookmarkResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestTimeTravel:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @parametrize
+ def test_method_get_bookmark(self, client: Cloudflare) -> None:
+ time_travel = client.d1.database.time_travel.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(TimeTravelGetBookmarkResponse, time_travel, path=["response"])
+
+ @parametrize
+ def test_method_get_bookmark_with_all_params(self, client: Cloudflare) -> None:
+ time_travel = client.d1.database.time_travel.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ timestamp=parse_datetime("2024-01-15T12:00:00Z"),
+ )
+ assert_matches_type(TimeTravelGetBookmarkResponse, time_travel, path=["response"])
+
+ @parametrize
+ def test_raw_response_get_bookmark(self, client: Cloudflare) -> None:
+ response = client.d1.database.time_travel.with_raw_response.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ time_travel = response.parse()
+ assert_matches_type(TimeTravelGetBookmarkResponse, time_travel, path=["response"])
+
+ @parametrize
+ def test_streaming_response_get_bookmark(self, client: Cloudflare) -> None:
+ with client.d1.database.time_travel.with_streaming_response.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ time_travel = response.parse()
+ assert_matches_type(TimeTravelGetBookmarkResponse, time_travel, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_get_bookmark(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.d1.database.time_travel.with_raw_response.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `database_id` but received ''"):
+ client.d1.database.time_travel.with_raw_response.get_bookmark(
+ database_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ def test_method_restore(self, client: Cloudflare) -> None:
+ time_travel = client.d1.database.time_travel.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(TimeTravelRestoreResponse, time_travel, path=["response"])
+
+ @parametrize
+ def test_method_restore_with_all_params(self, client: Cloudflare) -> None:
+ time_travel = client.d1.database.time_travel.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ bookmark="00000001-00000002-00004e2f-0a83ea2fceebc654de0640c422be4653",
+ timestamp=parse_datetime("2024-01-15T12:00:00Z"),
+ )
+ assert_matches_type(TimeTravelRestoreResponse, time_travel, path=["response"])
+
+ @parametrize
+ def test_raw_response_restore(self, client: Cloudflare) -> None:
+ response = client.d1.database.time_travel.with_raw_response.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ time_travel = response.parse()
+ assert_matches_type(TimeTravelRestoreResponse, time_travel, path=["response"])
+
+ @parametrize
+ def test_streaming_response_restore(self, client: Cloudflare) -> None:
+ with client.d1.database.time_travel.with_streaming_response.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ time_travel = response.parse()
+ assert_matches_type(TimeTravelRestoreResponse, time_travel, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ def test_path_params_restore(self, client: Cloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ client.d1.database.time_travel.with_raw_response.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `database_id` but received ''"):
+ client.d1.database.time_travel.with_raw_response.restore(
+ database_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+
+class TestAsyncTimeTravel:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @parametrize
+ async def test_method_get_bookmark(self, async_client: AsyncCloudflare) -> None:
+ time_travel = await async_client.d1.database.time_travel.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(TimeTravelGetBookmarkResponse, time_travel, path=["response"])
+
+ @parametrize
+ async def test_method_get_bookmark_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ time_travel = await async_client.d1.database.time_travel.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ timestamp=parse_datetime("2024-01-15T12:00:00Z"),
+ )
+ assert_matches_type(TimeTravelGetBookmarkResponse, time_travel, path=["response"])
+
+ @parametrize
+ async def test_raw_response_get_bookmark(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.d1.database.time_travel.with_raw_response.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ time_travel = await response.parse()
+ assert_matches_type(TimeTravelGetBookmarkResponse, time_travel, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_get_bookmark(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.d1.database.time_travel.with_streaming_response.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ time_travel = await response.parse()
+ assert_matches_type(TimeTravelGetBookmarkResponse, time_travel, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_get_bookmark(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.d1.database.time_travel.with_raw_response.get_bookmark(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `database_id` but received ''"):
+ await async_client.d1.database.time_travel.with_raw_response.get_bookmark(
+ database_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ @parametrize
+ async def test_method_restore(self, async_client: AsyncCloudflare) -> None:
+ time_travel = await async_client.d1.database.time_travel.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+ assert_matches_type(TimeTravelRestoreResponse, time_travel, path=["response"])
+
+ @parametrize
+ async def test_method_restore_with_all_params(self, async_client: AsyncCloudflare) -> None:
+ time_travel = await async_client.d1.database.time_travel.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ bookmark="00000001-00000002-00004e2f-0a83ea2fceebc654de0640c422be4653",
+ timestamp=parse_datetime("2024-01-15T12:00:00Z"),
+ )
+ assert_matches_type(TimeTravelRestoreResponse, time_travel, path=["response"])
+
+ @parametrize
+ async def test_raw_response_restore(self, async_client: AsyncCloudflare) -> None:
+ response = await async_client.d1.database.time_travel.with_raw_response.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ time_travel = await response.parse()
+ assert_matches_type(TimeTravelRestoreResponse, time_travel, path=["response"])
+
+ @parametrize
+ async def test_streaming_response_restore(self, async_client: AsyncCloudflare) -> None:
+ async with async_client.d1.database.time_travel.with_streaming_response.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ time_travel = await response.parse()
+ assert_matches_type(TimeTravelRestoreResponse, time_travel, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @parametrize
+ async def test_path_params_restore(self, async_client: AsyncCloudflare) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `account_id` but received ''"):
+ await async_client.d1.database.time_travel.with_raw_response.restore(
+ database_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
+ account_id="",
+ )
+
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `database_id` but received ''"):
+ await async_client.d1.database.time_travel.with_raw_response.restore(
+ database_id="",
+ account_id="023e105f4ecef8ad9ca31a8372d0c353",
+ )