# Package `seedir`

seedir is a Python package for creating, editing, and reading folder tree diagrams.

The general logic of seedir is based on representing directories in 3 different forms: real directories on a computer, text diagrams of directories, and "fake directories" (manipulable Python folder objects). seedir provides tools for going in between these formats.

# Getting started

The following examples will cover what you can do with seedir. We can start by importing the package with the `sd` alias:

    >>> import seedir as sd

## Displaying folder trees

The primary function of seedir is to create plain text diagrams of folders, for use in blogs, examples, Q&As, etc. The GitHub repo for seedir includes an example folder (`seedir/seedir/exampledir`) which will be used here.

To printout out the structure of this folder, you can use the primary `seedir()` function:

    >>> path = 'exampledir'
    >>> sd.seedir(path)
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    │ └─cataclysmic.txt
    ├─scrooge/
    │ ├─light.pdf
    │ ├─paycheck/
    │ │ └─electrophoresis.txt
    │ └─reliquary.pdf
    └─Vogel.txt

By default, the output is printed. To return a string instead, use the `printout` argument:

    >>> s = sd.seedir(path, printout=False)
    >>> print(type(s))
    <class 'str'>

## Trimming folder trees

Sometimes a directory is too large, is private, or contains certain irrelevant files. To handle this, there are a few arguments which allow you to edit the items included in the output.

### Including & excluding folders & files

One way is to call out specific folders of files to include or exclude:

    >>> sd.seedir(path, include_folders=['scrooge','paycheck'], exclude_files='reliquary.pdf')
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─scrooge/
    │ ├─light.pdf
    │ └─paycheck/
    │   └─electrophoresis.txt
    └─Vogel.txt

By passing `regex=True`, these "include" and "exclude" arguments also support regular expressions, :

    >>> sd.seedir(path, include_files='.*\.pdf$', regex=True) # all PDFs
    exampledir/
    ├─jowly.pdf
    ├─pedantic/
    └─scrooge/
      ├─light.pdf
      ├─paycheck/
      └─reliquary.pdf

### Masking

You can also use the `mask` parameter to functionally filter out items in the folder. Pathnames are passed to the mask function, and items are kept if `True` is returned:

    >>> import os

    >>> def foo(x): # omits folders with more than 2 items
    ...     if os.path.isdir(x) and len(os.listdir(x)) > 2:
    ...         return False
    ...     return True

    >>> sd.seedir(path, mask=foo)
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    │ └─cataclysmic.txt
    └─Vogel.txt

### Limiting the depth or number of items

You can also wholly limit the output by providing the `depthlimit` or `itemlimit` arguments. Respectively, these arguments limit the depth of folders to enter and the number of items to include per folder.

    >>> sd.seedir(path, depthlimit=1)
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    ├─scrooge/
    └─Vogel.txt

    >>> sd.seedir(path, itemlimit=3)
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    └─pedantic/
      └─cataclysmic.txt

New in v0.5.0! You can also pass a 2-tuple to `itemlimit` to have separate limits for folders and files, respectively:

    >>> sd.seedir(path, itemlimit=(None, 1))
    exampledir/
    ├─scrooge/
    │ ├─light.pdf
    │ └─paycheck/
    │   └─electrophoresis.txt
    ├─jowly.pdf
    └─pedantic/
      └─cataclysmic.txt

As `seedir()` uses recursion, these arguments can hedge the traversal of deep, complicated folders.

When limiting the tree, using the `beyond` argument can be helpful to show what is being cut. The special value `'content'` shows the number of folders and files:

    >>> sd.seedir(path, depthlimit=1, beyond='content')
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    │ └─0 folder(s), 1 file(s)
    ├─scrooge/
    │ └─1 folder(s), 2 file(s)
    └─Vogel.txt

### Sorting

Especially when using the `itemlimit`, but also generally, you may want to sort the output to determine which items appear first. You can apply a general sort using `sort=True`:

    >>> sd.seedir(path, itemlimit=4, sort=True)
    exampledir/
    ├─Vogel.txt
    ├─jowly.pdf
    ├─monkish.txt
    └─pedantic/
      └─cataclysmic.txt

