Skip to main content

Fileseq

Documentation Status Build status

A Python library for parsing frame ranges and file sequences commonly used in VFX and Animation applications.

Frame Range Shorthand

Support for:

  • Standard: 1-10
  • Comma Delimited: 1-10,10-20
  • Chunked: 1-100x5
  • Filled: 1-100y5
  • Staggered: 1-100:3 (1-100x3, 1-100x2, 1-100)
  • Negative frame numbers: -10-100
  • Subframes: 1001-1066x0.25, 1001.5-1066.0x0.5
  • Padding: #=4 padded, @=1 padded
  • Alternate padding: #=1 padded, @=1 padded
  • Printf Syntax Padding: %04d=4 padded, %01d=1 padded
  • Houdini Syntax Padding: $F4=4 padding, $F=1 padded
  • Udim Syntax Padding: or %(UDIM)d, always 4 padded

FrameSets

A FrameSet wraps a sequence of frames in a list container.

Iterate a FrameSet

fs = fileseq.FrameSet("1-5")
for f in fs:
  print(f)

Access Frames

Using Indices:

>>> fs = fileseq.FrameSet("1-100:8")
>>> fs[0] # First frame.
1
>>> fs[-1] # Last frame.
98

Using Convenience Methods:

>>> fs = fileseq.FrameSet("1-100:8")
>>> fs.start() # First frame.
1
>>> fs.end() # Last frame.
98

FileSequence

Instantiate from String

fileseq.FileSequence("/foo/bar.1-10#.exr")
fileseq.FileSequence("/foo/bar.1-10x0.25#.#.exr", allow_subframes=True)

Format Path for VFX Software

Using FileSequence.format Method:

>>> seq = fileseq.FileSequence("/foo/bar.1-10#.exr")
>>> seq.format(template='{dirname}{basename}{padding}{extension}') 
"/foo/bar.#.exr"
>>> seq = fileseq.FileSequence("/foo/bar.1-10#.#.exr", allow_subframes=True)
>>> seq.format(template='{dirname}{basename}{padding}{extension}')
"/foo/bar.#.#.exr"

Joining:

>>> seq = fileseq.FileSequence("/foo/bar.1-10#.exr")
>>> ''.join([seq.dirname(), seq.basename(), '%0{}d'.format(len(str(seq.end()))), seq.extension()])
"/foo/bar.%02d.exr"

Alternate Padding Styles:

>>> seq = fileseq.FileSequence("/foo/bar.1-10#.exr", pad_style=fileseq.PAD_STYLE_HASH1)
>>> list(seq)
['/foo/bar.1.exr',
 '/foo/bar.2.exr',
 '/foo/bar.3.exr',
 '/foo/bar.4.exr',
 '/foo/bar.5.exr',
 '/foo/bar.6.exr',
 '/foo/bar.7.exr',
 '/foo/bar.8.exr',
 '/foo/bar.9.exr',
 '/foo/bar.10.exr']
>>> seq = fileseq.FileSequence("/foo/bar.1-10#.exr", pad_style=fileseq.PAD_STYLE_HASH4)
>>> list(seq)
['/foo/bar.0001.exr',
 '/foo/bar.0002.exr',
 '/foo/bar.0003.exr',
 '/foo/bar.0004.exr',
 '/foo/bar.0005.exr',
 '/foo/bar.0006.exr',
 '/foo/bar.0007.exr',
 '/foo/bar.0008.exr',
 '/foo/bar.0009.exr',
 '/foo/bar.0010.exr']

Get List of File Paths

>>> seq = fileseq.FileSequence("/foo/bar.1-10#.exr")
>>> [seq[idx] for idx, fr in enumerate(seq.frameSet())]
['/foo/bar.0001.exr',
 '/foo/bar.0002.exr',
 '/foo/bar.0003.exr',
 '/foo/bar.0004.exr',
 '/foo/bar.0005.exr',
 '/foo/bar.0006.exr',
 '/foo/bar.0007.exr',
 '/foo/bar.0008.exr',
 '/foo/bar.0009.exr',
 '/foo/bar.0010.exr']

Get List of File Paths as pathlib.Path instances

