python-fsutil


Namepython-fsutil JSON
Version 0.14.1 PyPI version JSON
download
home_page
Summaryhigh-level file-system operations for lazy devs.
upload_time2024-03-19 14:50:02
maintainer
docs_urlNone
author
requires_python
licenseMIT License Copyright (c) 2020-present Fabio Caccamo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords python file system util utils utility utilities dir directory path fs os shutil glob
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![](https://img.shields.io/pypi/pyversions/python-fsutil.svg?color=blue&logo=python&logoColor=white)](https://www.python.org/)
[![](https://img.shields.io/pypi/v/python-fsutil.svg?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/python-fsutil/)
[![](https://static.pepy.tech/badge/python-fsutil/month)](https://pepy.tech/project/python-fsutil)
[![](https://img.shields.io/github/stars/fabiocaccamo/python-fsutil?logo=github&style=flat)](https://github.com/fabiocaccamo/python-fsutil/stargazers)
[![](https://img.shields.io/pypi/l/python-fsutil.svg?color=blue)](https://github.com/fabiocaccamo/python-fsutil/blob/main/LICENSE.txt)

[![](https://results.pre-commit.ci/badge/github/fabiocaccamo/python-fsutil/main.svg)](https://results.pre-commit.ci/latest/github/fabiocaccamo/python-fsutil/main)
[![](https://img.shields.io/github/actions/workflow/status/fabiocaccamo/python-fsutil/test-package.yml?branch=main&label=build&logo=github)](https://github.com/fabiocaccamo/python-fsutil)
[![](https://img.shields.io/codecov/c/gh/fabiocaccamo/python-fsutil?logo=codecov)](https://codecov.io/gh/fabiocaccamo/python-fsutil)
[![](https://img.shields.io/codacy/grade/fc40788ae7d74d1fb34a38934113c4e5?logo=codacy)](https://www.codacy.com/app/fabiocaccamo/python-fsutil)
[![](https://img.shields.io/codeclimate/maintainability/fabiocaccamo/python-fsutil?logo=code-climate)](https://codeclimate.com/github/fabiocaccamo/python-fsutil/)
[![](https://img.shields.io/badge/code%20style-black-000000.svg?logo=python&logoColor=black)](https://github.com/psf/black)
[![](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)

# python-fsutil
high-level file-system operations for lazy devs.

## Installation

```bash
pip install python-fsutil
```

## Usage

Just import the main module and call its methods.

```python
import fsutil
```

### Methods

-   [`assert_dir`](#assert_dir)
-   [`assert_exists`](#assert_exists)
-   [`assert_file`](#assert_file)
-   [`assert_not_dir`](#assert_not_dir)
-   [`assert_not_exists`](#assert_not_exists)
-   [`assert_not_file`](#assert_not_file)
-   [`clean_dir`](#clean_dir)
-   [`convert_size_bytes_to_string`](#convert_size_bytes_to_string)
-   [`convert_size_string_to_bytes`](#convert_size_string_to_bytes)
-   [`copy_dir`](#copy_dir)
-   [`copy_dir_content`](#copy_dir_content)
-   [`copy_file`](#copy_file)
-   [`create_dir`](#create_dir)
-   [`create_file`](#create_file)
-   [`create_tar_file`](#create_tar_file)
-   [`create_zip_file`](#create_zip_file)
-   [`delete_dir`](#delete_dir)
-   [`delete_dir_content`](#delete_dir_content)
-   [`delete_dirs`](#delete_dirs)
-   [`delete_file`](#delete_file)
-   [`delete_files`](#delete_files)
-   [`download_file`](#download_file) *(require `requests` to be installed)*
-   [`exists`](#exists)
-   [`extract_tar_file`](#extract_tar_file)
-   [`extract_zip_file`](#extract_zip_file)
-   [`get_dir_creation_date`](#get_dir_creation_date)
-   [`get_dir_creation_date_formatted`](#get_dir_creation_date_formatted)
-   [`get_dir_hash`](#get_dir_hash)
-   [`get_dir_last_modified_date`](#get_dir_last_modified_date)
-   [`get_dir_last_modified_date_formatted`](#get_dir_last_modified_date_formatted)
-   [`get_dir_size`](#get_dir_size)
-   [`get_dir_size_formatted`](#get_dir_size_formatted)
-   [`get_file_basename`](#get_file_basename)
-   [`get_file_creation_date`](#get_file_creation_date)
-   [`get_file_creation_date_formatted`](#get_file_creation_date_formatted)
-   [`get_file_extension`](#get_file_extension)
-   [`get_file_hash`](#get_file_hash)
-   [`get_file_last_modified_date`](#get_file_last_modified_date)
-   [`get_file_last_modified_date_formatted`](#get_file_last_modified_date_formatted)
-   [`get_file_size`](#get_file_size)
-   [`get_file_size_formatted`](#get_file_size_formatted)
-   [`get_filename`](#get_filename)
-   [`get_parent_dir`](#get_parent_dir)
-   [`get_permissions`](#get_permissions)
-   [`get_unique_name`](#get_unique_name)
-   [`is_dir`](#is_dir)
-   [`is_empty`](#is_empty)
-   [`is_empty_dir`](#is_empty_dir)
-   [`is_empty_file`](#is_empty_file)
-   [`is_file`](#is_file)
-   [`join_filename`](#join_filename)
-   [`join_filepath`](#join_filepath)
-   [`join_path`](#join_path)
-   [`list_dirs`](#list_dirs)
-   [`list_files`](#list_files)
-   [`make_dirs`](#make_dirs)
-   [`make_dirs_for_file`](#make_dirs_for_file)
-   [`move_dir`](#move_dir)
-   [`move_file`](#move_file)
-   [`read_file`](#read_file)
-   [`read_file_from_url`](#read_file_from_url) *(requires `requests` to be installed)*
-   [`read_file_json`](#read_file_json)
-   [`read_file_lines`](#read_file_lines)
-   [`read_file_lines_count`](#read_file_lines_count)
-   [`remove_dir`](#remove_dir)
-   [`remove_dir_content`](#remove_dir_content)
-   [`remove_dirs`](#remove_dirs)
-   [`remove_file`](#remove_file)
-   [`remove_files`](#remove_files)
-   [`rename_dir`](#rename_dir)
-   [`rename_file`](#rename_file)
-   [`rename_file_basename`](#rename_file_basename)
-   [`rename_file_extension`](#rename_file_extension)
-   [`replace_dir`](#replace_dir)
-   [`replace_file`](#replace_file)
-   [`search_dirs`](#search_dirs)
-   [`search_files`](#search_files)
-   [`set_permissions`](#set_permissions)
-   [`split_filename`](#split_filename)
-   [`split_filepath`](#split_filepath)
-   [`split_path`](#split_path)
-   [`transform_filepath`](#transform_filepath)
-   [`write_file`](#write_file)
-   [`write_file_json`](#write_file_json)


#### `assert_dir`

```python
# Raise an OSError if the given path doesn't exist or it is not a directory.
fsutil.assert_dir(path)
```

#### `assert_exists`

```python
# Raise an OSError if the given path doesn't exist.
fsutil.assert_exists(path)
```

#### `assert_file`

```python
# Raise an OSError if the given path doesn't exist or it is not a file.
fsutil.assert_file(path)
```

#### `assert_not_dir`

```python
# Raise an OSError if the given path is an existing directory.
fsutil.assert_not_dir(path)
```

#### `assert_not_exists`

```python
# Raise an OSError if the given path already exists.
fsutil.assert_not_exists(path)
```

#### `assert_not_file`

```python
# Raise an OSError if the given path is an existing file.
fsutil.assert_not_file(path)
```

#### `clean_dir`

```python
# Clean a directory by removing empty sub-directories and/or empty files.
fsutil.clean_dir(path, dirs=True, files=True)
```

#### `convert_size_bytes_to_string`

```python
# Convert the given size bytes to string using the right unit suffix.
size_str = fsutil.convert_size_bytes_to_string(size)
```

#### `convert_size_string_to_bytes`

```python
# Convert the given size string to bytes.
size_bytes = fsutil.convert_size_string_to_bytes(size)
```

#### `copy_dir`

```python
# Copy the directory at the given path and all its content to dest path.
# If overwrite is not allowed and dest path exists, an OSError is raised.
# More informations about kwargs supported options here:
# https://docs.python.org/3/library/shutil.html#shutil.copytree
fsutil.copy_dir(path, dest, overwrite=False, **kwargs)
```

#### `copy_dir_content`

```python
# Copy the content of the directory at the given path to dest path.
# More informations about kwargs supported options here:
# https://docs.python.org/3/library/shutil.html#shutil.copytree
fsutil.copy_dir_content(path, dest, **kwargs)
```

#### `copy_file`

```python
# Copy the file at the given path and its metadata to dest path.
# If overwrite is not allowed and dest path exists, an OSError is raised.
# More informations about kwargs supported options here:
# https://docs.python.org/3/library/shutil.html#shutil.copy2
fsutil.copy_file(path, dest, overwrite=False, **kwargs)
```

#### `create_dir`

```python
# Create directory at the given path.
# If overwrite is not allowed and path exists, an OSError is raised.
fsutil.create_dir(path, overwrite=False)
```

#### `create_file`

```python
# Create file with the specified content at the given path.
# If overwrite is not allowed and path exists, an OSError is raised.
fsutil.create_file(path, content="", overwrite=False)
```

#### `create_tar_file`

```python
# Create tar file at path compressing directories/files listed in content_paths.
# If overwrite is allowed and dest tar already exists, it will be overwritten.
fsutil.create_tar_file(path, content_paths, overwrite=True, compression="gzip")
```

#### `create_zip_file`

```python
# Create zip file at path compressing directories/files listed in content_paths.
# If overwrite is allowed and dest zip already exists, it will be overwritten.
fsutil.create_zip_file(path, content_paths, overwrite=True, compression=zipfile.ZIP_DEFLATED)
```

#### `delete_dir`

```python
# Alias for remove_dir.
fsutil.delete_dir(path)
```

#### `delete_dir_content`

```python
# Alias for remove_dir_content.
fsutil.delete_dir_content(path)
```

#### `delete_dirs`

```python
# Alias for remove_dirs.
fsutil.delete_dirs(*paths)
```

#### `delete_file`

```python
# Alias for remove_file.
fsutil.delete_file(path)
```

#### `delete_files`

```python
# Alias for remove_files.
fsutil.delete_files(*paths)
```

#### `download_file`

```python
# Download a file from url to the given dirpath and return the filepath.
# If dirpath is not provided, the file will be downloaded to a temp directory.
# If filename is provided, the file will be named using filename.
# It is possible to pass extra request options (eg. for authentication) using **kwargs.
filepath = fsutil.download_file(url, dirpath=None, filename="archive.zip", chunk_size=8192, **kwargs)
```

#### `exists`

```python
# Check if a directory of a file exists at the given path.
value = fsutil.exists(path)
```

#### `extract_tar_file`

```python
# Extract tar file at path to dest path.
# If autodelete, the archive will be deleted after extraction.
# If content_paths list is defined, only listed items will be extracted, otherwise all.
fsutil.extract_tar_file(path, dest, content_paths=None, autodelete=False)
```

#### `extract_zip_file`

```python
# Extract zip file at path to dest path.
# If autodelete, the archive will be deleted after extraction.
# If content_paths list is defined, only listed items will be extracted, otherwise all.
fsutil.extract_zip_file(path, dest, content_paths=None, autodelete=False)
```

#### `get_dir_creation_date`

```python
# Get the directory creation date.
date = fsutil.get_dir_creation_date(path)
```

#### `get_dir_creation_date_formatted`

```python
# Get the directory creation date formatted using the given format.
date_str = fsutil.get_dir_creation_date_formatted(path, format='%Y-%m-%d %H:%M:%S')
```

#### `get_dir_hash`

```python
# Get the hash of the directory at the given path using
# the specified algorithm function (md5 by default).
hash = fsutil.get_dir_hash(path, func="md5")
```

#### `get_dir_last_modified_date`

```python
# Get the directory last modification date.
date = fsutil.get_dir_last_modified_date(path)
```

#### `get_dir_last_modified_date_formatted`

```python
# Get the directory last modification date formatted using the given format.
date_str = fsutil.get_dir_last_modified_date_formatted(path, format="%Y-%m-%d %H:%M:%S")
```

#### `get_dir_size`

```python
# Get the directory size in bytes.
size = fsutil.get_dir_size(path)
```

#### `get_dir_size_formatted`

```python
# Get the directory size formatted using the right unit suffix.
size_str = fsutil.get_dir_size_formatted(path)
```

#### `get_file_basename`

```python
# Get the file basename from the given path/url.
basename = fsutil.get_file_basename(path)
```

#### `get_file_creation_date`

```python
# Get the file creation date.
date = fsutil.get_file_creation_date(path)
```

#### `get_file_creation_date_formatted`

```python
# Get the file creation date formatted using the given format.
date_str = fsutil.get_file_creation_date_formatted(path, format="%Y-%m-%d %H:%M:%S")
```

#### `get_file_extension`

```python
# Get the file extension from the given path/url.
extension = fsutil.get_file_extension(path)
```

#### `get_file_hash`

```python
# Get the hash of the file at the given path using
# the specified algorithm function (md5 by default).
filehash = fsutil.get_file_hash(path, func="md5")
```

#### `get_file_last_modified_date`

```python
# Get the file last modification date.
date = fsutil.get_file_last_modified_date(path)
```

#### `get_file_last_modified_date_formatted`

```python
# Get the file last modification date formatted using the given format.
date_str = fsutil.get_file_last_modified_date_formatted(path, format="%Y-%m-%d %H:%M:%S")
```

#### `get_file_size`

```python
# Get the file size in bytes.
size = fsutil.get_file_size(path)
```

#### `get_file_size_formatted`

```python
# Get the file size formatted using the right unit suffix.
size_str = fsutil.get_file_size_formatted(path)
```

#### `get_filename`

```python
# Get the filename from the given path/url.
filename = fsutil.get_filename(path)
```

#### `get_parent_dir`

```python
# Get the parent directory for the given path going up N levels.
parent_dir = fsutil.get_parent_dir(path, levels=1)
```

#### `get_permissions`

```python
# Get the file/directory permissions.
permissions = fsutil.get_permissions(path)
```

#### `get_unique_name`

```python
# Get a unique name for a directory/file ath the given directory path.
unique_name = fsutil.get_unique_name(path, prefix="", suffix="", extension="", separator="-")
```

#### `is_dir`

```python
# Determine whether the specified path represents an existing directory.
value = fsutil.is_dir(path)
```

#### `is_empty`

```python
# Determine whether the specified path represents an empty directory or an empty file.
value = fsutil.is_empty(path)
```

#### `is_empty_dir`

```python
# Determine whether the specified path represents an empty directory.
value = fsutil.is_empty_dir(path)
```

#### `is_empty_file`

```python
# Determine whether the specified path represents an empty file.
value = fsutil.is_empty_file(path)
```

#### `is_file`

```python
# Determine whether the specified path represents an existing file.
value = fsutil.is_file(path)
```

#### `join_filename`

```python
# Create a filename joining the file basename and the extension.
filename = fsutil.join_filename(basename, extension)
```

#### `join_filepath`

```python
# Create a filepath joining the directory path and the filename.
filepath = fsutil.join_filepath(dirpath, filename)
```

#### `join_path`

```python
# Create a path joining path and paths.
# If path is __file__ (or a .py file), the resulting path will be relative
# to the directory path of the module in which it's used.
path = fsutil.join_path(path, *paths)
```

#### `list_dirs`

```python
# List all directories contained at the given directory path.
dirs = fsutil.list_dirs(path)
```

#### `list_files`

```python
# List all files contained at the given directory path.
files = fsutil.list_files(path)
```

#### `make_dirs`

```python
# Create the directories needed to ensure that the given path exists.
# If a file already exists at the given path an OSError is raised.
fsutil.make_dirs(path)
```

#### `make_dirs_for_file`

```python
# Create the directories needed to ensure that the given path exists.
# If a directory already exists at the given path an OSError is raised.
fsutil.make_dirs_for_file(path)
```

#### `move_dir`

```python
# Move an existing dir from path to dest directory.
# If overwrite is not allowed and dest path exists, an OSError is raised.
# More informations about kwargs supported options here:
# https://docs.python.org/3/library/shutil.html#shutil.move
fsutil.move_dir(path, dest, overwrite=False, **kwargs)
```

#### `move_file`

```python
# Move an existing file from path to dest directory.
# If overwrite is not allowed and dest path exists, an OSError is raised.
# More informations about kwargs supported options here:
# https://docs.python.org/3/library/shutil.html#shutil.move
fsutil.move_file(path, dest, overwrite=False, **kwargs)
```

#### `read_file`

```python
# Read the content of the file at the given path using the specified encoding.
content = fsutil.read_file(path, encoding="utf-8")
```

#### `read_file_from_url`

```python
# Read the content of the file at the given url.
content = fsutil.read_file_from_url(url, **kwargs)
```

#### `read_file_json`

```python
# Read and decode a json encoded file at the given path.
data = fsutil.read_file_json(path, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None)
```

#### `read_file_lines`

```python
# Read file content lines.
# It is possible to specify the line indexes (negative indexes too),
# very useful especially when reading large files.
content = fsutil.read_file_lines(path, line_start=0, line_end=-1, strip_white=True, skip_empty=True, encoding="utf-8")
```

#### `read_file_lines_count`

```python
# Read file lines count.
lines_count = fsutil.read_file_lines_count(path)
```

#### `remove_dir`

```python
# Remove a directory at the given path and all its content.
# If the directory is removed with success returns True, otherwise False.
# More informations about kwargs supported options here:
# https://docs.python.org/3/library/shutil.html#shutil.rmtree
fsutil.remove_dir(path, **kwargs)
```

#### `remove_dir_content`

```python
# Removes all directory content (both sub-directories and files).
fsutil.remove_dir_content(path)
```

#### `remove_dirs`

```python
# Remove multiple directories at the given paths and all their content.
fsutil.remove_dirs(*paths)
```

#### `remove_file`

```python
# Remove a file at the given path.
# If the file is removed with success returns True, otherwise False.
fsutil.remove_file(path)
```

#### `remove_files`

```python
# Remove multiple files at the given paths.
fsutil.remove_files(*paths)
```

#### `rename_dir`

```python
# Rename a directory with the given name.
# If a directory or a file with the given name already exists, an OSError is raised.
fsutil.rename_dir(path, name)
```

#### `rename_file`

```python
# Rename a file with the given name.
# If a directory or a file with the given name already exists, an OSError is raised.
fsutil.rename_file(path, name)
```

#### `rename_file_basename`

```python
# Rename a file basename with the given basename.
fsutil.rename_file_basename(path, basename)
```

#### `rename_file_extension`

```python
# Rename a file extension with the given extension.
fsutil.rename_file_extension(path, extension)
```

#### `replace_dir`

```python
# Replace directory at the specified path with the directory located at src.
# If autodelete, the src directory will be removed at the end of the operation.
# Optimized for large directories.
fsutil.replace_dir(path, src, autodelete=False)
```

#### `replace_file`

```python
# Replace file at the specified path with the file located at src.
# If autodelete, the src file will be removed at the end of the operation.
# Optimized for large files.
fsutil.replace_file(path, src, autodelete=False)
```

#### `search_dirs`

```python
# Search for directories at path matching the given pattern.
dirs = fsutil.search_dirs(path, pattern="**/*")
```

#### `search_files`

```python
# Search for files at path matching the given pattern.
files = fsutil.search_files(path, pattern="**/*.*")
```

#### `set_permissions`

```python
# Set the file/directory permissions.
fsutil.set_permissions(path, 700)
```

#### `split_filename`

```python
# Split a filename and returns its basename and extension.
basename, extension = fsutil.split_filename(path)
```

#### `split_filepath`

```python
# Split a filename and returns its directory-path and filename.
dirpath, filename = fsutil.split_filepath(path)
```

#### `split_path`

```python
# Split a path and returns its path-names.
path_names = fsutil.split_path(path)
```

#### `transform_filepath`

```python
# Trasform a filepath by applying the provided optional changes.
filepath = fsutil.transform_filepath(path, dirpath=None, basename=lambda b: slugify(b), extension="webp")
```

#### `write_file`

```python
# Write file with the specified content at the given path.
fsutil.write_file(path, content, append=False, encoding="utf-8", atomic=False)
```

#### `write_file_json`

```python
# Write a json file at the given path with the specified data encoded in json format.
fsutil.write_file_json(path, data, encoding="utf-8", atomic=False, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False)
```

## Testing
```bash
# clone repository
git clone https://github.com/fabiocaccamo/python-fsutil.git && cd python-fsutil

# create virtualenv and activate it
python -m venv venv && . venv/bin/activate

# upgrade pip
python -m pip install --upgrade pip

# install requirements
python -m pip install -r requirements.txt -r requirements-test.txt

# install pre-commit to run formatters and linters
pre-commit install --install-hooks

# run tests using tox
tox

# or run tests using unittest
python -m unittest
```

## License
Released under [MIT License](LICENSE.txt).

---

## Supporting

- :star: Star this project on [GitHub](https://github.com/fabiocaccamo/python-fsutil)
- :octocat: Follow me on [GitHub](https://github.com/fabiocaccamo)
- :blue_heart: Follow me on [Twitter](https://twitter.com/fabiocaccamo)
- :moneybag: Sponsor me on [Github](https://github.com/sponsors/fabiocaccamo)

## See also

- [`python-benedict`](https://github.com/fabiocaccamo/python-benedict) - dict subclass with keylist/keypath support, I/O shortcuts (base64, csv, json, pickle, plist, query-string, toml, xml, yaml) and many utilities. ๐Ÿ“˜

- [`python-fontbro`](https://github.com/fabiocaccamo/python-fontbro) - friendly font operations on top of fontTools. ๐Ÿงข

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "python-fsutil",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "Fabio Caccamo <fabio.caccamo@gmail.com>",
    "keywords": "python,file,system,util,utils,utility,utilities,dir,directory,path,fs,os,shutil,glob",
    "author": "",
    "author_email": "Fabio Caccamo <fabio.caccamo@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/de/17/e7426ac2d9bad932bd6f893781c66c042660d92bec57adb50f36dc7380d5/python-fsutil-0.14.1.tar.gz",
    "platform": null,
    "description": "[![](https://img.shields.io/pypi/pyversions/python-fsutil.svg?color=blue&logo=python&logoColor=white)](https://www.python.org/)\n[![](https://img.shields.io/pypi/v/python-fsutil.svg?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/python-fsutil/)\n[![](https://static.pepy.tech/badge/python-fsutil/month)](https://pepy.tech/project/python-fsutil)\n[![](https://img.shields.io/github/stars/fabiocaccamo/python-fsutil?logo=github&style=flat)](https://github.com/fabiocaccamo/python-fsutil/stargazers)\n[![](https://img.shields.io/pypi/l/python-fsutil.svg?color=blue)](https://github.com/fabiocaccamo/python-fsutil/blob/main/LICENSE.txt)\n\n[![](https://results.pre-commit.ci/badge/github/fabiocaccamo/python-fsutil/main.svg)](https://results.pre-commit.ci/latest/github/fabiocaccamo/python-fsutil/main)\n[![](https://img.shields.io/github/actions/workflow/status/fabiocaccamo/python-fsutil/test-package.yml?branch=main&label=build&logo=github)](https://github.com/fabiocaccamo/python-fsutil)\n[![](https://img.shields.io/codecov/c/gh/fabiocaccamo/python-fsutil?logo=codecov)](https://codecov.io/gh/fabiocaccamo/python-fsutil)\n[![](https://img.shields.io/codacy/grade/fc40788ae7d74d1fb34a38934113c4e5?logo=codacy)](https://www.codacy.com/app/fabiocaccamo/python-fsutil)\n[![](https://img.shields.io/codeclimate/maintainability/fabiocaccamo/python-fsutil?logo=code-climate)](https://codeclimate.com/github/fabiocaccamo/python-fsutil/)\n[![](https://img.shields.io/badge/code%20style-black-000000.svg?logo=python&logoColor=black)](https://github.com/psf/black)\n[![](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n\n# python-fsutil\nhigh-level file-system operations for lazy devs.\n\n## Installation\n\n```bash\npip install python-fsutil\n```\n\n## Usage\n\nJust import the main module and call its methods.\n\n```python\nimport fsutil\n```\n\n### Methods\n\n-   [`assert_dir`](#assert_dir)\n-   [`assert_exists`](#assert_exists)\n-   [`assert_file`](#assert_file)\n-   [`assert_not_dir`](#assert_not_dir)\n-   [`assert_not_exists`](#assert_not_exists)\n-   [`assert_not_file`](#assert_not_file)\n-   [`clean_dir`](#clean_dir)\n-   [`convert_size_bytes_to_string`](#convert_size_bytes_to_string)\n-   [`convert_size_string_to_bytes`](#convert_size_string_to_bytes)\n-   [`copy_dir`](#copy_dir)\n-   [`copy_dir_content`](#copy_dir_content)\n-   [`copy_file`](#copy_file)\n-   [`create_dir`](#create_dir)\n-   [`create_file`](#create_file)\n-   [`create_tar_file`](#create_tar_file)\n-   [`create_zip_file`](#create_zip_file)\n-   [`delete_dir`](#delete_dir)\n-   [`delete_dir_content`](#delete_dir_content)\n-   [`delete_dirs`](#delete_dirs)\n-   [`delete_file`](#delete_file)\n-   [`delete_files`](#delete_files)\n-   [`download_file`](#download_file) *(require `requests` to be installed)*\n-   [`exists`](#exists)\n-   [`extract_tar_file`](#extract_tar_file)\n-   [`extract_zip_file`](#extract_zip_file)\n-   [`get_dir_creation_date`](#get_dir_creation_date)\n-   [`get_dir_creation_date_formatted`](#get_dir_creation_date_formatted)\n-   [`get_dir_hash`](#get_dir_hash)\n-   [`get_dir_last_modified_date`](#get_dir_last_modified_date)\n-   [`get_dir_last_modified_date_formatted`](#get_dir_last_modified_date_formatted)\n-   [`get_dir_size`](#get_dir_size)\n-   [`get_dir_size_formatted`](#get_dir_size_formatted)\n-   [`get_file_basename`](#get_file_basename)\n-   [`get_file_creation_date`](#get_file_creation_date)\n-   [`get_file_creation_date_formatted`](#get_file_creation_date_formatted)\n-   [`get_file_extension`](#get_file_extension)\n-   [`get_file_hash`](#get_file_hash)\n-   [`get_file_last_modified_date`](#get_file_last_modified_date)\n-   [`get_file_last_modified_date_formatted`](#get_file_last_modified_date_formatted)\n-   [`get_file_size`](#get_file_size)\n-   [`get_file_size_formatted`](#get_file_size_formatted)\n-   [`get_filename`](#get_filename)\n-   [`get_parent_dir`](#get_parent_dir)\n-   [`get_permissions`](#get_permissions)\n-   [`get_unique_name`](#get_unique_name)\n-   [`is_dir`](#is_dir)\n-   [`is_empty`](#is_empty)\n-   [`is_empty_dir`](#is_empty_dir)\n-   [`is_empty_file`](#is_empty_file)\n-   [`is_file`](#is_file)\n-   [`join_filename`](#join_filename)\n-   [`join_filepath`](#join_filepath)\n-   [`join_path`](#join_path)\n-   [`list_dirs`](#list_dirs)\n-   [`list_files`](#list_files)\n-   [`make_dirs`](#make_dirs)\n-   [`make_dirs_for_file`](#make_dirs_for_file)\n-   [`move_dir`](#move_dir)\n-   [`move_file`](#move_file)\n-   [`read_file`](#read_file)\n-   [`read_file_from_url`](#read_file_from_url) *(requires `requests` to be installed)*\n-   [`read_file_json`](#read_file_json)\n-   [`read_file_lines`](#read_file_lines)\n-   [`read_file_lines_count`](#read_file_lines_count)\n-   [`remove_dir`](#remove_dir)\n-   [`remove_dir_content`](#remove_dir_content)\n-   [`remove_dirs`](#remove_dirs)\n-   [`remove_file`](#remove_file)\n-   [`remove_files`](#remove_files)\n-   [`rename_dir`](#rename_dir)\n-   [`rename_file`](#rename_file)\n-   [`rename_file_basename`](#rename_file_basename)\n-   [`rename_file_extension`](#rename_file_extension)\n-   [`replace_dir`](#replace_dir)\n-   [`replace_file`](#replace_file)\n-   [`search_dirs`](#search_dirs)\n-   [`search_files`](#search_files)\n-   [`set_permissions`](#set_permissions)\n-   [`split_filename`](#split_filename)\n-   [`split_filepath`](#split_filepath)\n-   [`split_path`](#split_path)\n-   [`transform_filepath`](#transform_filepath)\n-   [`write_file`](#write_file)\n-   [`write_file_json`](#write_file_json)\n\n\n#### `assert_dir`\n\n```python\n# Raise an OSError if the given path doesn't exist or it is not a directory.\nfsutil.assert_dir(path)\n```\n\n#### `assert_exists`\n\n```python\n# Raise an OSError if the given path doesn't exist.\nfsutil.assert_exists(path)\n```\n\n#### `assert_file`\n\n```python\n# Raise an OSError if the given path doesn't exist or it is not a file.\nfsutil.assert_file(path)\n```\n\n#### `assert_not_dir`\n\n```python\n# Raise an OSError if the given path is an existing directory.\nfsutil.assert_not_dir(path)\n```\n\n#### `assert_not_exists`\n\n```python\n# Raise an OSError if the given path already exists.\nfsutil.assert_not_exists(path)\n```\n\n#### `assert_not_file`\n\n```python\n# Raise an OSError if the given path is an existing file.\nfsutil.assert_not_file(path)\n```\n\n#### `clean_dir`\n\n```python\n# Clean a directory by removing empty sub-directories and/or empty files.\nfsutil.clean_dir(path, dirs=True, files=True)\n```\n\n#### `convert_size_bytes_to_string`\n\n```python\n# Convert the given size bytes to string using the right unit suffix.\nsize_str = fsutil.convert_size_bytes_to_string(size)\n```\n\n#### `convert_size_string_to_bytes`\n\n```python\n# Convert the given size string to bytes.\nsize_bytes = fsutil.convert_size_string_to_bytes(size)\n```\n\n#### `copy_dir`\n\n```python\n# Copy the directory at the given path and all its content to dest path.\n# If overwrite is not allowed and dest path exists, an OSError is raised.\n# More informations about kwargs supported options here:\n# https://docs.python.org/3/library/shutil.html#shutil.copytree\nfsutil.copy_dir(path, dest, overwrite=False, **kwargs)\n```\n\n#### `copy_dir_content`\n\n```python\n# Copy the content of the directory at the given path to dest path.\n# More informations about kwargs supported options here:\n# https://docs.python.org/3/library/shutil.html#shutil.copytree\nfsutil.copy_dir_content(path, dest, **kwargs)\n```\n\n#### `copy_file`\n\n```python\n# Copy the file at the given path and its metadata to dest path.\n# If overwrite is not allowed and dest path exists, an OSError is raised.\n# More informations about kwargs supported options here:\n# https://docs.python.org/3/library/shutil.html#shutil.copy2\nfsutil.copy_file(path, dest, overwrite=False, **kwargs)\n```\n\n#### `create_dir`\n\n```python\n# Create directory at the given path.\n# If overwrite is not allowed and path exists, an OSError is raised.\nfsutil.create_dir(path, overwrite=False)\n```\n\n#### `create_file`\n\n```python\n# Create file with the specified content at the given path.\n# If overwrite is not allowed and path exists, an OSError is raised.\nfsutil.create_file(path, content=\"\", overwrite=False)\n```\n\n#### `create_tar_file`\n\n```python\n# Create tar file at path compressing directories/files listed in content_paths.\n# If overwrite is allowed and dest tar already exists, it will be overwritten.\nfsutil.create_tar_file(path, content_paths, overwrite=True, compression=\"gzip\")\n```\n\n#### `create_zip_file`\n\n```python\n# Create zip file at path compressing directories/files listed in content_paths.\n# If overwrite is allowed and dest zip already exists, it will be overwritten.\nfsutil.create_zip_file(path, content_paths, overwrite=True, compression=zipfile.ZIP_DEFLATED)\n```\n\n#### `delete_dir`\n\n```python\n# Alias for remove_dir.\nfsutil.delete_dir(path)\n```\n\n#### `delete_dir_content`\n\n```python\n# Alias for remove_dir_content.\nfsutil.delete_dir_content(path)\n```\n\n#### `delete_dirs`\n\n```python\n# Alias for remove_dirs.\nfsutil.delete_dirs(*paths)\n```\n\n#### `delete_file`\n\n```python\n# Alias for remove_file.\nfsutil.delete_file(path)\n```\n\n#### `delete_files`\n\n```python\n# Alias for remove_files.\nfsutil.delete_files(*paths)\n```\n\n#### `download_file`\n\n```python\n# Download a file from url to the given dirpath and return the filepath.\n# If dirpath is not provided, the file will be downloaded to a temp directory.\n# If filename is provided, the file will be named using filename.\n# It is possible to pass extra request options (eg. for authentication) using **kwargs.\nfilepath = fsutil.download_file(url, dirpath=None, filename=\"archive.zip\", chunk_size=8192, **kwargs)\n```\n\n#### `exists`\n\n```python\n# Check if a directory of a file exists at the given path.\nvalue = fsutil.exists(path)\n```\n\n#### `extract_tar_file`\n\n```python\n# Extract tar file at path to dest path.\n# If autodelete, the archive will be deleted after extraction.\n# If content_paths list is defined, only listed items will be extracted, otherwise all.\nfsutil.extract_tar_file(path, dest, content_paths=None, autodelete=False)\n```\n\n#### `extract_zip_file`\n\n```python\n# Extract zip file at path to dest path.\n# If autodelete, the archive will be deleted after extraction.\n# If content_paths list is defined, only listed items will be extracted, otherwise all.\nfsutil.extract_zip_file(path, dest, content_paths=None, autodelete=False)\n```\n\n#### `get_dir_creation_date`\n\n```python\n# Get the directory creation date.\ndate = fsutil.get_dir_creation_date(path)\n```\n\n#### `get_dir_creation_date_formatted`\n\n```python\n# Get the directory creation date formatted using the given format.\ndate_str = fsutil.get_dir_creation_date_formatted(path, format='%Y-%m-%d %H:%M:%S')\n```\n\n#### `get_dir_hash`\n\n```python\n# Get the hash of the directory at the given path using\n# the specified algorithm function (md5 by default).\nhash = fsutil.get_dir_hash(path, func=\"md5\")\n```\n\n#### `get_dir_last_modified_date`\n\n```python\n# Get the directory last modification date.\ndate = fsutil.get_dir_last_modified_date(path)\n```\n\n#### `get_dir_last_modified_date_formatted`\n\n```python\n# Get the directory last modification date formatted using the given format.\ndate_str = fsutil.get_dir_last_modified_date_formatted(path, format=\"%Y-%m-%d %H:%M:%S\")\n```\n\n#### `get_dir_size`\n\n```python\n# Get the directory size in bytes.\nsize = fsutil.get_dir_size(path)\n```\n\n#### `get_dir_size_formatted`\n\n```python\n# Get the directory size formatted using the right unit suffix.\nsize_str = fsutil.get_dir_size_formatted(path)\n```\n\n#### `get_file_basename`\n\n```python\n# Get the file basename from the given path/url.\nbasename = fsutil.get_file_basename(path)\n```\n\n#### `get_file_creation_date`\n\n```python\n# Get the file creation date.\ndate = fsutil.get_file_creation_date(path)\n```\n\n#### `get_file_creation_date_formatted`\n\n```python\n# Get the file creation date formatted using the given format.\ndate_str = fsutil.get_file_creation_date_formatted(path, format=\"%Y-%m-%d %H:%M:%S\")\n```\n\n#### `get_file_extension`\n\n```python\n# Get the file extension from the given path/url.\nextension = fsutil.get_file_extension(path)\n```\n\n#### `get_file_hash`\n\n```python\n# Get the hash of the file at the given path using\n# the specified algorithm function (md5 by default).\nfilehash = fsutil.get_file_hash(path, func=\"md5\")\n```\n\n#### `get_file_last_modified_date`\n\n```python\n# Get the file last modification date.\ndate = fsutil.get_file_last_modified_date(path)\n```\n\n#### `get_file_last_modified_date_formatted`\n\n```python\n# Get the file last modification date formatted using the given format.\ndate_str = fsutil.get_file_last_modified_date_formatted(path, format=\"%Y-%m-%d %H:%M:%S\")\n```\n\n#### `get_file_size`\n\n```python\n# Get the file size in bytes.\nsize = fsutil.get_file_size(path)\n```\n\n#### `get_file_size_formatted`\n\n```python\n# Get the file size formatted using the right unit suffix.\nsize_str = fsutil.get_file_size_formatted(path)\n```\n\n#### `get_filename`\n\n```python\n# Get the filename from the given path/url.\nfilename = fsutil.get_filename(path)\n```\n\n#### `get_parent_dir`\n\n```python\n# Get the parent directory for the given path going up N levels.\nparent_dir = fsutil.get_parent_dir(path, levels=1)\n```\n\n#### `get_permissions`\n\n```python\n# Get the file/directory permissions.\npermissions = fsutil.get_permissions(path)\n```\n\n#### `get_unique_name`\n\n```python\n# Get a unique name for a directory/file ath the given directory path.\nunique_name = fsutil.get_unique_name(path, prefix=\"\", suffix=\"\", extension=\"\", separator=\"-\")\n```\n\n#### `is_dir`\n\n```python\n# Determine whether the specified path represents an existing directory.\nvalue = fsutil.is_dir(path)\n```\n\n#### `is_empty`\n\n```python\n# Determine whether the specified path represents an empty directory or an empty file.\nvalue = fsutil.is_empty(path)\n```\n\n#### `is_empty_dir`\n\n```python\n# Determine whether the specified path represents an empty directory.\nvalue = fsutil.is_empty_dir(path)\n```\n\n#### `is_empty_file`\n\n```python\n# Determine whether the specified path represents an empty file.\nvalue = fsutil.is_empty_file(path)\n```\n\n#### `is_file`\n\n```python\n# Determine whether the specified path represents an existing file.\nvalue = fsutil.is_file(path)\n```\n\n#### `join_filename`\n\n```python\n# Create a filename joining the file basename and the extension.\nfilename = fsutil.join_filename(basename, extension)\n```\n\n#### `join_filepath`\n\n```python\n# Create a filepath joining the directory path and the filename.\nfilepath = fsutil.join_filepath(dirpath, filename)\n```\n\n#### `join_path`\n\n```python\n# Create a path joining path and paths.\n# If path is __file__ (or a .py file), the resulting path will be relative\n# to the directory path of the module in which it's used.\npath = fsutil.join_path(path, *paths)\n```\n\n#### `list_dirs`\n\n```python\n# List all directories contained at the given directory path.\ndirs = fsutil.list_dirs(path)\n```\n\n#### `list_files`\n\n```python\n# List all files contained at the given directory path.\nfiles = fsutil.list_files(path)\n```\n\n#### `make_dirs`\n\n```python\n# Create the directories needed to ensure that the given path exists.\n# If a file already exists at the given path an OSError is raised.\nfsutil.make_dirs(path)\n```\n\n#### `make_dirs_for_file`\n\n```python\n# Create the directories needed to ensure that the given path exists.\n# If a directory already exists at the given path an OSError is raised.\nfsutil.make_dirs_for_file(path)\n```\n\n#### `move_dir`\n\n```python\n# Move an existing dir from path to dest directory.\n# If overwrite is not allowed and dest path exists, an OSError is raised.\n# More informations about kwargs supported options here:\n# https://docs.python.org/3/library/shutil.html#shutil.move\nfsutil.move_dir(path, dest, overwrite=False, **kwargs)\n```\n\n#### `move_file`\n\n```python\n# Move an existing file from path to dest directory.\n# If overwrite is not allowed and dest path exists, an OSError is raised.\n# More informations about kwargs supported options here:\n# https://docs.python.org/3/library/shutil.html#shutil.move\nfsutil.move_file(path, dest, overwrite=False, **kwargs)\n```\n\n#### `read_file`\n\n```python\n# Read the content of the file at the given path using the specified encoding.\ncontent = fsutil.read_file(path, encoding=\"utf-8\")\n```\n\n#### `read_file_from_url`\n\n```python\n# Read the content of the file at the given url.\ncontent = fsutil.read_file_from_url(url, **kwargs)\n```\n\n#### `read_file_json`\n\n```python\n# Read and decode a json encoded file at the given path.\ndata = fsutil.read_file_json(path, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None)\n```\n\n#### `read_file_lines`\n\n```python\n# Read file content lines.\n# It is possible to specify the line indexes (negative indexes too),\n# very useful especially when reading large files.\ncontent = fsutil.read_file_lines(path, line_start=0, line_end=-1, strip_white=True, skip_empty=True, encoding=\"utf-8\")\n```\n\n#### `read_file_lines_count`\n\n```python\n# Read file lines count.\nlines_count = fsutil.read_file_lines_count(path)\n```\n\n#### `remove_dir`\n\n```python\n# Remove a directory at the given path and all its content.\n# If the directory is removed with success returns True, otherwise False.\n# More informations about kwargs supported options here:\n# https://docs.python.org/3/library/shutil.html#shutil.rmtree\nfsutil.remove_dir(path, **kwargs)\n```\n\n#### `remove_dir_content`\n\n```python\n# Removes all directory content (both sub-directories and files).\nfsutil.remove_dir_content(path)\n```\n\n#### `remove_dirs`\n\n```python\n# Remove multiple directories at the given paths and all their content.\nfsutil.remove_dirs(*paths)\n```\n\n#### `remove_file`\n\n```python\n# Remove a file at the given path.\n# If the file is removed with success returns True, otherwise False.\nfsutil.remove_file(path)\n```\n\n#### `remove_files`\n\n```python\n# Remove multiple files at the given paths.\nfsutil.remove_files(*paths)\n```\n\n#### `rename_dir`\n\n```python\n# Rename a directory with the given name.\n# If a directory or a file with the given name already exists, an OSError is raised.\nfsutil.rename_dir(path, name)\n```\n\n#### `rename_file`\n\n```python\n# Rename a file with the given name.\n# If a directory or a file with the given name already exists, an OSError is raised.\nfsutil.rename_file(path, name)\n```\n\n#### `rename_file_basename`\n\n```python\n# Rename a file basename with the given basename.\nfsutil.rename_file_basename(path, basename)\n```\n\n#### `rename_file_extension`\n\n```python\n# Rename a file extension with the given extension.\nfsutil.rename_file_extension(path, extension)\n```\n\n#### `replace_dir`\n\n```python\n# Replace directory at the specified path with the directory located at src.\n# If autodelete, the src directory will be removed at the end of the operation.\n# Optimized for large directories.\nfsutil.replace_dir(path, src, autodelete=False)\n```\n\n#### `replace_file`\n\n```python\n# Replace file at the specified path with the file located at src.\n# If autodelete, the src file will be removed at the end of the operation.\n# Optimized for large files.\nfsutil.replace_file(path, src, autodelete=False)\n```\n\n#### `search_dirs`\n\n```python\n# Search for directories at path matching the given pattern.\ndirs = fsutil.search_dirs(path, pattern=\"**/*\")\n```\n\n#### `search_files`\n\n```python\n# Search for files at path matching the given pattern.\nfiles = fsutil.search_files(path, pattern=\"**/*.*\")\n```\n\n#### `set_permissions`\n\n```python\n# Set the file/directory permissions.\nfsutil.set_permissions(path, 700)\n```\n\n#### `split_filename`\n\n```python\n# Split a filename and returns its basename and extension.\nbasename, extension = fsutil.split_filename(path)\n```\n\n#### `split_filepath`\n\n```python\n# Split a filename and returns its directory-path and filename.\ndirpath, filename = fsutil.split_filepath(path)\n```\n\n#### `split_path`\n\n```python\n# Split a path and returns its path-names.\npath_names = fsutil.split_path(path)\n```\n\n#### `transform_filepath`\n\n```python\n# Trasform a filepath by applying the provided optional changes.\nfilepath = fsutil.transform_filepath(path, dirpath=None, basename=lambda b: slugify(b), extension=\"webp\")\n```\n\n#### `write_file`\n\n```python\n# Write file with the specified content at the given path.\nfsutil.write_file(path, content, append=False, encoding=\"utf-8\", atomic=False)\n```\n\n#### `write_file_json`\n\n```python\n# Write a json file at the given path with the specified data encoded in json format.\nfsutil.write_file_json(path, data, encoding=\"utf-8\", atomic=False, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False)\n```\n\n## Testing\n```bash\n# clone repository\ngit clone https://github.com/fabiocaccamo/python-fsutil.git && cd python-fsutil\n\n# create virtualenv and activate it\npython -m venv venv && . venv/bin/activate\n\n# upgrade pip\npython -m pip install --upgrade pip\n\n# install requirements\npython -m pip install -r requirements.txt -r requirements-test.txt\n\n# install pre-commit to run formatters and linters\npre-commit install --install-hooks\n\n# run tests using tox\ntox\n\n# or run tests using unittest\npython -m unittest\n```\n\n## License\nReleased under [MIT License](LICENSE.txt).\n\n---\n\n## Supporting\n\n- :star: Star this project on [GitHub](https://github.com/fabiocaccamo/python-fsutil)\n- :octocat: Follow me on [GitHub](https://github.com/fabiocaccamo)\n- :blue_heart: Follow me on [Twitter](https://twitter.com/fabiocaccamo)\n- :moneybag: Sponsor me on [Github](https://github.com/sponsors/fabiocaccamo)\n\n## See also\n\n- [`python-benedict`](https://github.com/fabiocaccamo/python-benedict) - dict subclass with keylist/keypath support, I/O shortcuts (base64, csv, json, pickle, plist, query-string, toml, xml, yaml) and many utilities. \ud83d\udcd8\n\n- [`python-fontbro`](https://github.com/fabiocaccamo/python-fontbro) - friendly font operations on top of fontTools. \ud83e\udde2\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2020-present Fabio Caccamo  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "high-level file-system operations for lazy devs.",
    "version": "0.14.1",
    "project_urls": {
        "Documentation": "https://github.com/fabiocaccamo/python-fsutil#readme",
        "Download": "https://github.com/fabiocaccamo/python-fsutil/releases",
        "Funding": "https://github.com/sponsors/fabiocaccamo/",
        "Homepage": "https://github.com/fabiocaccamo/python-fsutil",
        "Issues": "https://github.com/fabiocaccamo/python-fsutil/issues",
        "Twitter": "https://twitter.com/fabiocaccamo"
    },
    "split_keywords": [
        "python",
        "file",
        "system",
        "util",
        "utils",
        "utility",
        "utilities",
        "dir",
        "directory",
        "path",
        "fs",
        "os",
        "shutil",
        "glob"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4fe6c8a2cdf34316bb96a7601ed47778818da266d4917bd9575d3a9ba46aedb7",
                "md5": "97fabbdb59038fcbfb9ed19b94c2b0a7",
                "sha256": "0d45e623f0f4403f674bdd8ae7aa7d24a4b3132ea45c65416bd2865e6b20b035"
            },
            "downloads": -1,
            "filename": "python_fsutil-0.14.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "97fabbdb59038fcbfb9ed19b94c2b0a7",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 16079,
            "upload_time": "2024-03-19T14:49:58",
            "upload_time_iso_8601": "2024-03-19T14:49:58.344259Z",
            "url": "https://files.pythonhosted.org/packages/4f/e6/c8a2cdf34316bb96a7601ed47778818da266d4917bd9575d3a9ba46aedb7/python_fsutil-0.14.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "de17e7426ac2d9bad932bd6f893781c66c042660d92bec57adb50f36dc7380d5",
                "md5": "edae6a3316fcd42989173c8eb3ec53d1",
                "sha256": "8fb204fa8059f37bdeee8a1dc0fff010170202ea47c4225ee71bb3c26f3997be"
            },
            "downloads": -1,
            "filename": "python-fsutil-0.14.1.tar.gz",
            "has_sig": false,
            "md5_digest": "edae6a3316fcd42989173c8eb3ec53d1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 26723,
            "upload_time": "2024-03-19T14:50:02",
            "upload_time_iso_8601": "2024-03-19T14:50:02.519031Z",
            "url": "https://files.pythonhosted.org/packages/de/17/e7426ac2d9bad932bd6f893781c66c042660d92bec57adb50f36dc7380d5/python-fsutil-0.14.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-19 14:50:02",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "fabiocaccamo",
    "github_project": "python-fsutil#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "tox": true,
    "lcname": "python-fsutil"
}
        
Elapsed time: 0.26787s