mentiora-loom 0.9.8__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.
- mentiora_loom-0.9.8/.gitignore +34 -0
- mentiora_loom-0.9.8/PKG-INFO +131 -0
- mentiora_loom-0.9.8/README.md +106 -0
- mentiora_loom-0.9.8/loom/__init__.py +447 -0
- mentiora_loom-0.9.8/loom/_admin_types.py +53 -0
- mentiora_loom-0.9.8/loom/_async_transport.py +217 -0
- mentiora_loom-0.9.8/loom/_codegen.py +163 -0
- mentiora_loom-0.9.8/loom/_errors.py +43 -0
- mentiora_loom-0.9.8/loom/_transport.py +144 -0
- mentiora_loom-0.9.8/loom/py.typed +0 -0
- mentiora_loom-0.9.8/loom/types.py +186 -0
- mentiora_loom-0.9.8/pyproject.toml +53 -0
- mentiora_loom-0.9.8/tests/__init__.py +0 -0
- mentiora_loom-0.9.8/tests/conftest.py +264 -0
- mentiora_loom-0.9.8/tests/test_admin_rpcs.py +154 -0
- mentiora_loom-0.9.8/tests/test_async_cancellation.py +91 -0
- mentiora_loom-0.9.8/tests/test_async_concurrent.py +74 -0
- mentiora_loom-0.9.8/tests/test_codegen_drift.py +210 -0
- mentiora_loom-0.9.8/tests/test_errors.py +43 -0
- mentiora_loom-0.9.8/tests/test_pypi_packaging.py +89 -0
- mentiora_loom-0.9.8/tests/test_transport.py +71 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
council/
|
|
2
|
+
specs/
|
|
3
|
+
target/
|
|
4
|
+
.claude/
|
|
5
|
+
.DS_Store
|
|
6
|
+
*.swp
|
|
7
|
+
.idea/
|
|
8
|
+
.vscode/
|
|
9
|
+
.envrc
|
|
10
|
+
.env
|
|
11
|
+
.env.local
|
|
12
|
+
.env.dev.local
|
|
13
|
+
|
|
14
|
+
# cargo-dist intermediates
|
|
15
|
+
dist-manifest.json
|
|
16
|
+
|
|
17
|
+
# Python SDK build artifacts (`python -m build`, used by publish-pypi.yml)
|
|
18
|
+
python-sdk/dist/
|
|
19
|
+
python-sdk/*.egg-info/
|
|
20
|
+
__pycache__/
|
|
21
|
+
.pytest_cache/
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
|
|
24
|
+
# event-log substrate (loom is a public repo — keep internal infra config + any
|
|
25
|
+
# telemetry/runtime artifacts OUT of git). Internal users configure the hosted
|
|
26
|
+
# backend via a LOCAL .feature-workflow/event-log.yaml (ignored below); the
|
|
27
|
+
# fallback queue can contain sensitive text and must never be committed.
|
|
28
|
+
.feature-workflow/event-log.yaml
|
|
29
|
+
.feature-workflow/event-log-fallback.jsonl
|
|
30
|
+
.feature-workflow/event-log-fallback.jsonl.lock
|
|
31
|
+
.feature-workflow/event-log.off
|
|
32
|
+
.feature-workflow/events/
|
|
33
|
+
.feature-workflow/backfill-checkpoint.json
|
|
34
|
+
.feature-workflow/backfill-checkpoint.json.tmp
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mentiora-loom
|
|
3
|
+
Version: 0.9.8
|
|
4
|
+
Summary: Python client library for the loom browser-automation daemon
|
|
5
|
+
Project-URL: Homepage, https://github.com/mentiora-ai/loom
|
|
6
|
+
Project-URL: Repository, https://github.com/mentiora-ai/loom
|
|
7
|
+
Project-URL: Issues, https://github.com/mentiora-ai/loom/issues
|
|
8
|
+
Author-email: Mentiora <hello@mentiora.ai>
|
|
9
|
+
License: Apache-2.0
|
|
10
|
+
Keywords: automation,browser,loom
|
|
11
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
+
Classifier: Operating System :: MacOS
|
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Topic :: Software Development :: Testing
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# loom (Python SDK)
|
|
27
|
+
|
|
28
|
+
Python client library for the [loom](https://github.com/mentiora-ai/loom)
|
|
29
|
+
browser-automation daemon.
|
|
30
|
+
|
|
31
|
+
## Prerequisites
|
|
32
|
+
|
|
33
|
+
The SDK talks to a running `loom-daemon` over a Unix socket. Install
|
|
34
|
+
loom (CLI + daemon + chromium pin) first via Homebrew, `cargo install`,
|
|
35
|
+
or the install script — see the
|
|
36
|
+
[main README](https://github.com/mentiora-ai/loom#install). Then start
|
|
37
|
+
the daemon:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
loom serve
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Install
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install mentiora-loom
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The distribution is named `mentiora-loom`; it still imports as `loom`
|
|
50
|
+
(`import loom`). Requires Python ≥ 3.11.
|
|
51
|
+
|
|
52
|
+
## Quick start (sync)
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
import loom
|
|
56
|
+
|
|
57
|
+
with loom.Session.create() as session:
|
|
58
|
+
receipt = session.navigate("https://example.com")
|
|
59
|
+
print(receipt.action_hash)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quick start (async)
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import asyncio
|
|
66
|
+
import loom
|
|
67
|
+
|
|
68
|
+
async def main():
|
|
69
|
+
async with await loom.AsyncSession.create() as session:
|
|
70
|
+
receipt = await session.navigate("https://example.com")
|
|
71
|
+
print(receipt.action_hash)
|
|
72
|
+
|
|
73
|
+
asyncio.run(main())
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## What the SDK exposes
|
|
77
|
+
|
|
78
|
+
- `Session` / `AsyncSession` — session lifecycle (create / close / abort
|
|
79
|
+
/ kill / replay / inspect / validate / export).
|
|
80
|
+
- `Session.{navigate, click, type_text, select, hover, scroll, wait,
|
|
81
|
+
evaluate, screenshot, snapshot}` — every web action surface.
|
|
82
|
+
- Admin RPCs: `kill_session(session_id, ...)` (force-terminate without a
|
|
83
|
+
handle), `daemon_health(deep=...)` (operational snapshot).
|
|
84
|
+
- Receipt + summary types in `loom.types` — `Receipt`, `SessionInfo`,
|
|
85
|
+
`SessionInspection`, `DiffReport`, `ExportInfo`, `ValidationResult`,
|
|
86
|
+
`GrantInfo`, `SchemaRegistry`, `LoomErrorCode`.
|
|
87
|
+
- Typed errors: `LoomError`, `LoomRPCError`, `LoomConnectionError`,
|
|
88
|
+
`LoomTokenError`.
|
|
89
|
+
|
|
90
|
+
## Cancellation (async only)
|
|
91
|
+
|
|
92
|
+
`AsyncSession` supports transparent cancellation via standard asyncio
|
|
93
|
+
primitives. Wrap a call in `asyncio.wait_for` or cancel its enclosing
|
|
94
|
+
task and the SDK fires a `request.cancel` envelope at the daemon, then
|
|
95
|
+
re-raises `asyncio.CancelledError` so `TaskGroup` / `asyncio.timeout`
|
|
96
|
+
keep working:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
import asyncio
|
|
100
|
+
import loom
|
|
101
|
+
|
|
102
|
+
async with await loom.AsyncSession.create() as s:
|
|
103
|
+
try:
|
|
104
|
+
await asyncio.wait_for(s.navigate("https://example.com"), timeout=5.0)
|
|
105
|
+
except asyncio.TimeoutError:
|
|
106
|
+
# SDK already sent request.cancel before the timeout re-raised.
|
|
107
|
+
...
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Sync `Session` is single-in-flight by design — there is no cancellation
|
|
111
|
+
hook. For cancellable work, reach for `AsyncSession`.
|
|
112
|
+
|
|
113
|
+
## Connection details
|
|
114
|
+
|
|
115
|
+
`Session.create()` defaults work when a single user runs the daemon on
|
|
116
|
+
their own machine. Override per-call if needed:
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
session = loom.Session.create(
|
|
120
|
+
socket_path="/var/run/loom/loom.sock", # custom daemon socket
|
|
121
|
+
token="...", # explicit HELLO-token
|
|
122
|
+
profile="standard", # or "safe", "full"
|
|
123
|
+
network_mode="live", # or "replay"
|
|
124
|
+
seed=42, # determinism seed
|
|
125
|
+
)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
Apache-2.0. See the [main repository](https://github.com/mentiora-ai/loom)
|
|
131
|
+
for details.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# loom (Python SDK)
|
|
2
|
+
|
|
3
|
+
Python client library for the [loom](https://github.com/mentiora-ai/loom)
|
|
4
|
+
browser-automation daemon.
|
|
5
|
+
|
|
6
|
+
## Prerequisites
|
|
7
|
+
|
|
8
|
+
The SDK talks to a running `loom-daemon` over a Unix socket. Install
|
|
9
|
+
loom (CLI + daemon + chromium pin) first via Homebrew, `cargo install`,
|
|
10
|
+
or the install script — see the
|
|
11
|
+
[main README](https://github.com/mentiora-ai/loom#install). Then start
|
|
12
|
+
the daemon:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
loom serve
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install mentiora-loom
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The distribution is named `mentiora-loom`; it still imports as `loom`
|
|
25
|
+
(`import loom`). Requires Python ≥ 3.11.
|
|
26
|
+
|
|
27
|
+
## Quick start (sync)
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
import loom
|
|
31
|
+
|
|
32
|
+
with loom.Session.create() as session:
|
|
33
|
+
receipt = session.navigate("https://example.com")
|
|
34
|
+
print(receipt.action_hash)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick start (async)
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import asyncio
|
|
41
|
+
import loom
|
|
42
|
+
|
|
43
|
+
async def main():
|
|
44
|
+
async with await loom.AsyncSession.create() as session:
|
|
45
|
+
receipt = await session.navigate("https://example.com")
|
|
46
|
+
print(receipt.action_hash)
|
|
47
|
+
|
|
48
|
+
asyncio.run(main())
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## What the SDK exposes
|
|
52
|
+
|
|
53
|
+
- `Session` / `AsyncSession` — session lifecycle (create / close / abort
|
|
54
|
+
/ kill / replay / inspect / validate / export).
|
|
55
|
+
- `Session.{navigate, click, type_text, select, hover, scroll, wait,
|
|
56
|
+
evaluate, screenshot, snapshot}` — every web action surface.
|
|
57
|
+
- Admin RPCs: `kill_session(session_id, ...)` (force-terminate without a
|
|
58
|
+
handle), `daemon_health(deep=...)` (operational snapshot).
|
|
59
|
+
- Receipt + summary types in `loom.types` — `Receipt`, `SessionInfo`,
|
|
60
|
+
`SessionInspection`, `DiffReport`, `ExportInfo`, `ValidationResult`,
|
|
61
|
+
`GrantInfo`, `SchemaRegistry`, `LoomErrorCode`.
|
|
62
|
+
- Typed errors: `LoomError`, `LoomRPCError`, `LoomConnectionError`,
|
|
63
|
+
`LoomTokenError`.
|
|
64
|
+
|
|
65
|
+
## Cancellation (async only)
|
|
66
|
+
|
|
67
|
+
`AsyncSession` supports transparent cancellation via standard asyncio
|
|
68
|
+
primitives. Wrap a call in `asyncio.wait_for` or cancel its enclosing
|
|
69
|
+
task and the SDK fires a `request.cancel` envelope at the daemon, then
|
|
70
|
+
re-raises `asyncio.CancelledError` so `TaskGroup` / `asyncio.timeout`
|
|
71
|
+
keep working:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import asyncio
|
|
75
|
+
import loom
|
|
76
|
+
|
|
77
|
+
async with await loom.AsyncSession.create() as s:
|
|
78
|
+
try:
|
|
79
|
+
await asyncio.wait_for(s.navigate("https://example.com"), timeout=5.0)
|
|
80
|
+
except asyncio.TimeoutError:
|
|
81
|
+
# SDK already sent request.cancel before the timeout re-raised.
|
|
82
|
+
...
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Sync `Session` is single-in-flight by design — there is no cancellation
|
|
86
|
+
hook. For cancellable work, reach for `AsyncSession`.
|
|
87
|
+
|
|
88
|
+
## Connection details
|
|
89
|
+
|
|
90
|
+
`Session.create()` defaults work when a single user runs the daemon on
|
|
91
|
+
their own machine. Override per-call if needed:
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
session = loom.Session.create(
|
|
95
|
+
socket_path="/var/run/loom/loom.sock", # custom daemon socket
|
|
96
|
+
token="...", # explicit HELLO-token
|
|
97
|
+
profile="standard", # or "safe", "full"
|
|
98
|
+
network_mode="live", # or "replay"
|
|
99
|
+
seed=42, # determinism seed
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
Apache-2.0. See the [main repository](https://github.com/mentiora-ai/loom)
|
|
106
|
+
for details.
|