Skip to content

Migrate Content Moderation plugin to cpex-content-moderation package#4481

Open
Lang-Akshay wants to merge 1 commit intomainfrom
content_moderation_plugin
Open

Migrate Content Moderation plugin to cpex-content-moderation package#4481
Lang-Akshay wants to merge 1 commit intomainfrom
content_moderation_plugin

Conversation

@Lang-Akshay
Copy link
Copy Markdown
Collaborator

@Lang-Akshay Lang-Akshay commented Apr 27, 2026

Closes #4218

Summary

This PR resolves issue #4218 by migrating Content Moderation from the in-tree plugin implementation to the published PyPI package cpex-content-moderation==1.0.0, consistent with the existing cpex-* migration pattern.

It updates all plugin kind references to cpex_content_moderation.ContentModerationPlugin, removes in-tree plugin code/tests now owned by the package, adds integration coverage for runtime discoverability and mode management, and introduces user-facing documentation for API-first dynamic configuration.

What Changed

1) Packaging and dependency wiring

  • Added cpex-content-moderation>=1.0.0 to plugin extras in pyproject.toml.
  • Added package release-age pin for cpex-content-moderation in [tool.uv.exclude-newer-package].
  • Updated uv.lock to include cpex-content-moderation and plugin extra resolution updates.

2) Migration away from in-tree plugin code

  • Removed in-tree plugin implementation directory:
    • plugins/content_moderation/README.md
    • plugins/content_moderation/TESTING.md
    • plugins/content_moderation/__init__.py
    • plugins/content_moderation/content_moderation.py
    • plugins/content_moderation/plugin-manifest.yaml
  • Removed in-tree unit/integration tests now owned by the package:
    • tests/unit/mcpgateway/plugins/plugins/content_moderation/test_content_moderation.py
    • tests/unit/mcpgateway/plugins/plugins/content_moderation/test_content_moderation_integration.py

3) Runtime/plugin config updates

Updated plugin kind from:

plugins.content_moderation.content_moderation.ContentModerationPlugin

to:

cpex_content_moderation.ContentModerationPlugin

in:

  • plugins/config.yaml
  • plugins/config-pii-guardian-policy.yaml
  • tests/performance/plugins/config.yaml
  • tests/unit/mcpgateway/plugins/fixtures/configs/init_hooks_plugins_test.yaml

4) Integration test coverage for dynamic discoverability

Extended tests/integration/test_plugin_runtime_management.py with TestContentModerationPluginDiscoverability to verify:

  • plugin appears in GET /admin/plugins
  • plugin detail returns correct kind and expected hooks
  • mode updates (enforce, permissive, disabled) via PUT /admin/plugins/ContentModeration
  • invalid mode returns 4xx (400/422)
  • unauthenticated access to plugin detail is rejected (401/403)

5) Documentation updates

  • Added docs/docs/using/plugins/content-moderation.md with:
    • plugin overview and hooks
    • config reference
    • API-first dynamic configuration walkthrough (curl + Python)
    • troubleshooting guidance
  • Added page to docs navigation in docs/docs/using/plugins/.pages.
  • Updated plugin catalog entry in docs/docs/using/plugins/plugins.md to reference the PyPI package and type Package.
  • Removed deleted in-tree content moderation test entries from docs/docs/testing/unittest.md.

6) Ancillary/non-functional edits in this branch

  • .secrets.baseline refreshed to remove references to deleted in-tree content moderation files.
  • Minor import/comment/format-only adjustments in:
    • mcpgateway/alembic/env.py
    • mcpgateway/common/validators.py
    • mcpgateway/main.py
    • mcpgateway/services/audit_trail_service.py
    • mcpgateway/transports/context.py
    • mcpgateway/transports/streamablehttp_transport.py

