Cette page a été traduite par une machine et n'a pas encore été révisée par une personne. L'anglais est la référence ; les corrections sont les bienvenues sur GitHub. GitHub
Cookwala / SDK et scénarios / 099
Validate a recipe, see an invalid one fail, and publish its hash
A publisher validates against the recipe schema (the one kind the hub checks in full), sees what a non-recipe gets back, and computes the hash that executors compare with ExecuteRequest.recipeHash.
Lire d'abord: /docs/CORE/ /docs/REGISTRY/
Étapes
Fetch koshari from the hub.
getRecipeValidate it as a recipe: no errors.
validateA document that is not a recipe fails with thirteen errors, one per required property plus the unknown field.
validateThe recipe's hash: an executor refuses a request whose recipeHash differs (recipe_hash_mismatch, scenario 097).
hash
Résultat
You can validate and hash before you publish, and put the hash in a registry entry. Next: 100 verifies a recall that travelled through a mirror.
Ligne de commande
cookwala validate
cookwala hash examples/koshari.cookwala.jsonSortie enregistrée
Statut: ok
[1] getRecipe: {"$schema": "https://cookwala.ai/v1/schemas/recipe.schema.json", "cookwala": "0.2.0", "id": "example-koshari", "revision": 1, "updated": "2026-10-04", "verification": {"level": "V1", "evidence": {"simulatorRuns": 0, "humanReviews": 1, "fieldReports": 0}, "reviewedBy": "cookwala.ai editorial (structure only)", "notes": "Example recipe written to exercise the standard: structured steps, end conditions, hazards and critical control points. Not simulated and not field-verified; values are typical home-cooking values, not measurements."}, "dish": {"names": {"en": "Koshari", "ar": "كشري"}, "cuisine"…
[2] validate: {"ok": true, "errors": []}
[3] validate: {"ok": false, "errors": [": 'cookwala' is a required property", ": 'id' is a required property", ": 'revision' is a required property", ": 'verification' is a required property", ": 'dish' is a required property", ": 'yield' is a required property", ": 'ingredients' is a required property", ": 'equipment' is a required property", ": 'process' is a required property", ": 'safety' is a required property", ": 'text' is a required property", ": 'license' is a required property", ": 'nonsense' does not match any of the regexes: '^x-'"]}
[4] hash: {"hash": "sha256:f7fc3745af51465fb7a849faa5b5927eeaa44030a703318bb293381fef8b3f45"}Code
Exécuter: python scenarios/out/099-publisher-validates-and-hashes-a-recipe/python.py
# Scenario 099: Validate a recipe, see an invalid one fail, and publish its hash
# A publisher validates against the recipe schema (the one kind the hub checks in full), sees what a non-recipe gets back, and computes the hash that executors compare with ExecuteRequest.recipeHash.
# Run a hub first: python hub/cookwala_hub.py --recipes examples
import json, os
from cookwala.client import CookwalaClient, CookwalaProblem
def load(path):
with open(path, encoding="utf-8") as f:
return json.load(f)
def pick(obj, path):
for part in path.replace("]", "").replace("[", ".").split("."):
obj = obj[int(part)] if part.isdigit() else (len(obj) if part == "length" else obj.get(part))
return obj
c = CookwalaClient(os.environ.get("COOKWALA_HUB", "http://localhost:7878"))
# Step 1: Fetch koshari from the hub.
recipe = c.get_recipe("koshari")
assert pick(recipe, "id") == "example-koshari", pick(recipe, "id")
print("ok", "id", "=", "example-koshari")
assert pick(recipe, "cookwala") == "0.2.0", pick(recipe, "cookwala")
print("ok", "cookwala", "=", "0.2.0")
# Step 2: Validate it as a recipe: no errors.
valid = c.validate("recipe", recipe)
assert pick(valid, "ok") == True, pick(valid, "ok")
print("ok", "ok", "=", True)
assert pick(valid, "errors.length") == 0, pick(valid, "errors.length")
print("ok", "errors.length", "=", 0)
# Step 3: A document that is not a recipe fails with thirteen errors, one per required property plus the unknown field.
invalid = c.validate("recipe", {"nonsense": 1})
assert pick(invalid, "ok") == False, pick(invalid, "ok")
print("ok", "ok", "=", False)
assert pick(invalid, "errors.length") == 13, pick(invalid, "errors.length")
print("ok", "errors.length", "=", 13)
# Step 4: The recipe's hash: an executor refuses a request whose recipeHash differs (recipe_hash_mismatch, scenario 097).
h = c.hash(recipe)
assert pick(h, "hash") == "sha256:f7fc3745af51465fb7a849faa5b5927eeaa44030a703318bb293381fef8b3f45", pick(h, "hash")
print("ok", "hash", "=", "sha256:f7fc3745af51465fb7a849faa5b5927eeaa44030a703318bb293381fef8b3f45")
print("scenario complete")