Skip to main content

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

Project description

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 "". But other rules remain the same, such as expecting a frame number component to be found just before the file extension component.

Project details


Download files

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

Source Distribution

fileseq-3.1.0.tar.gz (2.2 MB view details)

Uploaded Source

Built Distribution

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

fileseq-3.1.0-py3-none-any.whl (200.4 kB view details)

Uploaded Python 3

File details

Details for the file fileseq-3.1.0.tar.gz.

File metadata

  • Download URL: fileseq-3.1.0.tar.gz
  • Upload date:
  • Size: 2.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for fileseq-3.1.0.tar.gz
Algorithm Hash digest
SHA256 b421e1df810efe24c6ff46d3e091d47a32c13e8eec0b48b84b15b6d668d873a3
MD5 9acb8ec5c50e93257dfc43d70cfb905f
BLAKE2b-256 6a8511b031eda19047009a3b7f5a9c2001fef6900406b9a1165b13fbfd9e4736

See more details on using hashes here.

File details

Details for the file fileseq-3.1.0-py3-none-any.whl.

File metadata

  • Download URL: fileseq-3.1.0-py3-none-any.whl
  • Upload date:
  • Size: 200.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for fileseq-3.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5805b810bcd2ca6561c82f45823ffc0e2fcb180d8323e5205629878ed6b7995f
MD5 972e579e24a2b0e4fe2f441329c7f7ab
BLAKE2b-256 78be139a829ed06774cd9c8e677e7bf3f27d64e05e46eaccd5193bd610f0a033

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page