Skip to content

Commit 0cfff77

Browse files
committed
Drop of v.0.5.5
1 parent bc099af commit 0cfff77

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+4726
-1
lines changed

.flake8

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[flake8]
2+
exclude = .git,.venv,__pycache__

.vscode/settings.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"python.pythonPath": "c:\\v\\github\\microsoft\\msrc-appconfig\\.venv\\Scripts\\python.exe",
3+
"python.analysis.typeCheckingMode": "basic",
4+
"python.analysis.extraPaths": [
5+
"msrc-appconfig",
6+
"msrc-appconfig/tests",
7+
"msrc-appconfig-attrs",
8+
"msrc-appconfig-dataclasses",
9+
"msrc-appconfig-param"
10+
],
11+
"python.testing.pytestEnabled": true
12+
}

API.md

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
<!--
2+
THIS FILE HAS BEEN AUTO-GENERATED BY api_md.py
3+
-->
4+
# msrc.appconfig
5+
6+
Flexible typed application configuration.
7+
8+
| Functions | |
9+
| --- | --- |
10+
| [gather_config](#gather_config) | Gathers configuration values from files, shell and command line. |
11+
| [set_global](#set_global) | Designates the `appconfig` as global application configuration object. |
12+
| [get_global](#get_global) | Get global application configuration object. |
13+
| [from_files](#from_files) | Collects configuration values from the specified files. |
14+
| [from_environ](#from_environ) | Collects configuration values from shell variables. |
15+
| [from_argv](#from_argv) | Collects configuration values from command line arguments. |
16+
| [from_dict](#from_dict) | Instantiates configuration object from a dictionary of values. |
17+
| [to_dict](#to_dict) | Extracts data from a configuration object. |
18+
| [optional_file](#optional_file) | Returns a list with the file `Path` if the file exists. |
19+
| [script_config_file](#script_config_file) | Returns a list with the default script configuration file. |
20+
| [config_files_in_parents](#config_files_in_parents) | Returns a list of configuration files in parent directories. |
21+
| [to_arg_dict](#to_arg_dict) | Generates a dictionary of cmdline options to reproduce the instance. |
22+
| [to_argv](#to_argv) | Generates a flat list of cmdline options to reproduce the instance. |
23+
24+
## gather_config
25+
```python
26+
def msrc.appconfig.gather_config(
27+
config_type: Type[~AppConfig],
28+
override_defaults: Mapping[str, Union[str, Tuple[str, ...], List[str], int, Tuple[int, ...], List[int], float, Tuple[float, ...], List[float], bool, Tuple[bool, ...], List[bool], enum.Enum, Tuple[enum.Enum, ...], List[enum.Enum], Mapping[str, object]]] = {},
29+
config_files: Sequence[Union[str, os.PathLike]] = [],
30+
env_var_prefix: Union[str, NoneType] = None,
31+
argv: Union[Sequence[str], NoneType] = None,
32+
arg_aliases: Mapping[str, str] = {},
33+
set_global: bool = False,
34+
log_level: int = 20,
35+
) -> ~AppConfig
36+
```
37+
Gathers configuration values from files, shell and command line.
38+
39+
The function is a main tool to build application configuration object
40+
for a script.
41+
42+
`config_type` is the only required argument. Must be is a class object.
43+
The `config_type` can be a `typing.NamedTuple` or a class supported by
44+
one of the package extensions.
45+
46+
`override_defaults` is a mapping that allows to override the defaults
47+
in the `config_type` class.
48+
49+
`config_files` is a sequence of configuration file paths, strings
50+
or `PathLike` objects. The function reads the files in sequence.
51+
See also utility functions that help build the list for certain
52+
use cases: `script_config_file()`, `config_files_in_parents()`,
53+
`optional_file()`.
54+
See also `-c` command line option below.
55+
56+
`env_var_prefix` is a prefix to look for shell environment variables
57+
that override configuration values. The default is main script file name
58+
followed by underscore. For example, if you run a script in `script.py`
59+
then by default environment variables `SCRIPT_<config-element>=<value>`
60+
override values from `config_type` class, `override_defaults` mapping
61+
and configuration files.
62+
See also `-e` command line option below.
63+
64+
`argv` is an optional list of command line arguments to be used instead
65+
of `sys.argv`.
66+
67+
`arg_aliases` is a mapping `{short_option: long_option}`, where
68+
`short_option` must be a string of length one, and `long_option` can be
69+
a configuration element path. E.g. `arg_aliases=dict(b="foo.bar")`
70+
allows to use `-b` option as an alias of `--foo.bar` option to set the
71+
`config.foo.bar` value with command line arguments. `arg_aliases` override
72+
the built-in short options (see below).
73+
74+
`set_global` allows to set up global application configuration object.
75+
The default value is `False`. See `set_global()` function for details.
76+
77+
`log_level` sets logging level for the package. The default is `INFO`.
78+
To log more details set `log_level` to `DEBUG`, to reduce the amount of
79+
logging set `log_level` to `WARN` or `ERROR`. Set it to `NOTSET`to prevent
80+
setting up the logging system by the package: `log_level=logging.NOTSET`.
81+
See also `-l` command line option below.
82+
83+
The function uses standard argparser module to parse command line
84+
arguments. Four options amend configuration process, others override
85+
configuration values obtained from other sources.
86+
`-h [ELEMENT]` option prints general help or description of a
87+
confuguration element.
88+
`-l LEVEL|FILE` option sets up logging level overriding `log_level`
89+
argument. If file path is provided instead, the `logging.fileConfig()`
90+
function is called.
91+
`-c FILE ...` option specifies which configuration files to read. The files
92+
are appended to the list given in `config_files` argument`.
93+
See `msrc.config_type.read_files.from_file` function for details.
94+
`-e PREFIX` option overrides a prefix for environment variables to look up.
95+
See `msrc.config_type.read_environ.from_environ function for details.
96+
97+
To prevent looking up shell variables set `env_var_prefix` to `"-"`.
98+
To prevent reading from `sys.argv` set `argv` to `()`.
99+
To prevent setting up logging set `log_level` to `logging.NOTSET` value.
100+
101+
If `set_global==True`, sets up the collected configuration as
102+
a global object for current process. The shared object is easily accessible
103+
in other modules with `get_global()` function.
104+
105+
Returns the collected configuration.
106+
107+
## set_global
108+
```python
109+
def msrc.appconfig.set_global(
110+
appconfig: ~AppConfig,
111+
) -> None
112+
```
113+
Designates the `appconfig` as global application configuration object.
114+
115+
The configuration becomes available with 'get_global()' throughout the
116+
application code base. Must be called only once per process.
117+
118+
Raises `RuntimeError` if a configuration has already been set up.
119+
Meant to be used primarily behind `if __name__=="__main__"` guards.
120+
121+
Raises `TypeError` if type of appconfig is not a valid configuration
122+
schema.
123+
124+
## get_global
125+
```python
126+
def msrc.appconfig.get_global(
127+
appconfig: Type[~AppConfig],
128+
default: Union[~AppConfig, NoneType] = None,
129+
) -> ~AppConfig
130+
```
131+
Get global application configuration object.
132+
133+
`appconfig` must be a type. `appconfig` argument ensures an object
134+
returned by the function is an instance of this type, or `ValueError`
135+
is raised.
136+
137+
`default` object must be an instance of `appconfig` type. The function
138+
returns `default` if no global application configuration has been set up.
139+
140+
Raises `RuntimeError` if no global application configuration has been
141+
set up by `set_global()` or `gather_config(set_global=True)` and
142+
the `default` is `None`.
143+
144+
For example, if `AppConfig` is an appconfig schema where all elements
145+
have default values, then the following line never raises `RuntimeError`:
146+
```python
147+
value = msrc.appconfig.get_global(AppConfig, AppConfig()).parameter
148+
```
149+
In contrast this line:
150+
```python
151+
value = msrc.appconfig.get_global(AppConfig).parameter
152+
```
153+
raises `RuntimeError` if global configuration hasn't been set up.
154+
The following code never raises exceptions and can be used to safely
155+
check for a generic configuration:
156+
```python
157+
cfg_none = object()
158+
cfg = msrc.appconfig.get_global(object, cfg_none)
159+
if cfg is cfg_none:
160+
...
161+
```
162+
163+
## from_files
164+
```python
165+
def msrc.appconfig.from_files(
166+
config_schema: Type,
167+
files: Union[str, os.PathLike],
168+
) -> Mapping[str, Union[str, Tuple[str, ...], List[str], int, Tuple[int, ...], List[int], float, Tuple[float, ...], List[float], bool, Tuple[bool, ...], List[bool], enum.Enum, Tuple[enum.Enum, ...], List[enum.Enum], Mapping[str, object]]]
169+
```
170+
Collects configuration values from the specified files.
171+
172+
Accepts files with the following extensions: .ini, .json, .yaml, .yml.
173+
Given a file with a different extension, tries to look up a file
174+
with the same name and one of recognized extensions.
175+
176+
Each .json or .yaml/.yml file must represent a JSON or YAML dictionary.
177+
The function ignores keys that are not in schema.
178+
A special key '_include' may contain a path or a list of paths to read.
179+
The function reads included files before processing the rest of the keys,
180+
i.e. values in the file may override values from included files.
181+
182+
In case the same key is present in multiple files, the resulting dictionary
183+
contains a value from the last file.
184+
185+
## from_environ
186+
```python
187+
def msrc.appconfig.from_environ(
188+
config_schema: Type,
189+
env_var_prefix: str = '',
190+
) -> Mapping[str, Union[str, Tuple[str, ...], List[str], int, Tuple[int, ...], List[int], float, Tuple[float, ...], List[float], bool, Tuple[bool, ...], List[bool], enum.Enum, Tuple[enum.Enum, ...], List[enum.Enum], Mapping[str, object]]]
191+
```
192+
Collects configuration values from shell variables.
193+
194+
For a configuration element <element_name> takes value from an environment
195+
variable <env_var_prefix><element_name> if one exists.
196+
197+
## from_argv
198+
```python
199+
def msrc.appconfig.from_argv(
200+
config_schema: Type,
201+
argv: Sequence[str],
202+
arg_aliases: Mapping[str, str] = {},
203+
) -> Mapping[str, Union[str, Tuple[str, ...], List[str], int, Tuple[int, ...], List[int], float, Tuple[float, ...], List[float], bool, Tuple[bool, ...], List[bool], enum.Enum, Tuple[enum.Enum, ...], List[enum.Enum], Mapping[str, object]]]
204+
```
205+
Collects configuration values from command line arguments.
206+
207+
The function employs standard module argparse to parse arguments.
208+
If a configuration element has underscores in its name the option may use
209+
either underscores or dashes.
210+
211+
The optional `arg_aliases` argument allows to add short options to the
212+
command line interface. Aliases key must be a configuration element name,
213+
and corresponding value must be a single letter of the short option.
214+
215+
Unrecognized `argv` elements, if any, are under `_unknown_args` key in
216+
the returned mapping.
217+
218+
## from_dict
219+
```python
220+
def msrc.appconfig.from_dict(
221+
config_schema: Type[~AppConfig],
222+
data: Mapping[str, Union[str, Tuple[str, ...], List[str], int, Tuple[int, ...], List[int], float, Tuple[float, ...], List[float], bool, Tuple[bool, ...], List[bool], enum.Enum, Tuple[enum.Enum, ...], List[enum.Enum], Mapping[str, object]]],
223+
) -> ~AppConfig
224+
```
225+
Instantiates configuration object from a dictionary of values.
226+
227+
## to_dict
228+
```python
229+
def msrc.appconfig.to_dict(
230+
instance: ~AppConfig,
231+
include_defaults: bool = False,
232+
) -> Mapping[str, Union[str, Tuple[str, ...], List[str], int, Tuple[int, ...], List[int], float, Tuple[float, ...], List[float], bool, Tuple[bool, ...], List[bool], enum.Enum, Tuple[enum.Enum, ...], List[enum.Enum], Mapping[str, object]]]
233+
```
234+
Extracts data from a configuration object.
235+
236+
Returns a nested dictionary of configuration values.
237+
238+
When `include_defaults` is False (the default value) the resulting
239+
dictionary doesn't contain elements with built-in default values.
240+
241+
## optional_file
242+
```python
243+
def msrc.appconfig.optional_file(
244+
file_path: Union[str, os.PathLike],
245+
) -> List[pathlib.Path]
246+
```
247+
Returns a list with the file `Path` if the file exists.
248+
249+
Returns an empty list if `file_path` doesn't reference an existing file.
250+
251+
Useful to build a list of configuration files, e.g.:
252+
```python
253+
cfg = gather_config(
254+
AppConfig,
255+
config_files=optional_file('config.yml')
256+
)
257+
```
258+
259+
## script_config_file
260+
```python
261+
def msrc.appconfig.script_config_file(
262+
ext: Union[str, NoneType] = None,
263+
) -> List[pathlib.Path]
264+
```
265+
Returns a list with the default script configuration file.
266+
267+
`ext` is an optional configuration file extension. Must be one of
268+
supported extensions. If `ext` not specified, the function tries
269+
all supported extensions.
270+
271+
A default configuration file has a name of a main script file or
272+
a package name if a package is being run. The function lookes for
273+
the file in the main script directory, or in current directory if
274+
a package is being run.
275+
276+
Useful to build a list of configuration files, e.g.:
277+
```python
278+
cfg = gather_config(
279+
AppConfig,
280+
config_files=script_config_file('.yml')
281+
)
282+
```
283+
284+
## config_files_in_parents
285+
```python
286+
def msrc.appconfig.config_files_in_parents(
287+
file_name: str,
288+
base_path: Union[NoneType, str, pathlib.Path] = None,
289+
) -> List[pathlib.Path]
290+
```
291+
Returns a list of configuration files in parent directories.
292+
293+
`file_name` must be a file name with one of supported extensions.
294+
295+
`base_path` is an optional final path. The default is main script
296+
directory, or current directory if a package is being run.
297+
298+
Returns a list of all files found along the `base_path` starting
299+
from the root.
300+
301+
Useful to build a list of configuration files, e.g.:
302+
```python
303+
cfg = gather_config(
304+
AppConfig,
305+
config_files=config_files_in_parents('config.yml')
306+
)
307+
```
308+
309+
## to_arg_dict
310+
```python
311+
def msrc.appconfig.to_arg_dict(
312+
instance: ~AppConfig,
313+
) -> Dict[str, Union[str, Tuple[str, ...]]]
314+
```
315+
Generates a dictionary of cmdline options to reproduce the instance.
316+
317+
## to_argv
318+
```python
319+
def msrc.appconfig.to_argv(
320+
instance: ~AppConfig,
321+
) -> List[str]
322+
```
323+
Generates a flat list of cmdline options to reproduce the instance.

CONTRIBUTING.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Contributing
2+
3+
Welcome and thank you for your interest
4+
in contributing to `one-appconfig`! Before contributing to this
5+
project, please review this document for policies and procedures which
6+
will ease the contribution and review process for everyone. If you have
7+
questions, please contact Vassily Lyutsarev vassilyl@microsoft.com. This project adopted
8+
[Inner Source model](http://aka.ms/innersource).
9+
10+
## Issues and Feature Requests
11+
12+
Issues, bugs and proposed new features should be submitted to our [backlog](https://msrcambridge.visualstudio.com/One/_backlogs/backlog/msrc-appconfig/Issues/). The project uses [Basic process](https://docs.microsoft.com/en-us/azure/devops/boards/get-started/plan-track-work?view=azure-devops&tabs=basic-process) which assumes your input is filed
13+
as an _Issue_. You may also tag the issue with a Bug tag which is optional. Please specify in detail the versions of python and msrc-appconfig package, and a detailed repro for the issue.
14+
15+
## Style Guidelines
16+
17+
The project has adopted [PEP 8](https://www.python.org/dev/peps/pep-0008/) style for code.
18+
We use [flake8](https://pypi.org/project/flake8/) with default options to lint the code.
19+
Additionally, the [mypy](http://www.mypy-lang.org/) static type checker must run without issues on the code.
20+
21+
## Pull Request Process
22+
23+
1. Prepare your changes in a branch named `<your-alias>/<short-feature-description>`.
24+
Alternativly, you may create your personal
25+
[fork](https://docs.microsoft.com/en-us/azure/devops/repos/git/forks?view=azure-devops)
26+
of the repository in Forks project.
27+
1. All new code must come with corresponding [pytest](https://docs.pytest.org/en/latest/) tests. Keep code coverage at 100%.
28+
1. Ensure CI build is successful and tests, including any added or updated tests, pass prior to submitting the pull request.
29+
1. Update any documentation, user and contributor, that is impacted by your changes.
30+
1. Do not change the version number in VERSION.txt.
31+
1. Do not merge your pull request, this is the responsibility of a core developer.
32+
33+
## License Information
34+
35+
The project can be used for Microsoft internal purposes without any limitation.
36+
To use the package outside of Microsoft contact Vassily Lyutsarev vassilyl@microsoft.com.

0 commit comments

Comments
 (0)