Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
47 changes: 27 additions & 20 deletions openapi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,42 @@

## Generation

To generate the `openapi.yaml` file that corresponds exactly to what is implemented in each microservice, we start each microservice and fetch the `/openapi.json` file generated by the FastAPI server.
To generate the `openapi.yaml` files, the generator imports each FastAPI app in an isolated subprocess and calls its `.openapi()` method directly (no running server), then applies a series of schema fixes and validation passes.

To generate the updated OpenAPI schema, run:

```bash
uv run --frozen python -m script.generate_openapi_spec
```

## OpenAPI Specs Overview
## Output layout

The following table lists all the OpenAPI specifications that are merged into the final `openapi.yaml` file, along with their sources:
The generator no longer emits one spec per microservice and merges them. It now produces:

| Service | Source | Output File |
|---------|---------|-------------|
| Entity Store | Generated from `entity_store.server:app` | `entity-store.openapi.yaml` |
| Evaluator | Generated from `evaluator.server:app` | `evaluator.openapi.yaml` |
| Guardrails | Generated from `guardrails.app:app` | `guardrails.openapi.yaml` |
| Customization | Generated from `nemo-customizer-plugin` contributor routes | `customization.openapi.yaml` |
| Deployment Management | Direct copy from `deployment.openapi.yaml` | `deployment-management.openapi.yaml` |
| Jobs | Generated from `jobs.api.server:app` | `jobs.openapi.yaml` |
| Data Designer | Generated from `data_designer.api.server:app` | `data-designer.openapi.yaml` |
| Auditor | Generated from `auditor.server:app` | `auditor.openapi.yaml` |
| Safe Synthesizer API | Generated from `safe_synthesizer_api.server:app` | `safe-synthesizer.openapi.yaml` |
| Intake | Generated from `src.main:app` | `intake.openapi.yaml` |
| Models | Generated from `models.api.server:app` | `models.openapi.yaml` |
| Inference Gateway | Generated from `inference_gateway.api.server:create_app` | `inference-gateway.openapi.yaml` |
| Platform Common | Generated from `nemoplatform.server:app` | `nmp-common.openapi.yaml` |
**One aggregate platform spec**, built from the platform runner (`nmp.platform_runner.server:create_platform_openapi_app`) with plugin services deliberately excluded (`NEMO_PLUGIN_SERVICES_ALLOWLIST=""` — see `SERVICES` in `script/generate_openapi_spec.py`). This aggregate covers the core platform services (entities, jobs, models, inference gateway, secrets, files, platform-common, etc.) and lands in:

All specs are merged with the `--keep-versions` flag to preserve version information in the final `openapi.yaml`.
| File | Contents |
|------|----------|
| `openapi/openapi.yaml` | Final merged GA + EA platform spec |
| `openapi/ga/openapi.yaml` | GA-only platform spec |
| `openapi/ea/openapi.yaml` | EA-only platform spec |
| `openapi/ga/individual/platform.openapi.yaml` | The platform spec before GA/EA merge |

**One spec per opted-in plugin**, written next to each plugin — never merged into the platform spec. A plugin opts in by declaring a `[tool.nemo.openapi]` table in its own `pyproject.toml`; `discover_plugins()` (`script/openapi_helper/plugin_config.py`) enumerates those, builds each plugin's FastAPI app via the convention loader (or a `factory_override`), and emits:

| Plugin | Output File |
|--------|-------------|
| Agents | `plugins/nemo-agents/openapi/openapi.yaml` |
| Auditor | `plugins/nemo-auditor/openapi/openapi.yaml` |
| Customization | `plugins/nemo-customizer/openapi/openapi.yaml` |
| Data Designer | `plugins/nemo-data-designer/openapi/openapi.yaml` |
| Deployments | `plugins/nemo-deployments/openapi/openapi.yaml` |
| Evaluator | `plugins/nemo-evaluator/openapi/openapi.yaml` |
| Safe Synthesizer | `plugins/nemo-safe-synthesizer/openapi/openapi.yaml` |

The Customization spec is assembled at generation time from whichever customization contributors (`nemo.customization.contributors` entry points — e.g. `automodel`, `rl`, `unsloth`) are installed in the workspace, so its route surface depends on the synced environment. To add a new plugin to this list, add an (empty is fine) `[tool.nemo.openapi]` table to its `pyproject.toml`; if the plugin has more than one `nemo.services` entry point, set `service_name` in that table to disambiguate.

The platform GA and EA specs are merged with the `--keep-versions` flag to preserve version information in the final `openapi.yaml`.

### Conflicts

Expand All @@ -54,4 +61,4 @@ Currently, the examples are manually generated from notebooks. A robust system t

## NOTE

Ideally, the `nmp-common.openapi.yaml` file would be the platform OpenAPI spec directly, but for various reasons, it is not. We should get to that point soon. Until then, we take this merging approach to have a spec that corresponds 100% to what is implemented.
The aggregate platform spec is now generated directly from the platform runner (`nmp.platform_runner.server`), so it corresponds to what is actually mounted at runtime. Only the GA and EA variants of that single platform spec are merged; individual core services are no longer emitted and merged separately.
Loading