Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f6f83cc
initial tweaks to Dockerfile & dev compose
mbarlow12 Feb 6, 2026
412596f
feat(docker): reconcile Dockerfile & compose for dev/prod targets
mbarlow12 Feb 6, 2026
d61aaea
fix(docker): tighten Dockerfile and compose config
mbarlow12 Feb 9, 2026
8d5b19a
refactor(docker): split compose into base and local dev override
mbarlow12 Feb 9, 2026
d985079
docs(readme): add Make Targets section
mbarlow12 Feb 9, 2026
4bb97ee
refactor(docker): use volume mounts instead of develop.watch
mbarlow12 Feb 9, 2026
689b916
refactor(docker): collapse to 2-stage build (base + runtime)
mbarlow12 Feb 10, 2026
25d3a62
refactor(compose): widen volume mounts with scoped reload dirs
mbarlow12 Feb 10, 2026
d5de21b
dev(db): Adds a dev user to the seeding script for API
AlexAxthelm Feb 5, 2026
0f9d57a
style: ruff
AlexAxthelm Feb 5, 2026
3aa0d05
feat(auth): add stitch-auth package for OIDC JWT validation
mbarlow12 Feb 10, 2026
a62e20d
build: add stitch-auth to workspace members
mbarlow12 Feb 10, 2026
4301aba
fix(lock): regenerate uv.lock without API stitch-auth dep
mbarlow12 Feb 10, 2026
967d862
build(api): add stitch-auth dependency
mbarlow12 Feb 10, 2026
296271e
feat(api): add sub column to User, consolidate first_name/last_name t…
mbarlow12 Feb 10, 2026
bbebbb8
feat(api): integrate JWT auth with JIT user provisioning
mbarlow12 Feb 10, 2026
387ccd4
infra: add stitch-auth to Docker build, AUTH_DISABLED for local dev
mbarlow12 Feb 10, 2026
cc17a25
fix(stitch.api.db): improve type hints & LBYL in uow
mbarlow12 Feb 10, 2026
3eeaa1e
refactor(api): move auth code from deps.py to stitch.api.auth module
mbarlow12 Feb 10, 2026
7c39caa
build(lock): update uv.lock for stitch-auth API dependency
mbarlow12 Feb 10, 2026
5bd9155
ci: trigger workflow run after base branch change
mbarlow12 Feb 10, 2026
5ed8066
feat(auth): add local auth testing with localauth0 mock OIDC server
mbarlow12 Feb 10, 2026
dd2099c
md,yml formatting and localauth0 config
mbarlow12 Feb 10, 2026
267bc09
fix(auth): add access_token custom claims, auth-demo script, and docs…
mbarlow12 Feb 11, 2026
407bba4
fix(auth): handle garbage tokens in validator, add demo script confir…
mbarlow12 Feb 11, 2026
5a2dd60
ci: trigger workflow run after base branch change
mbarlow12 Feb 11, 2026
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
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
**/.pytest_cache
**/.mypy_cache
**/.ruff_cache
**/tests
build

8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
UV ?= uv
DOCKER_COMPOSE := docker compose
DOCKER_COMPOSE := docker compose -f docker-compose.yml
DOCKER_COMPOSE_DEV := $(DOCKER_COMPOSE) -f docker-compose.local.yml
PYTEST := $(UV) run pytest
RUFF := $(UV) run ruff

Expand Down Expand Up @@ -127,9 +128,12 @@ frontend-clean:

# docker
clean-docker:
$(DOCKER_COMPOSE) down --volumes --remove-orphans
$(DOCKER_COMPOSE_DEV) down --volumes --remove-orphans

dev-docker:
$(DOCKER_COMPOSE_DEV) up

prod-docker:
$(DOCKER_COMPOSE) up

.PHONY: all build clean \
Expand Down
113 changes: 102 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ Stitch is a platform that integrates diverse oil & gas asset datasets, applies A

