Skip to content

Manifest Format

Instead of (or in addition to) a register() function, plugins can declare their capabilities via a sonar-plugin.yaml manifest file. This is useful for simple format additions that don’t need custom logic.

Place sonar-plugin.yaml in your plugin package root:

my_sonar_plugin/
__init__.py
sonar-plugin.yaml
name: my-sonar-plugin
version: 1.0.0
description: Adds FooBar sonar format support
contributions:
formats:
- name: foobar
extensions: [".fb", ".fbar"]
magic_bytes: "f00bar"
magic_offset: 0
nav_extractors:
- format: foobar
python_name: my_sonar_plugin.extractors:FooBarExtractor
FieldRequiredDescription
nameYesPlugin name (must match entry point name)
versionYesSemantic version
descriptionNoHuman-readable description

Each entry adds a sonar format:

FieldRequiredDescription
nameYesFormat identifier (e.g., "foobar")
extensionsNoFile extensions (e.g., [".fb", ".fbar"])
magic_bytesNoHex-encoded magic bytes
magic_offsetNoByte offset for magic bytes (default: 0)

Each entry registers a navigation extractor:

FieldRequiredDescription
formatYesFormat this extractor handles
python_nameYesImportable path to the extractor class (module:ClassName)

The class must extend sonar_catalog.extractors.base.NavExtractor:

from sonar_catalog.extractors.base import NavExtractor, NavResult
class FooBarExtractor(NavExtractor):
supported_formats = ["foobar"]
def extract(self, file_path, sonar_format=None):
# Parse the file...
track = [[56.0, 3.0], [56.1, 3.1]]
return NavResult(track=track, source="foobar_extractor")

When a plugin module doesn’t have a register() function, the plugin manager looks for sonar-plugin.yaml inside the package and auto-registers the declared contributions:

You can use both. The register() function runs first (for complex logic), and the manifest provides additional declarative contributions. This is useful when you have some formats that are simple signature matches and others that need custom detection code.