fileseq.FilePathSequence supports the same semantics as fileseq.FileSequence but represents result paths as pathlib.Path instances instead of strings.

>>> seq = fileseq.FilePathSequence("/foo/bar.1-10#.exr")
>>> [seq[idx] for idx, fr in enumerate(seq.frameSet())]
[PosixPath('/foo/bar.0001.exr'),
 PosixPath('/foo/bar.0002.exr'),
 PosixPath('/foo/bar.0003.exr'),
 PosixPath('/foo/bar.0004.exr'),
 PosixPath('/foo/bar.0005.exr'),
 PosixPath('/foo/bar.0006.exr'),
 PosixPath('/foo/bar.0007.exr'),
 PosixPath('/foo/bar.0008.exr'),
 PosixPath('/foo/bar.0009.exr'),
 PosixPath('/foo/bar.0010.exr')]

Finding Sequences on Disk

Check a Directory for All Existing Sequences

seqs = fileseq.findSequencesOnDisk("/show/shot/renders/bty_foo/v1")

Or, to get results as pathlib.Path, use the FilePathSequence classmethod:

seqs = fileseq.FilePathSequence.findSequencesOnDisk("/show/shot/renders/bty_foo/v1")

Check a Directory for One Existing Sequence.

  • Use a '@' or '#' where you might expect to use '*' for a wildcard character.
  • For this method, it doesn't matter how many instances of the padding character you use, it will still find your sequence.

Yes:

fileseq.findSequenceOnDisk('/foo/bar.@.exr')

Yes:

fileseq.findSequenceOnDisk('/foo/bar.@@@@@.exr')

No:

fileseq.findSequenceOnDisk('/foo/bar.*.exr')
  • To find subframe sequences you must explicitly opt-in
fileseq.findSequenceOnDisk('/foo/bar.#.#.exr', allow_subframes=True)

Development

Getting Started

pip install hatch              # Install build tool
pip install -e ".[dev]"         # Install package with dev dependencies

Running Tests

hatch run test
hatch run test-cov  # with coverage report

Regenerating the Parser

After modifying src/fileseq/grammar/fileseq.g4:

hatch run generate  # Requires Java 11+

Building Documentation

hatch run docs:build
hatch run docs:serve  # View at http://localhost:8000

Limitations

While there may be many custom types of sequence patterns that could be considered a valid pipeline format, this library has taken an opinionated stance on acceptable sequence formats. This is done to keep parsing rules manageable and to not over-complicate the logic. The parsing rules can and have been expanded in some ways over time, such as adding support for new padding format patterns like printf "%04d", houdini "$F" and "<UDIM>". But other rules remain the same, such as expecting a frame number component to be found just before the file extension component.

Metadata

Release files for Fileseq 3.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for Fileseq 3.4.1
File Size Uploaded Provenance Actions
fileseq-3.4.1.tar.gz 2.2 MB Without provenance Details for fileseq-3.4.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for Fileseq 3.4.1
File Interpreter ABI Platform Actions
fileseq-3.4.1-py3-none-any.whl Python 3 none any Details for fileseq-3.4.1-py3-none-any.whl

Total release size: 2.4 MB

Release files / fileseq-3.4.1.tar.gz

Download URL fileseq-3.4.1.tar.gz
Size 2.2 MB
Tags Source
SHA-256 checksum
How to use checksums
8128d6556a996ca77cae241dd236ed265a7ba76744d5cde11907ab8f5871b2a4
BLAKE2b-256 checksum
How to use checksums
b6b3788ce6cfea902771ba2248d36ca0e5ff058c25596b3b0ad8e4d2c9c20c53
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Release files / fileseq-3.4.1-py3-none-any.whl

Download URL fileseq-3.4.1-py3-none-any.whl
Size 203.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9e5474ccd40532ed8432fcd2b0eaf7939e388b6b93ace33f373d17bed9d30184
BLAKE2b-256 checksum
How to use checksums
291d8b6904eb8e1f3065b66351fb79331cd996b53946e2e3019f77d60ff8113e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.17

Security for Fileseq 3.4.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A 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.

Release history Release notifications | RSS feed

This release

3.4.1 This release

2 release files No provenance

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