withruntime 0.3.0__tar.gz → 0.3.1__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.
- {withruntime-0.3.0 → withruntime-0.3.1}/PKG-INFO +1 -1
- {withruntime-0.3.0 → withruntime-0.3.1}/pyproject.toml +1 -1
- withruntime-0.3.1/tests/test_limits.py +61 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_async_products/__init__.py +2 -0
- withruntime-0.3.1/withruntime/_async_products/limits.py +20 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_sync_products/__init__.py +2 -0
- withruntime-0.3.1/withruntime/_sync_products/limits.py +21 -0
- withruntime-0.3.1/withruntime/_version.py +1 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime.egg-info/PKG-INFO +1 -1
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime.egg-info/SOURCES.txt +3 -0
- withruntime-0.3.0/withruntime/_version.py +0 -1
- {withruntime-0.3.0 → withruntime-0.3.1}/README.md +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/setup.cfg +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/tests/test_client.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/tests/test_images_volumes_interpreter.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/tests/test_previews_network_desktop.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/tests/test_referrals.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/__init__.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_async_client.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_async_products/desktop.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_async_products/images.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_async_products/interpreter.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_async_products/network.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_async_products/previews.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_async_products/referrals.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_async_products/volumes.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_clock.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_connection.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_errors.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_http.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_sync_client.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_sync_products/desktop.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_sync_products/images.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_sync_products/interpreter.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_sync_products/network.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_sync_products/previews.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_sync_products/referrals.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_sync_products/volumes.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime/_ws.py +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime.egg-info/dependency_links.txt +0 -0
- {withruntime-0.3.0 → withruntime-0.3.1}/withruntime.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "withruntime"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.1"
|
|
8
8
|
description = "Runtime Cloud: one client (sync and async) for every Runtime product. Sandboxes first."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""runtime.limits.get() against a stub API, sync and async. The route is
|
|
2
|
+
tested in packages/cloud (limits-api.test.ts)."""
|
|
3
|
+
import asyncio
|
|
4
|
+
import json
|
|
5
|
+
import threading
|
|
6
|
+
import unittest
|
|
7
|
+
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
|
|
8
|
+
|
|
9
|
+
from withruntime import AsyncRuntime, Runtime
|
|
10
|
+
|
|
11
|
+
LIMITS = {
|
|
12
|
+
"access": "full",
|
|
13
|
+
"daily": {"limitMicros": "25000000", "usedMicros": "3100000", "remainingMicros": "21900000", "window": "24h"},
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Stub(BaseHTTPRequestHandler):
|
|
18
|
+
seen: list = []
|
|
19
|
+
|
|
20
|
+
def log_message(self, *args):
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
def do_GET(self):
|
|
24
|
+
Stub.seen.append((self.command, self.path))
|
|
25
|
+
data = json.dumps(LIMITS).encode()
|
|
26
|
+
self.send_response(200)
|
|
27
|
+
self.send_header("content-type", "application/json")
|
|
28
|
+
self.send_header("content-length", str(len(data)))
|
|
29
|
+
self.end_headers()
|
|
30
|
+
self.wfile.write(data)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class LimitsTest(unittest.TestCase):
|
|
34
|
+
@classmethod
|
|
35
|
+
def setUpClass(cls):
|
|
36
|
+
cls.server = ThreadingHTTPServer(("127.0.0.1", 0), Stub)
|
|
37
|
+
threading.Thread(target=cls.server.serve_forever, daemon=True).start()
|
|
38
|
+
cls.url = f"http://127.0.0.1:{cls.server.server_address[1]}"
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def tearDownClass(cls):
|
|
42
|
+
cls.server.shutdown()
|
|
43
|
+
|
|
44
|
+
def setUp(self):
|
|
45
|
+
Stub.seen = []
|
|
46
|
+
|
|
47
|
+
def test_sync_get(self):
|
|
48
|
+
with Runtime(api_key="rk_test", base_url=self.url, max_retries=0) as runtime:
|
|
49
|
+
self.assertEqual(runtime.limits.get()["daily"]["remainingMicros"], "21900000")
|
|
50
|
+
self.assertEqual(Stub.seen, [("GET", "/v1/limits")])
|
|
51
|
+
|
|
52
|
+
def test_async_get(self):
|
|
53
|
+
async def go():
|
|
54
|
+
async with AsyncRuntime(api_key="rk_test", base_url=self.url, max_retries=0) as runtime:
|
|
55
|
+
return await runtime.limits.get()
|
|
56
|
+
|
|
57
|
+
self.assertEqual(asyncio.run(go())["access"], "full")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
unittest.main()
|
|
@@ -18,6 +18,7 @@ from typing import Any
|
|
|
18
18
|
from .desktop import AsyncDesktop
|
|
19
19
|
from .images import AsyncImages
|
|
20
20
|
from .interpreter import AsyncInterpreter
|
|
21
|
+
from .limits import AsyncLimits
|
|
21
22
|
from .network import AsyncNetwork
|
|
22
23
|
from .previews import AsyncPreviews
|
|
23
24
|
from .referrals import AsyncReferrals
|
|
@@ -28,6 +29,7 @@ SANDBOX: dict[str, Any] = {}
|
|
|
28
29
|
CLIENT["images"] = AsyncImages
|
|
29
30
|
CLIENT["volumes"] = AsyncVolumes
|
|
30
31
|
CLIENT["referrals"] = AsyncReferrals
|
|
32
|
+
CLIENT["limits"] = AsyncLimits
|
|
31
33
|
SANDBOX["interpreter"] = AsyncInterpreter
|
|
32
34
|
SANDBOX["previews"] = AsyncPreviews
|
|
33
35
|
SANDBOX["network"] = AsyncNetwork
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AsyncLimits:
|
|
7
|
+
"""``runtime.limits``. Whether this key is read-only, and the daily spending
|
|
8
|
+
limit an owner set on its agent. A key can read the limit, never change it:
|
|
9
|
+
the owner sets it at https://withruntime.com/account/keys. Past it, a
|
|
10
|
+
create, wake, extension or renewal fails with ``spending_limit_reached``
|
|
11
|
+
(HTTP 402). Money is integer microdollars in strings (1,000,000 = $1)."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, t: Any) -> None:
|
|
14
|
+
self._t = t
|
|
15
|
+
|
|
16
|
+
async def get(self) -> dict[str, Any]:
|
|
17
|
+
"""``access`` (``full``, ``read`` or ``selected``) and ``daily``:
|
|
18
|
+
``limitMicros`` (None for no limit), ``usedMicros`` in the last 24
|
|
19
|
+
hours, and ``remainingMicros`` (None for no limit)."""
|
|
20
|
+
return await self._t.json("GET", "/v1/limits")
|
|
@@ -4,6 +4,7 @@ from typing import Any
|
|
|
4
4
|
from .desktop import Desktop
|
|
5
5
|
from .images import Images
|
|
6
6
|
from .interpreter import Interpreter
|
|
7
|
+
from .limits import Limits
|
|
7
8
|
from .network import Network
|
|
8
9
|
from .previews import Previews
|
|
9
10
|
from .referrals import Referrals
|
|
@@ -14,6 +15,7 @@ SANDBOX: dict[str, Any] = {}
|
|
|
14
15
|
CLIENT["images"] = Images
|
|
15
16
|
CLIENT["volumes"] = Volumes
|
|
16
17
|
CLIENT["referrals"] = Referrals
|
|
18
|
+
CLIENT["limits"] = Limits
|
|
17
19
|
SANDBOX["interpreter"] = Interpreter
|
|
18
20
|
SANDBOX["previews"] = Previews
|
|
19
21
|
SANDBOX["network"] = Network
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""GENERATED from _async_products/limits.py by scripts/generate_sync.py. Do not edit."""
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Limits:
|
|
8
|
+
"""``runtime.limits``. Whether this key is read-only, and the daily spending
|
|
9
|
+
limit an owner set on its agent. A key can read the limit, never change it:
|
|
10
|
+
the owner sets it at https://withruntime.com/account/keys. Past it, a
|
|
11
|
+
create, wake, extension or renewal fails with ``spending_limit_reached``
|
|
12
|
+
(HTTP 402). Money is integer microdollars in strings (1,000,000 = $1)."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, t: Any) -> None:
|
|
15
|
+
self._t = t
|
|
16
|
+
|
|
17
|
+
def get(self) -> dict[str, Any]:
|
|
18
|
+
"""``access`` (``full``, ``read`` or ``selected``) and ``daily``:
|
|
19
|
+
``limitMicros`` (None for no limit), ``usedMicros`` in the last 24
|
|
20
|
+
hours, and ``remainingMicros`` (None for no limit)."""
|
|
21
|
+
return self._t.json("GET", "/v1/limits")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "0.3.1"
|
|
@@ -2,6 +2,7 @@ README.md
|
|
|
2
2
|
pyproject.toml
|
|
3
3
|
tests/test_client.py
|
|
4
4
|
tests/test_images_volumes_interpreter.py
|
|
5
|
+
tests/test_limits.py
|
|
5
6
|
tests/test_previews_network_desktop.py
|
|
6
7
|
tests/test_referrals.py
|
|
7
8
|
withruntime/__init__.py
|
|
@@ -21,6 +22,7 @@ withruntime/_async_products/__init__.py
|
|
|
21
22
|
withruntime/_async_products/desktop.py
|
|
22
23
|
withruntime/_async_products/images.py
|
|
23
24
|
withruntime/_async_products/interpreter.py
|
|
25
|
+
withruntime/_async_products/limits.py
|
|
24
26
|
withruntime/_async_products/network.py
|
|
25
27
|
withruntime/_async_products/previews.py
|
|
26
28
|
withruntime/_async_products/referrals.py
|
|
@@ -29,6 +31,7 @@ withruntime/_sync_products/__init__.py
|
|
|
29
31
|
withruntime/_sync_products/desktop.py
|
|
30
32
|
withruntime/_sync_products/images.py
|
|
31
33
|
withruntime/_sync_products/interpreter.py
|
|
34
|
+
withruntime/_sync_products/limits.py
|
|
32
35
|
withruntime/_sync_products/network.py
|
|
33
36
|
withruntime/_sync_products/previews.py
|
|
34
37
|
withruntime/_sync_products/referrals.py
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = "0.3.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|