diff --git a/api.md b/api.md index 84d42980a..bc4e96abc 100644 --- a/api.md +++ b/api.md @@ -62,6 +62,7 @@ Methods: - client.blueprints.delete(id) -> object - client.blueprints.logs(id) -> BlueprintBuildLogsListView - client.blueprints.preview(\*\*params) -> BlueprintPreviewView +- client.blueprints.create_and_await_build_complete(create_args, request_args=None) -> BlueprintView # Devboxes @@ -104,6 +105,7 @@ Methods: - client.devboxes.suspend(id) -> DevboxView - client.devboxes.upload_file(id, \*\*params) -> object - client.devboxes.write_file_contents(id, \*\*params) -> DevboxExecutionDetailView +- client.devboxes.create_and_await_running(create_args, request_args=None) -> DevboxView ## DiskSnapshots diff --git a/pyproject.toml b/pyproject.toml index cac5532d5..88d2dd96b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ dependencies = [ "distro>=1.7.0, <2", "sniffio", ] + requires-python = ">= 3.8" classifiers = [ "Typing :: Typed", @@ -93,6 +94,11 @@ typecheck = { chain = [ requires = ["hatchling==1.26.3", "hatch-fancy-pypi-readme"] build-backend = "hatchling.build" +[dependency-groups] +dev = [ + "ruff>=0.12.7", +] + [tool.hatch.build] include = [ "src/*" diff --git a/src/runloop_api_client/resources/blueprints.py b/src/runloop_api_client/resources/blueprints.py index 5c527e560..b99690ace 100644 --- a/src/runloop_api_client/resources/blueprints.py +++ b/src/runloop_api_client/resources/blueprints.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Dict, List, Iterable, Optional +from typing import Dict, List, Iterable, Optional, TypedDict import httpx @@ -28,7 +28,19 @@ from ..types.shared_params.launch_parameters import LaunchParameters from ..types.shared_params.code_mount_parameters import CodeMountParameters -__all__ = ["BlueprintsResource", "AsyncBlueprintsResource"] + +# Type for request arguments that combine polling config with additional request options +class BlueprintRequestArgs(TypedDict, total=False): + polling_config: PollingConfig | None + # 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 + extra_query: Query | None + extra_body: Body | None + timeout: float | httpx.Timeout | None | NotGiven + + +__all__ = ["BlueprintsResource", "AsyncBlueprintsResource", "BlueprintRequestArgs"] class BlueprintsResource(SyncAPIResource): @@ -188,13 +200,10 @@ def await_build_complete( PollingTimeout: If polling times out before blueprint is built RunloopError: If blueprint enters a non-built terminal state """ + def retrieve_blueprint() -> BlueprintView: return self.retrieve( - id, - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout + id, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ) def is_done_building(blueprint: BlueprintView) -> bool: @@ -203,44 +212,23 @@ def is_done_building(blueprint: BlueprintView) -> bool: blueprint = poll_until(retrieve_blueprint, is_done_building, polling_config) if blueprint.status != "build_complete": - raise RunloopError( - f"Blueprint entered non-built terminal state: {blueprint.status}" - ) + raise RunloopError(f"Blueprint entered non-built terminal state: {blueprint.status}") return blueprint def create_and_await_build_complete( self, *, - name: str, - code_mounts: Optional[Iterable[CodeMountParameters]] | NotGiven = NOT_GIVEN, - dockerfile: Optional[str] | NotGiven = NOT_GIVEN, - file_mounts: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - launch_parameters: Optional[LaunchParameters] | NotGiven = NOT_GIVEN, - system_setup_commands: Optional[List[str]] | NotGiven = NOT_GIVEN, - polling_config: PollingConfig | None = None, - # 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, - idempotency_key: str | None = None, + create_args: blueprint_create_params.BlueprintCreateParams, + request_args: BlueprintRequestArgs | None = None, ) -> BlueprintView: """Create a new Blueprint and wait for it to finish building. + This is a wrapper around the `create` method that waits for the blueprint to finish building. + Args: - dockerfile: The Dockerfile contents to use for building the Blueprint - file_mounts: Files to mount into the Blueprint - launch_parameters: Launch parameters for Devboxes created from this Blueprint - name: Name for the Blueprint - system_setup_commands: Commands to run during Blueprint build - polling_config: Optional polling configuration - 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 - idempotency_key: Specify a custom idempotency key for this request + create_args: Arguments to pass to the `create` method. See the `create` method for detailed documentation. + request_args: Optional request arguments including polling configuration and additional request options Returns: The built blueprint @@ -249,27 +237,19 @@ def create_and_await_build_complete( PollingTimeout: If polling times out before blueprint is built RunloopError: If blueprint enters a non-built terminal state """ - blueprint = self.create( - name=name, - dockerfile=dockerfile, - code_mounts=code_mounts, - file_mounts=file_mounts, - launch_parameters=launch_parameters, - system_setup_commands=system_setup_commands, - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - idempotency_key=idempotency_key, - ) + # Pass all create_args to the underlying create method + blueprint = self.create(**create_args) + + if request_args is None: + request_args = {} return self.await_build_complete( blueprint.id, - polling_config=polling_config, - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, + polling_config=request_args.get("polling_config", None), + extra_headers=request_args.get("extra_headers", None), + extra_query=request_args.get("extra_query", None), + extra_body=request_args.get("extra_body", None), + timeout=request_args.get("timeout", None), ) def list( @@ -597,7 +577,7 @@ async def retrieve( ), cast_to=BlueprintView, ) - + async def await_build_complete( self, id: str, @@ -627,13 +607,10 @@ async def await_build_complete( PollingTimeout: If polling times out before blueprint is built RunloopError: If blueprint enters a non-built terminal state """ + async def retrieve_blueprint() -> BlueprintView: return await self.retrieve( - id, - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout + id, extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout ) def is_done_building(blueprint: BlueprintView) -> bool: @@ -642,44 +619,23 @@ def is_done_building(blueprint: BlueprintView) -> bool: blueprint = await async_poll_until(retrieve_blueprint, is_done_building, polling_config) if blueprint.status != "build_complete": - raise RunloopError( - f"Blueprint entered non-built terminal state: {blueprint.status}" - ) + raise RunloopError(f"Blueprint entered non-built terminal state: {blueprint.status}") return blueprint async def create_and_await_build_complete( self, *, - name: str, - code_mounts: Optional[Iterable[CodeMountParameters]] | NotGiven = NOT_GIVEN, - dockerfile: Optional[str] | NotGiven = NOT_GIVEN, - file_mounts: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - launch_parameters: Optional[LaunchParameters] | NotGiven = NOT_GIVEN, - system_setup_commands: Optional[List[str]] | NotGiven = NOT_GIVEN, - polling_config: PollingConfig | None = None, - # 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, - idempotency_key: str | None = None, + create_args: blueprint_create_params.BlueprintCreateParams, + request_args: BlueprintRequestArgs | None = None, ) -> BlueprintView: """Create a new Blueprint and wait for it to finish building. + This is a wrapper around the `create` method that waits for the blueprint to finish building. + Args: - dockerfile: The Dockerfile contents to use for building the Blueprint - file_mounts: Files to mount into the Blueprint - launch_parameters: Launch parameters for Devboxes created from this Blueprint - name: Name for the Blueprint - system_setup_commands: Commands to run during Blueprint build - polling_config: Optional polling configuration - 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 - idempotency_key: Specify a custom idempotency key for this request + create_args: Arguments to pass to the `create` method. See the `create` method for detailed documentation. + request_args: Optional request arguments including polling configuration and additional request options Returns: The built blueprint @@ -688,27 +644,20 @@ async def create_and_await_build_complete( PollingTimeout: If polling times out before blueprint is built RunloopError: If blueprint enters a non-built terminal state """ - blueprint = await self.create( - name=name, - dockerfile=dockerfile, - code_mounts=code_mounts, - file_mounts=file_mounts, - launch_parameters=launch_parameters, - system_setup_commands=system_setup_commands, - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - idempotency_key=idempotency_key, - ) + # Pass all create_args to the underlying create method + blueprint = await self.create(**create_args) + + # Extract polling config and other request args + if request_args is None: + request_args = {} return await self.await_build_complete( blueprint.id, - polling_config=polling_config, - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, + polling_config=request_args.get("polling_config", None), + extra_headers=request_args.get("extra_headers", None), + extra_query=request_args.get("extra_query", None), + extra_body=request_args.get("extra_body", None), + timeout=request_args.get("timeout", None), ) def list( diff --git a/src/runloop_api_client/resources/devboxes/devboxes.py b/src/runloop_api_client/resources/devboxes/devboxes.py index 5657965c0..971bd5aca 100644 --- a/src/runloop_api_client/resources/devboxes/devboxes.py +++ b/src/runloop_api_client/resources/devboxes/devboxes.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Dict, Mapping, Iterable, Optional, cast +from typing import Dict, Mapping, Iterable, Optional, TypedDict, cast from typing_extensions import Literal import httpx @@ -110,11 +110,20 @@ from ...types.devbox_async_execution_detail_view import DevboxAsyncExecutionDetailView from ...types.shared_params.code_mount_parameters import CodeMountParameters -__all__ = ["DevboxesResource", "AsyncDevboxesResource"] +__all__ = ["DevboxesResource", "AsyncDevboxesResource", "DevboxRequestArgs"] DEVBOX_BOOTING_STATES = frozenset(("provisioning", "initializing")) +# Type for request arguments that combine polling config with additional request options +class DevboxRequestArgs(TypedDict, total=False): + polling_config: PollingConfig | None + extra_headers: Headers | None + extra_query: Query | None + extra_body: Body | None + timeout: float | httpx.Timeout | None | NotGiven + + def placeholder_devbox_view(id: str) -> DevboxView: return DevboxView( id=id, @@ -426,61 +435,16 @@ def is_done_booting(devbox: DevboxView) -> bool: def create_and_await_running( self, *, - blueprint_id: Optional[str] | NotGiven = NOT_GIVEN, - blueprint_name: Optional[str] | NotGiven = NOT_GIVEN, - code_mounts: Optional[Iterable[CodeMountParameters]] | NotGiven = NOT_GIVEN, - entrypoint: Optional[str] | NotGiven = NOT_GIVEN, - environment_variables: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - file_mounts: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - launch_parameters: Optional[LaunchParameters] | NotGiven = NOT_GIVEN, - metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - name: Optional[str] | NotGiven = NOT_GIVEN, - prebuilt: Optional[str] | NotGiven = NOT_GIVEN, - repo_connection_id: Optional[str] | NotGiven = NOT_GIVEN, - secrets: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - snapshot_id: Optional[str] | NotGiven = NOT_GIVEN, - polling_config: PollingConfig | None = None, - # 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, - idempotency_key: str | None = None, + create_args: devbox_create_params.DevboxCreateParams, + request_args: DevboxRequestArgs | None = None, ) -> DevboxView: """Create a new devbox and wait for it to be in running state. + This is a wrapper around the `create` method that waits for the devbox to reach running state. + Args: - blueprint_id: Blueprint ID to use for the Devbox. If none set, the Devbox will be created with - the default Runloop Devbox image. Only one of (Snapshot ID, Blueprint ID, - Blueprint name) should be specified. - blueprint_name: Name of Blueprint to use for the Devbox. When set, this will load the latest - successfully built Blueprint with the given name. Only one of (Snapshot ID, - Blueprint ID, Blueprint name) should be specified. - code_mounts: A list of code mounts to be included in the Devbox. - entrypoint: (Optional) When specified, the Devbox will run this script as its main - executable. The devbox lifecycle will be bound to entrypoint, shutting down when - the process is complete. - environment_variables: (Optional) Environment variables used to configure your Devbox. - file_mounts: (Optional) Map of paths and file contents to write before setup. - launch_parameters: Parameters to configure the resources and launch time behavior of the Devbox. - metadata: User defined metadata to attach to the devbox for organization. - name: (Optional) A user specified name to give the Devbox. - prebuilt: Reference to prebuilt Blueprint to create the Devbox from. Should not be used - together with (Snapshot ID, Blueprint ID, or Blueprint name). - repo_connection_id: Repository connection id the devbox should source its base image from. - secrets: (Optional) Map of environment variable names to secret names. The secret values - will be securely injected as environment variables in the Devbox. Example: - {"DB_PASS": "DATABASE_PASSWORD"} sets environment variable 'DB_PASS' to the - value of secret 'DATABASE_PASSWORD'. - snapshot_id: Snapshot ID to use for the Devbox. Only one of (Snapshot ID, Blueprint ID, - Blueprint name) should be specified. - polling_config: Optional polling configuration - 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 - idempotency_key: Specify a custom idempotency key for this request + create_args: Arguments to pass to the `create` method. See the `create` method for detailed documentation. + request_args: Optional request arguments including polling configuration and additional request options Returns: The devbox in running state @@ -489,30 +453,22 @@ def create_and_await_running( PollingTimeout: If polling times out before devbox is running RunloopError: If devbox enters a non-running terminal state """ + # Extract polling config and other request args + if request_args is None: + request_args = {} + + # Pass all create_args to the underlying create method devbox = self.create( - blueprint_id=blueprint_id, - blueprint_name=blueprint_name, - code_mounts=code_mounts, - entrypoint=entrypoint, - environment_variables=environment_variables, - file_mounts=file_mounts, - launch_parameters=launch_parameters, - metadata=metadata, - name=name, - prebuilt=prebuilt, - repo_connection_id=repo_connection_id, - secrets=secrets, - snapshot_id=snapshot_id, - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - idempotency_key=idempotency_key, + **create_args, + extra_headers=request_args.get("extra_headers", None), + extra_query=request_args.get("extra_query", None), + extra_body=request_args.get("extra_body", None), + timeout=request_args.get("timeout", None), ) return self.await_running( devbox.id, - polling_config=polling_config, + polling_config=request_args.get("polling_config", None), ) def list( @@ -1632,61 +1588,16 @@ async def retrieve( async def create_and_await_running( self, *, - blueprint_id: Optional[str] | NotGiven = NOT_GIVEN, - blueprint_name: Optional[str] | NotGiven = NOT_GIVEN, - code_mounts: Optional[Iterable[CodeMountParameters]] | NotGiven = NOT_GIVEN, - entrypoint: Optional[str] | NotGiven = NOT_GIVEN, - environment_variables: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - file_mounts: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - launch_parameters: Optional[LaunchParameters] | NotGiven = NOT_GIVEN, - metadata: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - name: Optional[str] | NotGiven = NOT_GIVEN, - prebuilt: Optional[str] | NotGiven = NOT_GIVEN, - repo_connection_id: Optional[str] | NotGiven = NOT_GIVEN, - secrets: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN, - snapshot_id: Optional[str] | NotGiven = NOT_GIVEN, - polling_config: PollingConfig | None = None, - # 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, - idempotency_key: str | None = None, + create_args: devbox_create_params.DevboxCreateParams, + request_args: DevboxRequestArgs | None = None, ) -> DevboxView: """Create a devbox and wait for it to be in running state. + This is a wrapper around the `create` method that waits for the devbox to reach running state. + Args: - blueprint_id: Blueprint ID to use for the Devbox. If none set, the Devbox will be created with - the default Runloop Devbox image. Only one of (Snapshot ID, Blueprint ID, - Blueprint name) should be specified. - blueprint_name: Name of Blueprint to use for the Devbox. When set, this will load the latest - successfully built Blueprint with the given name. Only one of (Snapshot ID, - Blueprint ID, Blueprint name) should be specified. - code_mounts: A list of code mounts to be included in the Devbox. - entrypoint: (Optional) When specified, the Devbox will run this script as its main - executable. The devbox lifecycle will be bound to entrypoint, shutting down when - the process is complete. - environment_variables: (Optional) Environment variables used to configure your Devbox. - file_mounts: (Optional) Map of paths and file contents to write before setup. - launch_parameters: Parameters to configure the resources and launch time behavior of the Devbox. - metadata: User defined metadata to attach to the devbox for organization. - name: (Optional) A user specified name to give the Devbox. - prebuilt: Reference to prebuilt Blueprint to create the Devbox from. Should not be used - together with (Snapshot ID, Blueprint ID, or Blueprint name). - repo_connection_id: Repository connection id the devbox should source its base image from. - secrets: (Optional) Map of environment variable names to secret names. The secret values - will be securely injected as environment variables in the Devbox. Example: - {"DB_PASS": "DATABASE_PASSWORD"} sets environment variable 'DB_PASS' to the - value of secret 'DATABASE_PASSWORD'. - snapshot_id: Snapshot ID to use for the Devbox. Only one of (Snapshot ID, Blueprint ID, - Blueprint name) should be specified. - polling_config: Optional polling configuration - 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 - idempotency_key: Specify a custom idempotency key for this request + create_args: Arguments to pass to the `create` method. See the `create` method for detailed documentation. + request_args: Optional request arguments including polling configuration and additional request options Returns: The devbox in running state @@ -1695,30 +1606,16 @@ async def create_and_await_running( PollingTimeout: If polling times out before devbox is running RunloopError: If devbox enters a non-running terminal state """ - devbox = await self.create( - blueprint_id=blueprint_id, - blueprint_name=blueprint_name, - code_mounts=code_mounts, - entrypoint=entrypoint, - environment_variables=environment_variables, - file_mounts=file_mounts, - launch_parameters=launch_parameters, - metadata=metadata, - name=name, - prebuilt=prebuilt, - repo_connection_id=repo_connection_id, - secrets=secrets, - snapshot_id=snapshot_id, - extra_headers=extra_headers, - extra_query=extra_query, - extra_body=extra_body, - timeout=timeout, - idempotency_key=idempotency_key, - ) + # Pass all create_args to the underlying create method + devbox = await self.create(**create_args) + + # Extract polling config and other request args + if request_args is None: + request_args = {} return await self.await_running( devbox.id, - polling_config=polling_config, + polling_config=request_args.get("polling_config", None), ) async def await_running( diff --git a/tests/api_resources/test_devboxes.py b/tests/api_resources/test_devboxes.py index b98989d0f..c83eb021a 100644 --- a/tests/api_resources/test_devboxes.py +++ b/tests/api_resources/test_devboxes.py @@ -1181,7 +1181,11 @@ def test_method_create_and_await_running_success(self, client: Runloop) -> None: mock_create.return_value = mock_devbox_creating mock_await.return_value = mock_devbox_running - result = client.devboxes.create_and_await_running(name="test") + result = client.devboxes.create_and_await_running( + create_args={ + "name": "test", + } + ) assert result.id == "test_id" assert result.status == "running" @@ -1219,7 +1223,14 @@ def test_method_create_and_await_running_with_config(self, client: Runloop) -> N mock_create.return_value = mock_devbox_creating mock_await.return_value = mock_devbox_running - result = client.devboxes.create_and_await_running(name="test", polling_config=config) + result = client.devboxes.create_and_await_running( + create_args={ + "name": "test", + }, + request_args={ + "polling_config": config, + }, + ) assert result.id == "test_id" assert result.status == "running" @@ -1237,7 +1248,11 @@ def test_method_create_and_await_running_create_failure(self, client: Runloop) - mock_create.side_effect = mock_error with pytest.raises(APIStatusError, match="Bad request"): - client.devboxes.create_and_await_running(name="test") + client.devboxes.create_and_await_running( + create_args={ + "name": "test", + } + ) @parametrize def test_method_create_and_await_running_await_failure(self, client: Runloop) -> None: @@ -1259,7 +1274,11 @@ def test_method_create_and_await_running_await_failure(self, client: Runloop) -> mock_await.side_effect = RunloopError("Devbox entered non-running terminal state: failed") with pytest.raises(RunloopError, match="Devbox entered non-running terminal state: failed"): - client.devboxes.create_and_await_running(name="test") + client.devboxes.create_and_await_running( + create_args={ + "name": "test", + } + ) class TestAsyncDevboxes: diff --git a/uv.lock b/uv.lock index d749fe798..3e8708e13 100644 --- a/uv.lock +++ b/uv.lock @@ -1215,9 +1215,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a1/0c/c5c5cd3689c32ed1fe8c5d234b079c12c281c051759770c05b8bed6412b5/pydantic_core-2.27.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7d0c8399fcc1848491f00e0314bd59fb34a9c008761bcb422a057670c3f65e35", size = 2004961, upload_time = "2024-12-18T11:31:52.446Z" }, ] +[[package]] +name = "ruff" +version = "0.12.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/81/0bd3594fa0f690466e41bd033bdcdf86cba8288345ac77ad4afbe5ec743a/ruff-0.12.7.tar.gz", hash = "sha256:1fc3193f238bc2d7968772c82831a4ff69252f673be371fb49663f0068b7ec71", size = 5197814, upload_time = "2025-07-29T22:32:35.877Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/d2/6cb35e9c85e7a91e8d22ab32ae07ac39cc34a71f1009a6f9e4a2a019e602/ruff-0.12.7-py3-none-linux_armv6l.whl", hash = "sha256:76e4f31529899b8c434c3c1dede98c4483b89590e15fb49f2d46183801565303", size = 11852189, upload_time = "2025-07-29T22:31:41.281Z" }, + { url = "https://files.pythonhosted.org/packages/63/5b/a4136b9921aa84638f1a6be7fb086f8cad0fde538ba76bda3682f2599a2f/ruff-0.12.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:789b7a03e72507c54fb3ba6209e4bb36517b90f1a3569ea17084e3fd295500fb", size = 12519389, upload_time = "2025-07-29T22:31:54.265Z" }, + { url = "https://files.pythonhosted.org/packages/a8/c9/3e24a8472484269b6b1821794141f879c54645a111ded4b6f58f9ab0705f/ruff-0.12.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e1c2a3b8626339bb6369116e7030a4cf194ea48f49b64bb505732a7fce4f4e3", size = 11743384, upload_time = "2025-07-29T22:31:59.575Z" }, + { url = "https://files.pythonhosted.org/packages/26/7c/458dd25deeb3452c43eaee853c0b17a1e84169f8021a26d500ead77964fd/ruff-0.12.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32dec41817623d388e645612ec70d5757a6d9c035f3744a52c7b195a57e03860", size = 11943759, upload_time = "2025-07-29T22:32:01.95Z" }, + { url = "https://files.pythonhosted.org/packages/7f/8b/658798472ef260ca050e400ab96ef7e85c366c39cf3dfbef4d0a46a528b6/ruff-0.12.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47ef751f722053a5df5fa48d412dbb54d41ab9b17875c6840a58ec63ff0c247c", size = 11654028, upload_time = "2025-07-29T22:32:04.367Z" }, + { url = "https://files.pythonhosted.org/packages/a8/86/9c2336f13b2a3326d06d39178fd3448dcc7025f82514d1b15816fe42bfe8/ruff-0.12.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a828a5fc25a3efd3e1ff7b241fd392686c9386f20e5ac90aa9234a5faa12c423", size = 13225209, upload_time = "2025-07-29T22:32:06.952Z" }, + { url = "https://files.pythonhosted.org/packages/76/69/df73f65f53d6c463b19b6b312fd2391dc36425d926ec237a7ed028a90fc1/ruff-0.12.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5726f59b171111fa6a69d82aef48f00b56598b03a22f0f4170664ff4d8298efb", size = 14182353, upload_time = "2025-07-29T22:32:10.053Z" }, + { url = "https://files.pythonhosted.org/packages/58/1e/de6cda406d99fea84b66811c189b5ea139814b98125b052424b55d28a41c/ruff-0.12.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74e6f5c04c4dd4aba223f4fe6e7104f79e0eebf7d307e4f9b18c18362124bccd", size = 13631555, upload_time = "2025-07-29T22:32:12.644Z" }, + { url = "https://files.pythonhosted.org/packages/6f/ae/625d46d5164a6cc9261945a5e89df24457dc8262539ace3ac36c40f0b51e/ruff-0.12.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d0bfe4e77fba61bf2ccadf8cf005d6133e3ce08793bbe870dd1c734f2699a3e", size = 12667556, upload_time = "2025-07-29T22:32:15.312Z" }, + { url = "https://files.pythonhosted.org/packages/55/bf/9cb1ea5e3066779e42ade8d0cd3d3b0582a5720a814ae1586f85014656b6/ruff-0.12.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06bfb01e1623bf7f59ea749a841da56f8f653d641bfd046edee32ede7ff6c606", size = 12939784, upload_time = "2025-07-29T22:32:17.69Z" }, + { url = "https://files.pythonhosted.org/packages/55/7f/7ead2663be5627c04be83754c4f3096603bf5e99ed856c7cd29618c691bd/ruff-0.12.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e41df94a957d50083fd09b916d6e89e497246698c3f3d5c681c8b3e7b9bb4ac8", size = 11771356, upload_time = "2025-07-29T22:32:20.134Z" }, + { url = "https://files.pythonhosted.org/packages/17/40/a95352ea16edf78cd3a938085dccc55df692a4d8ba1b3af7accbe2c806b0/ruff-0.12.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4000623300563c709458d0ce170c3d0d788c23a058912f28bbadc6f905d67afa", size = 11612124, upload_time = "2025-07-29T22:32:22.645Z" }, + { url = "https://files.pythonhosted.org/packages/4d/74/633b04871c669e23b8917877e812376827c06df866e1677f15abfadc95cb/ruff-0.12.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:69ffe0e5f9b2cf2b8e289a3f8945b402a1b19eff24ec389f45f23c42a3dd6fb5", size = 12479945, upload_time = "2025-07-29T22:32:24.765Z" }, + { url = "https://files.pythonhosted.org/packages/be/34/c3ef2d7799c9778b835a76189c6f53c179d3bdebc8c65288c29032e03613/ruff-0.12.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a07a5c8ffa2611a52732bdc67bf88e243abd84fe2d7f6daef3826b59abbfeda4", size = 12998677, upload_time = "2025-07-29T22:32:27.022Z" }, + { url = "https://files.pythonhosted.org/packages/77/ab/aca2e756ad7b09b3d662a41773f3edcbd262872a4fc81f920dc1ffa44541/ruff-0.12.7-py3-none-win32.whl", hash = "sha256:c928f1b2ec59fb77dfdf70e0419408898b63998789cc98197e15f560b9e77f77", size = 11756687, upload_time = "2025-07-29T22:32:29.381Z" }, + { url = "https://files.pythonhosted.org/packages/b4/71/26d45a5042bc71db22ddd8252ca9d01e9ca454f230e2996bb04f16d72799/ruff-0.12.7-py3-none-win_amd64.whl", hash = "sha256:9c18f3d707ee9edf89da76131956aba1270c6348bfee8f6c647de841eac7194f", size = 12912365, upload_time = "2025-07-29T22:32:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/4c/9b/0b8aa09817b63e78d94b4977f18b1fcaead3165a5ee49251c5d5c245bb2d/ruff-0.12.7-py3-none-win_arm64.whl", hash = "sha256:dfce05101dbd11833a0776716d5d1578641b7fddb537fe7fa956ab85d1769b69", size = 11982083, upload_time = "2025-07-29T22:32:33.881Z" }, +] + [[package]] name = "runloop-api-client" -version = "0.50.0" +version = "0.53.0" source = { editable = "." } dependencies = [ { name = "anyio", version = "4.5.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" }, @@ -1236,6 +1261,11 @@ aiohttp = [ { name = "httpx-aiohttp" }, ] +[package.dev-dependencies] +dev = [ + { name = "ruff" }, +] + [package.metadata] requires-dist = [ { name = "aiohttp", marker = "extra == 'aiohttp'" }, @@ -1249,6 +1279,9 @@ requires-dist = [ ] provides-extras = ["aiohttp"] +[package.metadata.requires-dev] +dev = [{ name = "ruff", specifier = ">=0.12.7" }] + [[package]] name = "sniffio" version = "1.3.1"