API Reference

class plant.Node(path)[source]

Node is a file abstraction.

The constructor takes a path as a parameter and grabs filesystem information about it.

Its attributes is_file and isdir are booleans and are useful for quickly identifying its ‘type’, which among Plant’s engine codebase is either ‘blob’, for a file and ‘dir’ for a directory.

It also has self.metadata, which is just a handy DotDict containing the results of calling os.stat (mode, ino, dev, nlink, uid, giu, size, atime, mtime, ctime)

basename

extracts the basename the node path

>>> from plant import Node
>>>
>>> Node('/srv/application/conf.py').basename
'conf.py'
Returns:bytes
cd(path)[source]

Shortcut for Node.goto(), also works for files, though has a better semantic outlook when handling directories.

>>> from plant import Node
>>>
>>> Node('/opt/media/mp3').cd('../mp4')
Node('/opt/media/mp4')
Parameters:pathbytes
Returns:a Node
contains(path)[source]

Checks if the given path exists as an immediate relative of the current node’s path

>>> from plant import Node
>>>
>>> Node('/opt/media/mp3').contains('unknown-track.mp3')
False
>>>
>>> Node('/opt/media/mp4').contains('../mp3/music1.mp3')
True
Parameters:pathbytes
Returns:bool
could_be_updated_by(other)[source]

check to see if the mtime of another Node is greater than the current one.

Parameters:other – the other Node
Returns:bool - true if the other node is “newer”
depth_of(path)[source]

Calculates the level of depth of the given path inside of the instance’s path.

Only really works with paths that are relative to the class.

>>> from plant import Node
>>>
>>> level = Node('/foo/bar').depth_of('/foo/bar/another/dir/file.py')
>>> level
2
Parameters:pathbytes
Returns:a bool
dir

returns a Node pointing to the current directory.

this call is idempotent in the sense that chaining up multiple class results in the same node.

>>> from plant import Node
>>>
>>> Node('/srv/application/conf.py').dir
Node('/srv/application')
>>>
>>> Node('/srv/application/conf.py').dir.dir
Node('/srv/application')
>>>
>>> Node('/srv/application/conf.py').dir.dir.dir
Node('/srv/application')
>>>
>>> # and so on
Returns:Node
directory

shortcut for Node.dir

>>> from plant import Node
>>>
>>> Node('/srv/application/conf.py').directory
Node('/srv/application')
>>>
>>> Node('/srv/application/conf.py').directory.directory
Node('/srv/application')
>>>
>>> Node('/srv/application/conf.py').directory.directory.directory
Node('/srv/application')
>>>
>>> # and so on
Returns:Node
find(relative_path)[source]

Calls Node.find_with_regex() with lazy=True but only returns the first occurrence.

>>> from plant import Node
>>>
>>> Node('/opt/media').find('[.](mp3|mp4)$')
Node('/opt/media/mp3/music1.mp3')
Parameters:relative_pathbytes
Returns:a Node
find_with_regex(pattern, flags=0, lazy=False)[source]

searches recursively for children that match the given regex returning a respective [python`Node`] instance for that given.

It works like Node.glob() but applies a regexp match rather instead.

>>> from plant import Node
>>>
>>> Node('/opt/media').find_with_regex('[.](mp3|mp4)$')
[
    Node('/opt/media/mp3/music1.mp3'),
    Node('/opt/media/mp3/music2.mp3'),
    Node('/opt/media/mp4/my-video.mp4'),
 ]
Parameters:
  • pattern – a valid fnmatch pattern string
  • lazy – bool - if True returns an iterator, defaults to a flat list
Returns:

an iterator or a list of Node

glob(pattern, lazy=False)[source]

searches for globs recursively in all the children node of the current node returning a respective [python`Node`] instance for that given.

Under the hood it applies the given pattern into fnmatch.fnmatch()

>>> from plant import Node
>>>
>>> mp3_node = Node('/opt/media/mp3')
>>> mp3_node.glob('*.mp3')
[
    Node('/opt/media/mp3/music1.mp3'),
    Node('/opt/media/mp3/music2.mp3'),
 ]
Parameters:
  • pattern – a valid fnmatch pattern string
  • lazy – bool - if True returns an iterator, defaults to a flat list