There are additional reverse and key arguments (akin to `sorted()` or `list.sort()`) which allow you to customize the sorting:

    >>> sd.seedir(path, sort=True, sort_reverse=True, sort_key=lambda s : len(s))
    exampledir/
    ├─monkish.txt
    ├─jowly.pdf
    ├─Vogel.txt
    ├─pedantic/
    │ └─cataclysmic.txt
    └─scrooge/
      ├─reliquary.pdf
      ├─light.pdf
      └─paycheck/
        └─electrophoresis.txt

The `first` argument allows you to select whether files or folders appear first:

    >>> sd.seedir(path, first='files')
    exampledir/
    ├─Vogel.txt
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    │ └─cataclysmic.txt
    └─scrooge/
      ├─light.pdf
      ├─reliquary.pdf
      └─paycheck/
        └─electrophoresis.txt

## Styles 💅

`seedir()` has a few builtin styles for formatting the output of the folder tree:

    >>> sd.seedir(path, style='emoji')
    📁 exampledir/
    ├─📄 jowly.pdf
    ├─📄 monkish.txt
    ├─📁 pedantic/
    │ └─📄 cataclysmic.txt
    ├─📁 scrooge/
    │ ├─📄 light.pdf
    │ ├─📁 paycheck/
    │ │ └─📄 electrophoresis.txt
    │ └─📄 reliquary.pdf
    └─📄 Vogel.txt

To make use of the 'emoji' style, install emoji (`pip install emoji`) or use `pip install seedir[emoji]`.

For any builtin style, you can customize the indent size:

    >>> sd.seedir(path, style='spaces', indent=4)
    exampledir/
        jowly.pdf
        monkish.txt
        pedantic/
            cataclysmic.txt
        scrooge/
            light.pdf
            paycheck/
                electrophoresis.txt
            reliquary.pdf
        Vogel.txt

    >>> sd.seedir(path, style='plus', indent=6)
    exampledir/
    +-----jowly.pdf
    +-----monkish.txt
    +-----pedantic/
    |     +-----cataclysmic.txt
    +-----scrooge/
    |     +-----light.pdf
    |     +-----paycheck/
    |     |     +-----electrophoresis.txt
    |     +-----reliquary.pdf
    +-----Vogel.txt

Each style is basically a collection of string "tokens" which are combined to form the header of each printed line (based on the depth and folder structure). You can see these tokens using `get_styleargs()`:

    >>> sd.get_styleargs('emoji')
    {'split': '├─', 'extend': '│ ', 'space': '  ', 'final': '└─', 'folderstart': '📁 ', 'filestart': '📄 ', 'folderend': '/', 'fileend': ''}

You can pass any of these tokens as `**kwargs` to explicitly customize styles with new symbols (note that passed tokens will not be affected by the `indent` parameter; it assumes you know how long you want them to be):

    >>> sd.seedir(path, space='  ', extend='||', split='-}', final='\\\\', folderstart=' ', filestart=' ', folderend='%')
    exampledir%
    -} jowly.pdf
    -} monkish.txt
    -} pedantic%
    ||\\ cataclysmic.txt
    -} scrooge%
    ||-} light.pdf
    ||-} paycheck%
    ||||\\ electrophoresis.txt
    ||\\ reliquary.pdf
    \\ Vogel.txt

There are also `uniform` and `anystart` arguments for customizing multiple tokens at once:

    >>> sd.seedir(path, uniform='----', anystart='>')
    >exampledir/
    ---->jowly.pdf
    ---->monkish.txt
    ---->pedantic/
    -------->cataclysmic.txt
    ---->scrooge/
    -------->light.pdf
    -------->paycheck/
    ------------>electrophoresis.txt
    -------->reliquary.pdf
    ---->Vogel.txt

## Programmatic formatting

Following a user-raised issue, seedir has added a `formatter` parameter for enabling some programmatic editing of the folder tree. This can be useful when you want to alter the style of the diagram based on things like the depth, item name, file extension, etc. The path of each item (relative to the root) is passed to `formatter`, which returns new settings to use for that item.

