runnee 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- runnee-0.1.0/.gitignore +13 -0
- runnee-0.1.0/CHANGELOG.md +9 -0
- runnee-0.1.0/CONTRIBUTING.md +29 -0
- runnee-0.1.0/LICENSE +21 -0
- runnee-0.1.0/PKG-INFO +113 -0
- runnee-0.1.0/README.md +88 -0
- runnee-0.1.0/RELEASING.md +31 -0
- runnee-0.1.0/SECURITY.md +11 -0
- runnee-0.1.0/examples/async_quickstart.py +13 -0
- runnee-0.1.0/examples/quickstart.py +6 -0
- runnee-0.1.0/openapi.json +7932 -0
- runnee-0.1.0/pyproject.toml +46 -0
- runnee-0.1.0/src/runnee/__init__.py +38 -0
- runnee-0.1.0/src/runnee/_http.py +375 -0
- runnee-0.1.0/src/runnee/_validation.py +78 -0
- runnee-0.1.0/src/runnee/clients.py +579 -0
- runnee-0.1.0/src/runnee/contracts.json +1547 -0
- runnee-0.1.0/src/runnee/errors.py +54 -0
- runnee-0.1.0/src/runnee/py.typed +0 -0
- runnee-0.1.0/src/runnee/types.py +273 -0
- runnee-0.1.0/tests/test_client.py +261 -0
runnee-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 — Unreleased
|
|
4
|
+
|
|
5
|
+
Explicit API-key constructor arguments are supported; existing configuration remains compatible.
|
|
6
|
+
|
|
7
|
+
Initial remote-only Runnee Cloud client: execution, retained history, saved scripts and versions, encrypted secret management, usage, sandbox limits, public plan/health information and scoped telemetry. Includes typed errors, bounded responses, timeouts, cancellation, safe retries and pagination.
|
|
8
|
+
|
|
9
|
+
No package has been published by this implementation. API-key issuance, account management, payment mutations and remote cancellation remain unavailable to SDK API keys.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thank you for contributing to the official Runnee Cloud SDK. This repository contains the remote API client only. Keep runtime, infrastructure and customer data out of changes.
|
|
4
|
+
|
|
5
|
+
## Local checks
|
|
6
|
+
|
|
7
|
+
Use Python 3.11 or later in a virtual environment.
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
python -m venv .venv
|
|
11
|
+
# Activate .venv using your shell.
|
|
12
|
+
python -m pip install -e ".[dev]"
|
|
13
|
+
python -m pytest
|
|
14
|
+
python -m mypy
|
|
15
|
+
python -m ruff check .
|
|
16
|
+
python -m ruff format --check .
|
|
17
|
+
python -m build
|
|
18
|
+
python -m twine check dist/*
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Pull requests
|
|
22
|
+
|
|
23
|
+
Add regression coverage for behavior changes. Keep public names compatible and document changes in CHANGELOG.md. Never commit real API keys, secret values, .env files or customer responses. Tests use synthetic keys and local HTTP mocks; they neither execute customer scripts nor require production credentials. Live API verification belongs in an isolated staging account.
|
|
24
|
+
|
|
25
|
+
The checked-in openapi.json is the public API contract snapshot. Coordinate API changes with the platform maintainers, then update this snapshot, client types, validation and tests together. Do not add methods for unimplemented endpoints.
|
|
26
|
+
|
|
27
|
+
## Releases and security
|
|
28
|
+
|
|
29
|
+
Follow [RELEASING.md](RELEASING.md). Use semantic versioning; breaking public changes require a major release (during 0.x, a new minor release). Security reports follow [SECURITY.md](SECURITY.md), rather than public issue reports.
|
runnee-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Runnee
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
runnee-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: runnee
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Official synchronous and asynchronous Python SDK for Runnee Cloud
|
|
5
|
+
Project-URL: Homepage, https://runnee.cloud/docs#sdk
|
|
6
|
+
Project-URL: Repository, https://github.com/Runnee-cloud/runnee-sdk-python
|
|
7
|
+
Project-URL: Issues, https://github.com/Runnee-cloud/runnee-sdk-python/issues
|
|
8
|
+
Author: Runnee
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: runnee,sdk,serverless
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Typing :: Typed
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Requires-Dist: httpx<1,>=0.27
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
19
|
+
Requires-Dist: mypy>=1.15; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest-asyncio>=0.25; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
22
|
+
Requires-Dist: ruff>=0.11; extra == 'dev'
|
|
23
|
+
Requires-Dist: twine>=6; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# runnee
|
|
27
|
+
|
|
28
|
+
Official synchronous and asynchronous Python SDK for Runnee Cloud. Remote execution only; no interpreter is distributed. Python 3.11+; one runtime dependency, HTTPX.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
Release candidate: registry commands apply after publication. Local installation from this repository: pip install .
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
pip install runnee
|
|
36
|
+
uv add runnee
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quickstart
|
|
40
|
+
|
|
41
|
+
Create a dashboard API key with scripts:execute and set RUNNEE_API_KEY on your server.
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
import os
|
|
45
|
+
from runnee import Runnee
|
|
46
|
+
|
|
47
|
+
with Runnee(api_key=os.environ["RUNNEE_API_KEY"]) as client:
|
|
48
|
+
result = client.execute(code="function main() { return 10 + 20; }", mode="dry-run")
|
|
49
|
+
if result["success"] and "executionResult" in result:
|
|
50
|
+
print(result["executionResult"].get("returnValue"))
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
import os
|
|
55
|
+
import asyncio
|
|
56
|
+
from runnee import AsyncRunnee
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
async def main():
|
|
60
|
+
async with AsyncRunnee(api_key=os.environ["RUNNEE_API_KEY"]) as client:
|
|
61
|
+
result = await client.execute(code="function main() { return 30; }")
|
|
62
|
+
print(result)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
asyncio.run(main())
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Use AsyncRunnee in FastAPI async routes; Runnee suits synchronous Flask/Django views and jobs. Clients own reusable connection pools; close them or use context managers.
|
|
69
|
+
|
|
70
|
+
## Configuration
|
|
71
|
+
|
|
72
|
+
Runnee(api_key=..., base_url="https://api.runnee.cloud", timeout=30, max_retries=2) and AsyncRunnee accept identical configuration. RUNNEE_BASE_URL is an optional fallback. timeout is seconds. HTTP requires loopback or explicit allow_insecure_http development use; redirects and environment proxy inheritance are disabled. Custom HTTPX transports support controlled testing.
|
|
73
|
+
|
|
74
|
+
RequestOptions(timeout=..., max_retries=..., idempotency_key=..., cancel_event=..., on_response=...) supplies per-call behavior. Async client cancellation uses asyncio task cancellation. Sync cancel_event is checked between attempts and received response chunks; an in-flight socket can wait until its HTTPX timeout. Async timeout bounds the complete operation; sync uses the remaining budget for network timeouts and checks the deadline while receiving chunks and between attempts. A client timeout does not change the script execution budget.
|
|
75
|
+
|
|
76
|
+
## API reference
|
|
77
|
+
|
|
78
|
+
- execute(code=..., mode="dry-run", event=..., retain_source=False, script_name=..., secret_names=..., script_id=..., options=...)
|
|
79
|
+
- executions.list(before=..., status=..., mode=...), get(id), iterate(...). Use for in sync or async for in async code. Pages contain at most20 items; history retention is3days.
|
|
80
|
+
- scripts.list(), create(name=..., code=...), get(id), update(id,name=...,code=...,expected_version=...), delete(id), get_version(id,version), restore(id,version=...,expected_version=...), storage().
|
|
81
|
+
- secrets.list(), get(name), create(name=...,value=...,allow_inline=False,script_ids=...), update(name,value=...,allow_inline=...,script_ids=...), delete(name).
|
|
82
|
+
- usage.get(), summary(), history(days=7|30|90); sandbox.get(); billing.plans(); health.get().
|
|
83
|
+
- telemetry.record_execution(input), record_event(input). External execution records consume quota.
|
|
84
|
+
|
|
85
|
+
Async methods use the same names with await. Returned dictionaries follow API camelCase names and have generated TypedDict definitions in runnee.types. Arguments follow Python snake_case. SDK API-key issuance/revocation, account/payment mutations and remote execution cancellation are not supported.
|
|
86
|
+
|
|
87
|
+
## Secret usage
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
import os
|
|
91
|
+
from runnee import Runnee
|
|
92
|
+
|
|
93
|
+
with Runnee(api_key=os.environ["RUNNEE_API_KEY"]) as client:
|
|
94
|
+
client.secrets.create(name="EXTERNAL_API_KEY", value=os.environ["EXTERNAL_API_KEY"], allow_inline=True)
|
|
95
|
+
result = client.execute(
|
|
96
|
+
code='use("secrets"); function main() { return secrets.has("EXTERNAL_API_KEY"); }',
|
|
97
|
+
secret_names=["EXTERNAL_API_KEY"],
|
|
98
|
+
)
|
|
99
|
+
client.secrets.update("EXTERNAL_API_KEY", value=os.environ["REPLACEMENT_API_KEY"])
|
|
100
|
+
client.secrets.delete("EXTERNAL_API_KEY")
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Metadata is readable with secrets:read; writes require secrets:write; grants require scripts:execute and secrets:use. Prefer script_ids policies over allow_inline; execute with script_id and the exact current saved source. Secrets remain inaccessible until explicitly named on an execution. Management responses never contain values. See SECURITY.md for disclosure boundaries.
|
|
104
|
+
|
|
105
|
+
## Reliability and errors
|
|
106
|
+
|
|
107
|
+
Read requests retry transient network failures and 429/500/502/503/504 with exponential jitter and Retry-After. Auth failures are never retried. Writes are not retried by default. Execute retries require an idempotency_key in RequestOptions. Reuse it after an uncertain network failure. Receipts expire after24hours and replay only summaries, not original output; HTTP409 can mean the original execution is pending. Inspect history before choosing a new key.
|
|
108
|
+
|
|
109
|
+
RunneeError subclasses: RunneeAuthenticationError, RunneePermissionError, RunneeValidationError, RunneeRateLimitError, RunneeTimeoutError, RunneeNetworkError, RunneeServerError, RunneeConflictError, RunneeNotFoundError, RunneeResponseError, RunneeCancelledError. Errors expose status/request_id; RateLimit exposes retry_after seconds. Script failures return success=False instead of raising an HTTP exception.
|
|
110
|
+
|
|
111
|
+
## Development
|
|
112
|
+
|
|
113
|
+
pip install -e '.[dev]'; pytest; mypy; ruff check .; ruff format --check .; python -m build. CI tests supported Python versions and both clients. See CONTRIBUTING.md, CHANGELOG.md and RELEASING.md. MIT licensed. Publication is a separate approved release step.
|
runnee-0.1.0/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# runnee
|
|
2
|
+
|
|
3
|
+
Official synchronous and asynchronous Python SDK for Runnee Cloud. Remote execution only; no interpreter is distributed. Python 3.11+; one runtime dependency, HTTPX.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Release candidate: registry commands apply after publication. Local installation from this repository: pip install .
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pip install runnee
|
|
11
|
+
uv add runnee
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quickstart
|
|
15
|
+
|
|
16
|
+
Create a dashboard API key with scripts:execute and set RUNNEE_API_KEY on your server.
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
import os
|
|
20
|
+
from runnee import Runnee
|
|
21
|
+
|
|
22
|
+
with Runnee(api_key=os.environ["RUNNEE_API_KEY"]) as client:
|
|
23
|
+
result = client.execute(code="function main() { return 10 + 20; }", mode="dry-run")
|
|
24
|
+
if result["success"] and "executionResult" in result:
|
|
25
|
+
print(result["executionResult"].get("returnValue"))
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
import os
|
|
30
|
+
import asyncio
|
|
31
|
+
from runnee import AsyncRunnee
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
async def main():
|
|
35
|
+
async with AsyncRunnee(api_key=os.environ["RUNNEE_API_KEY"]) as client:
|
|
36
|
+
result = await client.execute(code="function main() { return 30; }")
|
|
37
|
+
print(result)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
asyncio.run(main())
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Use AsyncRunnee in FastAPI async routes; Runnee suits synchronous Flask/Django views and jobs. Clients own reusable connection pools; close them or use context managers.
|
|
44
|
+
|
|
45
|
+
## Configuration
|
|
46
|
+
|
|
47
|
+
Runnee(api_key=..., base_url="https://api.runnee.cloud", timeout=30, max_retries=2) and AsyncRunnee accept identical configuration. RUNNEE_BASE_URL is an optional fallback. timeout is seconds. HTTP requires loopback or explicit allow_insecure_http development use; redirects and environment proxy inheritance are disabled. Custom HTTPX transports support controlled testing.
|
|
48
|
+
|
|
49
|
+
RequestOptions(timeout=..., max_retries=..., idempotency_key=..., cancel_event=..., on_response=...) supplies per-call behavior. Async client cancellation uses asyncio task cancellation. Sync cancel_event is checked between attempts and received response chunks; an in-flight socket can wait until its HTTPX timeout. Async timeout bounds the complete operation; sync uses the remaining budget for network timeouts and checks the deadline while receiving chunks and between attempts. A client timeout does not change the script execution budget.
|
|
50
|
+
|
|
51
|
+
## API reference
|
|
52
|
+
|
|
53
|
+
- execute(code=..., mode="dry-run", event=..., retain_source=False, script_name=..., secret_names=..., script_id=..., options=...)
|
|
54
|
+
- executions.list(before=..., status=..., mode=...), get(id), iterate(...). Use for in sync or async for in async code. Pages contain at most20 items; history retention is3days.
|
|
55
|
+
- scripts.list(), create(name=..., code=...), get(id), update(id,name=...,code=...,expected_version=...), delete(id), get_version(id,version), restore(id,version=...,expected_version=...), storage().
|
|
56
|
+
- secrets.list(), get(name), create(name=...,value=...,allow_inline=False,script_ids=...), update(name,value=...,allow_inline=...,script_ids=...), delete(name).
|
|
57
|
+
- usage.get(), summary(), history(days=7|30|90); sandbox.get(); billing.plans(); health.get().
|
|
58
|
+
- telemetry.record_execution(input), record_event(input). External execution records consume quota.
|
|
59
|
+
|
|
60
|
+
Async methods use the same names with await. Returned dictionaries follow API camelCase names and have generated TypedDict definitions in runnee.types. Arguments follow Python snake_case. SDK API-key issuance/revocation, account/payment mutations and remote execution cancellation are not supported.
|
|
61
|
+
|
|
62
|
+
## Secret usage
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import os
|
|
66
|
+
from runnee import Runnee
|
|
67
|
+
|
|
68
|
+
with Runnee(api_key=os.environ["RUNNEE_API_KEY"]) as client:
|
|
69
|
+
client.secrets.create(name="EXTERNAL_API_KEY", value=os.environ["EXTERNAL_API_KEY"], allow_inline=True)
|
|
70
|
+
result = client.execute(
|
|
71
|
+
code='use("secrets"); function main() { return secrets.has("EXTERNAL_API_KEY"); }',
|
|
72
|
+
secret_names=["EXTERNAL_API_KEY"],
|
|
73
|
+
)
|
|
74
|
+
client.secrets.update("EXTERNAL_API_KEY", value=os.environ["REPLACEMENT_API_KEY"])
|
|
75
|
+
client.secrets.delete("EXTERNAL_API_KEY")
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Metadata is readable with secrets:read; writes require secrets:write; grants require scripts:execute and secrets:use. Prefer script_ids policies over allow_inline; execute with script_id and the exact current saved source. Secrets remain inaccessible until explicitly named on an execution. Management responses never contain values. See SECURITY.md for disclosure boundaries.
|
|
79
|
+
|
|
80
|
+
## Reliability and errors
|
|
81
|
+
|
|
82
|
+
Read requests retry transient network failures and 429/500/502/503/504 with exponential jitter and Retry-After. Auth failures are never retried. Writes are not retried by default. Execute retries require an idempotency_key in RequestOptions. Reuse it after an uncertain network failure. Receipts expire after24hours and replay only summaries, not original output; HTTP409 can mean the original execution is pending. Inspect history before choosing a new key.
|
|
83
|
+
|
|
84
|
+
RunneeError subclasses: RunneeAuthenticationError, RunneePermissionError, RunneeValidationError, RunneeRateLimitError, RunneeTimeoutError, RunneeNetworkError, RunneeServerError, RunneeConflictError, RunneeNotFoundError, RunneeResponseError, RunneeCancelledError. Errors expose status/request_id; RateLimit exposes retry_after seconds. Script failures return success=False instead of raising an HTTP exception.
|
|
85
|
+
|
|
86
|
+
## Development
|
|
87
|
+
|
|
88
|
+
pip install -e '.[dev]'; pytest; mypy; ruff check .; ruff format --check .; python -m build. CI tests supported Python versions and both clients. See CONTRIBUTING.md, CHANGELOG.md and RELEASING.md. MIT licensed. Publication is a separate approved release step.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Releasing
|
|
2
|
+
|
|
3
|
+
This repository is prepared for public release but no registry publication is implied by its presence. Never publish before the matching API and secrets features have passed staging verification. The SDK does not deploy or configure the service.
|
|
4
|
+
|
|
5
|
+
## GitHub setup (maintainer)
|
|
6
|
+
|
|
7
|
+
Create an empty **public** repository named runnee-sdk-python under `Runnee-cloud` (or update all repository URLs first). From the prepared SDK folder:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
git init -b main
|
|
11
|
+
git add .
|
|
12
|
+
git commit -m "Initial public SDK release"
|
|
13
|
+
git remote add origin https://github.com/Runnee-cloud/runnee-sdk-python.git
|
|
14
|
+
git push -u origin main
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Review `git diff --cached` before committing. Never upload the parent application repository. Enable GitHub private vulnerability reporting, dependency alerts and branch protection. Create the `pypi` GitHub Actions environment; restrict it to main and require a maintainer review if available for your account. The workflow only publishes when manually requested with publish=true on main. Ordinary pushes and tags run CI only. A manual run with publish=false builds downloadable artifacts without publishing.
|
|
18
|
+
|
|
19
|
+
## Versioning
|
|
20
|
+
|
|
21
|
+
Use semantic versioning. Update all version constants and CHANGELOG.md together. Search for the previous version in tracked files, including HTTP User-Agent strings; review the diff and regenerate distribution files. The workflow checks the expected version before building. Once published, treat versioned artifacts as immutable. After publication, tag the exact tested commit `vVERSION` and attach checksums and artifacts to a GitHub release.
|
|
22
|
+
|
|
23
|
+
## PyPI
|
|
24
|
+
|
|
25
|
+
1. Confirm `runnee` availability and ownership at https://pypi.org/project/runnee/. A 404 does not reserve the name. If unavailable, select another distribution name and update pyproject.toml and installation documentation consistently.
|
|
26
|
+
2. Run the checks in CONTRIBUTING.md, `python -m build`, and `python -m twine check dist/*`. Inspect both the wheel and source archive.
|
|
27
|
+
3. In your PyPI account, add a **pending publisher** for project `runnee`: owner `Runnee-cloud`, repository `runnee-sdk-python`, workflow `release.yml`, environment `pypi`. For an existing project, add the same configuration in its Publishing settings.
|
|
28
|
+
4. Actions → Release → Run workflow on main; set the expected version and publish=true. Approve the pypi environment job. The workflow publishes the previously built distributions using OIDC; no PyPI token belongs in GitHub secrets.
|
|
29
|
+
5. Verify in a clean environment using `pip install runnee==VERSION` and check sync and async imports. Also verify `uv add runnee==VERSION`.
|
|
30
|
+
|
|
31
|
+
See [PyPI pending publishers](https://docs.pypi.org/trusted-publishers/creating-a-project-through-oidc/) and [publishing with OIDC](https://docs.pypi.org/trusted-publishers/using-a-publisher/).
|
runnee-0.1.0/SECURITY.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
Report vulnerabilities privately through GitHub private vulnerability reporting for the repository, when enabled. If unavailable, use the Runnee contact form and request a private security channel; do not post credentials or exploitable details publicly.
|
|
4
|
+
|
|
5
|
+
API keys belong only on trusted servers. These SDKs execute code remotely and contain no interpreter. Requests use HTTPS by default, do not follow redirects, and do not log credentials or retain raw response bodies in exceptions. HTTP is limited to loopback unless explicitly enabled for development. Never disable TLS verification in production.
|
|
6
|
+
|
|
7
|
+
Only the latest released minor version receives fixes while the SDK is pre-1.0. Dependencies should be patched promptly. Caller-provided transports are trusted code and must preserve authentication and TLS protections.
|
|
8
|
+
|
|
9
|
+
Execution retries require an idempotency key. Receipt replays omit the original output, and a pending result is not evidence that execution failed. Client cancellation stops waiting; it does not guarantee remote cancellation.
|
|
10
|
+
|
|
11
|
+
Secrets are encrypted by Runnee and granted explicitly to executions. Management returns metadata only. Do not put credentials in script source, events, telemetry, replies or errors. Redaction covers common accidental verbatim/encoded disclosure; it cannot stop an authorized malicious script from transforming or sending a secret to an external endpoint. Review secret-enabled scripts and narrow HTTP permissions. SDK request bodies necessarily contain values during create/rotate; configure application/APM instrumentation to omit them.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import asyncio
|
|
3
|
+
from runnee import AsyncRunnee
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async def main() -> None:
|
|
7
|
+
async with AsyncRunnee(api_key=os.environ["RUNNEE_API_KEY"]) as client:
|
|
8
|
+
result = await client.execute(code="function main(){return 10+20;}")
|
|
9
|
+
print(result)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if __name__ == "__main__":
|
|
13
|
+
asyncio.run(main())
|