Skip to content

Commit 3ce7318

Browse files
committed
Add example of how to combine configparser and argparse
1 parent 66f94d6 commit 3ce7318

File tree

5 files changed

+85
-0
lines changed

5 files changed

+85
-0
lines changed

Diff for: source-code/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ to create it. There is some material not covered in the presentation as well.
1818

1919
## What is it?
2020

21+
1. `application`: illustration of how to combine `configparser` and `argparse`.
2122
1. `cmd`: illustration of how to create a repl application.
2223
1. `code-evaluation`: illustrates how to evaluate a string containing
2324
Python code at runtime.

Diff for: source-code/application/README.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Application
2+
3+
Example of a very simple application that prints random integers between
4+
two given values. It uses argparse and configparser to handle configuration
5+
files and command line arguments.
6+
7+
The parameters are
8+
* `n`: the number of random values to generate,
9+
* `a`: the smallest value to generate, and
10+
* `b`: the largest value to generate.
11+
12+
The point is to illustrate specifying the parameters via
13+
1. defaults in the application, `n = 1`, `a = 0`, `b = 6`,
14+
1. a "system" configuration file, `etc/my_app.conf`, `n = 2`, `a = 1`, `b = 6`,
15+
1. optionally, a configurtion file specified as a command line option, i.e.,
16+
`--conf my_app.conf`, `n = 3`, `a = 2`,
17+
1. command line options.
18+
19+
## What is it?
20+
1. `my_apps.py`: Python script to print random integer values.
21+
1. `etc/my_app.conf`: "system" level configuration file.
22+
1. `my_app.conf`: optional "user" level configuration file.

Diff for: source-code/application/etc/my_app.conf

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[defaults]
2+
n = 2
3+
a = 1
4+
b = 6

Diff for: source-code/application/my_app.conf

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[defaults]
2+
n = 3
3+
a = 2

Diff for: source-code/application/my_app.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#!/usr/bin/env python
2+
3+
from argparse import ArgumentParser
4+
from configparser import ConfigParser
5+
from pathlib import Path
6+
import random
7+
import sys
8+
9+
10+
def generate_data(n, a=0, b=1):
11+
return [random.randint(a, b) for _ in range(n)]
12+
13+
def main():
14+
arg_parser = ArgumentParser(description='test application')
15+
arg_parser.add_argument('--conf',
16+
help='configuration file to use')
17+
arg_parser.add_argument('--verbose', action='store_true',
18+
help='verbose output')
19+
options, remaining_options = arg_parser.parse_known_args()
20+
system_conf = Path.cwd() / 'etc' / 'my_app.conf'
21+
cfg = ConfigParser()
22+
cfg['defaults'] = {'n': '1', 'a': '0', 'b': '6'}
23+
if options.verbose:
24+
print('application default values:', file=sys.stderr)
25+
cfg.write(sys.stderr)
26+
if system_conf.exists():
27+
cfg.read('etc/my_app.conf')
28+
if options.verbose:
29+
print('system configuration file values:', file=sys.stderr)
30+
cfg.write(sys.stderr)
31+
else:
32+
print(f'missing configuration file {system_conf}', file=sys.stderr)
33+
if options.conf:
34+
cfg.read(options.conf)
35+
if options.verbose:
36+
print('user configuration file values:', file=sys.stderr)
37+
cfg.write(sys.stderr)
38+
cfg_opts = dict(cfg['defaults'])
39+
arg_parser.set_defaults(**cfg_opts)
40+
arg_parser.add_argument('n', type=int, nargs='?',
41+
help='number of random values to generate')
42+
arg_parser.add_argument('--a', type=int, help='smallest value')
43+
arg_parser.add_argument('--b', type=int, help='largest value')
44+
arg_parser.parse_args(remaining_options, options)
45+
if options.verbose:
46+
print('final options:', file=sys.stderr)
47+
print(f'n = {options.n}\na = {options.a}\nb = {options.b}', end='\n\n',
48+
file=sys.stderr)
49+
values = generate_data(options.n, a=options.a, b=options.b)
50+
print('\n'.join(str(value) for value in values))
51+
return 0
52+
53+
if __name__ == '__main__':
54+
status = main()
55+
sys.exit(status)

0 commit comments

Comments
 (0)