pathvalidate is a Python library to sanitize/validate a string such as filenames/file-paths/etc.
Project Links
Meta
Author: Tsuyoshi Hombashi
Requires Python: >=3.9
Classifiers
Development Status
- 5 - Production/Stable
Intended Audience
- Developers
- Information Technology
License
- OSI Approved :: MIT License
Operating System
- OS Independent
Programming Language
- Python :: 3
- Python :: 3.9
- Python :: 3.10
- Python :: 3.11
- Python :: 3.12
- Python :: 3.13
- Python :: 3 :: Only
- Python :: Implementation :: CPython
- Python :: Implementation :: PyPy
Topic
- Software Development :: Libraries
- Software Development :: Libraries :: Python Modules
- System :: Filesystems
- Text Processing
Typing
- Typed
Summary
pathvalidate is a Python library to sanitize/validate a string such as filenames/file-paths/etc.
Features
- Sanitize/Validate a string as a:
file name
file path
- Sanitize will do:
Remove invalid characters for a target platform
Replace reserved names for a target platform
Normalize
Remove unprintable characters
Argument validator/sanitizer for argparse and click
- Multi platform support:
Linux
Windows
macOS
POSIX: POSIX-compliant systems (Linux, macOS, etc.)
universal: platform independent
Multibyte character support
CLI tool
You can find this package’s command line interface tool at the pathvalidate-cli repository.
Examples
Sanitize a filename
- Sample Code:
from pathvalidate import sanitize_filename fname = "fi:l*e/p\"a?t>h|.t<xt" print(f"{fname} -> {sanitize_filename(fname)}\n") fname = "\0_a*b:c<d>e%f/(g)h+i_0.txt" print(f"{fname} -> {sanitize_filename(fname)}\n")- Output:
fi:l*e/p"a?t>h|.t<xt -> filepath.txt _a*b:c<d>e%f/(g)h+i_0.txt -> _abcde%f(g)h+i_0.txt
The default target platform is universal. i.e. the sanitized file name is valid for any platform.
Sanitize a filepath
- Sample Code:
from pathvalidate import sanitize_filepath fpath = "fi:l*e/p\"a?t>h|.t<xt" print(f"{fpath} -> {sanitize_filepath(fpath)}\n") fpath = "\0_a*b:c<d>e%f/(g)h+i_0.txt" print(f"{fpath} -> {sanitize_filepath(fpath)}\n")- Output:
fi:l*e/p"a?t>h|.t<xt -> file/path.txt _a*b:c<d>e%f/(g)h+i_0.txt -> _abcde%f/(g)h+i_0.txt
Validate a filename
- Sample Code:
import sys from pathvalidate import ValidationError, validate_filename try: validate_filename("fi:l*e/p\"a?t>h|.t<xt") except ValidationError as e: print(f"{e}\n", file=sys.stderr) try: validate_filename("COM1") except ValidationError as e: print(f"{e}\n", file=sys.stderr)- Output:
[PV1100] invalid characters found: platform=universal, description=invalids=('/'), value='fi:l*e/p"a?t>h|.t<xt' [PV1002] found a reserved name by a platform: 'COM1' is a reserved name, platform=universal, reusable_name=False
Check a filename
- Sample Code:
from pathvalidate import is_valid_filename, sanitize_filename fname = "fi:l*e/p\"a?t>h|.t<xt" print(f"is_valid_filename('{fname}') return {is_valid_filename(fname)}\n") sanitized_fname = sanitize_filename(fname) print(f"is_valid_filename('{sanitized_fname}') return {is_valid_filename(sanitized_fname)}\n")- Output:
is_valid_filename('fi:l*e/p"a?t>h|.t<xt') return False is_valid_filename('filepath.txt') return True
filename/filepath validator for argparse
- Sample Code:
from argparse import ArgumentParser from pathvalidate.argparse import validate_filename_arg, validate_filepath_arg parser = ArgumentParser() parser.add_argument("--filename", type=validate_filename_arg) parser.add_argument("--filepath", type=validate_filepath_arg) options = parser.parse_args() if options.filename: print(f"filename: {options.filename}") if options.filepath: print(f"filepath: {options.filepath}")- Output:
$ ./examples/argparse_validate.py --filename eg filename: eg $ ./examples/argparse_validate.py --filename e?g usage: argparse_validate.py [-h] [--filename FILENAME] [--filepath FILEPATH] argparse_validate.py: error: argument --filename: [PV1100] invalid characters found: invalids=(':'), value='e:g', platform=Windows
filename/filepath sanitizer for argparse
- Sample Code:
from argparse import ArgumentParser from pathvalidate.argparse import sanitize_filename_arg, sanitize_filepath_arg parser = ArgumentParser() parser.add_argument("--filename", type=sanitize_filename_arg) parser.add_argument("--filepath", type=sanitize_filepath_arg) options = parser.parse_args() if options.filename: print("filename: {}".format(options.filename)) if options.filepath: print("filepath: {}".format(options.filepath))- Output:
$ ./examples/argparse_sanitize.py --filename e/g filename: eg
filename/filepath validator for click
- Sample Code:
import click from pathvalidate.click import validate_filename_arg, validate_filepath_arg @click.command() @click.option("--filename", callback=validate_filename_arg) @click.option("--filepath", callback=validate_filepath_arg) def cli(filename: str, filepath: str) -> None: if filename: click.echo(f"filename: {filename}") if filepath: click.echo(f"filepath: {filepath}") if __name__ == "__main__": cli()- Output:
$ ./examples/click_validate.py --filename ab filename: ab $ ./examples/click_validate.py --filepath e?g Usage: click_validate.py [OPTIONS] Try 'click_validate.py --help' for help. Error: Invalid value for '--filename': [PV1100] invalid characters found: invalids=('?'), value='e?g', platform=Windows
filename/filepath sanitizer for click
- Sample Code:
import click from pathvalidate.click import sanitize_filename_arg, sanitize_filepath_arg @click.command() @click.option("--filename", callback=sanitize_filename_arg) @click.option("--filepath", callback=sanitize_filepath_arg) def cli(filename, filepath): if filename: click.echo(f"filename: {filename}") if filepath: click.echo(f"filepath: {filepath}") if __name__ == "__main__": cli()- Output:
$ ./examples/click_sanitize.py --filename a/b filename: ab
For more information
More examples can be found at https://pathvalidate.rtfd.io/en/latest/pages/examples/index.html
Installation
Installation: pip
pip install pathvalidate
Installation: conda
conda install conda-forge::pathvalidate
Installation: apt
sudo add-apt-repository ppa:thombashi/ppa sudo apt update sudo apt install python3-pathvalidate
Dependencies
Python 3.9+ no external dependencies.
Documentation
Sponsors
3.3.1
Jun 15, 2025
3.3.0
Jun 15, 2025
3.2.3
Jan 03, 2025
3.2.2
Jan 01, 2025
3.2.1
Aug 23, 2024
3.2.0
Sep 17, 2023
3.1.0
Jul 16, 2023
3.0.0
May 22, 2023
2.5.2
Aug 20, 2022
2.5.1
Jul 31, 2022
2.5.0
Sep 26, 2021
2.4.1
Apr 03, 2021
2.4.0
Mar 21, 2021
2.3.2
Jan 03, 2021
2.3.1
Dec 13, 2020
2.3.0
May 03, 2020
2.2.2
Mar 28, 2020
2.2.1
Mar 20, 2020
2.2.0
Feb 12, 2020
2.1.0
Feb 01, 2020
2.0.1
Jan 13, 2020
2.0.0
Jan 13, 2020
1.1.1
Jan 04, 2020
1.1.0
Jan 04, 2020
1.0.0
Jan 03, 2020
0.29.1
Jan 02, 2020
0.29.0
Jun 16, 2019
0.28.2
May 18, 2019
0.28.1
May 11, 2019
0.28.0
May 01, 2019
0.27.2
Apr 29, 2019
0.27.1
Apr 29, 2019
0.27.0
Apr 29, 2019
0.26.0
Mar 15, 2019
0.25.0
Mar 14, 2019
0.24.1
Feb 12, 2019
0.24.0
Feb 03, 2019
0.23.1
Jan 13, 2019
0.23.0
Jan 06, 2019
0.22.0
Dec 23, 2018
0.21.4
Nov 24, 2018
0.21.3
Oct 01, 2018
0.21.2
Aug 19, 2018
0.21.1
Jul 28, 2018
0.20.0
Jul 13, 2018
0.19.0
Jul 08, 2018
0.18.0
Jul 07, 2018
0.17.3
May 27, 2018
0.17.2
May 27, 2018
0.17.1
Apr 21, 2018
0.17.0
Apr 21, 2018
0.16.3
Feb 18, 2018
0.16.2
Oct 01, 2017
0.16.1
Aug 13, 2017
0.16.0
Jul 01, 2017
0.15.0
Mar 18, 2017
0.14.1
Feb 24, 2017
0.14.0
Feb 11, 2017
0.13.0
Jan 03, 2017
0.12.1
Dec 28, 2016
0.12.0
Dec 28, 2016
0.11.0
Dec 25, 2016
0.10.1
Dec 24, 2016
0.10.0
Dec 23, 2016
0.9.4
Dec 10, 2016
0.9.3
Nov 20, 2016
0.9.2
Nov 20, 2016
0.9.1
Nov 17, 2016
0.9.0
Nov 13, 2016
0.8.3
Oct 29, 2016
0.8.2
Oct 27, 2016
0.8.1
Oct 22, 2016
0.8.0
Oct 22, 2016
0.7.1
Sep 19, 2016
0.6.0
Sep 19, 2016
0.5.2
Aug 20, 2016
0.5.1
Jul 23, 2016
0.5.0
Jul 17, 2016
0.4.2
Jun 19, 2016
0.4.1
May 29, 2016
0.4.0
May 28, 2016
0.3.0
May 22, 2016
0.2.0
May 21, 2016
0.1.0
Mar 24, 2016