diff --git a/README.md b/README.md index db63ab8..af0d56d 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,11 @@ from ioutil import File data = [{'a': 1, 'b': 2}, {'a': 3, 'b': 4}] path = '.../file.csv' -csv = File.getinstance('csv') -csv.write(data=data, path=path) # to write csv -csv.read(path=path) # to read csv +File.write(data=data, path=path) # to write file +File.read(path=path) # to read file ``` -### Command Line (not recommended) +### Command Line (not recommended) To write a text file. diff --git a/ioutil/__init__.py b/ioutil/__init__.py index 684612e..a7f8963 100644 --- a/ioutil/__init__.py +++ b/ioutil/__init__.py @@ -1,6 +1,8 @@ """to read and write files""" - -from typing import Literal +from __future__ import annotations +import os +from srutil import util +from typing import Literal, Any, AnyStr from ioutil._file import _File from ioutil._csv import Csv @@ -9,14 +11,42 @@ from ioutil._json import Json from ioutil._parquet import Parquet +_FS = Literal["csv", "json", "parquet", "toml", "text"] + class File: @staticmethod - def getinstance(_format: Literal["csv", "json", "parquet", "toml", "text"]) -> _File: - _instance = {"csv": Csv, "json": Json, "parquet": Parquet, "toml": TOML, "text": Text}.get(_format) - if not _instance: - _instance = _File - return _instance() + def __getinstance(path: AnyStr | os.PathLike = None, _format: _FS = None) -> _File: + if path and not _format: + ext = list(os.path.splitext(path)).pop() + _format = {".csv": "csv", ".json": "json", ".parquet": ".parquet", ".toml": "toml", ".txt": "text"}.get(ext) + if _format: + _instance = {"csv": Csv, "json": Json, "parquet": Parquet, "toml": TOML, "text": Text}.get(_format) + return _instance() + else: + raise ValueError("Invalid file type") + + @staticmethod + def __remove_unwanted_params(f: _File, params: dict) -> dict: + method_list = {'read': f.read, 'write': f.write} + params_of_method = util.paramsofmethod(method_list.get(util.whocalledme())).keys() + new_params = dict() + for key, value in params.items(): + if key in params_of_method: + new_params.setdefault(key, value) + return new_params + + @staticmethod + def read(path: AnyStr | os.PathLike, _format: _FS = None, **kwargs) -> Any: + f = File.__getinstance(path=path, _format=_format) + kwargs = File.__remove_unwanted_params(f, kwargs) + return f.read(path=path, **kwargs) + + @staticmethod + def write(data, path: AnyStr | os.PathLike, _format: _FS = None, **kwargs) -> bool: + f = File.__getinstance(path=path, _format=_format) + kwargs = File.__remove_unwanted_params(f, kwargs) + return f.write(data=data, path=path, **kwargs) csv = Csv() @@ -26,7 +56,7 @@ def getinstance(_format: Literal["csv", "json", "parquet", "toml", "text"]) -> _ toml = TOML() __author__ = 'srg' -__version__ = '1.0.2' +__version__ = '1.0.3' __all__ = [ 'File', diff --git a/ioutil/__main__.py b/ioutil/__main__.py index f6109bb..3ae625d 100644 --- a/ioutil/__main__.py +++ b/ioutil/__main__.py @@ -5,10 +5,9 @@ import sys import argparse from srutil import util -from typing import AnyStr, Any +from typing import Any -from . import File, __version__, __package__, __all__ -from ._file import _File +from . import File, __version__, __package__ def _epilog() -> str: @@ -33,11 +32,12 @@ def get_argument() -> argparse.Namespace: parser.add_argument_group(group) options = parser.parse_args() if not options.format: - _format = list(os.path.splitext(options.path)).pop().lstrip('.') - if _format != 'File' and _format not in __all__: + _ext = list(os.path.splitext(options.path)).pop() + _format = {".csv": "csv", ".json": "json", ".parquet": ".parquet", ".toml": "toml", ".txt": "text"} + if _ext not in _format: parser.error("the following arguments are required: -f/--format") else: - options.format = _format + options.format = _format.get(_ext) if not options.read and not options.write: parser.error("one of the following arguments are required: -r/--read or -w/--write") if options.read and options.write: @@ -47,41 +47,18 @@ def get_argument() -> argparse.Namespace: return options -def _remove_unwanted_params(f: _File, params: dict) -> dict: - method_list = {'read': f.read, 'write': f.write} - params_of_method = util.paramsofmethod(method_list.get(util.whocalledme())).keys() - new_params = dict() - for key, value in params.items(): - if key in params_of_method: - new_params.setdefault(key, value) - return new_params - - def _get_data(_data: str, _format: str) -> Any: return _data if _format == 'text' else ast.literal_eval(_data) -def read(f: _File, path: AnyStr | os.PathLike, **kwargs) -> None: - kwargs = _remove_unwanted_params(f, kwargs) - data = f.read(path=path, **kwargs) - print(data) - - -def write(f: _File, data, path: AnyStr | os.PathLike, **kwargs) -> None: - kwargs = _remove_unwanted_params(f, kwargs) - status = f.write(data=data, path=path, **kwargs) - print(status) - - def main(): options = get_argument() - f = File.getinstance(options.format) - mode = options.mode if options.mode else 'w' if options.write else 'r' + mode = options.mode if options.mode else None if options.read: - read(f, options.path, mode=mode, _rfv=options.rfv) + print(File.read(options.path, _format=options.format, mode=mode, _rfv=options.rfv)) elif options.write: data = _get_data(options.data, options.format) - write(f, data, options.path, mode=mode) + print(File.write(data, options.path, _format=options.format, mode=mode)) if __name__ == "__main__": diff --git a/pyproject.toml b/pyproject.toml index aa107bd..cfc5091 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "ioutil" -version = "1.0.2" +version = "1.0.3" description = "To read and write files." readme = "README.md" requires-python = ">=3.6"