From 791ad623984af2a67524cfd854e623be28f1fab1 Mon Sep 17 00:00:00 2001 From: Holger Frey Date: Fri, 21 Oct 2022 10:29:56 +0200 Subject: [PATCH] cleaned up the cli interface I was annoyed by the cli interface quite some time. It should now adhere more to what is expected from a POSIX cli --- README.md | 13 +++--- pyproject.toml | 4 +- src/sensospot_parser/__init__.py | 78 +++++++++----------------------- 3 files changed, 30 insertions(+), 65 deletions(-) diff --git a/README.md b/README.md index 502838e..f2a7ee0 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ There is no affiliation on my side regarding Sensovation or Miltenyi, I just use raw_data = sensospot_parser.parse_folder() sorted(raw_data.columns) == [ - 'Analysis.Datetime', 'Analysis.Image', 'Analysis.Name', + 'Analysis.Datetime', 'Analysis.Image', 'Analysis.Name', 'Bkg.Area', 'Bkg.Mean', 'Bkg.Median', 'Bkg.StdDev', 'Bkg.Sum', 'Exposure.Id', 'Parameters.Channel', 'Parameters.Time', @@ -54,18 +54,17 @@ There is a `columns` module available, providing constans that define the column ## CLI -For the (propably) most important function, there is even a cli command +For the (propably) most important function, there is a cli command + ```sh -Usage: sensospot_parse [OPTIONS] SOURCE +Usage: sensospot_parse [OPTIONS] SOURCES Arguments: - SOURCE: Folder with Sensospot measurement + SOURCES: One or more folders with Sensospot measurements Options: - -o, --outfile TEXT Output file name, use a dash '-' for stdout, default: - 'collected_data.csv' + -o, --output FILE Output file path, defaults to 'collected_data.csv' -q, --quiet Ignore Sanity Check - -r, --recurse Recurse into folders one level down --help Show this message and exit. ``` diff --git a/pyproject.toml b/pyproject.toml index 55072e4..c295a30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,12 +15,14 @@ authors = [ # see https://pypi.org/classifiers/ classifiers = [ - "Development Status :: 2 - Pre-Alpha", + "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", + "Intended Audience :: Science/Research", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3 :: Only", + "Topic :: Scientific/Engineering", "License :: Freely Distributable", ] diff --git a/src/sensospot_parser/__init__.py b/src/sensospot_parser/__init__.py index 19fb897..177a645 100644 --- a/src/sensospot_parser/__init__.py +++ b/src/sensospot_parser/__init__.py @@ -3,10 +3,10 @@ Parsing the numerical output from Sensovations Sensospot image analysis. """ -__version__ = "0.9.1" +__version__ = "1.0.0" -from pathlib import Path +import pathlib import click import pandas @@ -19,23 +19,23 @@ DEFAULT_OUTPUT_FILENAME = "collected_data.csv" @click.command() @click.argument( - "source", + "sources", type=click.Path( exists=True, file_okay=False, dir_okay=True, readable=True, - writable=True, ), + required=True, + nargs=-1, ) @click.option( "-o", - "--outfile", - default=DEFAULT_OUTPUT_FILENAME, - help=( - "Output file name, use a dash '-' for stdout, " - f"default: '{DEFAULT_OUTPUT_FILENAME}'" - ), + "--output", + is_flag=False, + flag_value=DEFAULT_OUTPUT_FILENAME, + type=click.Path(exists=False, dir_okay=False), + help=f"Output file path, defaults to '{DEFAULT_OUTPUT_FILENAME}'", ) @click.option( "-q", @@ -44,54 +44,18 @@ DEFAULT_OUTPUT_FILENAME = "collected_data.csv" default=False, help="Ignore Sanity Check", ) -@click.option( - "-r", - "--recurse", - is_flag=True, - default=False, - help="Recurse into folders one level down", -) -def main(source, outfile, quiet=False, recurse=False): - if recurse: - _parse_recursive(source, outfile, quiet) - else: - _parse_one_folder(source, outfile, quiet) +def main(sources, output, quiet=False): + """Parses the measurement results of the Sensospot reader + The resulting output is either echoed to stdout or saved to a file. -def _output(data, folder, outfile): - """output a datafarme to stdout or csv file - - data: the pandas dataframe - folder: the folder to save the file to - outfile: the name of the outfile, '-' will output to stdout """ - if outfile.strip() == "-": - click.echo(data.to_csv(None, sep="\t", index=False)) - else: - csv_file = Path(folder) / outfile - data.to_csv(csv_file, sep="\t", index=False) - - -def _parse_one_folder(source, outfile, quiet): - """parses the data of one folder""" - source_path = Path(source) - # read the raw data of a folder - raw_data = parse_folder(source_path, quiet=quiet) - _output(raw_data, source_path, outfile) - return raw_data - - -def _parse_recursive(source, outfile, quiet): - """parses all folders one level down and collects the data""" - child_outfile = DEFAULT_OUTPUT_FILENAME - source_path = Path(source) - folders = (i for i in source_path.iterdir() if i.is_dir()) - non_hidden = (i for i in folders if not i.name.startswith(".")) - collection = ( - _parse_one_folder(f, child_outfile, quiet) for f in non_hidden + paths = (pathlib.Path(source) for source in sources) + collection = (parse_folder(source) for source in paths) + result = pandas.concat(collection, ignore_index=True).to_csv( + output, sep="\t", index=False ) - try: - collected = pandas.concat(collection, ignore_index=True) - _output(collected.reset_index(), source_path, outfile) - except ValueError as e: - print(str(e)) + # if 'output' is None, the call to 'to_csv()' returns the csv as text + # if 'output' is not None, 'to_csv()' writes to the file and returns None + if result: + click.echo(result)