From 1098b01335ab7fdf2c20f89395648e4b3d39597c Mon Sep 17 00:00:00 2001 From: Ofer Mendelevitch Date: Sat, 11 Jul 2026 14:56:32 -0700 Subject: [PATCH] =?UTF-8?q?docs(publisher):=20fix=20project=E2=86=92enviro?= =?UTF-8?q?nment=20API=20drift=20in=20publishing=20guides?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Publisher API renamed the top-level concept from "project" to "environment", but the publishing user guides still used the old terms, so copy-pasted commands and configs failed against a current server: - publisher.config.json key `projects` → `environments` (in publishing.malloynb and all 14 examples in connections.malloynb). - List/status curls use `/api/v0/environments` and `/api/v0/status` (were `/api/v1/projects`, a bare `/status`, and a bad Compose healthcheck). - MCP tool `malloy_projectList` → `malloy_environmentList`, and the tool parameter `projectName` → `environmentName`. - REST query endpoint: the removed `.../queryResults/` path is now `POST .../models//query`; `QueryResult.result` is a JSON string, so the examples parse it and pass `compactJson`. The SDK's `optionalProjectName` prop keeps its name (it maps to environmentName internally) and is left unchanged. Signed-off-by: Ofer Mendelevitch --- .../publishing/connections.malloynb | 30 +++++++++---------- .../publishing/mcp_agents.malloynb | 10 +++---- .../publishing/publishing.malloynb | 18 +++++------ .../user_guides/publishing/rest_api.malloynb | 25 +++++++++------- 4 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/documentation/user_guides/publishing/connections.malloynb b/src/documentation/user_guides/publishing/connections.malloynb index 46041033..397d9254 100644 --- a/src/documentation/user_guides/publishing/connections.malloynb +++ b/src/documentation/user_guides/publishing/connections.malloynb @@ -15,7 +15,7 @@ Publisher uses `publisher.config.json` for database connections. This file lives ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -53,7 +53,7 @@ For packages with embedded parquet/CSV files, **no connection configuration is n ```json { - "projects": [ + "environments": [ { "name": "default", "packages": [ @@ -92,7 +92,7 @@ DuckDB can federate queries to external databases (BigQuery, Snowflake, PostgreS ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -128,7 +128,7 @@ source: events is duckdb.table('my_bq.my_dataset.events') ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -162,7 +162,7 @@ source: events is duckdb.table('my_bq.my_dataset.events') ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -219,7 +219,7 @@ source: events is duckdb.table('my_bq.my_dataset.events') ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -248,7 +248,7 @@ Embed the service account JSON directly in the config: ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -272,7 +272,7 @@ Embed the service account JSON directly in the config: ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -299,7 +299,7 @@ Embed the service account JSON directly in the config: ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -326,7 +326,7 @@ Embed the service account JSON directly in the config: ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -355,7 +355,7 @@ Embed the service account JSON directly in the config: ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -383,7 +383,7 @@ Embed the service account JSON directly in the config: ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -411,7 +411,7 @@ Embed the service account JSON directly in the config: ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -436,11 +436,11 @@ For Presto, use `"type": "presto"` with the same configuration options. ## Multi-Environment Configuration -You can configure multiple projects for different environments: +You can configure multiple environments (for example, staging and production): ```json { - "projects": [ + "environments": [ { "name": "staging", "connections": [ diff --git a/src/documentation/user_guides/publishing/mcp_agents.malloynb b/src/documentation/user_guides/publishing/mcp_agents.malloynb index 89461120..62750427 100644 --- a/src/documentation/user_guides/publishing/mcp_agents.malloynb +++ b/src/documentation/user_guides/publishing/mcp_agents.malloynb @@ -94,16 +94,16 @@ Publisher exposes these tools to AI agents: | Tool | Parameters | Description | |------|------------|-------------| -| `malloy_projectList` | — | List all available projects | -| `malloy_packageList` | `projectName` | List packages in a project | -| `malloy_packageGet` | `projectName`, `packageName` | Get models in a package | -| `malloy_modelGetText` | `projectName`, `packageName`, `modelPath` | Get raw model source code | +| `malloy_environmentList` | — | List all available environments | +| `malloy_packageList` | `environmentName` | List packages in an environment | +| `malloy_packageGet` | `environmentName`, `packageName` | Get models in a package | +| `malloy_modelGetText` | `environmentName`, `packageName`, `modelPath` | Get raw model source code | ### Query Execution | Tool | Parameters | Description | |------|------------|-------------| -| `malloy_executeQuery` | `projectName`, `packageName`, `modelPath`, `query` | Run a Malloy query, returns JSON results | +| `malloy_executeQuery` | `environmentName`, `packageName`, `modelPath`, `query` | Run a Malloy query, returns JSON results | --- diff --git a/src/documentation/user_guides/publishing/publishing.malloynb b/src/documentation/user_guides/publishing/publishing.malloynb index 7f6b442c..2e12857b 100644 --- a/src/documentation/user_guides/publishing/publishing.malloynb +++ b/src/documentation/user_guides/publishing/publishing.malloynb @@ -46,7 +46,7 @@ npx @malloy-publisher/server --server_root . The `--server_root` should point to the directory that **contains** your package folder(s), not the package itself. ``` -projects/ ← Run npx from HERE (--server_root .) +my-data/ ← Run npx from HERE (--server_root .) ├── publisher.config.json ← Server configuration └── my-analytics/ ← This is your package ├── publisher.json @@ -77,7 +77,7 @@ That's it for local files. If your models use DuckDB with `.parquet`, `.csv`, or ```json { - "projects": [ + "environments": [ { "name": "default", "connections": [ @@ -166,7 +166,7 @@ services: - ./packages:/publisher/packages restart: unless-stopped healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:4000/status"] + test: ["CMD", "curl", "-f", "http://localhost:4000/api/v0/status"] interval: 30s timeout: 10s retries: 3 @@ -192,13 +192,13 @@ Publisher reads runtime settings from environment variables. The most common one ### Health Check ```bash -curl http://localhost:4000/status +curl http://localhost:4000/api/v0/status ``` -### List Projects +### List Environments ```bash -curl http://localhost:4000/api/v1/projects +curl http://localhost:4000/api/v0/environments ``` See the [REST API](rest_api.malloynb) documentation for all available endpoints. @@ -216,13 +216,13 @@ See the [REST API](rest_api.malloynb) documentation for all available endpoints. ## State Persistence -Publisher persists configuration changes in a local DuckDB database (`publisher.db`). This means changes made via the REST API—adding projects, packages, or connections—survive server restarts. +Publisher persists configuration changes in a local DuckDB database (`publisher.db`). This means changes made via the REST API—adding environments, packages, or connections—survive server restarts. ### How It Works 1. **First start**: Publisher reads `publisher.config.json` and syncs it to `publisher.db` 2. **Subsequent starts**: Publisher loads from the database, ignoring config file changes -3. **API changes**: Adding/removing projects, packages, or connections updates the database +3. **API changes**: Adding/removing environments, packages, or connections updates the database ### Reinitializing from Config @@ -247,7 +247,7 @@ By default, Publisher allows configuration changes via the API. To lock the conf ```json { "frozenConfig": true, - "projects": [...] + "environments": [...] } ``` diff --git a/src/documentation/user_guides/publishing/rest_api.malloynb b/src/documentation/user_guides/publishing/rest_api.malloynb index 894160aa..fa07fcd4 100644 --- a/src/documentation/user_guides/publishing/rest_api.malloynb +++ b/src/documentation/user_guides/publishing/rest_api.malloynb @@ -27,7 +27,7 @@ The REST API lets you: | Capability | Description | |------------|-------------| -| **Browse models** | List projects, packages, and models available on the server | +| **Browse models** | List environments, packages, and models available on the server | | **Get model schema** | Retrieve sources, measures, dimensions, and views defined in a model | | **Execute queries** | Run Malloy queries and get JSON results | | **Explore databases** | List schemas, tables, and columns from connected databases | @@ -40,18 +40,16 @@ The REST API lets you: Run a query against a model: ```bash -curl -X POST "http://localhost:4000/api/v0/projects/my-project/packages/ecommerce/queryResults/orders.malloy" \ +curl -X POST "http://localhost:4000/api/v0/environments/my-env/packages/ecommerce/models/orders.malloy/query" \ -H "Content-Type: application/json" \ - -d '{"query": "run: orders -> { aggregate: order_count, total_revenue }"}' + -d '{"query": "run: orders -> { aggregate: order_count, total_revenue }", "compactJson": true}' ``` -Response: +Response — `result` is a JSON string. Parse it to get the rows. With `"compactJson": true` it's a plain array of row objects; omit it for the full Malloy result with type metadata used for rendering: ```json { - "result": [ - { "order_count": 12345, "total_revenue": 1234567.89 } - ] + "result": "[{\"order_count\":12345,\"total_revenue\":1234567.89}]" } ``` @@ -64,11 +62,18 @@ Response: ```javascript async function fetchMetrics() { const response = await fetch( - 'http://localhost:4000/api/v0/projects/prod/packages/analytics/queryResults/orders.malloy?query=' + - encodeURIComponent('run: orders -> { aggregate: total_revenue }') + 'http://localhost:4000/api/v0/environments/prod/packages/analytics/models/orders.malloy/query', + { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + query: 'run: orders -> { aggregate: total_revenue }', + compactJson: true, + }), + } ); const data = await response.json(); - return data.result; + return JSON.parse(data.result); } ```