From ce1d22cfd38533dd241e199e78543f50a68c4feb Mon Sep 17 00:00:00 2001 From: Daniel Pressler Date: Wed, 11 Feb 2026 09:01:31 -0700 Subject: [PATCH] Document key features in README --- README.md | 62 ++++++++++++++++++++++++++++++++++------ docs/.gitignore | 1 + docs/make.py | 71 +++++++++++++++++++++++++++++++++------------- docs/zensical.toml | 3 +- 4 files changed, 109 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 6905f89..bdd99ed 100644 --- a/README.md +++ b/README.md @@ -30,15 +30,53 @@ $ conda install --channel conda-forge jbpy ## License This repository is licensed under the [MIT license](./LICENSE). -## Testing -Some tests rely on the [JITC Quick Look Test Data](https://jitc.fhu.disa.mil/projects/nitf/testdata.aspx). -If this data is available, it can be used by setting the `JBPY_JITC_QUICKLOOK_DIR` environment variable. +## Features +### Jbp objects +`jbpy.Jbp` objects provide a dict-like interface to JBP files. + +```python +>>> from tempfile import TemporaryFile +>>> import jbpy +>>> ntf = jbpy.Jbp() +>>> ntf["FileHeader"]["OSTAID"].value = "README" +>>> ntf.finalize() +>>> file = TemporaryFile() +>>> _ = ntf.dump(file) -```bash -JBPY_JITC_QUICKLOOK_DIR= pytest ``` -## Support Data Extensions +```python +>>> ntf2 = jbpy.Jbp() +>>> _ = file.seek(0) +>>> _ = ntf2.load(file) +>>> ntf2["FileHeader"]["OSTAID"].print() +OSTAID 10 @ 15 b'README ' + +``` + +### Utilities +**jbpy** command-line utilities make it easy to inspect JBP files. + +```console +$ jbpdump NITF_TXT_POS_04.ntf --text-segment 0 +Text Only Segment. +``` + +Directly accessing URLs is possible when [`smart_open`](https://pypi.org/project/smart-open/) is installed. + +```console +$ jbpinfo https://capella-open-data.s3.amazonaws.com/data/2020/12/7/CAPELLA_C02_SM_SICD_HH_20201207083444_20201207083448/CAPELLA_C02_SM_SICD_HH_20201207083444_20201207083448.ntf | head -n 7 +FHDR 4 @ 0 b'NITF' +FVER 5 @ 4 b'02.10' +CLEVEL 2 @ 9 b'06' +STYPE 4 @ 11 b'BF01' +OSTAID 10 @ 15 b'CAPELLA HQ' +FDT 14 @ 25 b'20230701003316' +FTITLE 80 @ 39 b'SICD: CAPELLA_C02_SM_SICD_HH_20201207083444_20201207083448.ntf ' + +``` + +### Support Data Extensions The JBP document provides extensibility through Support Data Extensions (SDEs) such as Tagged Record Extensions (TREs) and Data Extension Segments (DES). To mimic this extensibility, `jbpy` defines two entry point groups which are used to load SDE plugins: @@ -52,7 +90,7 @@ they are declared under these entry point groups as described below. > [!WARNING] > There is not currently a mechanism to arbitrate multiple SDEs that are registered under the same plugin name. -### TREs +#### TREs A TRE plugin is named using a 6-character (left-justified and space-padded) TRETAG. The object reference must resolve to a function with no required arguments that instantiates a `jbpy.core.Tre` object. @@ -71,7 +109,7 @@ Once registered, a TRE object can be instantiated using `jbpy.tre_factory`: ``` -### DES Subheaders +#### DES Subheaders A DES subheader plugin is named using a 27-character string formed by concatenating the 25-character DESID and 2-digit DESVER. The object reference must resolve to a function that accepts a string-valued name and instantiates a @@ -91,3 +129,11 @@ Once registered, a DES subheader object can be instantiated using `jbpy.des_subh >>> des_subhdr = jbpy.des_subheader_factory("MY DES SUBHEADER", 24) ``` + +## Testing +Some tests rely on the [JITC Quick Look Test Data](https://jitc.fhu.disa.mil/projects/nitf/testdata.aspx). +If this data is available, it can be used by setting the `JBPY_JITC_QUICKLOOK_DIR` environment variable. + +```bash +JBPY_JITC_QUICKLOOK_DIR= pytest +``` diff --git a/docs/.gitignore b/docs/.gitignore index a49ebec..5ab0515 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,2 +1,3 @@ src/api/ +src/cli.md site/ diff --git a/docs/make.py b/docs/make.py index 97cd1a3..07f318c 100644 --- a/docs/make.py +++ b/docs/make.py @@ -1,26 +1,59 @@ +import os import pathlib import shutil +import subprocess import pdoc import pdoc.render here = pathlib.Path(__file__).parent -out = here / "src" / "api" -if out.exists(): - shutil.rmtree(out) - -# Render parts of pdoc's documentation into src/api... -pdoc.render.configure( - docformat="numpy", - template_directory=here / "pdoc-template", -) -modules = [ - "jbpy", - "jbpy.core", - "jbpy.image_data", -] -pdoc.pdoc(*modules, output_directory=out) - -# ...and rename the .html files to .md so that zensical picks them up! -for f in out.glob("**/*.html"): - f.rename(f.with_suffix(".md")) + + +def create_api_doc(): + out = here / "src" / "api" + if out.exists(): + shutil.rmtree(out) + + # Render parts of pdoc's documentation into src/api... + pdoc.render.configure( + docformat="numpy", + template_directory=here / "pdoc-template", + ) + modules = [ + "jbpy", + "jbpy.core", + "jbpy.image_data", + ] + pdoc.pdoc(*modules, output_directory=out) + + # ...and rename the .html files to .md so that zensical picks them up! + for f in out.glob("**/*.html"): + f.rename(f.with_suffix(".md")) + + +def create_cli_doc(): + TOOLS_TO_INCLUDE = [ + "jbpdump", + "jbpinfo", + ] + outfile = here / "src/cli.md" + + content = ["# CLI Reference"] + for tool in TOOLS_TO_INCLUDE: + this_help_str = subprocess.check_output( + [tool, "--help"], text=True, env=os.environ | {"WIDTH": "70"} + ) + content.append(f"## `{tool}`") + content.extend( + ["```console", f"$ {tool} --help"] + + this_help_str.splitlines() + + [ + "```", + "", + ] + ) + outfile.write_text("\n".join(content)) + + +create_api_doc() +create_cli_doc() diff --git a/docs/zensical.toml b/docs/zensical.toml index 56fb3cc..2122fca 100644 --- a/docs/zensical.toml +++ b/docs/zensical.toml @@ -14,11 +14,12 @@ Copyright © 2026, Valkyrie Systems Corporation nav = [ { "Get started" = "index.md"}, + { "CLI Reference" = "cli.md"}, {"API Reference" = [ {"jbpy" = "api/jbpy.md"}, {"jbpy.core" = "api/jbpy/core.md"}, {"jbpy.image_data" = "api/jbpy/image_data.md"}, - ]} + ]}, ]