Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 11 additions & 13 deletions src/blaxel/core/sandbox/default/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,12 +436,12 @@ async def update_metadata(
return cls(response)

@classmethod
async def update_ttl(cls, sandbox_name: str, ttl: str) -> "SandboxInstance":
async def update_ttl(cls, sandbox_name: str, ttl: str | None) -> "SandboxInstance":
"""Update sandbox TTL without recreating it.

Args:
sandbox_name: The name of the sandbox to update
ttl: The new TTL value (e.g., "5m", "1h", "30s")
ttl: The new TTL value (e.g., "5m", "1h", "30s"), or None/"" to clear

Returns:
A new SandboxInstance with updated TTL
Expand All @@ -455,8 +455,8 @@ async def update_ttl(cls, sandbox_name: str, ttl: str) -> "SandboxInstance":
if updated_sandbox.spec is None or updated_sandbox.spec.runtime is None:
raise ValueError(f"Sandbox {sandbox_name} has invalid spec")

# Update TTL
updated_sandbox.spec.runtime.ttl = ttl
# Update TTL (None or empty string clears the TTL)
updated_sandbox.spec.runtime.ttl = None if ttl is None or ttl == "" else ttl

# Call the update API
response = await update_sandbox(
Expand All @@ -469,13 +469,13 @@ async def update_ttl(cls, sandbox_name: str, ttl: str) -> "SandboxInstance":

@classmethod
async def update_lifecycle(
cls, sandbox_name: str, lifecycle: SandboxLifecycle
cls, sandbox_name: str, lifecycle: SandboxLifecycle | None
) -> "SandboxInstance":
"""Update sandbox lifecycle configuration without recreating it.

Args:
sandbox_name: The name of the sandbox to update
lifecycle: The new lifecycle configuration
lifecycle: The new lifecycle configuration, or None to clear

Returns:
A new SandboxInstance with updated lifecycle
Expand All @@ -484,19 +484,17 @@ async def update_lifecycle(
sandbox_instance = await cls.get(sandbox_name)
sandbox = sandbox_instance.sandbox

# Prepare the updated sandbox object
updated_sandbox = Sandbox.from_dict(sandbox.to_dict())
if updated_sandbox.spec is None:
# Use dict approach to properly serialize null lifecycle
body = sandbox.to_dict()
if "spec" not in body:
raise ValueError(f"Sandbox {sandbox_name} has invalid spec")

# Update lifecycle
updated_sandbox.spec.lifecycle = lifecycle
body["spec"]["lifecycle"] = lifecycle.to_dict() if lifecycle is not None else None

# Call the update API
response = await update_sandbox(
sandbox_name=sandbox_name,
client=client,
body=updated_sandbox,
body=body,
)

return cls(response)
Expand Down
24 changes: 11 additions & 13 deletions src/blaxel/core/sandbox/sync/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,12 +338,12 @@ def update_metadata(
return cls(response)

@classmethod
def update_ttl(cls, sandbox_name: str, ttl: str) -> "SyncSandboxInstance":
def update_ttl(cls, sandbox_name: str, ttl: str | None) -> "SyncSandboxInstance":
"""Update sandbox TTL without recreating it.

Args:
sandbox_name: The name of the sandbox to update
ttl: The new TTL value (e.g., "5m", "1h", "30s")
ttl: The new TTL value (e.g., "5m", "1h", "30s"), or None/"" to clear

Returns:
A new SyncSandboxInstance with updated TTL
Expand All @@ -357,8 +357,8 @@ def update_ttl(cls, sandbox_name: str, ttl: str) -> "SyncSandboxInstance":
if updated_sandbox.spec is None or updated_sandbox.spec.runtime is None:
raise ValueError(f"Sandbox {sandbox_name} has invalid spec")

# Update TTL
updated_sandbox.spec.runtime.ttl = ttl
# Update TTL (None or empty string clears the TTL)
updated_sandbox.spec.runtime.ttl = None if ttl is None or ttl == "" else ttl

# Call the update API
response = update_sandbox(
Expand All @@ -371,13 +371,13 @@ def update_ttl(cls, sandbox_name: str, ttl: str) -> "SyncSandboxInstance":

@classmethod
def update_lifecycle(
cls, sandbox_name: str, lifecycle: SandboxLifecycle
cls, sandbox_name: str, lifecycle: SandboxLifecycle | None
) -> "SyncSandboxInstance":
"""Update sandbox lifecycle configuration without recreating it.

Args:
sandbox_name: The name of the sandbox to update
lifecycle: The new lifecycle configuration
lifecycle: The new lifecycle configuration, or None to clear

Returns:
A new SyncSandboxInstance with updated lifecycle
Expand All @@ -386,19 +386,17 @@ def update_lifecycle(
sandbox_instance = cls.get(sandbox_name)
sandbox = sandbox_instance.sandbox

# Prepare the updated sandbox object
updated_sandbox = Sandbox.from_dict(sandbox.to_dict())
if updated_sandbox.spec is None:
# Use dict approach to properly serialize null lifecycle
body = sandbox.to_dict()
if "spec" not in body:
raise ValueError(f"Sandbox {sandbox_name} has invalid spec")

# Update lifecycle
updated_sandbox.spec.lifecycle = lifecycle
body["spec"]["lifecycle"] = lifecycle.to_dict() if lifecycle is not None else None

# Call the update API
response = update_sandbox(
sandbox_name=sandbox_name,
client=client,
body=updated_sandbox,
body=body,
)

return cls(response)
Expand Down
Loading