The following example edits the style tokens for items with particular names or file extensions:

    >>> import os

    >>> def my_style(item):
    ...
    ...     outdict = {}
    ...
    ...     # get the extension
    ...     ext = os.path.splitext(item)[1]
    ...
    ...     if ext == '.txt':
    ...         outdict['filestart'] = '✏️'
    ...
    ...     if os.path.basename(item) == 'scrooge':
    ...         outdict['folderstart'] = '👉'
    ...
    ...     return outdict

    >>> sd.seedir(path, formatter=my_style)
    exampledir/
    ├─jowly.pdf
    ├─✏️monkish.txt
    ├─pedantic/
    │ └─✏️cataclysmic.txt
    ├─👉scrooge/
    │ ├─light.pdf
    │ ├─paycheck/
    │ │ └─✏️electrophoresis.txt
    │ └─reliquary.pdf
    └─✏️Vogel.txt

The `formatter` parameter can also dynamically set other options, such as the filtering arguments outlined above. The following example sets a mask that removes files, but only in the root directory:

    >>> import os
    >>> def no_root_files(item):
    ...     if os.path.basename(item) == 'exampledir':
    ...         mask = lambda x: os.path.isdir(x)
    ...         return {'mask': mask}

    >>> sd.seedir(path, formatter=no_root_files)
    exampledir/
    ├─pedantic/
    │ └─cataclysmic.txt
    └─scrooge/
      ├─light.pdf
      ├─paycheck/
      │ └─electrophoresis.txt
      └─reliquary.pdf

Note that by default, any changes set by the `formatter` are unset for sub-directories. You can turn on the `sticky_formatter` option to make changes persist:

    >>> def mark(item):
    ...     d = {}
    ...     parent = os.path.basename(os.path.dirname(item))
    ...     if parent == 'pedantic':
    ...         d['folderstart'] = '✔️ '
    ...         d['filestart'] = '✔️ '
    ...     if parent == 'scrooge':
    ...         d['folderstart'] = '❌ '
    ...         d['filestart'] = '❌ '
    ...
    ...     return d

    # The function only makes changes to items in the 'pedantic' and 'scrooge'
    # folders explicilty.
    >>> sd.seedir(path, formatter=mark)
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    │ └─✔️ cataclysmic.txt
    ├─scrooge/
    │ ├─❌ light.pdf
    │ ├─❌ paycheck/
    │ │ └─electrophoresis.txt
    │ └─❌ reliquary.pdf
    └─Vogel.txt

    # By passing `sticky_formatter`, changes are also applied to subdirectories
    >>> sd.seedir(path, formatter=mark, sticky_formatter=True)
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    │ └─✔️ cataclysmic.txt
    ├─scrooge/
    │ ├─❌ light.pdf
    │ ├─❌ paycheck/
    │ │ └─❌ electrophoresis.txt
    │ └─❌ reliquary.pdf
    └─Vogel.txt

Some properties (e.g., the depth of the folder relative to the parent) are a little more difficult to determine with a system paths. However, switching to object-oriented FakeDirs (introduced in the following section) make accessing interfolder relations a little easier:

    >>> # now items passed are FakeDir / FakeFile, not system path
    >>> def formatter(item):
    ...     if item.depth > 1: # we can access the depth attribute
    ...         return sd.get_styleargs('plus')

    >>> f = sd.fakedir(path)
    >>> f.seedir(formatter=formatter)
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    | +-cataclysmic.txt
    ├─scrooge/
    | +-light.pdf
    | +-paycheck/
    | | +-electrophoresis.txt
    | +-reliquary.pdf
    └─Vogel.txt

## Pathlib

As of version 0.4.0, `sd.realdir.seedir()` also accepts pathlib objects:

    >>> import pathlib
    >>> p = pathlib.Path(path)
    >>> p
    PosixPath('exampledir')

    >>> sd.seedir(p)
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    │ └─cataclysmic.txt
    ├─scrooge/
    │ ├─light.pdf
    │ ├─paycheck/
    │ │ └─electrophoresis.txt
    │ └─reliquary.pdf
    └─Vogel.txt

Most of the features demonstrated above apply as usual. The only major difference is that arguments accepting callables (`mask` & `fromatter`) will now be passed `pathlib.Path` objects, instead of strings:

    >>> mask = lambda x: x.is_dir() or x.suffix == '.txt'
    >>> sd.seedir(p, mask=mask)
    exampledir/
    ├─scrooge/
    │ └─paycheck/
    │   └─electrophoresis.txt
    ├─monkish.txt
    ├─pedantic/
    │ └─cataclysmic.txt
    └─Vogel.txt

## Fake directories