Returns:

an iterator or a list of Node

goto(path)[source]

Returns a Node pointing to the given directory

>>> from plant import Node
>>>
>>> Node('/opt/media/mp3/').goto('../mp4/my-video.mp4')
Node('/opt/media/mp4/my-video.mp4')
Parameters:pathbytes
Returns:a Node
join(*path)[source]

Joins the given path with that of the current node’s

Does not check if the target file exists, it simply concatenates strings using the native platform’s path separator.

>>> from plant import Node
>>>
>>> Node('/opt/media/mp3').join('unknown-track.mp3')
'/opt/media/mp3/unknown-track.mp3'

>>> Node('/opt/media/mp4').join('..' , 'mp3', 'music1.mp3')
'/opt/media/mp3/music1.mp3'
Parameters:pathbytes
Returns:bytes
list()[source]

returns a list of files children of the current directory if the node points to a file, it’s siblings will be listed

>>> from plant import Node
>>>
>>> Node('/srv/application/conf.py').list()
[
    Node('/srv/application/conf.py'),
    Node('/srv/application/README.rst')
]
Returns:a list of Node
classmethod new(*args, **kw)[source]

creates a new instance of Node mostly used internally by its methods.

Parameters:
  • *args
  • **kw
Returns:

a new instance of Node

open(path, *args, **kw)[source]

performs an io.open() on the given relative path to the current node.

>>> from plant import Node
>>>
>>> documents = Node('/opt/documents')

>>> with documents.open('hello-world.txt', 'wb', 'utf-8') as f:
...     f.write('HELLO WORLD')

>>> documents.open('hello-world.txt').read()
'HELLO WORLD'
Parameters:
Returns:

io.FileIO

parent

returns a Node pointing to the parent directory.

it stops at the root node.

>>> from plant import Node
>>>
>>> Node('/srv/application').parent
Node('/srv')
>>>
>>> Node('/srv/application').parent.parent
Node('/')
>>>
>>> # it stops at the root node
>>> Node('/srv/application').parent.parent.parent
Node('/')
Returns:Node

Returns the path to a related file. (is under a subtree the same tree as the node).

It’s useful to know how to go back to the root of this node instance.

>>> from plant import Node
>>>
>>> way_back = Node('/foo/bar').path_to_related('/foo/bar/another/dir/file.py')
>>> way_back
'../../'

>>> way_back = Node('/foo/bar/docs/static/file.css').path_to_related('/foo/bar/docs/intro/index.md')
>>> way_back
'../static/file.css'
Parameters:pathbytes
Returns:a bytes
relative(path)[source]

returns the relative from the current Node to the given string

>>> from plant import Node
>>>
>>> Node('/opt/media/mp3/').relative('/opt/media/mp4/my-video.mp4')
'../mp4/my-video.mp4'
Parameters:path – a path string
Returns:bytes
trip_at(path, lazy=False)[source]

Iterates recursively on a subpath of the current Node

It basically performs a py:func:os.walk at the given path and yields the absolute path to each file

>>> from plant import Node
>>>
>>> Node('/opt/media').trip_at('mp3', lazy=False)
[
    '/opt/media/mp3/music1.mp3',
    '/opt/media/mp3/music2.mp3',
 ]
Parameters:
  • path – a path string
  • lazy – bool - if True returns an iterator, defaults to a flat list
Returns:

an iterator or a list of bytes

walk(lazy=False)[source]

Same as Node.trip_at() but iterates recursively within the current Node instead.

>>> from plant import Node
>>>
>>> Node('/opt/media').walk(lazy=False)
[
    '/opt/media/mp3/music1.mp3',
    '/opt/media/mp3/music2.mp3',
    '/opt/media/mp4/my-video.mp4',
 ]
Parameters:
  • path – a path string
  • lazy – bool - if True returns an iterator, defaults to a flat list
Returns:

an iterator or a list of bytes

plant.handy.slugify(text, repchar=u'-')[source]

takes a string and replaces all non-alphanumeric characters with the given repchar.

Parameters:
  • text – the string to be slugified
  • repchar – defaults to -, the replacement char
Returns:

:py:`bytes`