|
1 |
| -""" |
2 |
| -This is a skeleton file that can serve as a starting point for a Python |
3 |
| -console script. To run this script uncomment the following lines in the |
4 |
| -``[options.entry_points]`` section in ``setup.cfg``:: |
5 |
| -
|
6 |
| - console_scripts = |
7 |
| - fibonacci = cli.skeleton:run |
8 |
| -
|
9 |
| -Then run ``pip install .`` (or ``pip install -e .`` for editable mode) |
10 |
| -which will install the command ``fibonacci`` inside your current environment. |
11 |
| -
|
12 |
| -Besides console scripts, the header (i.e. until ``_logger``...) of this file can |
13 |
| -also be used as template for Python modules. |
14 |
| -
|
15 |
| -Note: |
16 |
| - This file can be renamed depending on your needs or safely removed if not needed. |
17 |
| -
|
18 |
| -References: |
19 |
| - - https://setuptools.pypa.io/en/latest/userguide/entry_point.html |
20 |
| - - https://pip.pypa.io/en/stable/reference/pip_install |
21 |
| -""" |
22 |
| - |
23 |
| -import argparse |
24 |
| -import logging |
25 |
| -import sys |
26 |
| - |
27 |
| -from cli import __version__ |
28 |
| - |
29 |
| -__author__ = "nathfavour" |
30 |
| -__copyright__ = "nathfavour" |
31 |
| -__license__ = "MIT" |
32 |
| - |
33 |
| -_logger = logging.getLogger(__name__) |
34 |
| - |
35 |
| - |
36 |
| -# ---- Python API ---- |
37 |
| -# The functions defined in this section can be imported by users in their |
38 |
| -# Python scripts/interactive interpreter, e.g. via |
39 |
| -# `from cli.skeleton import fib`, |
40 |
| -# when using this Python module as a library. |
41 |
| - |
42 |
| - |
43 |
| -def fib(n): |
44 |
| - """Fibonacci example function |
45 |
| -
|
46 |
| - Args: |
47 |
| - n (int): integer |
48 |
| -
|
49 |
| - Returns: |
50 |
| - int: n-th Fibonacci number |
51 |
| - """ |
52 |
| - assert n > 0 |
53 |
| - a, b = 1, 1 |
54 |
| - for _i in range(n - 1): |
55 |
| - a, b = b, a + b |
56 |
| - return a |
57 |
| - |
58 |
| - |
59 |
| -# ---- CLI ---- |
60 |
| -# The functions defined in this section are wrappers around the main Python |
61 |
| -# API allowing them to be called directly from the terminal as a CLI |
62 |
| -# executable/script. |
63 |
| - |
64 |
| - |
65 |
| -def parse_args(args): |
66 |
| - """Parse command line parameters |
67 |
| -
|
68 |
| - Args: |
69 |
| - args (List[str]): command line parameters as list of strings |
70 |
| - (for example ``["--help"]``). |
71 |
| -
|
72 |
| - Returns: |
73 |
| - :obj:`argparse.Namespace`: command line parameters namespace |
74 |
| - """ |
75 |
| - parser = argparse.ArgumentParser(description="Just a Fibonacci demonstration") |
76 |
| - parser.add_argument( |
77 |
| - "--version", |
78 |
| - action="version", |
79 |
| - version=f"cli {__version__}", |
80 |
| - ) |
81 |
| - parser.add_argument(dest="n", help="n-th Fibonacci number", type=int, metavar="INT") |
82 |
| - parser.add_argument( |
83 |
| - "-v", |
84 |
| - "--verbose", |
85 |
| - dest="loglevel", |
86 |
| - help="set loglevel to INFO", |
87 |
| - action="store_const", |
88 |
| - const=logging.INFO, |
89 |
| - ) |
90 |
| - parser.add_argument( |
91 |
| - "-vv", |
92 |
| - "--very-verbose", |
93 |
| - dest="loglevel", |
94 |
| - help="set loglevel to DEBUG", |
95 |
| - action="store_const", |
96 |
| - const=logging.DEBUG, |
97 |
| - ) |
98 |
| - return parser.parse_args(args) |
99 |
| - |
100 |
| - |
101 |
| -def setup_logging(loglevel): |
102 |
| - """Setup basic logging |
103 |
| -
|
104 |
| - Args: |
105 |
| - loglevel (int): minimum loglevel for emitting messages |
106 |
| - """ |
107 |
| - logformat = "[%(asctime)s] %(levelname)s:%(name)s:%(message)s" |
108 |
| - logging.basicConfig( |
109 |
| - level=loglevel, stream=sys.stdout, format=logformat, datefmt="%Y-%m-%d %H:%M:%S" |
110 |
| - ) |
111 |
| - |
112 |
| - |
113 |
| -def main(args): |
114 |
| - """Wrapper allowing :func:`fib` to be called with string arguments in a CLI fashion |
115 |
| -
|
116 |
| - Instead of returning the value from :func:`fib`, it prints the result to the |
117 |
| - ``stdout`` in a nicely formatted message. |
118 |
| -
|
119 |
| - Args: |
120 |
| - args (List[str]): command line parameters as list of strings |
121 |
| - (for example ``["--verbose", "42"]``). |
122 |
| - """ |
123 |
| - args = parse_args(args) |
124 |
| - setup_logging(args.loglevel) |
125 |
| - _logger.debug("Starting crazy calculations...") |
126 |
| - print(f"The {args.n}-th Fibonacci number is {fib(args.n)}") |
127 |
| - _logger.info("Script ends here") |
128 |
| - |
129 |
| - |
130 |
| -def run(): |
131 |
| - """Calls :func:`main` passing the CLI arguments extracted from :obj:`sys.argv` |
132 |
| -
|
133 |
| - This function can be used as entry point to create console scripts with setuptools. |
134 |
| - """ |
135 |
| - main(sys.argv[1:]) |
136 |
| - |
137 |
| - |
138 |
| -if __name__ == "__main__": |
139 |
| - # ^ This is a guard statement that will prevent the following code from |
140 |
| - # being executed in the case someone imports this file instead of |
141 |
| - # executing it as a script. |
142 |
| - # https://docs.python.org/3/library/__main__.html |
143 |
| - |
144 |
| - # After installing your project with pip, users can also run your Python |
145 |
| - # modules as scripts via the ``-m`` flag, as defined in PEP 338:: |
146 |
| - # |
147 |
| - # python -m cli.skeleton 42 |
148 |
| - # |
149 |
| - run() |
0 commit comments