Can You Build a Schedule Feed Archive Checker?
From the earlier reference collection. Read the current software blog.
An archive checker verifies that a schedule archive can be read and contains expected GTFS files with sensible names before deeper validation.
Check the archive before its contents
A schedule-feed archive checker answers a narrow but useful question: can this archive be opened, and does it contain the expected files under predictable names? This is an early validation step, not a guarantee that every record or relationship is valid. The GTFS schedule reference defines the dataset files and their requirements; use it to decide which files are required for the type of feed you are checking.
Start by testing whether the downloaded object is a readable ZIP archive. Report a clear failure for a truncated or corrupt file, then stop before attempting to parse tables. If the archive opens, list its entries and normalize path separators for comparison. Do not extract files to arbitrary paths: a checker can inspect entries directly and avoid path traversal risks.
Match names carefully
Identify required files by their expected names, such as agency.txt, stops.txt, routes.txt, trips.txt, and stop_times.txt, while accounting for whether the feed format or publisher permits a directory prefix. If you support prefixed paths, require one unambiguous set of files under a consistent root. Two copies of stops.txt in different folders should produce a warning or error, not an arbitrary choice.
Report missing and unexpectedly named files separately. For example, stop_times.csv may contain tabular data but does not satisfy an expected stop_times.txt name under a strict check. Avoid silently renaming entries during validation; doing so can make a malformed archive appear compliant and obscure the publisher’s actual artifact.
Inspect basic archive integrity
Most ZIP libraries can test whether members can be read and whether their stored checksums match. Check each relevant member and report which entry failed. Also consider limits on total uncompressed size and entry count when archives come from outside the organization; a tiny compressed file can expand into an unreasonable amount of data.
The checker should distinguish an unreadable archive, a corrupt member, a missing required file, and an unexpected name. These categories point to different fixes. Include the archive filename and a concise list of findings, but avoid dumping every entry unless a verbose option is requested. Preserve the input archive so someone can reproduce a failure later.
Keep the boundary explicit
Use a stable exit status for a clean archive and a different status for validation findings, and document the mapping. A clean result should mean only that the archive passed the checks implemented here. It does not prove that the tables have valid headers, that identifiers join correctly, or that service dates make sense.
Test a valid fixture, a missing required file, a duplicate file in nested directories, a renamed file, and a damaged member. Include an archive with an unusual but allowed optional file so the checker does not reject harmless additions. A small boundary check is most useful when its report states both what it verified and where deeper schedule validation begins.