opencraw (Python)
Build OpenCraw recipes in Python, and drive the real CLI. Standard library only; it
needs Python 3.12+ and, to validate or run, the opencraw CLI (npm i -g @opencraw/cli, or
OPENCRAW_CLI set to the command that starts it; with neither, npx @opencraw/cli is used).
A recipe stays a plain dict in the engine's own shape, so the recipe guide (docs/recipes/authoring.md) is the reference for every key. The constructors only save typing, and the engine, not this package, says what is valid.
from opencraw import input_recipe, output_recipe, run, step, validate
product = output_recipe(
"product",
{
"url": {"type": "url", "required": True, "key": True},
"title": {"type": "string", "required": True},
},
)
shops = [
input_recipe(
f"shop-{name}",
"product",
"web",
[url],
[
step("goto", url="{{start.url}}"),
step("extract", id="title", selector=selector, kind="css", take="text"),
step("emit"),
],
{"url": {"from": "start.url"}, "title": {"from": "title"}},
)
for name, url, selector in [
("a", "https://a.example", "h1"),
("b", "https://b.example", ".name"),
]
]
result = validate(
[product, *shops]
) # Validation(ok, output): problems are data, not exceptions
records = run(
[product, *shops], "--only", "shop-a"
) # records as dicts; OpenCrawError if the crawl fails
Reserved words: pass a step's as or from through **{"as": "json"}.
write_recipes(folder, recipes) writes <id>.input.json and <id>.output.json for the CLI, the Studio
and the MCP server.
A hook written in Python
A recipe's hook ({ "op": "hook", "name": "slug" }) can be a Python script. The hooks module registers it
with commandHook (@opencraw/core), and the script is a few lines:
# hooks/slug.py
import re
from opencraw import serve_hook
serve_hook(
lambda value, args, request: re.sub(r"[^a-z0-9]+", "-", str(value).lower()).strip(
"-"
)
)
serve_hook(handler) reads the request from stdin, calls handler(input, args, request) (input is None
for a hook step; request carries context and idempotencyKey) and writes the answer to stdout. What the
handler returns is the output; an exception becomes an error answer with its message, so the step fails with
that reason. A handler whose work takes longer raises HookPending(retry_after_ms): OpenCraw runs the script
again after that wait, with the same idempotencyKey, until it returns or the hook's maxWaitMs passes, so the
script starts the work once and looks it up by that key on later runs. The request and answer shapes are in
packages/core/schemas/callout-*.schema.json.
Not in this package: a Python engine and generated typed models. The crawl itself always runs in the
OpenCraw CLI. It is published to PyPI as opencraw: mnci ci release versions and publishes what sits
under python-packages/.
Development
nx test opencraw (pytest; the CLI integration tests use this repository's built CLI and skip without it),
nx lint opencraw (Ruff), nx typecheck opencraw (mypy strict).
Metadata
Release files for opencraw 0.0.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| opencraw-0.0.6.tar.gz | 9.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| opencraw-0.0.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 17.8 kB
Release files / opencraw-0.0.6.tar.gz
| Download URL | opencraw-0.0.6.tar.gz |
|---|---|
| Size | 9.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e4a7c2b942afe6e817154e569f83813163d92b4ccb389c6233cb837084d7cd7f
|
|
BLAKE2b-256 checksum How to use checksums |
ec923d72a620c03b7ad189adc9702d4daaafe85bdfcd09afab4b31f086c7cbaa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / opencraw-0.0.6-py3-none-any.whl
| Download URL | opencraw-0.0.6-py3-none-any.whl |
|---|---|
| Size | 8.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1174deacd72d38c055cbd46afd02e7be6602771e065571636edab354482ad8c2
|
|
BLAKE2b-256 checksum How to use checksums |
d71f5f01b0f9976854654b9903c5a2ca3766515d659ab2608491714d49aa7a20
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|