Skip to content

Add POST /playbooks/reload endpoint for hot-reload#121

Merged
peaktwilight merged 1 commit into
mainfrom
feat/playbook-registry-reload-endpoint
Apr 21, 2026
Merged

Add POST /playbooks/reload endpoint for hot-reload#121
peaktwilight merged 1 commit into
mainfrom
feat/playbook-registry-reload-endpoint

Conversation

@peaktwilight

@peaktwilight peaktwilight commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds PlaybookRegistry.clear_and_reload() which wipes the playbook module cache + _PLAYBOOK_REGISTRY and re-runs discovery against the configured directories.
  • Exposes a new POST /api/v1/playbooks/reload endpoint guarded by Permission.PLAYBOOKS_MANAGE that calls the helper, syncs the refreshed registry to the database, and returns the loaded playbook count.
  • No more full API restart required to pick up playbook source changes.

In-flight playbook executions keep a reference to the pre-reload function object and complete with the old code; subsequent invocations use the refreshed registry.

Closes #112.

Test plan

  • ruff check src/ tests/ passes
  • Unit test: clear_and_reload refreshes registry metadata when a playbook file is mutated on disk
  • Unit test: clear_and_reload drops playbooks whose files were deleted
  • Integration test: endpoint returns 401 without auth, 403 for non-admin, 200 + count for admin
  • Integration test: mutating a playbook on disk and POSTing the endpoint reflects the new metadata in the registry
  • Full suite: pytest tests/ — 551 passed

Summary by CodeRabbit

  • New Features

    • Added an authenticated API endpoint to reload playbooks dynamically without restarting the application; admin-only access required. Returns count of reloaded playbooks.
  • Tests

    • Added test coverage for playbook reload functionality, including authentication and authorization checks, and metadata refresh verification.

Closes #112.

Playbooks previously required a full API restart to pick up source changes.
This adds a PlaybookRegistry.clear_and_reload() helper that wipes the module
cache + _PLAYBOOK_REGISTRY and re-imports all configured playbook directories,
exposed via an admin-only POST endpoint that also syncs the refreshed
registry back to the database.

In-flight executions hold a reference to the pre-reload function object and
complete with the old code; new invocations use the refreshed registry.
@coderabbitai

coderabbitai Bot commented Apr 21, 2026

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

Added authenticated API endpoint /playbooks/reload to enable hot-reload of playbook registry. The endpoint clears in-memory registry, forces module re-import via clear_and_reload(), syncs definitions to database, and returns reload count. Includes registry refresh logic and comprehensive test coverage.

Changes

Cohort / File(s) Summary
Playbook Hot-Reload Endpoint
src/opensoar/api/playbooks.py
Added new POST /playbooks/reload endpoint requiring authentication. Instantiates PlaybookRegistry, calls clear_and_reload() to refresh registry state, syncs updated playbook definitions to database via sync_to_db(), and returns reloaded playbook count with status message.
Registry Refresh Logic
src/opensoar/core/registry.py
Introduced clear_and_reload() method that computes module name prefixes from configured playbook directories, removes stale entries from sys.modules, invalidates import caches, clears global _PLAYBOOK_REGISTRY, re-discovers playbooks, and returns the updated count.
Test Coverage
tests/test_playbooks_api.py
Added TestClearAndReload unit tests for registry refresh (metadata updates, file deletion handling) and TestReloadEndpoint integration tests for endpoint authentication/authorization (401 unauthenticated, 403 non-admin, 200 admin) and registry synchronization after file mutations.

Sequence Diagram

sequenceDiagram
    actor Client
    participant API as /playbooks/reload
    participant Registry as PlaybookRegistry
    participant Modules as sys.modules
    participant ImportLib as importlib
    participant DB as Database

    Client->>API: POST /playbooks/reload (authenticated)
    API->>Registry: instantiate with settings.playbook_directories
    Registry->>Modules: remove stale playbook module entries
    Registry->>ImportLib: invalidate_caches()
    Registry->>Registry: clear global _PLAYBOOK_REGISTRY
    Registry->>Registry: discover() re-scan playbooks
    Registry->>Modules: import refreshed modules
    API->>DB: sync_to_db(session)
    API->>Client: return {count, status}
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 The playbooks now spring back to life,
No restart needed, no frantic strife,
With hot-reload bouncing through the code,
Changes bloom fresh on the SOAR road!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add POST /playbooks/reload endpoint for hot-reload' accurately and concisely summarizes the main change—a new API endpoint for hot-reloading playbooks to address the startup-only registry refresh limitation.
Linked Issues check ✅ Passed All core objectives from issue #112 are met: the PR implements the recommended API endpoint approach for hot-reload, allowing playbook registry refresh without full restart, and includes comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes directly support the hot-reload objective: the new endpoint, registry clear/reload method, and comprehensive test coverage are all in-scope and necessary for the feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/playbook-registry-reload-endpoint

Comment @coderabbitai help to get the list of available commands and usage tips.

@peaktwilight
peaktwilight merged commit 9ad663c into main Apr 21, 2026
7 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No hot-reload for playbook registry

1 participant