Skip to main content

A tool that parses your data into whatever you desire

Project description

Honk Parser

A tool that parses your data into whatever you desire.

Installation

honk-parser is available on PyPI and can be installed using pip:

pip install honk-parser

Overview

honk-parser is a CLI tool that reads structured data from files or standard input, parses it using a specified method, and applies a template to display or transform the result. The tool is built around a flexible plugin system that allows you to extend both parsing methods and output templates.

honk --help

Displays general help information about the tool.

Core Concepts

  • Parsing Method: A function that converts raw text (e.g., JSON, TOML) into a Python object.
  • Template: A function that takes a parsed data object and outputs it in a desired format (e.g., plain text, JSON, Markdown table).
  • Plugin: A Python module that registers new parsing methods and templates.

Subcommands

honk-parser provides two main subcommands: parse and plugin.

Parse Command

The parse command reads data and processes it through a parser and a template.

honk parse [OPTIONS] <TEMPLATE> [OPTIONS]

Options

Option Description
-p, --path PATH Path to the file to read from. If omitted, reads from stdin.
-m, --method METHOD Parsing method to use. Can be omitted when reading from a file — the file extension is used automatically.
-t, --target TARGET Target object path within the parsed data. Defaults to "." (the root).
-d, --delim DELIM Delimiter for the target path. Defaults to "/".

Examples

Parse a JSON file and echo the result:

honk parse -p data.json echo

Parse TOML from stdin and output as JSON:

echo 'name = "honk"' | honk parse -m toml json

Extract a nested value using a target path:

honk parse -p data.json -t "user/name" echo

Use a wildcard (*) in the target path:

honk parse -p data.json -t "user/*/name" echo

Use a custom delimiter for the target path:

honk parse -p data.json -t "user.name" -d "." echo

Plugin Command

The plugin command manages which plugins are loaded.

honk plugin [SUBCOMMAND] [OPTIONS]

Subcommands

Subcommand Description
load MODULE Load a plugin module by name.
unload MODULE Unload a previously loaded plugin.
list List all currently loaded plugins.

Plugin Loading Mechanism

When honk-parser starts, it looks for a plugins.json file in the current working directory. If the file exists, it loads all modules listed in it. If it doesn't exist, the stdplugin is loaded by default.

The plugin commands modify this plugins.json file, making plugin configuration persistent across invocations.

Examples

Load a custom plugin:

honk plugin load my_plugin

Unload a plugin:

honk plugin unload my_plugin

List loaded plugins:

honk plugin list

Output:

Loaded plugins:
- stdplugin
- my_plugin

Plugin System

honk-parser's plugin system allows you to extend the tool with custom parsing methods and templates. Plugins are Python modules that use the @parser and @template decorators to register new functionality.

How Plugins Work

  1. A plugin is a Python module that imports honk and uses its decorators.
  2. The plugin file should be placed in a directory that is in Python's module search path, or you can use a local module by running honk from the directory containing it.
  3. To load a plugin, use honk plugin load <module_name>.
  4. The plugin's @parser and @template decorators register functions that become available via the -m option and as template names.

Creating a Plugin

Here's a minimal plugin that adds a custom parser and template:

# my_plugin.py
import honk
import click

from typing import Mapping


@honk.parser("custom")
def parse_custom(text: str) -> dict[str, str]:
    """Parse custom-formatted text into a dictionary."""
    result: dict[str, str] = {}

    for line in text.split("\n"):
        if ":" in line:
            key, value = line.split(":", 1)
            result[key] = value.strip()
    return result


@honk.template(help="Display data in custom format")
def custom_format(data: Mapping[str, str]) -> None:
    """Render data as key: value pairs."""
    for key, value in data.items():
        click.echo(f"{key}: {value}")

After loading this plugin:

honk plugin load my_plugin

You can use it:

echo "name: honk" | honk parse -m custom custom-format

Standard Plugin (stdplugin)

The standard plugin is loaded by default and provides built-in parsers and templates for common use cases.

Built-in Parsers

Method Description
json Parses JSON data using json.loads
toml Parses TOML data using tomllib.loads

Built-in Templates

Template Description
echo Prints the parsed data as-is using click.echo
json Prints the parsed data in JSON format
map-map Renders a mapping of mappings as a Markdown table
map-arr Renders a mapping of arrays as a Markdown table
arr-map Renders an array of mappings as a Markdown table

map-map Template

Parses nested mappings (e.g., Mapping[str, Mapping[str, Any]]) and outputs a Markdown table.

Options:

Option Description
--header TEXT Header text for the first column
--excluded-col TEXT Columns to exclude (supports * wildcards), can be used multiple times
--excluded-row TEXT Rows to exclude (supports * wildcards), can be used multiple times
-s, --swap Swap columns and rows

Example:

honk parse -p data.json map-map --header "Files" --excluded-col "*_display"

map-arr Template

Parses a mapping of arrays (e.g., Mapping[str, Sequence[Any]]) and outputs a Markdown table.

Options:

Option Description
-e, --excluded TEXT Keys to exclude (supports * wildcards)

Example:

honk parse -p data.json map-arr -e "*_display"

