Skip to content

feat(sdk): 1.1.2 — @route wires into FastAPI, CycloneDX SBOM in .dryadepkg#6

Merged
DryadeCore merged 1 commit into
mainfrom
fix/1.1.2-route-decorator-and-sbom
May 20, 2026
Merged

feat(sdk): 1.1.2 — @route wires into FastAPI, CycloneDX SBOM in .dryadepkg#6
DryadeCore merged 1 commit into
mainfrom
fix/1.1.2-route-decorator-and-sbom

Conversation

@DryadeCore
Copy link
Copy Markdown
Contributor

Summary

Lands the final two author-surface gaps from the `sdk_proof` end-to-end run.

Gap #4 — `@route` was a no-op. The decorator now stamps `_dryade_route_meta` (keeping the legacy `spec` attribute for backwards compatibility), and the SDK ships two new helpers:

  • `collect_routes(plugin)` — walks the plugin, returns `[(meta, callable), ...]` ordered by `qualname`.
  • `build_router(plugin) -> fastapi.APIRouter` — produces a FastAPI router from every decorated method. Lazy-imports FastAPI. Plugins with pre-built `self.router` get it back unchanged (no double-mount).

Gap #6 — no SBOM in `.dryadepkg`. `dryade plugin package` now embeds a CycloneDX 1.5 SBOM as `sbom.cdx.json` next to `dryade.json`. Full SBOM via `cyclonedx-py` (added to `[cli]` extras) when available, minimal shim otherwise. The manifest carries an `sbom: cyclonedx-py | minimal-shim` field so consumers can read the source without unpacking the SBOM.

Tests

  • `tests/test_route_decorator.py` (8 cases): decorator metadata, `collect_routes` ordering + legacy fallback, `build_router` output via FastAPI TestClient, `self.router` passthrough, empty-router path.
  • `tests/test_package_sbom.py` (2 cases): `.dryadepkg` contains a valid CycloneDX 1.5 SBOM; manifest flags SBOM source.

Companion host fix in DryadeAI/Dryade#962 unblocks the load gate so SDK-authored plugins satisfy `isinstance(plugin, Plugin)` (structural Protocol) without inheriting from `core.ee.*`.

🤖 Generated with Claude Code

…depkg

Two author-surface gaps from sdk_proof e2e:

Gap #4@route was a no-op decorator. The decorator now stamps a
canonical _dryade_route_meta dict on the wrapped callable (keeping the
legacy `spec` attribute for backwards compatibility), and the SDK ships
two new helpers in dryade_plugins_sdk.plugin:

  - collect_routes(plugin) — walks dir(plugin), returns
    [(meta, callable), ...] ordered by __qualname__.
  - build_router(plugin) -> fastapi.APIRouter — produces a FastAPI
    router from every decorated method; lazy-imports FastAPI so plugins
    without routes don't pull it in; returns plugin.router unchanged
    when present so the legacy pattern keeps working.

with_tool example now uses @route + build_router as the canonical
reference pattern.

Gap #6 — dryade plugin package emitted no SBOM. The packager now embeds
a CycloneDX 1.5 SBOM as sbom.cdx.json in every .dryadepkg. Full SBOM via
cyclonedx-py when available, minimal shim otherwise. The manifest's
`sbom` field records the source (minimal-shim | cyclonedx-py) so
consumers can read the source without unpacking the SBOM file.

Tests:
  - tests/test_route_decorator.py: 8 cases covering decorator metadata,
    collect_routes ordering + legacy-spec fallback, build_router output
    via FastAPI TestClient, plugin.router passthrough, empty-router path.
  - tests/test_package_sbom.py: asserts every .dryadepkg contains a
    valid CycloneDX 1.5 SBOM and the manifest carries the sbom-source
    flag.

Co-Authored-By: Dammerzone <dammerzone@users.noreply.github.com>
@DryadeCore DryadeCore merged commit 7674379 into main May 20, 2026
7 of 11 checks passed
@DryadeCore DryadeCore deleted the fix/1.1.2-route-decorator-and-sbom branch May 20, 2026 07:16
@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies feature labels May 20, 2026
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome to dryade-plugins-sdk! Thanks for your first PR.

Please confirm:

  • Tests pass locally (pytest -x)
  • Examples still build (pytest tests/test_examples_build.py)
  • PR title follows Conventional Commits

A maintainer will review shortly. Want to be added to the All Contributors list? Drop a comment like @all-contributors please add @yourname for code.

DryadeCore pushed a commit that referenced this pull request May 26, 2026
…depkg (#6)

Two author-surface gaps from end-to-end author testing:

Gap #4@route was a no-op decorator. The decorator now stamps a
canonical _dryade_route_meta dict on the wrapped callable (keeping the
legacy `spec` attribute for backwards compatibility), and the SDK ships
two new helpers in dryade_plugins_sdk.plugin:

  - collect_routes(plugin) — walks dir(plugin), returns
    [(meta, callable), ...] ordered by __qualname__.
  - build_router(plugin) -> fastapi.APIRouter — produces a FastAPI
    router from every decorated method; lazy-imports FastAPI so plugins
    without routes don't pull it in; returns plugin.router unchanged
    when present so the legacy pattern keeps working.

with_tool example now uses @route + build_router as the canonical
reference pattern.

Gap #6 — dryade plugin package emitted no SBOM. The packager now embeds
a CycloneDX 1.5 SBOM as sbom.cdx.json in every .dryadepkg. Full SBOM via
cyclonedx-py when available, minimal shim otherwise. The manifest's
`sbom` field records the source (minimal-shim | cyclonedx-py) so
consumers can read the source without unpacking the SBOM file.

Tests:
  - tests/test_route_decorator.py: 8 cases covering decorator metadata,
    collect_routes ordering + legacy-spec fallback, build_router output
    via FastAPI TestClient, plugin.router passthrough, empty-router path.
  - tests/test_package_sbom.py: asserts every .dryadepkg contains a
    valid CycloneDX 1.5 SBOM and the manifest carries the sbom-source
    flag.

Co-authored-by: Dryade <contact@dryade.ai>
Co-authored-by: Dammerzone <dammerzone@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies documentation Improvements or additions to documentation feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant