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
14 changes: 7 additions & 7 deletions src/deno_sandbox/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
AsyncSandboxApi,
SandboxApi,
)
from .console import AsyncConsoleClient, ConsoleClient
from .console import AsyncConsoleClient
from .options import Options, get_internal_options

__all__ = ["DenoDeploy", "AsyncDenoDeploy", "Options"]
Expand All @@ -21,13 +21,13 @@ def __init__(self, options: Optional[Options] = None):
internal_options = get_internal_options(options)
bridge = AsyncBridge()

client = ConsoleClient(internal_options, bridge)
self.apps = Apps(client)
self.revisions = Revisions(client)
self.timelines = Timelines(client)
client = AsyncConsoleClient(internal_options)
self.apps = Apps(client, bridge)
self.revisions = Revisions(client, bridge)
self.timelines = Timelines(client, bridge)
self.sandbox = SandboxApi(client, bridge)
self.snapshots = Snapshots(client)
self.volumes = Volumes(client)
self.snapshots = Snapshots(client, bridge)
self.volumes = Volumes(client, bridge)


class AsyncDenoDeploy:
Expand Down
19 changes: 10 additions & 9 deletions src/deno_sandbox/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
AppUpdate,
)
from .utils import convert_to_snake_case
from .bridge import AsyncBridge
from .console import (
PaginatedList,
ConsoleClient,
AsyncConsoleClient,
AsyncPaginatedList,
)
Expand Down Expand Up @@ -56,30 +56,31 @@ async def delete(self, app: str) -> None:


class Apps:
def __init__(self, client: ConsoleClient):
def __init__(self, client: AsyncConsoleClient, bridge: AsyncBridge):
self._client = client
self._async = AsyncApps(client._async)
self._bridge = bridge
self._async = AsyncApps(client)

def get(self, id_or_slug: str) -> App | None:
"""Get an app by its ID or slug."""
return self._client._bridge.run(self._async.get(id_or_slug))
return self._bridge.run(self._async.get(id_or_slug))

def list(
self, options: Optional[AppListOptions] = None
) -> PaginatedList[App, AppListOptions]:
"""List apps of an org."""

paginated = self._client._bridge.run(self._async.list(options))
return PaginatedList(self._client._bridge, paginated)
paginated = self._bridge.run(self._async.list(options))
return PaginatedList(self._bridge, paginated)

def create(self, options: Optional[AppInit] = None) -> App:
"""Create a new app."""
return self._client._bridge.run(self._async.create(options))
return self._bridge.run(self._async.create(options))

def update(self, app: str, update: AppUpdate) -> App:
"""Update an existing app."""
return self._client._bridge.run(self._async.update(app, update))
return self._bridge.run(self._async.update(app, update))

def delete(self, app: str) -> None:
"""Delete an app by its ID or slug."""
self._client._bridge.run(self._async.delete(app))
self._bridge.run(self._async.delete(app))
86 changes: 1 addition & 85 deletions src/deno_sandbox/console.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
from __future__ import annotations

from datetime import datetime, timezone
from typing import Any, Generic, Literal, Optional, TypedDict, TypeVar, cast
import httpx

from .api_types_generated import (
RevisionWithoutTimelines,
SandboxListOptions,
SandboxMeta,
Timeline,
)
from .bridge import AsyncBridge
Expand All @@ -29,10 +26,6 @@ class ExposeSSHResult(TypedDict):
port: int


class ExposeHTTPResult(TypedDict):
domain: str


