# Run your first check Scan a small file with YARA in one complete Python example. ## 1. Set up your client You need Python, an API base URL, and an owner-scoped API token. Get the URL and token from the person operating your deployment. Install `httpx` with `python -m pip install httpx`, then set `SECURITY_RUN_URL` and `SECURITY_RUN_API_KEY` in your terminal. ## 2. Run the example Save the Python example as `first_check.py` and run `python first_check.py`. It creates a rule that looks for `security.run`, uploads the rule and sample, starts YARA, and waits for the result. You do not need to create input files first. ## 3. Check what happened Expect a `succeeded` state, a native exit code of `0`, and `destroyed` cleanup. The downloaded YARA output should contain `example`, the matched rule name. If any of these differ, use [Fix a failed or stuck run](https://www.security.run/docs/troubleshooting.html). ## 4. Scan your own file Replace `b"hello security.run"` with `Path("your-file.bin").read_bytes()` and add `from pathlib import Path`. Replace the rule bytes with your own rule file. Keep the staged filenames aligned with the names passed in `args`. ## Next [Upload several files](https://www.security.run/docs/upload-inputs.html), [pass flags and configuration](https://www.security.run/docs/native-invocations.html), or [try another tool](https://www.security.run/docs/tools.html). ## first_check.py ```python import hashlib, os, time, uuid import httpx base = os.environ["SECURITY_RUN_URL"].rstrip("/") token = os.environ["SECURITY_RUN_API_KEY"] with httpx.Client(base_url=base, headers={"Authorization": f"Bearer {token}"}) as api: def upload(name, data): key = str(uuid.uuid4()) response = api.post("/v1/artifacts", headers={"Idempotency-Key": key}, json={ "filename": name, "size": len(data), "sha256": hashlib.sha256(data).hexdigest()}) response.raise_for_status() artifact = response.json() api.put(artifact["upload_url"], content=data).raise_for_status() api.post(artifact["complete_url"], headers={"Idempotency-Key": key}).raise_for_status() return artifact["id"] rules = upload("rules.yar", b'rule example { strings: $s = "security.run" condition: $s }') sample_id = upload("sample.txt", b"hello security.run") response = api.post("/v1/tool-runs", headers={"Idempotency-Key": str(uuid.uuid4())}, json={ "tool": "yara", "timeout_seconds": 30, "invocation": {"executable": "yara", "args": ["-s", "rules.yar", "sample.txt"], "files": [{"path": "rules.yar", "artifact_id": rules}, {"path": "sample.txt", "artifact_id": sample_id}]}}) response.raise_for_status() run = response.json() deadline = time.monotonic() + 240 while run["state"] not in {"succeeded", "failed", "timed_out", "cancelled", "outcome_unknown"}: if time.monotonic() >= deadline: raise TimeoutError(run["id"]) time.sleep(0.5) response = api.get(f'/v1/tool-runs/{run["id"]}') response.raise_for_status() run = response.json() print(run["state"], run["cleanup_status"], run.get("result")) for output in run["outputs"]: response = api.get(output["download_url"]) response.raise_for_status() data = response.content assert hashlib.sha256(data).hexdigest() == output["sha256"] print(output["name"], data.decode("utf-8", errors="replace")) ```