You can also create or edit directory examples by using "fake directories" in `seedir`. These are Python representations of folders and files, which can be manipulated in ways similar to real directories.

### Making from scratch

`FakeDir` is a folder class; you can be used to initialize an example folder tree. `FakeDir` objects have a `FakeDir.seedir()` method, which is fundamentally similar to `seedir()` for real system paths:

    >>> x = sd.FakeDir('myfakedir')
    >>> x.seedir()
    myfakedir/

To add items to `x`, you can create subitems, initialize new directories, or move existing ones:

    >>> x.create_file(['__init__.py', 'main.py', 'styles.txt'])
    [FakeFile(myfakedir/__init__.py), FakeFile(myfakedir/main.py), FakeFile(myfakedir/styles.txt)]

    >>> y = sd.FakeDir('resources', parent=x)

    >>> z = sd.FakeDir('images')
    >>> z.parent = y

    >>> for n in ['a', 'b', 'c']:
    ...     z.create_file(n + '.png')
    FakeFile(myfakedir/resources/images/a.png)
    FakeFile(myfakedir/resources/images/b.png)
    FakeFile(myfakedir/resources/images/c.png)

    >>> x.seedir(sort=True, first='folders')
    myfakedir/
    ├─resources/
    │ └─images/
    │   ├─a.png
    │   ├─b.png
    │   └─c.png
    ├─__init__.py
    ├─main.py
    └─styles.txt

You can use path-like strings to index fake directories:

    >>> x['resources/images/a.png']
    FakeFile(myfakedir/resources/images/a.png)

You can also use the `listdir` or `get_child_names` methods to get the children of a folder (or their names):

    >>> x['resources/images'].listdir()
    [FakeFile(myfakedir/resources/images/a.png), FakeFile(myfakedir/resources/images/b.png), FakeFile(myfakedir/resources/images/c.png)]

    >>> x['resources/images'].get_child_names()
    ['a.png', 'b.png', 'c.png']

You can use the `delete` method to remove items by name or by object:

    >>> x['resources/images'].delete([x['resources/images/a.png'], 'b.png'])
    >>> x.seedir()
    myfakedir/
    ├─__init__.py
    ├─main.py
    ├─styles.txt
    └─resources/
      └─images/
        └─c.png

You can also move items within the tree:

    >>> x['styles.txt'].parent = x['resources']
    >>> x.seedir()
    myfakedir/
    ├─__init__.py
    ├─main.py
    └─resources/
      ├─images/
      │ └─c.png
      └─styles.txt

### Turn existing directories into fakes

The `fakedir()` function allows you to convert real directories into `FakeDir` objects:

    >>> f = sd.fakedir(path) # using path from above
    >>> f.seedir()
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    ├─pedantic/
    │ └─cataclysmic.txt
    ├─scrooge/
    │ ├─light.pdf
    │ ├─paycheck/
    │ │ └─electrophoresis.txt
    │ └─reliquary.pdf
    └─Vogel.txt

    >>> type(f)
    <class 'seedir.fakedir.FakeDir'>

Similar to `seedir()`, `fakedir()` has options to limit the incoming folders and files:

    >>> f = sd.fakedir(path, exclude_folders='scrooge', exclude_files='Vogel.txt')
    >>> f.seedir()
    exampledir/
    ├─jowly.pdf
    ├─monkish.txt
    └─pedantic/
      └─cataclysmic.txt

Fake directories created from your system directories can be combined with other ones created from scratch:

    >>> f.parent = x
    >>> x.seedir()
    myfakedir/
    ├─__init__.py
    ├─main.py
    ├─resources/
    │ ├─images/
    │ │ └─c.png
    │ └─styles.txt
    └─exampledir/
      ├─jowly.pdf
      ├─monkish.txt
      └─pedantic/
        └─cataclysmic.txt

### Creating folder trees from text

The `fakedir_fromstring()` method allows you to read in existing folder tree diagrams. Given this:

    somedir/
      - folder1
      - folder2
      - folder3
        - file1
        - file2
        - subfolder
          - subfolder
            - deepfile
      - folder4

