Development Workflow¶
Test, lint, and typecheck¶
uv run pytest -q # all tests
uv run pytest tests/test_parcels.py -q # one file
uv run pytest -k "building_key" -q # by keyword
uv run ruff check src/ tests/ # lint
uv run mypy src/buildings_scraper/ # types
Note
Tests marked llm_quality make live LLM calls and require NVIDIA_API_KEY or
OPENROUTER_API_KEY. Every other test runs offline, using respx HTTP fixtures.
Tooling configuration¶
The following is drawn from pyproject.toml as a quick reference.
ruff
line-length = 100target-version = "py311"- Lint rule sets:
["E", "F", "I", "UP", "B"]
mypy
python_version = "3.11"files = ["src", "tests"]ignore_missing_imports = truewarn_unused_ignores = true
pytest
testpaths = ["tests"]addopts = "-q"
Offline vs. paid runs¶
Local development and testing should generally use the --offline flag, which skips paid
discovery steps:
uv run buildings-scraper leads --city "Chicago, IL" --offline
CLI entry point¶
The buildings-scraper command is registered as a console script:
buildings-scraper = "buildings_scraper.cli.main:main"
It becomes available automatically after uv sync.
Repo layout at a glance¶
For the full architectural picture, see System Overview. At a glance:
| Path | Purpose |
|---|---|
src/buildings_scraper/ |
The Python package |
scripts/ |
Pipeline trigger entrypoints and read-only reporters |
client-api/ |
Vercel/TypeScript project — public bulk-sync API |
internal-api/ |
Vercel/TypeScript project — internal dashboard/outreach/refresh backend |
ios/ |
Xcode project for the iOS app |
extension/relive-overlay/ |
The Chrome extension (retired) |
landing/ |
Next.js marketing landing page |
deploy/ |
Coolify/VPS jobs and Windows scheduled-task scripts |
client-api/ and internal-api/ are separate Node/TypeScript projects, each with its own
package.json.
Node/TypeScript projects (client-api, internal-api)¶
npm run check # tsc --noEmit
npm test # vitest run