Skip to content

Commit

Permalink
feat(api): OpenAPI spec update via Stainless API (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
stainless-app[bot] authored and stainless-bot committed Apr 19, 2024
1 parent 9839ac0 commit cce36c0
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 36 deletions.
35 changes: 28 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ client = Riza(
api_key=os.environ.get("RIZA_API_KEY"),
)

sandbox_execute_response = client.sandbox.execute()
sandbox_execute_response = client.sandbox.execute(
code='print("Hello world!")',
language="PYTHON",
)
print(sandbox_execute_response.exit_code)
```

Expand All @@ -57,7 +60,10 @@ client = AsyncRiza(


async def main() -> None:
sandbox_execute_response = await client.sandbox.execute()
sandbox_execute_response = await client.sandbox.execute(
code='print("Hello world!")',
language="PYTHON",
)
print(sandbox_execute_response.exit_code)


Expand Down Expand Up @@ -91,7 +97,10 @@ from rizaio import Riza
client = Riza()

try:
client.sandbox.execute()
client.sandbox.execute(
code='print("Hello world!")',
language="PYTHON",
)
except rizaio.APIConnectionError as e:
print("The server could not be reached")
print(e.__cause__) # an underlying Exception, likely raised within httpx.
Expand Down Expand Up @@ -134,7 +143,10 @@ client = Riza(
)

# Or, configure per-request:
client.with_options(max_retries=5).sandbox.execute()
client.with_options(max_retries=5).sandbox.execute(
code='print("Hello world!")',
language="PYTHON",
)
```

### Timeouts
Expand All @@ -157,7 +169,10 @@ client = Riza(
)

# Override per-request:
client.with_options(timeout=5 * 1000).sandbox.execute()
client.with_options(timeout=5 * 1000).sandbox.execute(
code='print("Hello world!")',
language="PYTHON",
)
```

On timeout, an `APITimeoutError` is thrown.
Expand Down Expand Up @@ -196,7 +211,10 @@ The "raw" Response object can be accessed by prefixing `.with_raw_response.` to
from rizaio import Riza

client = Riza()
response = client.sandbox.with_raw_response.execute()
response = client.sandbox.with_raw_response.execute(
code="print(\"Hello world!\")",
language="PYTHON",
)
print(response.headers.get('X-My-Header'))

sandbox = response.parse() # get the object that `sandbox.execute()` would have returned
Expand All @@ -214,7 +232,10 @@ The above interface eagerly reads the full response body when you make the reque
To stream the response body, use `.with_streaming_response` instead, which requires a context manager and only reads the response body once you call `.read()`, `.text()`, `.json()`, `.iter_bytes()`, `.iter_text()`, `.iter_lines()` or `.parse()`. In the async client, these are async methods.

```python
with client.sandbox.with_streaming_response.execute() as response:
with client.sandbox.with_streaming_response.execute(
code='print("Hello world!")',
language="PYTHON",
) as response:
print(response.headers.get("X-My-Header"))

for line in response.iter_lines():
Expand Down
50 changes: 40 additions & 10 deletions src/rizaio/resources/sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ def with_streaming_response(self) -> SandboxWithStreamingResponse:
def execute(
self,
*,
code: str,
language: Literal["PYTHON", "JAVASCRIPT", "TYPESCRIPT", "RUBY", "PHP"],
args: List[str] | NotGiven = NOT_GIVEN,
code: str | NotGiven = NOT_GIVEN,
env: Dict[str, str] | NotGiven = NOT_GIVEN,
language: Literal["UNSPECIFIED", "PYTHON", "JAVASCRIPT", "TYPESCRIPT", "RUBY", "PHP"] | NotGiven = NOT_GIVEN,
stdin: str | NotGiven = NOT_GIVEN,
# 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.
Expand All @@ -52,8 +52,23 @@ def execute(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SandboxExecuteResponse:
"""
"""Run a script in a secure, isolated sandbox.
Scripts can read from stdin and
write to stdout or stderr. They can access environment variables and command
line arguments.
Args:
code: The code to execute in the sandbox.
language: The interpreter to use when executing code.
args: List of command line arguments to pass to the script.
env: Set of key-value pairs to add to the script's execution environment.
stdin: Input to pass to the script via `stdin`.
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
Expand All @@ -66,10 +81,10 @@ def execute(
"/v1/execute",
body=maybe_transform(
{
"args": args,
"code": code,
"env": env,
"language": language,
"args": args,
"env": env,
"stdin": stdin,
},
sandbox_execute_params.SandboxExecuteParams,
Expand All @@ -93,10 +108,10 @@ def with_streaming_response(self) -> AsyncSandboxWithStreamingResponse:
async def execute(
self,
*,
code: str,
language: Literal["PYTHON", "JAVASCRIPT", "TYPESCRIPT", "RUBY", "PHP"],
args: List[str] | NotGiven = NOT_GIVEN,
code: str | NotGiven = NOT_GIVEN,
env: Dict[str, str] | NotGiven = NOT_GIVEN,
language: Literal["UNSPECIFIED", "PYTHON", "JAVASCRIPT", "TYPESCRIPT", "RUBY", "PHP"] | NotGiven = NOT_GIVEN,
stdin: str | NotGiven = NOT_GIVEN,
# 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.
Expand All @@ -105,8 +120,23 @@ async def execute(
extra_body: Body | None = None,
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
) -> SandboxExecuteResponse:
"""
"""Run a script in a secure, isolated sandbox.
Scripts can read from stdin and
write to stdout or stderr. They can access environment variables and command
line arguments.
Args:
code: The code to execute in the sandbox.
language: The interpreter to use when executing code.
args: List of command line arguments to pass to the script.
env: Set of key-value pairs to add to the script's execution environment.
stdin: Input to pass to the script via `stdin`.
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
Expand All @@ -119,10 +149,10 @@ async def execute(
"/v1/execute",
body=await async_maybe_transform(
{
"args": args,
"code": code,
"env": env,
"language": language,
"args": args,
"env": env,
"stdin": stdin,
},
sandbox_execute_params.SandboxExecuteParams,
Expand Down
15 changes: 10 additions & 5 deletions src/rizaio/types/sandbox_execute_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@
from __future__ import annotations

from typing import Dict, List
from typing_extensions import Literal, TypedDict
from typing_extensions import Literal, Required, TypedDict

__all__ = ["SandboxExecuteParams"]


class SandboxExecuteParams(TypedDict, total=False):
args: List[str]
code: Required[str]
"""The code to execute in the sandbox."""

code: str
language: Required[Literal["PYTHON", "JAVASCRIPT", "TYPESCRIPT", "RUBY", "PHP"]]
"""The interpreter to use when executing code."""

env: Dict[str, str]
args: List[str]
"""List of command line arguments to pass to the script."""

language: Literal["UNSPECIFIED", "PYTHON", "JAVASCRIPT", "TYPESCRIPT", "RUBY", "PHP"]
env: Dict[str, str]
"""Set of key-value pairs to add to the script's execution environment."""

stdin: str
"""Input to pass to the script via `stdin`."""
6 changes: 6 additions & 0 deletions src/rizaio/types/sandbox_execute_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@

class SandboxExecuteResponse(BaseModel):
exit_code: Optional[int] = None
"""The exit code returned by the script.
Will be `0` on success and non-zero on failure.
"""

stderr: Optional[str] = None
"""The contents of `stderr` after executing the script."""

stdout: Optional[str] = None
"""The contents of `stdout` after executing the script."""
38 changes: 28 additions & 10 deletions tests/api_resources/test_sandbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,29 @@ class TestSandbox:

@parametrize
def test_method_execute(self, client: Riza) -> None:
sandbox = client.sandbox.execute()
sandbox = client.sandbox.execute(
code='print("Hello world!")',
language="PYTHON",
)
assert_matches_type(SandboxExecuteResponse, sandbox, path=["response"])

@parametrize
def test_method_execute_with_all_params(self, client: Riza) -> None:
sandbox = client.sandbox.execute(
code='print("Hello world!")',
language="PYTHON",
args=["string", "string", "string"],
code="string",
env={"foo": "string"},
language="UNSPECIFIED",
stdin="string",
)
assert_matches_type(SandboxExecuteResponse, sandbox, path=["response"])

@parametrize
def test_raw_response_execute(self, client: Riza) -> None:
response = client.sandbox.with_raw_response.execute()
response = client.sandbox.with_raw_response.execute(
code='print("Hello world!")',
language="PYTHON",
)

assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
Expand All @@ -44,7 +50,10 @@ def test_raw_response_execute(self, client: Riza) -> None:

@parametrize
def test_streaming_response_execute(self, client: Riza) -> None:
with client.sandbox.with_streaming_response.execute() as response:
with client.sandbox.with_streaming_response.execute(
code='print("Hello world!")',
language="PYTHON",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

Expand All @@ -59,23 +68,29 @@ class TestAsyncSandbox:

@parametrize
async def test_method_execute(self, async_client: AsyncRiza) -> None:
sandbox = await async_client.sandbox.execute()
sandbox = await async_client.sandbox.execute(
code='print("Hello world!")',
language="PYTHON",
)
assert_matches_type(SandboxExecuteResponse, sandbox, path=["response"])

@parametrize
async def test_method_execute_with_all_params(self, async_client: AsyncRiza) -> None:
sandbox = await async_client.sandbox.execute(
code='print("Hello world!")',
language="PYTHON",
args=["string", "string", "string"],
code="string",
env={"foo": "string"},
language="UNSPECIFIED",
stdin="string",
)
assert_matches_type(SandboxExecuteResponse, sandbox, path=["response"])

@parametrize
async def test_raw_response_execute(self, async_client: AsyncRiza) -> None:
response = await async_client.sandbox.with_raw_response.execute()
response = await async_client.sandbox.with_raw_response.execute(
code='print("Hello world!")',
language="PYTHON",
)

assert response.is_closed is True
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
Expand All @@ -84,7 +99,10 @@ async def test_raw_response_execute(self, async_client: AsyncRiza) -> None:

@parametrize
async def test_streaming_response_execute(self, async_client: AsyncRiza) -> None:
async with async_client.sandbox.with_streaming_response.execute() as response:
async with async_client.sandbox.with_streaming_response.execute(
code='print("Hello world!")',
language="PYTHON",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"

Expand Down
8 changes: 4 additions & 4 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter) -> No
with pytest.raises(APITimeoutError):
self.client.post(
"/v1/execute",
body=cast(object, dict()),
body=cast(object, dict(code='print("Hello world!")', language="PYTHON")),
cast_to=httpx.Response,
options={"headers": {RAW_RESPONSE_HEADER: "stream"}},
)
Expand All @@ -712,7 +712,7 @@ def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter) -> Non
with pytest.raises(APIStatusError):
self.client.post(
"/v1/execute",
body=cast(object, dict()),
body=cast(object, dict(code='print("Hello world!")', language="PYTHON")),
cast_to=httpx.Response,
options={"headers": {RAW_RESPONSE_HEADER: "stream"}},
)
Expand Down Expand Up @@ -1384,7 +1384,7 @@ async def test_retrying_timeout_errors_doesnt_leak(self, respx_mock: MockRouter)
with pytest.raises(APITimeoutError):
await self.client.post(
"/v1/execute",
body=cast(object, dict()),
body=cast(object, dict(code='print("Hello world!")', language="PYTHON")),
cast_to=httpx.Response,
options={"headers": {RAW_RESPONSE_HEADER: "stream"}},
)
Expand All @@ -1399,7 +1399,7 @@ async def test_retrying_status_errors_doesnt_leak(self, respx_mock: MockRouter)
with pytest.raises(APIStatusError):
await self.client.post(
"/v1/execute",
body=cast(object, dict()),
body=cast(object, dict(code='print("Hello world!")', language="PYTHON")),
cast_to=httpx.Response,
options={"headers": {RAW_RESPONSE_HEADER: "stream"}},
)
Expand Down

0 comments on commit cce36c0

Please sign in to comment.