arr-map Template

Parses an array of mappings (e.g., Sequence[Mapping[str, Any]]) and outputs a Markdown table.

Options:

Option Description
-e, --excluded TEXT Columns to exclude (supports * wildcards)

Example:

honk parse -p data.json arr-map -e "internal_id"

Plugin API

@parser Decorator

The @parser decorator registers a function as a parsing method for a given file extension.

@honk.parser(ext: str)
def parse_function(text: str) -> Any:
    ...

Parameters:

  • ext (str): The file extension (e.g., "json", "toml") that this parser handles.

Requirements:

  • The decorated function must accept a single str argument (the raw text content).
  • The function should return a parsed Python object (e.g., dict, list).

Example:

import honk


@honk.parser("csv")
def parse_csv(text: str) -> list[dict[str, str]]:
    """Parse CSV data into a list of dictionaries."""
    header, *rows = text.replace(" ", "").strip("\n").split("\n")

    cols = header.split(",")

    return [{k: v for k, v in zip(cols, row.split(","))} for row in rows]

@template Decorator

The @template decorator registers a function as an output template.

@honk.template(*args, **kwargs)
def template_function(data, ...) -> None:
    ...

You can apply click's decorators to add options and arguments.

Parameters:

  • *args, **kwargs: These are passed through to click's @command decorator.

Requirements:

  • The decorated function must accept the parsed data as its first argument (named data by convention).
  • Additional parameters can be added and will be exposed as Click options.
  • The function should output the result (e.g., using click.echo).

Example:

import honk
import click

from typing import Sequence


@honk.template(help="Display data as a simple list")
@click.option("--prefix", default="- ", help="Prefix for each item")
def list_format(data: Sequence[str], prefix: str) -> None:
    """Render a list with a custom prefix."""
    for item in data:
        click.echo(f"{prefix}{item}")

Wildcard Matching

The standard plugin uses wildcard matching for exclusion patterns. The match_wildcard function supports * as a wildcard character:

  • *_display matches any string ending with _display
  • test* matches any string starting with test
  • *log* matches any string containing log

Complete Example

Here's a complete example showing a custom plugin that parses a simple key-value format and displays it as a table:

# kv_plugin.py
import click

from typing import Mapping

import honk


@honk.parser("kv")
def parse_kv(text: str) -> dict[str, str]:
    """Parse key=value pairs."""
    result: dict[str, str] = {}
    for line in text.split("\n"):
        if "=" in line:
            key, value = line.split("=", 1)
            result[key] = value
    return result


@honk.template(help="Display key-value pairs as a table")
@click.option("--sort", is_flag=True, help="Sort keys alphabetically")
def kv_table(data: Mapping[str, str], sort: bool) -> None:
    """Render key-value pairs in a Markdown table."""
    keys = sorted(data.keys()) if sort else list(data.keys())
    click.echo("| Key | Value |")
    click.echo("| --- | ----- |")
    for key in keys:
        click.echo(f"| {key} | {data[key]} |")

Load and use:

honk plugin load kv_plugin
echo "name=honk\nversion=0.2" | honk parse -m kv kv-table --sort

Output:

| Key | Value |
| --- | ----- |
| name | honk |
| version | 0.2 |

Target Path Syntax

The -t, --target option allows you to extract nested data from the parsed object.

  • Use / as the default delimiter (or specify a custom delimiter with -d).
  • Use numeric indices for array access.
  • Use * as a wildcard to iterate over all keys in a mapping.

Examples:

Target Description
. The entire parsed object
user/name The name field under user
users/0/name The name of the first user
users/*/name All name fields from all users (returns a dict)
data.results With -d ".", accesses nested using dot notation

Example with wildcard:

honk parse -p users.json -t "users/*/name" echo

This extracts all user names from a users array or mapping.

Development

Running Tests

The project uses pytest for testing. Tests are organized in the tests/ directory.

pytest tests/

Building from Source

uv build

License

No licence =)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

honk_parser-0.2.0.tar.gz (11.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

honk_parser-0.2.0-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file honk_parser-0.2.0.tar.gz.

File metadata

  • Download URL: honk_parser-0.2.0.tar.gz
  • Upload date:
  • Size: 11.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for honk_parser-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b6de4141fb91e9437a4429eb21eeacdd81640f4dc097c3f2abb38f048daa5cf9
MD5 076fcf53ed5c5ce16cd9e60d3602502c
BLAKE2b-256 dd2e09fb2212da2431cb79015cb191d98271cd72a5e933dc91ca909af8217e1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for honk_parser-0.2.0.tar.gz:

Publisher: release.yaml on Pependr/honk-parser

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file honk_parser-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: honk_parser-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 9.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for honk_parser-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7f913092281713418632eabc97b13b140c9ac82ccb82f90454c3987cf05c80a0
MD5 a41d10ed740f77e684b3b453217e862c
BLAKE2b-256 52855fb576d07511517ad874f6486c811c2225e752356d05a1fb70206b8787cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for honk_parser-0.2.0-py3-none-any.whl:

Publisher: release.yaml on Pependr/honk-parser

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page