Skip to main content

python-dirtt — Directory Tree Templater

Dirtt generates directory and file structures from simple XML or JSON templates that describe repeatedly used filesystem layouts — project scaffolds, VFX show structures, or any tree you build more than once.

Write the layout once as a template, then stamp it out anywhere with variables filled in:

$ dirtt create -t project.xml --var project_root=/jobs --var project_path=commercial_spot
created tree: 81 actions
  • Zero runtime dependencies — pure Python standard library
  • Python 3.10+
  • Templates in XML (the classic dirtt dialect, unchanged since 0.x) or JSON
  • --dry-run prints the full plan without touching the filesystem
  • Introspection: point dirtt at an existing tree and get a template back

(c) 2011–2026 Robert Moggach and contributors. Licensed under the MIT license.

Install

pip install python-dirtt

Command line

dirtt create -t TEMPLATE [--var KEY=VALUE ...] [--dest DIR] [--dry-run] [-i] [-w] [-v]
dirtt list                     # show the packaged example templates
dirtt placeholders -t TEMPLATE # show the variables a template requires
dirtt introspect PATH [-o FILE]# generate a template from a real tree

create prompts interactively for any {{placeholder}} you don't pass with --var. --dry-run prints each planned action (mkdir, write, symlink) instead of performing it. -i/--interactive confirms each directory; answering no skips that directory and everything inside it. -w/--warn fails instead of continuing when a directory already exists.

Library

from dirtt import build

# create the tree
build("project.xml", {"project_root": "/jobs", "project_path": "myproject"})

# or preview first
for action in build("project.xml", context, dry_run=True):
    print(action.describe())

The stages are also available separately:

from dirtt import load_template, plan, execute, introspect

tree = load_template("project.xml", context)   # frozen dataclass Tree
actions = plan(tree, dest="/somewhere/else")   # ordered list[Action], absolute paths
execute(actions)                               # apply (or dry_run=True)

xml = introspect("/jobs/existing_project")     # tree -> template

Errors raise dirtt.DirttError subclasses (TemplateError, BuildError); the library never prints or exits.

XML templates

The dialect is unchanged from dirtt 0.x:

<?xml version="1.0" encoding="UTF-8"?>
<dirtt name="Project Tree" version="1.0"
       dirname="{{project_root}}" basename="{{project_path}}"
       username="pipeline" group="artist" perms="02755"
       xmlns:xi="http://www.w3.org/2001/XInclude">
  <dir basename="src" perms="02755">
    <file basename="README.md" href="readme_snippet.md" perms="0644"/>
  </dir>
  <dir basename="renders" id="renders-dir"/>
  <link basename="latest" idref="renders-dir"/>
  <xi:include href="shared_structure.xml"/>
</dirtt>
  • dirtt — the root directory: dirname (parent path) + basename (directory name). If basename is omitted it is split off dirname.
  • dir — a directory; nests dir, file, and link elements.
  • file — a file; href names a content template (resolved next to the tree template, then in the packaged templates) rendered with the same {{variables}}; without href the file is created empty.
  • link — a symlink; ref is a literal target path, idref points at the id of a dir in the same tree. Links are created last.
  • xi:include — splice another template's children in place; href may be relative, absolute, or an http(s):// URL.
  • perms is octal text ("02775"); username/group are applied with chown only when running as root, and skipped otherwise.

JSON templates

The same schema as JSON — children are tagged with "type":

{
  "name": "Project Tree",
  "dirname": "{{project_root}}",
  "basename": "{{project_path}}",
  "perms": "02755",
  "children": [
    { "type": "dir", "basename": "src", "children": [
      { "type": "file", "basename": "notes.txt", "content": "for {{project_path}}" }
    ]},
    { "type": "dir", "basename": "renders", "id": "renders-dir" },
    { "type": "link", "basename": "latest", "idref": "renders-dir" },
    { "include": "shared_structure.json" }
  ]
}

Files may carry inline "content" (JSON only) or an "href" like XML.

Migrating from 0.2.x

0.2.x 1.0
mktree.py --template ... --interactive dirtt create -t ... -i
mktemplate.py -p PATH dirtt introspect PATH
mkproject.py dirtt create with your studio's template
DirectoryTreeHandler(verbose, template, kwargs).run() build(template, kwargs)
dirtt.util.template (Paste engine, eval-based) {{name}} placeholders only
Python 2, distutils Python 3.10+, pyproject.toml

Your existing XML templates work as-is. The old template engine's {{if}}/{{for}}/{{py:}} constructs were never used by tree templates and are no longer supported.

Development

git clone https://github.com/rjmoggach/python-dirtt
cd python-dirtt
uv run --group dev pytest

Contributions welcome — code, tests, docs, bug reports, ideas.

Download files

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

Source Distribution

python_dirtt-1.0.1.tar.gz (24.8 kB view details)

Uploaded Source

Built Distribution

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

python_dirtt-1.0.1-py3-none-any.whl (25.0 kB view details)

Uploaded Python 3

File details

Details for the file python_dirtt-1.0.1.tar.gz.

File metadata

  • Download URL: python_dirtt-1.0.1.tar.gz
  • Upload date:
  • Size: 24.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for python_dirtt-1.0.1.tar.gz
Algorithm Hash digest
SHA256 7667f9f5132c68916203c4f6cbccf490b307d58ee4d4fefc643f66f5a53a8186
MD5 47b398f6f1bceaa1f45da7e57414a8e4
BLAKE2b-256 6acadb716e0658d95345a852d8a55199d0c7c36a75d6affe0b9128a8ead354fe

See more details on using hashes here.

File details

Details for the file python_dirtt-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: python_dirtt-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 25.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for python_dirtt-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f2fedfb3a3d6a8404315a24a10967dd47d6953821f61e013156555a3d602d7d0
MD5 55f6602654f3e9b9b13e1dedd9a4f84d
BLAKE2b-256 9d3b0be1b284e95cc0cfafa289e31990a41fe6c2e8ac9d46d109c552e6317439

See more details on using hashes here.

Release history Release notifications | RSS feed

1.2.0

2 files

1.1.0

2 files

1.0.3

2 files

1.0.2

2 files

This release

1.0.1 This release

2 files

0.2

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page