Passed
Push — main ( ddff4b...7b3fbc )
by Douglas
04:33
created

mandos.entries.common_args.Arg.out_path()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nop 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
"""
2
Common argument processing and arguments for Typer.
3
"""
4
5
from inspect import cleandoc
6
from pathlib import Path
7
from typing import Mapping, Optional, TypeVar, Sequence
0 ignored issues
show
Unused Code introduced by
Unused Sequence imported from typing
Loading history...
Unused Code introduced by
Unused Mapping imported from typing
Loading history...
8
9
import typer
0 ignored issues
show
introduced by
Unable to import 'typer'
Loading history...
10
from mandos.model.settings import MANDOS_SETTINGS
11
12
T = TypeVar("T", covariant=True)
0 ignored issues
show
Coding Style Naming introduced by
Class name "T" doesn't conform to PascalCase naming style ('[^\\W\\da-z][^\\W_]+$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
13
14
15
class _Args:
16
    @staticmethod
17
    def _arg(doc: str, *names, default: Optional[T] = None, req: bool = False, **kwargs):
18
        kwargs = dict(
19
            help=cleandoc(doc),
20
            **kwargs,
21
            allow_dash=True,
22
        )
23
        return typer.Argument(default, **kwargs) if req else typer.Option(default, *names, **kwargs)
24
25
    @staticmethod
26
    def _path(
27
        doc: str, *names, default: Optional[str], f: bool, d: bool, out: bool, req: bool, **kwargs
0 ignored issues
show
Coding Style Naming introduced by
Variable name "f" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
Coding Style Naming introduced by
Variable name "d" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
28
    ):
29
        # if it's None, we're going to have a special default set afterward, so we'll explain it in the doc
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
30
        if out and default is None:
31
            kwargs = dict(show_default=True, **kwargs)
32
        kwargs = {
33
            **dict(
34
                exists=not out,
35
                dir_okay=d,
36
                file_okay=f,
37
                readable=out,
38
                writable=not out,
39
            ),
40
            **kwargs,
41
        }
42
        return _Args._arg(doc, *names, default=default, req=req, **kwargs)
43
44
45
class Arg(_Args):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
46
    @staticmethod