Issue #4218 Acceptance Criteria Mapping

  • cpex-content-moderation added and pinned in plugin dependency flow (pyproject.toml + uv.lock).
  • In-tree plugins/content_moderation/ removed from this repository.
  • Runtime discoverability and plugin-management behavior covered by new integration tests.
  • Existing policy YAML references updated to new kind path (cpex_content_moderation.ContentModerationPlugin).
  • New user docs page added and linked from plugin index/navigation.

Impact

  • Behavioral intent: no change to plugin semantics; distribution and loading path changed from in-repo module to external package.
  • Operationally: installing plugin extras now pulls cpex-content-moderation directly from PyPI.
  • Maintenance: plugin code and most plugin-specific tests now live with the package, reducing core-repo coupling.

…d tests

- Deleted the content moderation plugin manifest file.
- Updated  to remove references to the content moderation plugin and added a new entry for .
- Added integration tests for the content moderation plugin's discoverability and management via the runtime plugin management API.
- Updated performance tests to reflect the new plugin structure.
- Removed outdated unit tests for the content moderation plugin and replaced them with new tests that align with the updated plugin architecture.
- Adjusted configuration files to use the new plugin kind for content moderation.

Signed-off-by: Lang-Akshay <[email protected]>
@Lang-Akshay Lang-Akshay changed the title Migrate content_moderation plugin to cpex-content-moderation PyPI package Migrate Content Moderation plugin to cpex-content-moderation package Apr 27, 2026
@msureshkumar88
Copy link
Copy Markdown
Collaborator

Thanks for this migration — the overall approach is clean and consistent with the existing cpex-* pattern. A few things worth addressing before merge:

Requests for change

1. Integration tests need a skip guard or CI confirmation

TestContentModerationPluginDiscoverability assumes PLUGINS_ENABLED=true and cpex-content-moderation installed. If CI runs without [plugins] extras, these tests will fail with an opaque 404 or empty plugin list rather than a useful skip. Worth either confirming the CI environment always runs make install-dev (with plugins), or adding a guard:

pytest.importorskip("cpex_content_moderation", reason="cpex-content-moderation not installed")

2. Mode toggle tests have no state reset

test_content_moderation_mode_toggle_disabled restores mode to permissive inline (appreciated), but if test_content_moderation_mode_toggle_enforce fails mid-run, subsequent toggle tests start in an undefined state. A teardown_method or class-scoped autouse fixture that resets to the default disabled mode would make these robust and order-independent.

3. Unused auth_headers fixture parameter in three tests

test_content_moderation_appears_in_plugin_list, test_content_moderation_detail_returns_correct_kind, and test_content_moderation_detail_has_expected_hooks accept auth_headers as a parameter but call _fresh_headers() directly — the parameter is never used. Either drop it or switch to auth_headers consistently.

4. Stray # First-Party comments

Two misplaced import-section comments snuck in:

  • mcpgateway/services/audit_trail_service.py line 458 — # First-Party appears inside a function body above a lazy import, which is a module-level convention.
  • mcpgateway/transports/context.py line 469 — # First-Party appears before a ContextVar variable definition, not an import.

These look like copy-paste artifacts; worth removing.


Suggestions (non-blocking)

Config schema migration note — the in-tree plugin used a nested config: { provider, ibm_watson: { api_key, ... } } structure; the new docs show a flat provider_config: { granite_guardian_url, watson_api_key, ... } layout. Users upgrading from the in-tree version would benefit from a one-liner in the docs noting the schema changed, not just the kind path.

Redis dependency in troubleshooting — the docs correctly note mode changes persist via Redis, but the troubleshooting section doesn't mention Redis as a prerequisite for persistence. A short note there ("ensure Redis is running if you expect mode changes to survive restarts") would save people time.


The core migration is in good shape — pyproject.toml, the four YAML config files, secrets baseline, and doc additions all look correct. Addressing the items above (especially #1 and #2) would make this solid.

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.

[CHORE]: Package content_moderation plugin as cpex-* PyPI package and document dynamic configuration

2 participants