|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +## Repository Purpose |
| 4 | + |
| 5 | +This repository is the Python monorepo for Tilebox SDK packages. It is organized as a `uv` workspace with multiple publishable packages that share common development tooling and a shared dependency graph. |
| 6 | + |
| 7 | +## Monorepo Architecture |
| 8 | + |
| 9 | +The workspace is split into four packages: |
| 10 | + |
| 11 | +- `tilebox-grpc`: Shared low-level gRPC/protobuf plumbing (`_tilebox.grpc`), sync and async channel handling, error mapping, pagination, replay, and async-to-sync helpers. |
| 12 | +- `tilebox-datasets`: Datasets SDK (`tilebox.datasets`) with sync + async clients, query/data model helpers, protobuf conversion, and generated datasets-related protobuf stubs. |
| 13 | +- `tilebox-workflows`: Workflows SDK (`tilebox.workflows`) with job/cluster/automation clients, task model + runner, observability/tracing, and generated workflows protobuf stubs. |
| 14 | +- `tilebox-storage`: Storage SDK (`tilebox.storage`) for provider-specific payload downloads (ASF, Copernicus, Umbra, Landsat, local FS), built mostly on async internals with sync wrappers. |
| 15 | + |
| 16 | +Design choices to keep in mind: |
| 17 | + |
| 18 | +- Namespace package layout: multiple packages contribute modules under shared top-level namespaces like `tilebox.*`. |
| 19 | +- Layering pattern: generated protobuf/gRPC types -> service wrappers -> data/domain classes -> user-facing clients. |
| 20 | +- Sync + async parity: many APIs exist in both forms; sync wrappers are often derived from async implementations. |
| 21 | +- External API communication is gRPC-first, with protobuf-generated contracts. |
| 22 | + |
| 23 | +## Developer Tooling |
| 24 | + |
| 25 | +Use `uv` for all local development. |
| 26 | + |
| 27 | +### Setup |
| 28 | + |
| 29 | +```bash |
| 30 | +uv sync |
| 31 | +``` |
| 32 | + |
| 33 | +### Test Commands |
| 34 | + |
| 35 | +```bash |
| 36 | +# All packages with coverage aggregation |
| 37 | +./tests.sh |
| 38 | + |
| 39 | +# Single package examples |
| 40 | +uv run --package tilebox-datasets pytest tilebox-datasets |
| 41 | +uv run --package tilebox-workflows pytest tilebox-workflows |
| 42 | +uv run --package tilebox-storage pytest tilebox-storage |
| 43 | +uv run --package tilebox-grpc pytest tilebox-grpc |
| 44 | +``` |
| 45 | + |
| 46 | +### Lint / Format / Type Check |
| 47 | + |
| 48 | +```bash |
| 49 | +uv run ruff format . |
| 50 | +uv run ruff check --fix . |
| 51 | +uv run ty check |
| 52 | +``` |
| 53 | + |
| 54 | +### Pre-commit |
| 55 | + |
| 56 | +```bash |
| 57 | +uv run prek run --all-files |
| 58 | +``` |
| 59 | + |
| 60 | +Pre-commit hooks include YAML checks, EOF fixer, `sync-with-uv`, Ruff, and `ty`. |
| 61 | + |
| 62 | +## Code Style And Paradigms |
| 63 | + |
| 64 | +- Python target: `>=3.10`. |
| 65 | +- Linting/formatting is Ruff-based and fairly strict (`select = ["ALL"]`) with explicit ignores configured in root `pyproject.toml`. |
| 66 | +- Type hints are used broadly across public APIs and internals. |
| 67 | +- Prefer dataclasses and explicit domain objects for request/response translation. |
| 68 | +- Service modules generally wrap generated gRPC stubs and convert to internal Pythonic types. |
| 69 | +- Logging uses `loguru` in several packages; workflows also supports explicit logger/tracer configuration. |
| 70 | +- Tests use `pytest`, with async coverage (`pytest-asyncio`) and property-based testing (`hypothesis`) in multiple packages. |
| 71 | + |
| 72 | +## Protobuf And Generated Code |
| 73 | + |
| 74 | +Generated files live under paths such as: |
| 75 | + |
| 76 | +- `tilebox-datasets/tilebox/datasets/datasets/v1/*_pb2*.py` |
| 77 | +- `tilebox-datasets/tilebox/datasets/tilebox/v1/*_pb2*.py` |
| 78 | +- `tilebox-datasets/tilebox/datasets/buf/validate/*_pb2*.py` |
| 79 | +- `tilebox-workflows/tilebox/workflows/workflows/v1/*_pb2*.py` |
| 80 | + |
| 81 | +Regenerate protobuf code with: |
| 82 | + |
| 83 | +```bash |
| 84 | +uv run generate-protobuf |
| 85 | +``` |
| 86 | + |
| 87 | +This uses `buf.gen.datasets.yaml` and `buf.gen.workflows.yaml`, then runs import-fixup logic via `tools/generate_protobuf.py`. |
| 88 | + |
| 89 | +### Important Boundary: API Schema Source Of Truth |
| 90 | + |
| 91 | +- Many protobuf contracts are sourced from the separate `api` repository/module (`buf.build/tilebox/api`, with optional local `../api` input in buf configs). |
| 92 | +- Do **not** hand-edit generated `*_pb2.py`, `*_pb2.pyi`, or `*_pb2_grpc.py` files. |
| 93 | +- If a requested change requires modifying protobuf schema/contracts, that change must be made in the `api` repo first. |
| 94 | +- Whenever schema/proto edits are needed, ask the developer to point you to the `api` repo so those changes can be implemented there and then regenerated here. |
0 commit comments