vdi2770-validate
Point it at a VDI 2770 container and it tells you, offline, whether the archive is one — and if something is wrong, what to do about it.
VDI 2770 is how manufacturers hand over technical documentation in the process industry: PDFs bundled into ZIP "document containers" with an XML metadata file, those bundled into a "documentation container". Operators in the process industry increasingly ask for it in purchase orders, and a container rejected on intake holds up a delivery. The reference implementation is a Java library and web service; this is a small offline CLI you can drop into a CI job.
Unofficial. Not affiliated with VDI, the Digital Data Chain Consortium, or IDTA. Names are used descriptively.
$ vdi2770-validate check corpus/examples/missingdocuments/folders.zip
error F1 A file named in the metadata is not in the container
at folders.zip!/VDI2770_Main.xml:56:2
'VDI2770_Main.pdf' is declared but not in the archive
-> Add the missing file to the container, or remove its DigitalFile entry from the metadata. The two must agree.
error Z7 The documentation container has no VDI2770_Main.pdf
at folders.zip
-> Add the main document as VDI2770_Main.pdf at the root of the documentation container, next to VDI2770_Main.xml.
warn F2 A file in the container is not named in the metadata
at folders.zip!/456-29201/VDI2770_Metadata.xml
-> Declare the file as a DigitalFile in the metadata, or remove it from the container. An undeclared file is invisible to the recipient's system.
warn F2 A file in the container is not named in the metadata
at folders.zip!/456-29201/demo.pdf
-> Declare the file as a DigitalFile in the metadata, or remove it from the container. An undeclared file is invisible to the recipient's system.
warn F2 A file in the container is not named in the metadata
at folders.zip!/456-29201/demo.xlsx
-> Declare the file as a DigitalFile in the metadata, or remove it from the container. An undeclared file is invisible to the recipient's system.
warn F2 A file in the container is not named in the metadata
… 6 more warnings of the same kind
That is real output on a container that ships with this repository, so the same command works after cloning.
What it will not tell you
Whether a PDF really is PDF/A. That needs a full PDF/A validator such as
veraPDF. This tool reports what a file claims, which catches the common failure:
files that never claimed at all. It says so on every line where it matters, and the
JSON output carries "pdfaVerified": false on every path. The rest of the refusals
are in docs/scope.md.
How it is built
- Offline by design. No network at runtime, proven by a test that makes sockets raise. Nothing is extracted to disk; a supplier archive does not get to pick a path on your filesystem or expand an XML entity.
- Rules are data.
rules.json— each rule carries where its requirement comes from, a remedy sentence, and — where the reference implementation checks the same thing — the message keys it uses. - 23 of 34 rules have a minimal fixture pair — a container that violates the rule and a conforming one differing in as little as a single member. The rest are exercised by the vendored corpus. A rule that fires nowhere fails the build.
- Rules cannot reach the parser. A test fails if a rule module imports
zipfileor an XML library, so a rule cannot accidentally check how a document was spelled instead of what it says. Rules may read the readers' constants — the reserved file names, the container kinds — but not call a parser.
Two packages
The reader lives in vdi2770, a separate
package with no dependencies: it opens a container, refuses what it should refuse,
and hands back a typed model with a line number on every node. It decides nothing.
This package is that library plus a rule set. The split is not cosmetic — a test fails if the reader can so much as import the rules — and it exists because a rule set is an opinion. If your customer's supplement disagrees with ours, or you want the parsed model for something other than a verdict, take the reader and leave the opinion behind:
pip install vdi2770
The classification table, and a disagreement
VDI 2770 defines twelve document classes. Two sources publish that table for free — IDTA 02004 v2.0.1 Table 1, and the MIT reference implementation. Both renderings of every name are stored, so you can check rather than trust: they agree on all twelve German names and disagree on five English ones (02-03, 02-04, 03-01, 03-04, 04-01). So matching here is keyed on the class id and the German name, and an English name never fails a document — it produces a note that shows both renderings.
$ vdi2770-validate classes
02-03 Bauteile Assemblies [sources disagree]
IDTA 02004: 'Assemblies' reference impl: 'Components'
Details in docs/divergences.md.
Licensing
Apache-2.0. The VDI 2770 guideline text is sold by DIN Media and was not read,
quoted, or paraphrased. Every rule names its source in rules.json instead: the schema
VDI publishes free, a freely published table, ZIP and XML mechanics, the MIT reference
implementation (observed there, not verified against the standard), or a judgement of
our own that has to explain itself.
See docs/licensing.md and NOTICE.
Contributions take a Signed-off-by line (DCO).
Related
iirds-validate — the same idea for iiRDS. standards-watch — a daily watch on these standards.
Release files for vdi2770-validate 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vdi2770_validate-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / vdi2770_validate-0.4.0-py3-none-any.whl
| Download URL | vdi2770_validate-0.4.0-py3-none-any.whl |
|---|---|
| Size | 38.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
04a11822c90c3e2cd2a9d262ee61b40d6d74b568c23216c66bdff9bb52b47f87
|
|
BLAKE2b-256 checksum How to use checksums |
b774275d1125bd5e7f15a6b020e2984a9b26099ceca0fef19cad3a10e7f1882f
|
| 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 Aug 24, 2026.
Transparency log