class AsyncPaginatedList(Generic[T, O]):
def __init__(
self,
Expand Down Expand Up @@ -218,82 +211,5 @@ async def __aenter__(self):
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.close()

# Sandbox-related methods (used by sandbox.py)
async def _sandboxes_list(
self, options: Optional[SandboxListOptions] = None
) -> AsyncPaginatedList[SandboxMeta, SandboxListOptions]:
sandboxes: AsyncPaginatedList[
SandboxMeta, SandboxListOptions
] = await self.get_paginated(
path="/api/v3/sandboxes", cursor=None, params=options
)
return sandboxes

async def _kill_sandbox(self, sandbox_id: str) -> None:
await self.delete(f"/api/v3/sandboxes/{sandbox_id}")

async def _extend_timeout(self, sandbox_id: str, stop_at_ms: int) -> datetime:
url = self._options["sandbox_url"].join(f"/api/v3/sandbox/{sandbox_id}")

result = await self._request("PATCH", url, {"stop_at_ms": stop_at_ms})

data = result.json()

return datetime.fromtimestamp(data["stop_at_ms"] / 1000, tz=timezone.utc)

async def _expose_http(self, sandbox_id: str, params: dict[str, int]) -> str:
url = self._options["sandbox_url"].join(
f"/api/v3/sandbox/{sandbox_id}/expose/http"
)

result = await self._request("POST", url, params)

data = cast(ExposeHTTPResult, result.json())
return data["domain"]

async def _expose_ssh(self, sandbox_id: str) -> ExposeSSHResult:
url = self._options["sandbox_url"].join(
f"/api/v3/sandbox/{sandbox_id}/expose/ssh"
)
response = await self._request("POST", url, {})

return cast(ExposeSSHResult, response.json())


class ConsoleClient:
def __init__(self, options: InternalOptions, bridge: AsyncBridge):
self._async = AsyncConsoleClient(options)
self._bridge = bridge

def close(self):
self._bridge.run(self._async.close())

def __enter__(self):
return self

def __exit__(self, exc_type, exc_val, exc_tb):
self._bridge.run(self._async.__aexit__(exc_type, exc_val, exc_tb))

# Sandbox-related methods (used by sandbox.py)
def _sandboxes_list(
self, options: Optional[SandboxListOptions] = None
) -> PaginatedList[SandboxMeta, SandboxListOptions]:
paginated: AsyncPaginatedList[SandboxMeta, SandboxListOptions] = (
self._bridge.run(self._async._sandboxes_list(options))
)
return PaginatedList(self._bridge, paginated)

def _kill_sandbox(self, sandbox_id: str) -> None:
self._bridge.run(self._async._kill_sandbox(sandbox_id))

def _extend_timeout(self, sandbox_id: str, stop_at_ms: int) -> None:
self._bridge.run(self._async._extend_timeout(sandbox_id, stop_at_ms))

def _expose_http(self, sandbox_id: str, params: dict[str, int]) -> str:
return self._bridge.run(self._async._expose_http(sandbox_id, params))

def _expose_ssh(self, sandbox_id: str) -> ExposeSSHResult:
return self._bridge.run(self._async._expose_ssh(sandbox_id))


__all__ = ["AsyncConsoleClient", "ConsoleClient"]
__all__ = ["AsyncConsoleClient"]
32 changes: 10 additions & 22 deletions src/deno_sandbox/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from .console import AsyncConsoleClient, ConsoleClient
from .rpc import AsyncRpcClient, RpcClient
from .rpc import AsyncRpcClient
from .bridge import AsyncBridge


class AsyncSandboxEnv:
def __init__(self, client: AsyncConsoleClient, rpc: AsyncRpcClient):
self._client = client
def __init__(self, rpc: AsyncRpcClient):
self._rpc = rpc

async def get(self, key: str) -> str:
Expand Down Expand Up @@ -42,34 +41,23 @@ async def delete(self, key: str) -> None:


class SandboxEnv:
def __init__(self, client: ConsoleClient, rpc: RpcClient):
self._client = client
def __init__(self, rpc: AsyncRpcClient, bridge: AsyncBridge):
self._rpc = rpc
self._bridge = bridge
self._async = AsyncSandboxEnv(rpc)

def get(self, key: str) -> str:
"""Get the value of an environment variable."""

params = {"key": key}
result = self._rpc.call("envGet", params)

return result
return self._bridge.run(self._async.get(key))

def set(self, key: str, value: str) -> None:
"""Set the value of an environment variable."""

params = {"key": key, "value": value}
self._rpc.call("envSet", params)
self._bridge.run(self._async.set(key, value))

def to_object(self) -> dict[str, str]:
"""Get all environment variables."""

params = {}
result = self._rpc.call("envToObject", params)

return result
return self._bridge.run(self._async.to_object())

def delete(self, key: str) -> None:
"""Delete an environment variable."""

params = {"key": key}
self._rpc.call("envDelete", params)
self._bridge.run(self._async.delete(key))
Loading