You can do:

    >>> s = '''somedir/
    ...   - folder1
    ...   - folder2
    ...   - folder3
    ...     - file1
    ...     - file2
    ...     - subfolder
    ...       - subfolder
    ...         - deepfile
    ...   - folder4'''

    >>> g = sd.fakedir_fromstring(s)
    >>> g.seedir()
    somedir/
    ├─folder1
    ├─folder2
    ├─folder3/
    │ ├─file1
    │ ├─file2
    │ └─subfolder/
    │   └─subfolder/
    │     └─deepfile
    └─folder4

This can be used to read in examples found online. For instance:

    >>> s = '''test/                      # root folder
    ...     packA/                 # package packA
    ...         subA/              # subpackage subA
    ...             __init__.py
    ...             sa1.py
    ...             sa2.py
    ...         __init__.py
    ...         a1.py
    ...         a2.py
    ...     packB/                 # package packB (implicit namespace package)
    ...         b1.py
    ...         b2.py
    ...     math.py
    ...     random.py
    ...     other.py
    ...     start.py'''

    >>> h = sd.fakedir_fromstring(s, parse_comments=True) # handling the added comments
    >>> h.seedir(style='emoji')
    📁 test/
    ├─📁 packA/
    │ ├─📁 subA/
    │ │ ├─📄 __init__.py
    │ │ ├─📄 sa1.py
    │ │ └─📄 sa2.py
    │ ├─📄 __init__.py
    │ ├─📄 a1.py
    │ └─📄 a2.py
    ├─📁 packB/
    │ ├─📄 b1.py
    │ └─📄 b2.py
    ├─📄 math.py
    ├─📄 random.py
    ├─📄 other.py
    └─📄 start.py

This function has not been extensively tested, so expect failures/misreadings!

### Creating random directories

You can also use seedir to create randomly generated directories.

    >>> r = sd.randomdir(seed=4.21, extensions=['png', 'jpg', 'pdf'], name='sorandom')
    >>> r.seedir()
    sorandom/
    ├─plethora.pdf
    ├─randy.jpg
    ├─giddap.pdf
    ├─adage/
    └─Gobi/
      ├─inventive.pdf
      ├─Noel.jpg
      ├─archaic/
      │ └─bream.pdf
      ├─salve/
      └─NY/
        └─Bahrein.jpg

Additional parameters dictate the size of the tree created:

    >>> sd.randomdir(files=range(5), # making an unnecessarily large tree
    ...              folders=[1,2],
    ...              stopchance=.3,
    ...              depth=5,
    ...              extensions=['png', 'jpg', 'pdf'],
    ...              seed=4.21).seedir()
    MyFakeDir/
    ├─plethora.pdf
    ├─randy.jpg
    ├─giddap.pdf
    ├─adage.jpg
    ├─oint/
    │ ├─inventive.pdf
    │ ├─Noel.jpg
    │ ├─archaic.pdf
    │ ├─NY/
    │ │ ├─neonatal.png
    │ │ ├─pyknotic.png
    │ │ ├─wife.png
    │ │ ├─Mickelson/
    │ │ │ └─Caruso/
    │ │ │   ├─royal.pdf
    │ │ │   ├─aurora.pdf
    │ │ │   ├─stampede.pdf
    │ │ │   ├─divan.pdf
    │ │ │   └─Coffey/
    │ │ │     ├─sad.pdf
    │ │ │     ├─cob.pdf
    │ │ │     ├─natural.jpg
    │ │ │     ├─skinflint.pdf
    │ │ │     └─exploration/
    │ │ └─Westchester/
    │ │   ├─metamorphism.jpg
    │ │   ├─Pulitzer.jpg
    │ │   ├─permissive.png
    │ │   ├─wakerobin/
    │ │   │ ├─talon.jpg
    │ │   │ ├─peace.pdf
    │ │   │ ├─drowse.jpg
    │ │   │ ├─rutabaga/
    │ │   │ └─silage/
    │ │   │   ├─pert.png
    │ │   │   ├─defensible.png
    │ │   │   ├─lexicon.png
    │ │   │   ├─eureka.pdf
    │ │   │   └─impasse/
    │ │   └─calve/
    │ │     ├─superstitious.png
    │ │     └─embroider/
    │ │       ├─safekeeping.pdf
    │ │       ├─brig.png
    │ │       ├─systemic.pdf
    │ │       ├─caddis.png
    │ │       └─borosilicate/
    │ └─Pentecost/
    │   ├─visceral.pdf
    │   ├─replica.png
    │   ├─rockaway.jpg
    │   ├─luxe.jpg
    │   └─breath/
    │     ├─contain.jpg
    │     └─homophobia/
    │       ├─crewman.jpg
    │       └─restroom/
    └─joss/
      ├─Technion.jpg
      ├─Mynheer.png
      ├─begonia/
      └─Djakarta/
        ├─Lionel.png
        ├─Cantonese.pdf
        ├─drafty.jpg
        ├─half/
        │ └─builtin/
        │   ├─ermine.jpg
        │   └─Cretan/
        │     ├─happenstance.pdf
        │     ├─insoluble.jpg
        │     ├─Audrey/
        │     └─octennial/
        └─recipient/
          ├─splintery.jpg
          ├─bottom.png
          ├─stunk.png
          ├─Polyhymnia/
          └─Holocene/
            ├─plaque.pdf
            ├─westerly.png
            ├─glassine.jpg
            ├─titanium.pdf
            └─square/