47
    def out_file(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
48
        return _Args._path(
49
            doc, *names, default=default, f=True, d=False, out=True, req=True, **kwargs
50
        )
51
52
    @staticmethod
53
    def out_dir(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
54
        return _Args._path(
55
            doc, *names, default=default, f=True, d=True, out=True, req=True, **kwargs
56
        )
57
58
    @staticmethod
59
    def out_path(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
60
        return _Args._path(
61
            doc, *names, default=default, f=True, d=True, out=False, req=True, **kwargs
62
        )
63
64
    @staticmethod
65
    def in_file(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
66
        return _Args._path(
67
            doc, *names, default=default, f=True, d=False, out=False, req=True, **kwargs
68
        )
69
70
    @staticmethod
71
    def in_dir(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
72
        return _Args._path(
73
            doc, *names, default=default, f=False, d=True, out=False, req=True, **kwargs
74
        )
75
76
    @staticmethod
77
    def in_path(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
78
        return _Args._path(
79
            doc, *names, default=default, f=True, d=True, out=False, req=True, **kwargs
80
        )
81
82
    @staticmethod
83
    def x(doc: str, *names, default: Optional[T] = None, **kwargs):
0 ignored issues
show
Coding Style Naming introduced by
Method name "x" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
84
        return _Args._arg(doc, *names, default=default, req=True, **kwargs)
85
86
87
class Opt(_Args):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
88
    @staticmethod
89
    def out_file(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
90
        return _Args._path(
91
            doc, *names, default=default, f=True, d=False, out=True, req=False, **kwargs
92
        )
93
94
    @staticmethod
95
    def out_dir(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
96
        return _Args._path(
97
            doc, *names, default=default, f=True, d=True, out=True, req=False, **kwargs
98
        )
99
100
    @staticmethod
101
    def out_path(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
102
        return _Args._path(
103
            doc,
104
            *names,
105
            default=default,
106
            f=True,
107
            d=True,
108
            out=False,
109
            req=False,
110
            exists=False,
111
            **kwargs,
112
        )
113
114
    @staticmethod
115
    def in_file(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
116
        return _Args._path(
117
            doc, *names, default=default, f=True, d=False, out=False, req=False, **kwargs
118
        )
119
120
    @staticmethod
121
    def in_dir(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
122
        return _Args._path(
123
            doc, *names, default=default, f=False, d=True, out=False, req=False, **kwargs
124
        )
125
126
    @staticmethod
127
    def in_path(doc: str, *names, default: Optional[str] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
128
        return _Args._path(
129
            doc,
130
            *names,
131
            default=default,
132
            f=True,
133
            d=True,
134
            out=False,
135
            req=False,
136
            exists=False,
137
            **kwargs,
138
        )
139
140
    @staticmethod
141
    def val(doc: str, *names, default: Optional[T] = None, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
142
        return _Args._arg(doc, *names, default=default, req=False, **kwargs)
143
144
    @staticmethod
145
    def flag(doc: str, *names, **kwargs):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
146
        return _Args._arg(doc, *names, default=False, req=False, **kwargs)
147
148
149
class CommonArgs:
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
150
151
    output_formats = r"""
152
        The filename extension must be one of: .feather; .snappy/.parquet;
153
        .csv, .tsv, .tab, .json (with optional .gz/.bz2/.zip/.xz);
154
        Feather (.feather) and Parquet (.snappy) are recommended.
155
        If only a filename suffix is provided, only sets the format and filename suffix.
156
        If no extension is provided, interprets that path as a directory and uses the default format (Feather).
157
158
        Will fail if the file exists, unless `--replace` is passed.
159
    """
160
161
    input_formats = r"""
162
        The filename extension must be one of: .feather; .snappy/.parquet;
163
        .csv, .tsv, .tab (with optional .gz/.bz2/.zip/.xz);
164
        Feather (.feather) and Parquet (.snappy) are recommended formats.
165
        (Some other formats, such as .json or .h5, may be permitted but are discouraged.)
166
    """
167
168
    file_input = Arg.in_file("The path to a file output by `:concat` or `:search`.", "input")
169
170
    compounds = Arg.in_file(
171
        """
172
        The path to the input file.
173
        One of:
174
175
          (A) *.txt, *.lines, or *.list (optionally with .gz/.zip/.xz/.bz2)), with one InChI Key per line;
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
176
177
          (B) A *.csv, *.tsv, *.tab file (or .gz/.zip/.xz/.bz2 variant) with a column called 'inchikey'; OR
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
178
179
          (C) An Arrow *.feather file or Parquet *.snappy file with a column called 'inchikey'
180
        """
181
    )
182
183
    dir_input = Arg.in_dir(
184
        rf"""
185
        The path to a directory containing files output from mandos search.
186
187
        {input_formats}
188
        Note that *all* matching files will be included.
189
        Provide ``--exclude`` if needed.
190
        """
191
    )
192
193
    to_single = Opt.out_file(
194
        rf"""
195
        The path to the output file.
196
197
        {output_formats}
198
199
        [default: <input-path>/{...}.{MANDOS_SETTINGS.default_table_suffix}.gz]
200
        """,
201
        "--to",
202
    )
203
204
    input_matrix: Path = Arg.in_file(
205
        rf"""
206
        The path to a similarity matrix file to write to.
207
208
        {input_formats}
209
        .txt/.txt.gz/etc. is assumed to be whitespace-delimited.
210
        TCompounds can be referenced by InChI Key or compound ID (matching what you provided for the search).
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (109/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
211
        The set of compounds here must exactly match the set of compounds in the input files.
212
        For Excel and text formats, the first row and the first column (header and index) indicate the compounds.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (113/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
213
214
        Values must be floating-point.
215
        """
216
    )
217
    replace: bool = typer.Option(
218
        False, help="Replace output file(s) if they exist. See also: --skip"
219
    )
220
221
    taxa = Opt.val(
222
        r"""
223
        The IDs or names of UniProt taxa, comma-separated.
224
        Taxon names and common names can be used for vertebrate species (where available).
225
226
        This can have a significant effect on searches. See the docs for more info.
227
228
        [default: 7742] (Euteleostomi)
229
        """,
230
        "--taxa",
231
        "7742",
232
        show_default=False,
233
    )
234
235
    seed = Opt.val(r"A random seed (integer).", "--seed", default=0)
236
237
    n_samples = Opt.val(
238
        "Number of bootstrap samples (positive integer).",
239
        "--samples",
240
        min=1,
241
        default=2000,
242
    )
243
244
    exclude = Opt.val("A glob pattern matching input filenames to ignore.")
245
246
    verbose: bool = Opt.flag(
247
        r"Configure logger to output INFO (use ``--quiet`` for less info)",
248
        "-v",
249
        "--verbose",
250
    )
251
252
    quiet: bool = Opt.flag(
253
        r"Configure logger to output only ERROR (use ``--verbose`` for more info)",
254
        "-q",
255
        "--quiet",
256
    )
257
258
    in_cache: bool = Opt.flag(
259
        r"Do not download any data and fail if needed data is not cached.",
260
        hidden=True,
261
    )
262
263
    as_of: Optional[str] = Opt.val(
264
        f"""
265
        Restrict to data that was cached as of some date and time.
266
        This option can be useful for reproducibility.
267
268
        Note that this should imply that underlying data sources (such as of deposition or publication)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (103/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
269
        are restricted by this datetime, but that is not checked.
270
271
        Examples:
272
273
            - --as-of 2021-10-11T14:12:13Z
274
            - --as-of 2021-10-11T14:12:13+14:00
275
            - --as-of 2021-10-11T14:12:13.496Z
276
            - --as-of "2021-10-11 14:12:13,496,915+14:00"
277
            - --as-of "2021-10-11 14:12:13-8:00 [America/Los_Angeles]"
278
279
        This is a subset of ISO 8601, represented as ``YYYY-mm-dd('T'|' '):hh:MM:ss(i)Z``.
280
        Precision must be nanosecond or less, and ``,`` and ``.`` are equivalent as a thousands separator.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
281
        You can provide an IANA zone name in square brackets for context, but the offset is still required.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
282
        """
0 ignored issues
show
introduced by
Using an f-string that does not have any interpolated variables
Loading history...
283
    )
284
285
    log_path = Opt.out_path(
286
        r"""
287
        Also log to a file.
288
        The suffix can be .log, .log.gz, .log.zip, or .json, .json.gz, or .json.gz.
289
        You can prefix the path with :LEVEL: to control the level. For example, ``:INFO:out.log``
290
        """,
291
        "--log",
292
        show_default=True,
293
    )
294
295
    no_setup: bool = Opt.flag(
296
        r"Skip setup, such as configuring logging.",
297
        "--no-setup",
298
        hidden=True,
299
    )
300
301
302
cli = typer.Typer()
303
304
305
@cli.command()
306
def run(
0 ignored issues
show
Coding Style Naming introduced by
Argument name "x" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
307
    path: Path = CommonArgs.dir_input,
0 ignored issues
show
Unused Code introduced by
The argument path seems to be unused.
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
308
    x=CommonArgs.log_path,
0 ignored issues
show
Unused Code introduced by
The argument x seems to be unused.
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
309
):
310
    pass
311
312
313
if __name__ == "__main__":
314
    typer.run(run)
315
316
317
__all__ = ["CommonArgs", "Arg", "Opt"]
318