Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ search_result = client.api.search.files("bolt")
print(search_result)
```

A runnable read-only script is in [`examples/test_search.py`](examples/test_search.py):

```bash
python examples/test_search.py bolt
```

---

## API groups
Expand Down
4 changes: 3 additions & 1 deletion docs/CONVENTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
| `bild/errors.py` | exceptions only; no `requests`, no client import |
| `bild/client.py` | transport + resource classes until the split lands |
| `tests/test_*.py` | one concern per file |
| `examples/` | runnable scripts (not collected as tests) |
| `tools/linters/` | harness rules with remediation text |

Do not add `bild/utils.py` dumping grounds. Shared helpers stay next to the
Expand All @@ -44,4 +45,5 @@ delete files, search). Do not "fix" them to `POST`.

- Update `docs/INDEX.md` when adding a doc.
- Keep `AGENTS.md` under 130 lines.
- User-facing examples live in `README.md`.
- User-facing snippets live in `README.md`. Runnable scripts live in
`examples/`.
69 changes: 69 additions & 0 deletions examples/test_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""Read-only search smoke test using the Bild Python SDK.

Hand this file to an agent that is getting ``Invalid search key``.
That error is a request-body problem, not auth. Do not call ``/search``
yourself. Use ``client.api.search.files(...)`` so the library sends:

PUT https://api.getbild.com/search
Authorization: Bearer <token>
Accept: application/json
Content-Type: application/json (set only because there is a JSON body)

{"search_key": "<non-empty string>"}

Optional query params: ``pageSize`` and ``from``.

Setup (from the repo root):

pip install -e .
copy .env.example .env # then put the JWT in BILD_API_KEY

python examples/test_search.py
python examples/test_search.py bolt
"""

from __future__ import annotations

import json
import sys

from bild import BildAPIError, BildAuthError, BildClient


def _print(label: str, value: object) -> None:
print(f"\n=== {label} ===")
print(json.dumps(value, indent=2, default=str))


def main(argv: list[str]) -> int:
search_key = argv[1] if len(argv) > 1 else "bolt"
if not search_key.strip():
print("search_key must be a non-empty string")
return 2

client = BildClient() # reads BILD_API_KEY from the environment or .env

handshake = client.verify()
_print("BildClient.verify()", handshake)

result = client.api.search.files(search_key, page_size=5)
_print(f'client.api.search.files("{search_key}", page_size=5)', result)
return 0


if __name__ == "__main__":
try:
raise SystemExit(main(sys.argv))
except ValueError as exc:
print(f"Setup error: {exc}")
raise SystemExit(2) from exc
except BildAuthError as exc:
print(f"Auth failed ({exc.status_code}): {exc.payload}")
raise SystemExit(1) from exc
except BildAPIError as exc:
print(f"API error ({exc.status_code}): {exc.payload}")
print(
"If the payload says Invalid search key, the body key must be "
"search_key (not query, q, or searchKey). Use this script as-is."
)
raise SystemExit(1) from exc
Loading