Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
9 changes: 8 additions & 1 deletion src/runloop_api_client/sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@

from __future__ import annotations

from .sync import DevboxOps, RunloopSDK, SnapshotOps, BlueprintOps, StorageObjectOps
from .sync import DevboxOps, ScorerOps, RunloopSDK, SnapshotOps, BlueprintOps, StorageObjectOps
from .async_ import (
AsyncDevboxOps,
AsyncScorerOps,
AsyncRunloopSDK,
AsyncSnapshotOps,
AsyncBlueprintOps,
AsyncStorageObjectOps,
)
from .devbox import Devbox, NamedShell
from .scorer import Scorer
from .snapshot import Snapshot
from .blueprint import Blueprint
from .execution import Execution
from .async_devbox import AsyncDevbox, AsyncNamedShell
from .async_scorer import AsyncScorer
from .async_snapshot import AsyncSnapshot
from .storage_object import StorageObject
from .async_blueprint import AsyncBlueprint
Expand All @@ -35,6 +38,8 @@
"AsyncDevboxOps",
"BlueprintOps",
"AsyncBlueprintOps",
"ScorerOps",
"AsyncScorerOps",
"SnapshotOps",
"AsyncSnapshotOps",
"StorageObjectOps",
Expand All @@ -48,6 +53,8 @@
"AsyncExecutionResult",
"Blueprint",
"AsyncBlueprint",
"Scorer",
"AsyncScorer",
"Snapshot",
"AsyncSnapshot",
"StorageObject",
Expand Down
17 changes: 17 additions & 0 deletions src/runloop_api_client/sdk/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .._types import Body, Query, Headers, Timeout, NotGiven
from ..lib.polling import PollingConfig
from ..types.devboxes import DiskSnapshotListParams, DiskSnapshotUpdateParams
from ..types.scenarios import ScorerListParams, ScorerCreateParams, ScorerUpdateParams, ScorerValidateParams
from ..types.devbox_list_params import DevboxListParams
from ..types.object_list_params import ObjectListParams
from ..types.devbox_create_params import DevboxCreateParams, DevboxBaseCreateParams
Expand Down Expand Up @@ -140,3 +141,19 @@ class SDKObjectCreateParams(ObjectCreateParams, LongRequestOptions):

class SDKObjectDownloadParams(ObjectDownloadParams, BaseRequestOptions):
pass


class SDKScorerCreateParams(ScorerCreateParams, LongRequestOptions):
pass


class SDKScorerListParams(ScorerListParams, BaseRequestOptions):
pass


class SDKScorerUpdateParams(ScorerUpdateParams, LongRequestOptions):
pass


