pftag
A string template processor: %{tags} in text are resolved when the text is used, each optionally piped through functions. Both a library and a command.
Overview
A template is ordinary text with tags in it. A tag is %{, a name, optional functions, }:
run-%{timestamp}-on-%{hostname}.log
%{inputWorkingFile|rmext}.jpg
%{timestamp|replace(:,-)|md5(6)}
%{"Subject12345"|sha256(8)}
Names resolve against the core tags (timestamp, date, hostname, platform, user, pid) and against dictionaries the calling program registers. Functions read left to right, each feeding the next; text after the closing } is kept. Nothing outside %{...} is a tag, so printf "%s", date +%Y%m%d and %20 in a URL pass through untouched. An unknown name is left as written unless --strict.
The full reference is docs/tags.adoc. The pf* family uses pftag wherever a user writes a template on the command line: pfdo_run's --exec string, pflog's telemetry URLs.
Installation
pip install pftag # no dependencies
pip install 'pftag[names]' # adds faker, for the dcmname pseudonym function
Python 3.11 or newer.
Command
pftag --tag "run-%{timestamp}-on-%{hostname}.log"
pftag --tag "run-%{timestamp|replace(:,-)|md5(6)}.log"
pftag --tag "run-%{timestamp|strftime(%Y%m%d-%H%M)}.log"
pftag --lookupDictAdd '{"s": {"user": "chris"}}' --tag "user %{user}, hash %{user|md5(8)}"
pftag --tag "%{nope}" --strict # exit 1: unknown tag
pftag --tag "..." --json # the whole result: tags found, unknown, legacy, functions applied, errors
pftag --man
Library
import shlex
from pftag import Pftag, TagOptions
tagger = Pftag(TagOptions(lookups={"run": {"subject": "sub-01", "file": "T1.nii.gz"}}))
tagger("%{subject}/%{file|rmext}.jpg").result # 'sub-01/T1.nii.jpg'
tagger.argv_process(shlex.split("convert %{file} %{file|rmext}.jpg")).argv
process(template) is for text; argv_process(argv) is for commands: split the user's command first, then each argument is a template of its own, so a value with a space or a quote cannot change the shape of the command. lookup_add(name, values) registers a dictionary; a FunctionRegistry passed to Pftag takes new functions with add(name, fn), where fn(value, args) -> str.
Functions
| function | effect |
|---|---|
rmext, ext, basename, dirname |
path parts |
replace(a, b), re(pattern, repl) |
literal and regular-expression replacement |
upper, lower, strip[(chars)], pad(width[, char]), slice(start[, stop]) |
text shaping |
md5[(n)], sha256[(n)] |
hashing |
strftime(format) |
format a timestamp |
mask(pattern) |
* keeps a character, anything else replaces it |
dcmname[(seed)] |
a LAST^FIRST pseudonym, stable for a seed; needs pftag[names] |
Changes in 3.0
- Tags are
%{...}only. The bare%nameform is gone; a bare%is always literal. A bare%nameof a known name is reported as a 1.x tag (and fails under--strict) so that old templates do not pass through silently. - Functions are
|fn(arg, arg)in pipe order; arguments bare or quoted;fnorfn(). A quoted head starts a chain from literal text, replacing%literalandecho. - Names may contain underscores;
%{dict.name}qualifies; two dictionaries defining one name is an error at registration. argv_processfor commands. Values are substituted once, never re-processed.- Functions renamed to common names:
replace,re,mask;ext,basename,dirname,strip,pad,slice,sha256,strftimeadded;chrplc,strrepl,strmsk,echogone.dcmnamemoves behind thenamesextra and seeds its own generator. - Core tags:
timestamp,date,hostname,platform,user,pid;os,release,machine,arch,literalgone. - No configurable markers, no dependencies, no
pudb/loguru/XDG_CONFIG_HOMEside effects;pyproject.tomlonly, CI on 3.11–3.14 and 3.14t, published from av*tag; the Docker image is no longer built.
Metadata
Release files for pftag 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pftag-3.0.0.tar.gz | 22.1 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pftag-3.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 42.5 kB
Release files / pftag-3.0.0.tar.gz
| Download URL | pftag-3.0.0.tar.gz |
|---|---|
| Size | 22.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1a4b7ff288ae6c766d7ceea2b9204657b2f10069b693b1471159c240386d09b4
|
|
BLAKE2b-256 checksum How to use checksums |
47fcf8f1b1bf227d6b8e10a5d7c8b290de17446e7ca1529a7567ba1fc0300044
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logRelease files / pftag-3.0.0-py3-none-any.whl
| Download URL | pftag-3.0.0-py3-none-any.whl |
|---|---|
| Size | 20.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5fd1bf0a8be0519a13713388b9915b23df3338d2bc8dc84f7ae5d8288f4f40d4
|
|
BLAKE2b-256 checksum How to use checksums |
11a138e3616980f5ca43efba099b25c993bf2f424b0ff25c5c196614d3f9d7ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logSecurity for pftag 3.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pftag-3.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.