GeoInsight API is a backend-only FastAPI service for geospatial analysis workflows.
It currently supports project and AOI management, PostGIS-backed vector layer metadata, controlled land-use seed data, and AOI-based land-use composition analysis.
This service currently supports:
- Health checks (
/health,/health/db) - Project CRUD
- AOI CRUD
- PostGIS-backed AOI geometry storage
- Vector layer metadata CRUD
- Controlled demo land-use seed data
- Land-use composition analysis by AOI using PostGIS
The API is intentionally backend-only while the core geospatial workflow is being validated.
- Python + FastAPI
- PostgreSQL/PostGIS
- SQLAlchemy
- GeoAlchemy2
- Alembic for migrations
- Docker Compose for local orchestration
- Shapely + PyProj for geometry handling
- Pytest for tests
- Ruff for formatting/linting
- Copy the local environment file:
cp .env.example .env- Install dependencies using
uv:
uv sync --devStart the app and PostGIS:
docker compose up --buildStop services:
docker compose downStop services and remove the local database volume:
docker compose down -vIf your shell has the .env variables loaded:
docker exec -it geoinsight-db psql -U "$DATABASE_USER" -d "$DATABASE_NAME"Otherwise, use the values from .env directly:
docker exec -it geoinsight-db psql -U <database_user> -d <database_name>Useful psql commands:
\dt public.*
\d <table_name>
SELECT * FROM alembic_version;Check the current migration revision:
uv run alembic currentApply the latest migrations:
uv run alembic upgrade headCreate a new migration when needed:
uv run alembic revision --autogenerate -m "describe change"Check whether models and migrations are in sync:
uv run alembic checkIf the local development database has a broken or stale migration state and local data is disposable, reset it:
docker compose down -v
docker compose up -d db
uv run alembic upgrade headSeed controlled demo land-use data:
uv run python scripts/seed_land_use.pyThis creates one land_use vector layer with demo polygon features for:
- forest
- agriculture
- urban
- water
- grassland
Assuming the app is running on http://127.0.0.1:8000.
curl -s http://127.0.0.1:8000/health
curl -s http://127.0.0.1:8000/health/dbcurl -s -X POST http://127.0.0.1:8000/v1/projects \
-H "Content-Type: application/json" \
-d '{
"name": "Demo project",
"description": "Project for local API walkthrough"
}'curl -s http://127.0.0.1:8000/v1/projectsReplace <project_id> with an ID returned by the create/list project calls.
curl -s -X POST http://127.0.0.1:8000/v1/projects/<project_id>/aois \
-H "Content-Type: application/json" \
-d '{
"name": "Demo AOI",
"geometry": {
"type": "Polygon",
"coordinates": [[
[44.50, 40.10],
[44.51, 40.10],
[44.51, 40.11],
[44.50, 40.11],
[44.50, 40.10]
]]
}
}'curl -s http://127.0.0.1:8000/v1/projects/<project_id>/aoisuv run python scripts/seed_land_use.pycurl -s http://127.0.0.1:8000/v1/vector-layersCopy the ID of the seeded land_use vector layer.
Replace <aoi_id> and <layer_id> with real IDs.
curl -s -X POST http://127.0.0.1:8000/v1/aois/<aoi_id>/land-use-composition \
-H "Content-Type: application/json" \
-d '{
"layer_id": "<layer_id>"
}'GET /healthGET /health/db
POST /v1/projectsGET /v1/projectsGET /v1/projects/{project_id}PATCH /v1/projects/{project_id}DELETE /v1/projects/{project_id}
POST /v1/projects/{project_id}/aoisGET /v1/projects/{project_id}/aoisGET /v1/aois/{aoi_id}PATCH /v1/aois/{aoi_id}DELETE /v1/aois/{aoi_id}
POST /v1/vector-layersGET /v1/vector-layersGET /v1/vector-layers/{layer_id}DELETE /v1/vector-layers/{layer_id}
POST /v1/aois/{aoi_id}/land-use-composition
Run formatting locally:
uv run ruff format .
uv run ruff check . --fixRun all tests locally:
uv run pytestRun a focused test file:
uv run pytest tests/<test_file_name>.pyThe database tests require the PostGIS container to be running and migrations to be applied.
The next milestone is focused on exposing persisted vector analysis results, including:
- result detail endpoint
- AOI-level result listing endpoint
- stronger spatial correctness tests
Pull requests and pushes to main are checked by GitHub Actions.
The CI workflow runs:
- Alembic migrations
- Alembic migration consistency check
- Ruff formatting check
- Ruff lint check
- Pytest
CI uses a disposable PostGIS service container and does not require external database secrets.