cli.py 5.64 KB
Newer Older
Huste, Tobias (FWCC) - 111645's avatar
Huste, Tobias (FWCC) - 111645 committed
1
#!/usr/bin/env python
mdolling-gfz's avatar
add sqa    
mdolling-gfz committed
2

3
# hifis-surveyval
mdolling-gfz's avatar
add sqa    
mdolling-gfz committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Framework to help developing analysis scripts for the HIFIS Software survey.
#
# SPDX-FileCopyrightText: 2021 HIFIS Software <support@hifis.net>
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

Huste, Tobias (FWCC) - 111645's avatar
Huste, Tobias (FWCC) - 111645 committed
23
24
25
26
27
# -*- coding: utf-8 -*-

"""
This is the entry point for the command-line interface (CLI) application.

28
It can be used as a handy facility for running the task from a command line.
Huste, Tobias (FWCC) - 111645's avatar
Huste, Tobias (FWCC) - 111645 committed
29
30
31
32

.. note::

    To learn more about Click visit the
33
    `project website <http://click.pocoo.org/7/>`_.
34
35
    There is also a very helpful `tutorial video
    <https://www.youtube.com/watch?v=kNke39OZ2k0>`_.
Huste, Tobias (FWCC) - 111645's avatar
Huste, Tobias (FWCC) - 111645 committed
36
37
38
39

    To learn more about running Luigi, visit the Luigi project's
    `Read-The-Docs <http://luigi.readthedocs.io/en/stable/>`_ page.

40
.. currentmodule:: hifis_surveyval.cli
Huste, Tobias (FWCC) - 111645's avatar
Huste, Tobias (FWCC) - 111645 committed
41
42
43
.. moduleauthor:: HIFIS Software <software@hifis.net>
"""
import logging
44
import pathlib
45
from csv import reader
46

Huste, Tobias (FWCC) - 111645's avatar
Huste, Tobias (FWCC) - 111645 committed
47
import click
48
import pkg_resources
49
import yaml
50

51
52
from hifis_surveyval.core import util
from hifis_surveyval.core.dispatch import Dispatcher
53
from hifis_surveyval.core.preprocess import Preprocessor
54
from hifis_surveyval.core.settings import Settings
55
from hifis_surveyval.data_container import DataContainer
56
from hifis_surveyval.hifis_surveyval import HIFISSurveyval
57

58
settings: Settings = Settings()
Huste, Tobias (FWCC) - 111645's avatar
Huste, Tobias (FWCC) - 111645 committed
59
60
61


@click.group()
mdolling-gfz's avatar
mdolling-gfz committed
62
63
64
65
66
67
68
@click.option(
    "--verbose",
    "-v",
    count=True,
    default=0,
    show_default=True,
    help="Enable verbose output. "
69
    "Increase verbosity by setting this option up to 3 times.",
mdolling-gfz's avatar
mdolling-gfz committed
70
)
71
def cli(verbose: int) -> None:
72
73
74
75
76
77
    """
    Analyze a given CSV file with a set of independent python scripts.

    Args:
        verbose (int): Indicates the verbosity level on the CLI.
    """
78
79
80
    # NOTE that click takes above documentation for generating help text
    # Thus the documentation refers to the application per se and not the
    # function (as it should)
81
82
83
84
85
86
87
88
89
90

    settings.set_verbosity(verbose)
    if not settings.VERBOSITY == logging.ERROR:
        click.echo(
            click.style(
                f"Verbose logging is enabled. "
                f"(LEVEL={logging.getLogger().getEffectiveLevel()})",
                fg="yellow",
            )
        )
Huste, Tobias (FWCC) - 111645's avatar
Huste, Tobias (FWCC) - 111645 committed
91
92
93


@cli.command()
94
def version() -> None:
Huste, Tobias (FWCC) - 111645's avatar
Huste, Tobias (FWCC) - 111645 committed
95
    """Get the library version."""
96
97
    version_string: str = pkg_resources.require("hifis_surveyval")[0].version
    click.echo(click.style(f"{version_string}", bold=True))
98
99


100
@cli.command()
101
102
103
104
105
106
@click.option(
    "--config",
    "-c",
    is_flag=True,
    show_default=True,
    help="Create a default config as file. "
107
    "Overwrites any existing configuration file.",
108
109
110
111
112
113
114
)
@click.option(
    "--script",
    "-s",
    is_flag=True,
    show_default=True,
    help="Create an example script in the given script folder. "
115
    "Overwrites any existing example script file.",
116
)
117
118
119
120
121
122
123
124
125
@click.option(
    "--preprocess",
    "-p",
    is_flag=True,
    show_default=True,
    help="Create an empty preprocessing script in the given location. "
    "Overwrites any existing preprocessing script.",
)
def init(config: bool, script: bool, preprocess: bool) -> None:
126
    """
127
128
129
    Create a configuration file and an example script in the default locations.

    It will overwrite any existing configuration and example file.
130

131
132
133
134
    Args:
        config (bool): Indicates whether to create a configuration file.
        script (bool): Indicates whether to create an example analysis
                       script.
135
    """
136
    if not config and not script and not preprocess:
137
138
        config = True
        script = True
139
        preprocess = True
140
141
142
143
144

    if config:
        settings.create_default_config_file()
    if script:
        util.create_example_script(settings)
145
146
    if preprocess:
        util.create_preprocessing_script(settings)
147
148


149
150
151
152
@click.argument(
    "survey_data",
    type=click.Path(exists=True, dir_okay=False, path_type=pathlib.Path),
)
153
@cli.command()
154
def analyze(survey_data: click.Path) -> None:
155
    """
156
    Read the survey data and run all defined analysis scripts.
157

158
    The metadata are read from a file specified in the settings.
159

160
    Args:
161
        survey_data (click.File): File that contains all data for the analysis.
162
163
    """
    settings.load_config_file()
164

165
    surveyval: HIFISSurveyval = HIFISSurveyval(settings=settings)
166
    raw_data: DataContainer = DataContainer()
167
    logging.info(f"Analyzing file {survey_data.name}")
168

169
170
171
172
173
    # Load the metadata
    logging.info(f"Attempt to load metadata from {settings.METADATA}")

    with settings.METADATA.open(mode="r") as metadata_io_stream:
        metadata_yaml = yaml.safe_load(metadata_io_stream)
174
        raw_data.load_metadata(metadata_yaml)
175
176
177
178

    #  Load the actual survey data
    with survey_data.open(mode="r") as data_io_stream:
        csv_reader = reader(data_io_stream)
179
180
181
182
183
184
        raw_data.load_survey_data(csv_data=list(csv_reader))

    # preproces the data
    preprocessed_data: DataContainer = Preprocessor.preprocess(
        settings=settings, data=raw_data
    )
185

186
187
188
189
    # run analysis scripts
    dispatcher: Dispatcher = Dispatcher(
        surveyval=surveyval, data=preprocessed_data
    )
190
191
    dispatcher.discover()
    dispatcher.load_all_modules()