Skip to main content

wex_addon_services_platform

Version: 12.10.1

This addon extends wex with install, setup, and ready lifecycle commands for self-hosted platform services: GitLab, GitLab Runner, Supabase, n8n, Odoo, Ollama, Nextcloud, RabbitMQ, SonarQube, Listmonk, Temporal, and OpenClaw. Each command handles the work its platform requires — writing service configuration into the app config, generating secrets, fetching upstream config files, or verifying that the container is healthy. It targets wex app developers who run one or more of these platforms as Docker services inside a wex-managed app.

Table of Contents

Installation

pip install wexample-wex-addon-services-platform

Requires Python >=3.10.

Quickstart

Install the package into the same Python environment as wex:

pip install wexample-wex-addon-services-platform

The package exposes one public symbol:

from wexample_wex_addon_services_platform import ServicesPlatformAddonManager

Pass it to the kernel at startup alongside the other addon managers your wex instance loads:

from wexample_wex_core.common.kernel import Kernel
from wexample_wex_core.addons.core.core_addon_manager import CoreAddonManager
from wexample_wex_addon_services_platform import ServicesPlatformAddonManager

kernel = Kernel(entrypoint_path=wex_dir)
kernel.setup(addons=[CoreAddonManager, ServicesPlatformAddonManager])

Once the kernel is running, add a platform service to a wex app from the app's root directory — ollama for this example:

wex service/install --service ollama

The command writes service.ollama into the app's config.yml, creates the ollama/ host directory, and runs the service-specific install hook (src/wexample_wex_addon_services_platform/services/ollama/commands/service/install.py), which sets service.ollama.host and service.ollama.port. After that wex app/start brings the container up.

To verify the container is healthy after start:

wex @ollama::service/ready

The same service/install --service <name> call works for every platform the addon ships: supabase, n8n, gitlab, gitlab_runner, odoo, nextcloud, rabbitmq, sonarqube, listmonk, temporal, and openclaw. Platforms that require secrets — Supabase generates JWT keys and fetches upstream config files; n8n generates a basic-auth password — do all of that inside their own install hook with no extra input required.

Tests

This project uses pytest for testing and pytest-cov for code coverage analysis.

Installation

First, install the required testing dependencies:

.venv/bin/python -m pip install pytest pytest-cov

Basic Usage

Run all tests with coverage:

.venv/bin/python -m pytest --cov --cov-report=html

Common Commands

# Run tests with coverage for a specific module
.venv/bin/python -m pytest --cov=your_module

# Show which lines are not covered
.venv/bin/python -m pytest --cov=your_module --cov-report=term-missing

# Generate an HTML coverage report
.venv/bin/python -m pytest --cov=your_module --cov-report=html

# Combine terminal and HTML reports
.venv/bin/python -m pytest --cov=your_module --cov-report=term-missing --cov-report=html

# Run specific test file with coverage
.venv/bin/python -m pytest tests/test_file.py --cov=your_module --cov-report=term-missing

Viewing HTML Reports

After generating an HTML report, open htmlcov/index.html in your browser to view detailed line-by-line coverage information.

Coverage Threshold

To enforce a minimum coverage percentage:

.venv/bin/python -m pytest --cov=your_module --cov-fail-under=80

This will cause the test suite to fail if coverage drops below 80%.

Architecture

The addon is a Python package that registers a collection of platform-service definitions into the wex kernel. It adds no runtime framework of its own — every piece it ships is either a service descriptor, a Docker Compose file, or a command function that runs when the user invokes a wex CLI verb.

Addon manager

src/wexample_wex_addon_services_platform/services_platform_addon_manager.py is the single entry point the host kernel needs:

from wexample_wex_addon_services_platform import ServicesPlatformAddonManager

kernel.setup(addons=[..., ServicesPlatformAddonManager])

ServicesPlatformAddonManager extends AbstractAddonManager from wexample_wex_core and implements get_package_module(), which returns the wexample_wex_addon_services_platform module object. The framework uses that to walk the package tree and auto-discover every @command-decorated function inside it.

Service modules

Each platform lives under src/wexample_wex_addon_services_platform/services/<name>/. The layout inside that directory is:

path what it owns
service.yml name, tags, optional vars block, optional dependencies, pointer to the Compose file
docker/docker-compose.yml canonical container definition used by the wex runtime
samples/env/{prod,dev}/docker/docker-compose.yml override fragments for concrete environments
app_service.py AppService subclass; declares the host directory tree the container requires
commands/<group>/<verb>.py one file per CLI command

