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
- A plugin is a Python module that imports
honkand uses its decorators. - 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
honkfrom the directory containing it. - To load a plugin, use
honk plugin load <module_name>. - The plugin's
@parserand@templatedecorators register functions that become available via the-moption 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
strargument (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 toclick's@commanddecorator.
Requirements:
- The decorated function must accept the parsed data as its first argument (named
databy 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:
*_displaymatches any string ending with_displaytest*matches any string starting withtest*log*matches any string containinglog
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file honk_parser-0.2.1.tar.gz.
File metadata
- Download URL: honk_parser-0.2.1.tar.gz
- Upload date:
- Size: 11.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef4b331ee1eec2c51ee091888c9bd4afd7fa558118658e62eca414de60d4c10f
|
|
| MD5 |
8f74d3fb8a0b0ab9785d3d8dcdeecebf
|
|
| BLAKE2b-256 |
6fa024211949ce16ebfe51afce37eb56844afca12243bba0c64bb3b399e7a74a
|
Provenance
The following attestation bundles were made for honk_parser-0.2.1.tar.gz:
Publisher:
release.yaml on Pependr/honk-parser
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
honk_parser-0.2.1.tar.gz -
Subject digest:
ef4b331ee1eec2c51ee091888c9bd4afd7fa558118658e62eca414de60d4c10f - Sigstore transparency entry: 1938579899
- Sigstore integration time:
-
Permalink:
Pependr/honk-parser@8262925e6ecb0b2dc525a37ae0ff170e215073c8 -
Branch / Tag:
refs/tags/0.2.1 - Owner: https://github.com/Pependr
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@8262925e6ecb0b2dc525a37ae0ff170e215073c8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file honk_parser-0.2.1-py3-none-any.whl.
File metadata
- Download URL: honk_parser-0.2.1-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d76ef6e43bbbca8f9537bfe06512067f29fe6322125d417130c8128e1a0f9d3d
|
|
| MD5 |
23ba73e972dfe4b06ebf71f85a461fbc
|
|
| BLAKE2b-256 |
94d424531526575503ecc533190fa52053d3a1840d507d47fcdcbffaf334a7d8
|
Provenance
The following attestation bundles were made for honk_parser-0.2.1-py3-none-any.whl:
Publisher:
release.yaml on Pependr/honk-parser
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
honk_parser-0.2.1-py3-none-any.whl -
Subject digest:
d76ef6e43bbbca8f9537bfe06512067f29fe6322125d417130c8128e1a0f9d3d - Sigstore transparency entry: 1938580011
- Sigstore integration time:
-
Permalink:
Pependr/honk-parser@8262925e6ecb0b2dc525a37ae0ff170e215073c8 -
Branch / Tag:
refs/tags/0.2.1 - Owner: https://github.com/Pependr
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@8262925e6ecb0b2dc525a37ae0ff170e215073c8 -
Trigger Event:
push
-
Statement type: