Skip to main content
|travis build| |Coverage Status| |PyPI version| |License: MIT|

Build/Coverage Status
^^^^^^^^^^^^^^^^^^^^^

+-------------------+------------------+---------------------+
| Branch | Build | Coverage |
+===================+==================+=====================+
| **master** | |travis build| | |Coverage Status| |
+-------------------+------------------+---------------------+
| **development** | |travis build| | |Coverage Status| |
+-------------------+------------------+---------------------+

📁 ODir 📁
========

Dealing with paths and directories isn't rocket science, but it can be a
pain. **ODir** allows you to build directory trees by treating your
directory tree as a first-class object.

**Documentation** can be found here
https://opath.readthedocs.io/en/latest/

**without ODir**

.. code:: python

# define paths
top = os.path.abspath('top')
middle = os.path.join(str(top), 'middle')
bottom = os.path.join(str(middle), 'bottom')
os.makedirs(bottom)
with open(os.path.join(bottom, 'bottomlog.txt', 'w') as f:
f.write("some log information")

**with ODir**

.. code:: python

# define paths
env = ODir('top').add('middle').add('bottom').root
env.bottom.write('log.txt', 'w', 'some log information')

Installation
============

Installation via pip is the easiest way...

.. code:: bash

pip install opath

Alternatives
============

Projects like
`pathlib <https://docs.python.org/3/library/pathlib.html>`__ or
`path.py <https://github.com/jaraco/path.py>`__ encapsulating paths into
objects and may be better suited for you purposes.

However, ODir provides some useful features for managing large directory
tree structures. \* building directory and file structure trees as an
abstract tree \* quick access to deeply nested directories and files
using custom attribute names \* directories and files are treated as
nested attributes in python objects

Examples
========

.. figure:: images/dir_example.gif?raw=true
:alt: live\_example

live\_example

Its very easy to create, move, or delete directory trees. For example,
the following builds the directory skeleton for this repo.

.. figure:: images/directory_example.png?raw=true
:alt: demo

demo

.. code:: python

from opath import *

# create folder structure
env = ODir('opath')
env.add('opath', alias='core')
env.core.add('tests')
env.tests.add('env')
env.tests.add('env2')

# make the directory
env.set_dir(Path(__file__).absolute().parent)
env.mkdirs()

# write some files
env.write('README.md', 'w', '# ODir\nThis is a test readme file')
env.core.write("__init__.py", "w", "__version__ = \"1.0\"")

Other things you can do:

Abstracting the directory structure lets your create, remove, copy, move
directory trees easily.

.. figure:: images/rmdirs_example.gif?raw=true
:alt: rmdirs\_example

rmdirs\_example

All paths are easily accessible.

.. code:: python

print(env.test.abspath) # absolute path
print(env.test.path) # relative path

You can even read and write files intuitively.

.. code:: python

# writes file to 'test' folder
env.test.write('test.txt', 'w', 'some data')

# reads test file
env.test.read('test.txt', 'r')

# open file and read lines
env.test.open('test.txt', 'r').readlines()

All iterables are chainable making it easy to do complex things. Pretty
cool!

.. code:: python

# recurseively write a log file to all subfolders of 'core'
env.core.descendents.write('log.txt', 'w', 'some log file')

# read all files named 'log.txt' for subfolders in 'test'
env.test.children.read('log.txt', 'r')

# readlines files named 'log.txt' for subfolders in 'test'
env.test.children.open('log.txt', 'r').readlines()

# recursively get stats on folders
d = env.descendents()
zip(d, d.stat().st_mtime)

Better documentation about chaining methods is soon to come along with
recipes.

Basic usage
===========

Use ``add`` to create folders.

.. code:: python

from opath import *

env = ODir('bin')
env.add('subfolder1')
env.add('subfolder2')
env.print()

>>>
*bin
| *subfolder1
| *subfolder2

Functions return ODir objects and so can be chained together.

.. code:: python

env = ODir('bin')
env.add('subfolder1').add('subsubfolder')
env.print()

>>>
*bin
| *subfolder1
| | *subsubfolder

Files can be written quickly

.. code:: python

env = ODir('bin')
env.add('subfolder1').add('subsubfolder')
env.subsubfolder.write('My Data', 'w')

Or a OFile can be added:

.. code:: python

env = ODir('bin')
env.add_file('myfile.txt', attr='myfile')
env.myfile.write('this is my data', 'w')

Folders create accesible ODir attributes automatically. Alternative
attribute names can be set using 'alias='

.. code:: python

env = ODir('bin')
env.add('subfolder1')
env.subfolder1.add('misc')
env.subfolder1.misc.add('.hidden', alias='hidden')
env.subfolder1.misc.hidden.add('hiddenbin')
env.print()

*bin
| *subfolder1
| | *misc
| | | *.hidden ("hidden")
| | | | *hiddenbin

By default, attributes are *pushed* back the the root directory. The
following is equivalent to above.

.. code:: python

env = ODir('bin')
env.add('subfolder1')
env.subfolder1.add('misc')
env.misc.add('.hidden', alias='hidden')
env.hidden.add('hiddenbin')
env.print()

*bin
| *subfolder1
| | *misc
| | | *.hidden ("hidden")
| | | | *hiddenbin

Making, moving, copying, and deleting directories
=================================================

The location of the root folder can be set by ``set_bin``

.. code:: python

env.set_bin('../bin')

Directories can be created, deleted, copied or moved using ``mkdirs``,
``cpdirs``, ``mvdirs``, ``rmdirs``

.. code:: python

env.mkdirs()
env_copy = env.cpdirs()
# you can do stuff with env_copy independently
env.mvdirs('~/Document')
env_copy.rmdirs()

Advanced usage
==============

All iterables return special list-like objects that can be chained in
one-liners.

.. code:: python

env.descendents() # returns a ChainList object

# find all txt files
env.descendents(include_self=True).glob("*.txt")

# recursively change permissions for directories
env.abspaths.chmod(0o444)

.. |travis build| image:: https://img.shields.io/travis/jvrana/opath.svg
:target: https://travis-ci.org/jvrana/opath
.. |Coverage Status| image:: https://coveralls.io/repos/github/jvrana/opath/badge.svg?branch=master
:target: https://coveralls.io/github/jvrana/opath?branch=master
.. |PyPI version| image:: https://badge.fury.io/py/REPO.svg
:target: https://badge.fury.io/py/REPO
.. |License: MIT| image:: https://img.shields.io/badge/License-MIT-yellow.svg
:target: https://opensource.org/licenses/MIT
.. |travis build| image:: https://img.shields.io/travis/jvrana/opath/master.svg
:target: https://travis-ci.org/jvrana/opath/master
.. |travis build| image:: https://img.shields.io/travis/jvrana/opath/development.svg
:target: https://travis-ci.org/jvrana/opath/development
.. |Coverage Status| image:: https://coveralls.io/repos/github/jvrana/opath/badge.svg?branch=development
:target: https://coveralls.io/github/jvrana/opath?branch=development

Metadata

Release files for opath 0.5.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 opath 0.5.1
File Size Uploaded
opath-0.5.1.tar.gz 11.8 kB Details

Release files / opath-0.5.1.tar.gz

Download URL opath-0.5.1.tar.gz
Size 11.8 kB
Tags Source
SHA-256 checksum
How to use checksums
5ad8ace1a4ace310eb504db476fe53378e9b8ac3fb2c4326eeea698d3176bea1
BLAKE2b-256 checksum
How to use checksums
ed90d3836626dfd7ab17b34980336741ea42fca09fdc077f070c809c160c142d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release history Release notifications | RSS feed

This release

0.5.1 This release

1 release file

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