Services that ship today: gitlab, gitlab_runner, supabase, n8n, odoo, ollama, openclaw, nextcloud, temporal, rabbitmq, sonarqube, listmonk, jenkins.

AppService subclass

Services whose containers require specific host directories or permission modes carry an AppService subclass that overrides get_workdir_contribution(). The method returns a nested dict describing the expected directory tree; the framework's filestate layer rectifies it — creating missing entries and enforcing owner/permissions — each time the app starts.

For example, src/wexample_wex_addon_services_platform/services/supabase/app_service.py declares supabase/db/data with owner: 105:106, permissions: 700 (the uid:gid of the supabase/postgres image user), and src/wexample_wex_addon_services_platform/services/n8n/app_service.py declares n8n/ with owner: 1000:1000, permissions: 750 (the node user in the n8n image).

Services that have no special filesystem requirements — or whose container runs as root and manages its own tree — have no AppService subclass.

Commands

Commands follow three lifecycle verbs:

service/install — runs once per service per app. It reads the app's config.yml, writes the service's required keys (host, port, credentials, generated secrets), then calls app_workdir.get_runtime_config(rebuild=True) to flush the cached config. Supabase's install (src/wexample_wex_addon_services_platform/services/supabase/commands/service/install.py) also generates a full JWT key set and fetches official config files from GitHub with curl. n8n's install (src/wexample_wex_addon_services_platform/services/n8n/commands/service/install.py) generates a random basic-auth password.

service/setup — idempotent filesystem preparation. It creates files or directories the container needs on first boot but cannot create itself (e.g., Supabase's pgsodium_root.key, GitLab Runner's config.toml stub). Unlike install it is safe to run repeatedly.

service/ready — health check. Each implementation derives the container name as {app_project_name}_{service_name} from the runtime config, then runs a docker exec against a service-specific health endpoint. Supabase checks kong health inside the supabase_kong container (src/wexample_wex_addon_services_platform/services/supabase/commands/service/ready.py); n8n curls localhost:5678/healthz; ollama curls localhost:11434/api/tags; gitlab calls gitlab-healthcheck.

Supabase also ships two database commands under commands/db/: src/wexample_wex_addon_services_platform/services/supabase/commands/db/migrate.py (applies pending migrations via supabase db push inside the supabase_cli helper container, hooked to run before app::maintenance/disable) and db/reset (drops schemas and replays migrations; tagged DANGEROUS).

GitLab Runner adds a commands/runner/ group with register, unregister, and list verbs that call docker exec … gitlab-runner inside the running container.

Domain tags

src/wexample_wex_addon_services_platform/const/tags.py defines DomainTag — a class of string constants (domain:ai, domain:ci, domain:db, domain:git, domain:platform, etc.) attached to every command via the @command(tags=[...]) decorator. Tags allow the kernel and external tools to filter commands by functional area without inspecting their names.

Call path

When the user runs wex @supabase::service/install:

  1. The kernel resolves supabase to the service registered under that name, and service/install to the command file at src/wexample_wex_addon_services_platform/services/supabase/commands/service/install.py.
  2. The framework constructs an ExecutionContext (carrying the IO layer and the kernel) and resolves the service: AppService parameter by looking up the app's active supabase service object.
  3. The command function runs: it reads app config, writes keys, generates secrets, fetches files, and rebuilds the runtime config.
  4. For service/ready, the same resolution path leads to a function that runs docker exec and returns a BooleanResponse.

Container names are always {APP_PROJECT_NAME}_{service_name}, where APP_PROJECT_NAME is the value the Docker Compose environment variable ${APP_PROJECT_NAME} expands to at runtime. Commands that need to reach a container resolve this from service.app_workdir.get_runtime_config().search("app.project_name").get_str().

Integration in the Suite

This package is part of the Wexample Suite — a collection of high-quality, modular tools designed to work seamlessly together across multiple languages and environments.

The suite includes packages for configuration management, file handling, prompts, and more. Each package can be used independently or as part of the integrated suite.

Visit the Wexample Suite documentation for the complete package ecosystem.

Dependencies

  • requests:
  • wexample-wex-addon-app: >=31.1.0
  • wexample-wex-core: >=30.2.0

Versioning & Compatibility Policy

Wexample packages follow Semantic Versioning (SemVer):

  • MAJOR: Breaking changes
  • MINOR: New features, backward compatible
  • PATCH: Bug fixes, backward compatible

We maintain backward compatibility within major versions and provide clear migration guides for breaking changes.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Free to use in both personal and commercial projects.

About us

