mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-07 07:55:16 +02:00
116 lines
4.4 KiB
Bash
Executable file
116 lines
4.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Regenerate every file the SDKs derive from authoritative backend state:
|
|
#
|
|
# 1. Typed node dataclasses / TS interfaces (from node_specs registry)
|
|
# 2. Filtered OpenAPI spec (routes tagged via @sdk_expose)
|
|
# 3. Pydantic request/response models + TS interfaces (datamodel-codegen
|
|
# / openapi-typescript)
|
|
# 4. Client method mixins (_generated_client.py / _generated_client.ts)
|
|
# 5. Full OpenAPI spec for the Mintlify docs site
|
|
# (docs/api-reference/openapi.json)
|
|
#
|
|
# Run from anywhere — the script resolves the repo root relative to itself.
|
|
# Requires:
|
|
# - `python` in the `dograh` conda env, `api/.env` sourced; the `api`
|
|
# package must be importable. `datamodel-code-generator` installed
|
|
# (`pip install datamodel-code-generator`).
|
|
# - `node` (>= 22.6 for native .mts support) and npm. openapi-typescript
|
|
# is a devDependency of sdk/typescript; `npm install` in that dir is
|
|
# done for you if node_modules is missing.
|
|
#
|
|
# Invoked manually after editing any NodeSpec or after adding/removing an
|
|
# `@sdk_expose` decorator. CI runs this and asserts the git diff is empty.
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$REPO_ROOT"
|
|
|
|
if [ -f "$REPO_ROOT/api/.env" ]; then
|
|
set -a
|
|
# shellcheck disable=SC1091
|
|
source "$REPO_ROOT/api/.env"
|
|
set +a
|
|
fi
|
|
|
|
SPECS_JSON="$(mktemp -t dograh-specs-XXXXXX.json)"
|
|
OPENAPI_JSON="$(mktemp -t dograh-openapi-XXXXXX.json)"
|
|
trap 'rm -f "$SPECS_JSON" "$OPENAPI_JSON"' EXIT
|
|
|
|
# ── 1. Node-spec typed dataclasses ────────────────────────────────────
|
|
|
|
echo "→ Dumping node specs from in-process registry..."
|
|
python -m api.services.workflow.node_specs > "$SPECS_JSON"
|
|
|
|
echo "→ Generating Python typed dataclasses..."
|
|
PYTHONPATH="$REPO_ROOT/sdk/python/src" python -m dograh_sdk.codegen \
|
|
--input "$SPECS_JSON" \
|
|
--out "sdk/python/src/dograh_sdk/typed"
|
|
|
|
echo "→ Generating TypeScript typed interfaces..."
|
|
node "sdk/typescript/scripts/codegen.mts" \
|
|
--input "$SPECS_JSON" \
|
|
--out "sdk/typescript/src/typed"
|
|
|
|
# ── 2. SDK-scoped OpenAPI spec ────────────────────────────────────────
|
|
|
|
echo "→ Dumping filtered OpenAPI (sdk_expose routes only)..."
|
|
python - <<PY
|
|
import json
|
|
from loguru import logger
|
|
logger.remove()
|
|
from fastapi.openapi.utils import get_openapi
|
|
from api.app import app
|
|
|
|
sdk_routes = [
|
|
r for r in app.routes
|
|
if getattr(r, "openapi_extra", None)
|
|
and "x-sdk-method" in (r.openapi_extra or {})
|
|
]
|
|
spec = get_openapi(title=app.title, version=app.version, routes=sdk_routes)
|
|
with open("$OPENAPI_JSON", "w") as f:
|
|
json.dump(spec, f)
|
|
print(f" → {len(sdk_routes)} operations, "
|
|
f"{len(spec.get('components', {}).get('schemas', {}))} schemas reachable")
|
|
PY
|
|
|
|
# ── 3. Request/response models (off-the-shelf) ────────────────────────
|
|
|
|
echo "→ Generating Python Pydantic models (datamodel-codegen)..."
|
|
datamodel-codegen \
|
|
--input "$OPENAPI_JSON" \
|
|
--input-file-type openapi \
|
|
--output "sdk/python/src/dograh_sdk/_generated_models.py" \
|
|
--output-model-type pydantic_v2.BaseModel \
|
|
--target-python-version 3.10 \
|
|
--use-schema-description \
|
|
--use-field-description \
|
|
--use-annotated \
|
|
--use-union-operator \
|
|
--field-constraints \
|
|
--wrap-string-literal
|
|
|
|
echo "→ Generating TypeScript types (openapi-typescript)..."
|
|
if [ ! -d "sdk/typescript/node_modules" ]; then
|
|
(cd sdk/typescript && npm install --silent)
|
|
fi
|
|
(cd sdk/typescript && npx --no-install openapi-typescript \
|
|
"$OPENAPI_JSON" \
|
|
--output "src/_generated_models.ts" \
|
|
--root-types \
|
|
--root-types-no-schema-prefix)
|
|
|
|
# ── 4. Client method mixins ──────────────────────────────────────────
|
|
|
|
echo "→ Emitting client method mixins..."
|
|
python -m sdk.codegen.client_codegen \
|
|
--input "$OPENAPI_JSON" \
|
|
--py-out "sdk/python/src/dograh_sdk/_generated_client.py" \
|
|
--ts-out "sdk/typescript/src/_generated_client.ts"
|
|
|
|
# ── 5. Docs OpenAPI spec ─────────────────────────────────────────────
|
|
|
|
echo "→ Dumping full OpenAPI spec for docs site..."
|
|
python -m scripts.dump_docs_openapi
|
|
|
|
echo "✓ SDK regenerated."
|