Local development is run via Docker Compose (DB + API + Frontend) with optional DB initialization/seeding.

The stack uses two compose files:

- **`docker-compose.yml`** — base services (API, DB, frontend, etc.)
- **`docker-compose.local.yml`** — local dev overrides (dev build target, debug logging, file-watch sync)

### Prerequisites

- Docker Desktop (includes Docker Engine + Docker Compose)
Expand All @@ -29,15 +34,14 @@ Edit `.env` as needed (passwords, seed settings, etc.).

Start (and build) the stack:
```bash
docker compose up --build

# or, if you have make installed:
make dev-docker
docker compose -f docker-compose.yml -f docker-compose.local.yml up --build
```

or, if already built:
Or use `make dev-docker` (see [Make Targets](#make-targets)).

Or, if already built:
```bash
docker compose up db api frontend
docker compose -f docker-compose.yml -f docker-compose.local.yml up db api frontend
```

Useful URLs:
Expand All @@ -50,17 +54,104 @@ Note: The `db-init` service runs automatically (via `depends_on`) to apply schem
- `STITCH_DB_SEED_MODE`
- `STITCH_DB_SEED_PROFILE`

### Auth Testing (optional)

By default, auth is disabled (`AUTH_DISABLED=true`) — all requests get a hardcoded dev user with no token required. To test real JWT auth flows locally with a mock OIDC server:

1. Update `.env`:
```
AUTH_DISABLED=false
AUTH_ISSUER=http://localauth0:3000/
AUTH_AUDIENCE=stitch-api-local
AUTH_JWKS_URI=http://localauth0:3000/.well-known/jwks.json
```

2. Start with the `auth-test` profile:
```bash
docker compose -f docker-compose.yml -f docker-compose.local.yml --profile auth-test up --build
```

3. Get a token and make requests:
```bash
# Health check (always open)
curl localhost:8000/api/v1/health

# No token → 401
curl localhost:8000/api/v1/resources/

# Get a valid token
TOKEN=$(curl -s -X POST localhost:3100/oauth/token \
-H "Content-Type: application/json" \
-d '{"client_id":"client_id","client_secret":"client_secret","audience":"stitch-api-local","grant_type":"client_credentials"}' \
| jq -r '.access_token')

# Authenticated request → 200
curl -H "Authorization: Bearer $TOKEN" localhost:8000/api/v1/resources/
```

Swagger UI (`/docs`) also supports the "Authorize" button for token entry.

See [docs/auth-testing.md](docs/auth-testing.md) for the full scenario guide.

## Reset (wipe DB volumes safely)

Stop containers and delete the Postgres volume (this removes all local DB data):
```bash
docker compose down -v

# or, if you have make installed:
make clean-docker
docker compose -f docker-compose.yml -f docker-compose.local.yml down -v
```

Then start fresh:
```bash
docker compose up db api frontend
docker compose -f docker-compose.yml -f docker-compose.local.yml up db api frontend
```

## Make Targets

Most common operations have `make` shortcuts. Run `make <target>` from the repo root.

### Build

| Target | Description |
|---|---|
| `make all` | Build all Python packages and the frontend |
| `make build-python` | Build all discovered Python packages (under `packages/`) |
| `make build-python PKG=stitch-core` | Build a single package by name |
| `make frontend` | Build the frontend |

Python package discovery is automatic — any subdirectory of `packages/` with a `pyproject.toml` is included. Builds are incremental via stamp files under `build/`.

### Check / Lint / Test

| Target | Description |
|---|---|
| `make check` | Run all checks (lint, test, format-check, lock-check) |
| `make lint` | Run Python and frontend linters |
| `make test` | Run Python and frontend tests |
| `make format` | Auto-format Python and frontend code |
| `make format-check` | Check formatting without modifying files |
| `make lock-check` | Verify `uv.lock` is up to date |

### Docker

| Target | Description |
|---|---|
| `make dev-docker` | Start the full local-dev stack |
| `make prod-docker` | Start without local-dev overrides |
| `make docker-exec SVC=api` | Open a shell in a running container |
| `make docker-run SVC=api` | Spin up a one-off container with a shell |
| `make docker-logs SVC=api` | Tail logs for a service |
| `make docker-ps` | List running containers |
| `make stop-docker` | Stop containers (keep volumes) |
| `make clean-docker` | Stop containers and delete volumes |

`SVC` defaults to `api` if omitted.

### Clean

| Target | Description |
|---|---|
| `make clean` | Run all clean targets |
| `make clean-build` | Remove `build/` and `dist/` |
| `make clean-cache` | Remove `.ruff_cache` and `.pytest_cache` |
| `make clean-docker` | Stop containers and delete volumes |
| `make frontend-clean` | Remove frontend `dist/`, `node_modules`, and stamps |
52 changes: 23 additions & 29 deletions deployments/api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,44 +1,38 @@
FROM python:3.12.12-slim-trixie AS builder
# ── base: Python + uv + third-party deps ─────────────────────────────
FROM python:3.12-slim-trixie AS base

# better console streaming for docker logs
ENV PYTHONUNBUFFERED=1 \
UV_COMPILE_BYTECODE=1 \
UV_LINK_MODE=copy
UV_LINK_MODE=copy \
UV_PYTHON_DOWNLOADS=0 \
UV_NO_DEV=1

WORKDIR /app

# Install uv
# Ref: https://docs.astral.sh/uv/guides/integration/docker/#installing-uv
COPY --from=ghcr.io/astral-sh/uv:0.9.25 /uv /uvx /bin/

# --- Copy workspace metadata
COPY pyproject.toml uv.lock ./

# Copy the member pyprojects (and/or whole packages) that are needed to resolve deps
COPY deployments/api/pyproject.toml deployments/api/pyproject.toml
COPY deployments/api/src /app/src

COPY packages/stitch-core/pyproject.toml packages/stitch-core/pyproject.toml
COPY packages/stitch-core/src packages/stitch-core/src
WORKDIR /app

# Install deps for the api project (important: target the subproject)
# Create venv and sync using the lock for the API project
# Third-party deps only — cached until uv.lock changes.
# All metadata via bind mounts (not copied into the layer).
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --project deployments/api --no-install-workspace
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-workspace --package stitch-api

# -------------------------------------------------------
# ── runtime target ────────────────────────────────────────────────────
FROM base AS runtime

FROM python:3.12.12-slim-trixie AS runtime
RUN groupadd --system --gid 999 stitch-app \
&& useradd --system --gid 999 --uid 999 --create-home stitch-app

ENV PYTHONUNBUFFERED=1
WORKDIR /app
COPY ./deployments/api /app/deployments/api
COPY ./packages /app/packages

# Copy the ready-to-run virtualenv
COPY --from=builder /app/.venv /app/.venv
ENV PATH="/app/.venv/bin:$PATH"
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --locked --package stitch-api

# Copy only the API source (runtime code)
COPY deployments/api/src /app/src
ENV PYTHONPATH=/app/src
ENV PATH="/app/.venv/bin:$PATH"
USER stitch-app

CMD ["uvicorn", "stitch.api.main:app", "--host", "0.0.0.0", "--port", "8000"]
2 changes: 2 additions & 0 deletions deployments/api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies = [
"greenlet>=3.3.0",
"pydantic-settings>=2.12.0",
"sqlalchemy>=2.0.44",
"stitch-auth",
"stitch-core",
]

Expand Down Expand Up @@ -39,4 +40,5 @@ python_functions = ["test_*"]
addopts = ["-v", "--strict-markers", "--tb=short"]

[tool.uv.sources]
stitch-auth = { workspace = true }
stitch-core = { workspace = true }
Loading