Wexample stands as a cornerstone of the digital ecosystem — a collective of seasoned engineers, researchers, and creators driven by a relentless pursuit of technological excellence. More than a media platform, it has grown into a vibrant community where innovation meets craftsmanship, and where every line of code reflects a commitment to clarity, durability, and shared intelligence.

This packages suite embodies this spirit. Trusted by professionals and enthusiasts alike, it delivers a consistent, high-quality foundation for modern development — open, elegant, and battle-tested. Its reputation is built on years of collaboration, refinement, and rigorous attention to detail, making it a natural choice for those who demand both robustness and beauty in their tools.

Wexample cultivates a culture of mastery. Each package, each contribution carries the mark of a community that values precision, ethics, and innovation — a community proud to shape the future of digital craftsmanship.

Known Limitations & Roadmap

Current limitations and planned features are tracked in the GitHub issues.

See the project roadmap for upcoming features and improvements.

Status & Compatibility

Maturity: Production-ready

Python Support: >=3.10

OS Support: Linux, macOS, Windows

Status: Actively maintained

Migration Notes

When upgrading between major versions, refer to the migration guides in the documentation.

Breaking changes are clearly documented with upgrade paths and examples.

Metadata

Release files for wexample-wex-addon-services-platform 12.10.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wexample-wex-addon-services-platform 12.10.1
File Size Uploaded
wexample_wex_addon_services_platform-12.10.1.tar.gz 39.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wexample-wex-addon-services-platform 12.10.1
File Interpreter ABI Platform
wexample_wex_addon_services_platform-12.10.1-py3-none-any.whl Python 3 none any Details

Total release size: 126.1 kB

Release files / wexample_wex_addon_services_platform-12.10.1.tar.gz

Download URL wexample_wex_addon_services_platform-12.10.1.tar.gz
Size 39.9 kB
Tags Source
SHA-256 checksum
How to use checksums
b09aa2aef2f6d54a2ea09463ebc5ad1b51507775d242435fd2ea46d7bbed1385
BLAKE2b-256 checksum
How to use checksums
d229260f288f57a7e8ef163abf60e461c485127874fdb645964204aa56aa6239
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.25.9 CPython/3.12.3 Linux/6.8.0-139-generic

Release files / wexample_wex_addon_services_platform-12.10.1-py3-none-any.whl

Download URL wexample_wex_addon_services_platform-12.10.1-py3-none-any.whl
Size 86.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7b80bca67614ae673707a64053b1eef4ca1defcc742c4fdd7fde195fda6b99d3
BLAKE2b-256 checksum
How to use checksums
74cbe1863730de8e7f3e73038fafd0ea4610b803874eca47eade5667c4e61095
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via pdm/2.25.9 CPython/3.12.3 Linux/6.8.0-139-generic

Release history Release notifications | RSS feed

This release

12.10.1 This release

2 release files

12.8.4

2 release files

12.8.3

2 release files

12.8.2

2 release files

12.7.3

2 release files

12.7.2

2 release files

12.7.1

2 release files

12.7.0

2 release files

12.6.0

2 release files

12.5.0

2 release files

12.4.4

2 release files

12.4.3

2 release files

12.4.2

2 release files

12.4.1

2 release files

12.4.0

2 release files

12.3.0

2 release files

12.2.0

2 release files

11.9.3

2 release files

11.9.2

2 release files

11.9.1

2 release files

11.9.0

2 release files

11.8.5

2 release files

11.8.4

2 release files

11.8.3

2 release files

11.8.2

2 release files

11.8.1

2 release files

11.8.0

2 release files

11.7.0

2 release files

11.6.0

2 release files

11.5.0

2 release files

11.4.0

2 release files

11.3.0

2 release files

11.2.1

2 release files

11.2.0

2 release files

11.1.1

2 release files

11.1.0

2 release files

11.0.0

2 release files

10.0.3

2 release files

10.0.2

2 release files

10.0.1

2 release files

10.0.0

2 release files

9.1.3

2 release files

9.1.2

2 release files

9.1.1

2 release files

9.1.0

2 release files

9.0.1

2 release files

9.0.0

2 release files

8.0.0

2 release files

7.7.1

2 release files

7.7.0

2 release files

7.6.1

2 release files

7.6.0

2 release files

7.5.0

2 release files

7.4.0

2 release files

7.3.0

2 release files

7.2.0

2 release files

7.1.0

2 release files

7.0.6

2 release files

7.0.5

2 release files

7.0.4

2 release files

7.0.3

2 release files

7.0.2

2 release files

7.0.1

2 release files

7.0.0

2 release files

5.0.0

2 release files

4.0.0

2 release files

3.0.0

2 release files

2.0.0

2 release files

1.0.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page