### Turning fake directories into real ones

Finally, there is a `FakeDir.realize()` method which can covert fake directories into real folders on your computer.

    x = sd.randomdir()
    x.realize(path='where/to/create/it/')

All files created will be empty.

## Extending seedir

It is also possible to use seedir to generate folder tree diagrams for other types of Python objects that have directory-like structures. This can be done by subclassing the `FolderStructure` class, which implements the main algorithm:

    >>> from seedir.folderstructure import FolderStructure

FolderStructure is an abstract class, which requires three arguments to be implemented:

1. `FolderStructure.getname()`: returns a string name for the object
2. ``FolderStructure.isdir()`: returns a boolean indicating whether the object passed is a folder or not.
3. `FolderStructure.listdir()`: when called on the folder-like object, returns a list of child objects

Once these methods are implemented, your custom FolderStructure can be called on inputs to create folder structures. The following example demonstrates creating a "folder" structure for factorizing numbers:

    >>> def factors(n):
    ...     return [i for i in range(2, n) if n % i == 0]

    # note that the isdir_func always returns true, treating all numbers as "folders"
    >>> class FactorStructure(FolderStructure):
    ...
    ...     def getname(self, item):
    ...         return str(item)
    ...
    ...     def isdir(self, item):
    ...         return True
    ...
    ...     def listdir(self, item):
    ...         return factors(item)

    >>> factorizer = FactorStructure()
    >>> factorizer(36, folderend='')
    36
    ├─2
    ├─3
    ├─4
    │ └─2
    ├─6
    │ ├─2
    │ └─3
    ├─9
    │ └─3
    ├─12
    │ ├─2
    │ ├─3
    │ ├─4
    │ │ └─2
    │ └─6
    │   ├─2
    │   └─3
    └─18
      ├─2
      ├─3
      ├─6
      │ ├─2
      │ └─3
      └─9
        └─3

## Cheatsheet

Expand source code

    # -*- coding: utf-8 -*-
    """
    [seedir](https://github.com/earnestt1234/seedir) is a Python package for
    creating, editing, and reading folder tree diagrams.

    The general logic of seedir is based on representing directories in 3
    different forms: real directories on a computer, text diagrams of directories,
    and "fake directories" (manipulable Python folder objects). seedir provides
    tools for going in between these formats.

    .. include:: ../docs/gettingstarted.md

    ## Cheatsheet

    ![](https://raw.githubusercontent.com/earnestt1234/seedir/master/img/seedir_diagram.png)

    """

    #imports for package namespace
    from .realdir import seedir

    from .fakedir import (fakedir,
                          fakedir_fromstring,
                          populate,
                          randomdir,)

    from .fakedir import FakeDir
    from .fakedir import FakeFile

    from .printing import (get_styleargs,
                           STYLE_DICT,)

## Sub-modules

`seedir.errors`

  Custom exceptions for seedir.

`seedir.fakedir`

  Code for creating and editing "fake directories" within the `seedir` package; i.e. Python folder tree objects. This module can be used to make …

`seedir.folderstructure`

  The primary algorithm for determining the folder structure returned by `seedir()` and `FakeDir.seedir()`.

`seedir.printing`

  General module of resources and helpers for printing and making folder trees in seedir.

`seedir.realdir`

  This module provides code for producing folder structure strings for directories. Currently, the only tool here is `seedir`, the primary function of …