class SDKScorerValidateParams(ScorerValidateParams, LongRequestOptions):
pass
68 changes: 68 additions & 0 deletions src/runloop_api_client/sdk/async_.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
LongRequestOptions,
SDKDevboxListParams,
SDKObjectListParams,
SDKScorerListParams,
SDKDevboxCreateParams,
SDKObjectCreateParams,
SDKScorerCreateParams,
SDKBlueprintListParams,
SDKBlueprintCreateParams,
SDKDiskSnapshotListParams,
Expand All @@ -27,6 +29,7 @@
from .._client import DEFAULT_MAX_RETRIES, AsyncRunloop
from ._helpers import detect_content_type
from .async_devbox import AsyncDevbox
from .async_scorer import AsyncScorer
from .async_snapshot import AsyncSnapshot
from .async_blueprint import AsyncBlueprint
from .async_storage_object import AsyncStorageObject
Expand Down Expand Up @@ -475,6 +478,67 @@ async def upload_from_bytes(
return obj


class AsyncScorerOps:
"""High-level async manager for creating and managing scenario scorers.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably good to describe as 'benchmark scenario scorers' since 'scenario' isn't particularly obvious outside the benchmark context.


Accessed via ``runloop.scorer`` from :class:`AsyncRunloopSDK`, provides
coroutines to create, list, and access scorers.

Example:
>>> runloop = AsyncRunloopSDK()
>>> scorer = await runloop.scorer.create(type="my_scorer", bash_script="echo 'score=1.0'")
>>> scorers = await runloop.scorer.list()
"""

def __init__(self, client: AsyncRunloop) -> None:
"""Initialize the manager.

:param client: Generated AsyncRunloop client to wrap
:type client: AsyncRunloop
"""
self._client = client

async def create(
self,
**params: Unpack[SDKScorerCreateParams],
) -> AsyncScorer:
"""Create a new scenario scorer.

:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKScorerCreateParams` for available parameters
:return: Wrapper bound to the newly created scorer
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Wrapper bound to..." is a bit of an odd and implementation-specific description. How about "Handle to the newly created scorer"?

:rtype: AsyncScorer
"""
response = await self._client.scenarios.scorers.create(
**params,
)
return AsyncScorer(self._client, response.id)

def from_id(self, scorer_id: str) -> AsyncScorer:
"""Return a scorer wrapper for the given ID.

:param scorer_id: Scorer ID to wrap
:type scorer_id: str
:return: Wrapper for the scorer resource
:rtype: AsyncScorer
"""
return AsyncScorer(self._client, scorer_id)

async def list(
self,
**params: Unpack[SDKScorerListParams],
) -> list[AsyncScorer]:
"""List all scenario scorers.

:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKScorerListParams` for available parameters
:return: List of scorer wrappers
:rtype: list[AsyncScorer]
"""
page = await self._client.scenarios.scorers.list(
**params,
)
return [AsyncScorer(self._client, item.id) async for item in page]


class AsyncRunloopSDK:
"""High-level asynchronous entry point for the Runloop SDK.

Expand All @@ -488,6 +552,8 @@ class AsyncRunloopSDK:
:vartype devbox: AsyncDevboxOps
:ivar blueprint: High-level async interface for blueprint management
:vartype blueprint: AsyncBlueprintOps
:ivar scorer: High-level async interface for scorer management
:vartype scorer: AsyncScorerOps
:ivar snapshot: High-level async interface for snapshot management
:vartype snapshot: AsyncSnapshotOps
:ivar storage_object: High-level async interface for storage object management
Expand All @@ -504,6 +570,7 @@ class AsyncRunloopSDK:
api: AsyncRunloop
devbox: AsyncDevboxOps
blueprint: AsyncBlueprintOps
scorer: AsyncScorerOps
snapshot: AsyncSnapshotOps
storage_object: AsyncStorageObjectOps

Expand Down Expand Up @@ -547,6 +614,7 @@ def __init__(

self.devbox = AsyncDevboxOps(self.api)
self.blueprint = AsyncBlueprintOps(self.api)
self.scorer = AsyncScorerOps(self.api)
self.snapshot = AsyncSnapshotOps(self.api)
self.storage_object = AsyncStorageObjectOps(self.api)

Expand Down
90 changes: 90 additions & 0 deletions src/runloop_api_client/sdk/async_scorer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""Scorer resource class for asynchronous operations."""

from __future__ import annotations

from typing_extensions import Unpack, override

from ._types import (
BaseRequestOptions,
SDKScorerUpdateParams,
SDKScorerValidateParams,
)
from .._client import AsyncRunloop
from ..types.scenarios import ScorerUpdateResponse, ScorerRetrieveResponse, ScorerValidateResponse


class AsyncScorer:
"""Asynchronous wrapper around a scenario scorer resource."""

def __init__(
self,
client: AsyncRunloop,
scorer_id: str,
) -> None:
"""Initialize the wrapper.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments leak system internals and don't really help a caller understand how to use the code. Can you update them to say something more helpful?


:param client: Generated AsyncRunloop client
:type client: AsyncRunloop
:param scorer_id: Scorer ID returned by the API
:type scorer_id: str
"""
self._client = client
self._id = scorer_id

@override
def __repr__(self) -> str:
return f"<AsyncScorer id={self._id!r}>"

@property
def id(self) -> str:
"""Return the scorer ID.

:return: Unique scorer ID
:rtype: str
"""
return self._id

async def get_info(
self,
**options: Unpack[BaseRequestOptions],
) -> ScorerRetrieveResponse:
"""Retrieve the latest scorer details.

:param options: Optional request configuration
:return: API response describing the scorer
:rtype: ScorerRetrieveResponse
"""
return await self._client.scenarios.scorers.retrieve(
self._id,
**options,
)

async def update(
self,
**params: Unpack[SDKScorerUpdateParams],
) -> ScorerUpdateResponse:
"""Update the scorer.

:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKScorerUpdateParams` for available parameters
:return: API response with updated scorer details
:rtype: ScorerUpdateResponse
"""
return await self._client.scenarios.scorers.update(
self._id,
**params,
)

async def validate(
self,
**params: Unpack[SDKScorerValidateParams],
) -> ScorerValidateResponse:
"""Validate the scorer with a given context.

:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKScorerValidateParams` for available parameters
:return: API response with validation results
:rtype: ScorerValidateResponse
"""
return await self._client.scenarios.scorers.validate(
self._id,
**params,
)
90 changes: 90 additions & 0 deletions src/runloop_api_client/sdk/scorer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""Scorer resource class for synchronous operations."""

from __future__ import annotations

from typing_extensions import Unpack, override

from ._types import (
BaseRequestOptions,
SDKScorerUpdateParams,
SDKScorerValidateParams,
)
from .._client import Runloop
from ..types.scenarios import ScorerUpdateResponse, ScorerRetrieveResponse, ScorerValidateResponse


class Scorer:
"""Synchronous wrapper around a scenario scorer resource."""

def __init__(
self,
client: Runloop,
scorer_id: str,
) -> None:
"""Initialize the wrapper.

:param client: Generated Runloop client
:type client: Runloop
:param scorer_id: Scorer ID returned by the API
:type scorer_id: str
"""
self._client = client
self._id = scorer_id

@override
def __repr__(self) -> str:
return f"<Scorer id={self._id!r}>"

@property
def id(self) -> str:
"""Return the scorer ID.

:return: Unique scorer ID
:rtype: str
"""
return self._id

def get_info(
self,
**options: Unpack[BaseRequestOptions],
) -> ScorerRetrieveResponse:
"""Retrieve the latest scorer details.

:param options: Optional request configuration
:return: API response describing the scorer
:rtype: ScorerRetrieveResponse
"""
return self._client.scenarios.scorers.retrieve(
self._id,
**options,
)

def update(
self,
**params: Unpack[SDKScorerUpdateParams],
) -> ScorerUpdateResponse:
"""Update the scorer.

:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKScorerUpdateParams` for available parameters
:return: API response with updated scorer details
:rtype: ScorerUpdateResponse
"""
return self._client.scenarios.scorers.update(
self._id,
**params,
)

def validate(
self,
**params: Unpack[SDKScorerValidateParams],
) -> ScorerValidateResponse:
"""Validate the scorer with a given context.

:param params: See :typeddict:`~runloop_api_client.sdk._types.SDKScorerValidateParams` for available parameters
:return: API response with validation results
:rtype: ScorerValidateResponse
"""
return self._client.scenarios.scorers.validate(
self._id,
**params,
)
Loading